From bb9ae344122229a04d22d779c190af424e5dabf8 Mon Sep 17 00:00:00 2001 From: PopcornFX Bot Date: Tue, 16 Apr 2024 16:40:26 +0200 Subject: [PATCH] PopcornFX Plugin v2.19.1 --- .github/workflows/draft-release.yml | 30 + AE.code-workspace | 65 + .../Include/AEAttribute_Main.h | 39 + .../Include/AEAttribute_ParamDefine.h | 58 + .../Include/AEAttribute_PluginInterface.h | 99 + .../Include/AEAttribute_SequenceData.h | 52 + AE_Effect_Attribute/PkgInfo | 1 + .../Precompiled/ae_precompiled.cpp | 1 + .../Precompiled/ae_precompiled.h | 13 + .../Sources/AEAttribute_Main.cpp | 172 + .../Sources/AEAttribute_ParamDefine.cpp | 66 + .../Sources/AEAttribute_PluginInterface.cpp | 928 ++ .../Sources/AEAttribute_SequenceData.cpp | 59 + .../AE_Effect_Attribute.plugin-Info.plist | 24 + .../Sources/AE_Effect_Attribute_PiPL.r | 73 + .../Include/AEAttributeSampler_Main.h | 39 + .../Include/AEAttributeSampler_ParamDefine.h | 105 + .../AEAttributeSampler_PluginInterface.h | 107 + .../Include/AEAttributeSampler_SequenceData.h | 52 + AE_Effect_AttributeSampler/PkgInfo | 1 + .../Precompiled/ae_precompiled.cpp | 1 + .../Precompiled/ae_precompiled.h | 8 + .../Sources/AEAttributeSampler_Main.cpp | 170 + .../AEAttributeSampler_ParamDefine.cpp | 169 + .../AEAttributeSampler_PluginInterface.cpp | 780 ++ .../AEAttributeSampler_SequenceData.cpp | 59 + ..._Effect_AttributeSampler.plugin-Info.plist | 24 + .../Sources/AE_Effect_AttributeSampler_PiPL.r | 73 + AE_Effect_Emitter/Include/AEEffect_Main.h | 39 + .../Include/AEEffect_ParamDefine.h | 149 + .../Include/AEEffect_PluginInterface.h | 98 + .../Include/AEEffect_SequenceData.h | 65 + AE_Effect_Emitter/PkgInfo | 1 + .../Precompiled/ae_precompiled.cpp | 1 + .../Precompiled/ae_precompiled.h | 8 + AE_Effect_Emitter/Sources/AEEffect_Main.cpp | 169 + .../Sources/AEEffect_ParamDefine.cpp | 155 + .../Sources/AEEffect_PluginInterface.cpp | 1304 +++ .../Sources/AEEffect_SequenceData.cpp | 88 + .../AE_Effect_Emitter.plugin-Info.plist | 24 + .../Sources/AE_Effect_Emitter_PiPL.r | 73 + AE_GeneralPlugin/GeneralPlugin.manifest | 15 + .../Include/AEGP_AEPKConversion.h | 77 + AE_GeneralPlugin/Include/AEGP_AssetBaker.h | 222 + AE_GeneralPlugin/Include/AEGP_Attribute.h | 216 + AE_GeneralPlugin/Include/AEGP_Define.h | 41 + AE_GeneralPlugin/Include/AEGP_FileDialog.h | 82 + AE_GeneralPlugin/Include/AEGP_FileDialogMac.h | 23 + AE_GeneralPlugin/Include/AEGP_FileWatcher.h | 43 + .../Include/AEGP_FrameCollector.h | 46 + AE_GeneralPlugin/Include/AEGP_LayerHolder.h | 152 + AE_GeneralPlugin/Include/AEGP_Log.h | 51 + AE_GeneralPlugin/Include/AEGP_Main.h | 30 + AE_GeneralPlugin/Include/AEGP_PackExplorer.h | 61 + AE_GeneralPlugin/Include/AEGP_ParticleScene.h | 54 + .../Include/AEGP_PopcornFXPlugins.h | 55 + AE_GeneralPlugin/Include/AEGP_RenderContext.h | 120 + AE_GeneralPlugin/Include/AEGP_Scene.h | 316 + AE_GeneralPlugin/Include/AEGP_SkinnedMesh.h | 122 + .../Include/AEGP_SkinnedMeshInstance.h | 82 + AE_GeneralPlugin/Include/AEGP_System.h | 60 + AE_GeneralPlugin/Include/AEGP_UpdateAEState.h | 90 + AE_GeneralPlugin/Include/AEGP_VaultHandler.h | 99 + AE_GeneralPlugin/Include/AEGP_WinFileDialog.h | 111 + AE_GeneralPlugin/Include/AEGP_WinSystem.h | 34 + AE_GeneralPlugin/Include/AEGP_World.h | 322 + .../Panels/AEGP_GraphicalResourcesTreeModel.h | 163 + .../Include/Panels/AEGP_PanelQT.h | 201 + .../Include/RenderApi/AEGP_BaseContext.h | 68 + .../Include/RenderApi/AEGP_CopyPixels.h | 45 + .../Include/RenderApi/AEGP_CopyTask.h | 70 + .../Include/RenderApi/AEGP_D3D11Context.h | 77 + .../Include/RenderApi/AEGP_D3D12Context.h | 105 + .../Include/RenderApi/AEGP_MetalContext.h | 90 + AE_GeneralPlugin/PkgInfo | 1 + .../Precompiled/ae_precompiled.cpp | 1 + AE_GeneralPlugin/Precompiled/ae_precompiled.h | 28 + .../Sources/AEGP_AEPKConversion.cpp | 492 + AE_GeneralPlugin/Sources/AEGP_AssetBaker.cpp | 799 ++ AE_GeneralPlugin/Sources/AEGP_Attribute.cpp | 758 ++ AE_GeneralPlugin/Sources/AEGP_FileDialog.cpp | 107 + .../Sources/AEGP_FileDialogMac.mm | 66 + AE_GeneralPlugin/Sources/AEGP_FileWatcher.cpp | 113 + .../Sources/AEGP_FrameCollector.cpp | 45 + AE_GeneralPlugin/Sources/AEGP_LayerHolder.cpp | 155 + AE_GeneralPlugin/Sources/AEGP_Log.cpp | 108 + AE_GeneralPlugin/Sources/AEGP_Main.cpp | 475 + .../Sources/AEGP_PackExplorer.cpp | 124 + .../Sources/AEGP_ParticleScene.cpp | 134 + .../Sources/AEGP_PopcornFXPlugins.cpp | 282 + .../Sources/AEGP_RenderContext.cpp | 703 ++ AE_GeneralPlugin/Sources/AEGP_Scene.cpp | 2057 ++++ AE_GeneralPlugin/Sources/AEGP_SkinnedMesh.cpp | 451 + .../Sources/AEGP_SkinnedMeshInstance.cpp | 261 + AE_GeneralPlugin/Sources/AEGP_System.cpp | 276 + .../Sources/AEGP_UpdateAEState.cpp | 1233 +++ .../Sources/AEGP_VaultHandler.cpp | 492 + .../Sources/AEGP_WinFileDialog.cpp | 183 + AE_GeneralPlugin/Sources/AEGP_WinSystem.cpp | 216 + AE_GeneralPlugin/Sources/AEGP_World.cpp | 2674 +++++ .../AE_GeneralPlugin.plugin-Info.plist | 24 + .../Sources/AE_GeneralPlugin_PiPL.r | 41 + .../AEGP_GraphicalResourcesTreeModel.cpp | 931 ++ .../Sources/Panels/AEGP_PanelQT.cpp | 736 ++ .../Sources/RenderApi/AEGP_BaseContext.cpp | 54 + .../Sources/RenderApi/AEGP_CopyPixels.cpp | 193 + .../Sources/RenderApi/AEGP_D3D11Context.cpp | 506 + .../Sources/RenderApi/AEGP_D3D12Context.cpp | 712 ++ .../Sources/RenderApi/AEGP_MetalContext.mm | 188 + AE_Suites/PopcornFX_BasePluginInterface.h | 293 + AE_Suites/PopcornFX_Define.h | 90 + AE_Suites/PopcornFX_Define_Version.h | 9 + AE_Suites/PopcornFX_Suite.h | 1407 +++ AE_Suites/PopcornFX_UID.h | 67 + CopyQTDllsForAE.py | 105 + External/AE SDK/Headers/A.h | 196 + External/AE SDK/Headers/AEConfig.h | 102 + External/AE SDK/Headers/AEFX_ArbParseHelper.c | 171 + External/AE SDK/Headers/AEFX_ArbParseHelper.h | 75 + .../AE SDK/Headers/AEFX_ChannelDepthTpl.h | 59 + .../Headers/AEFX_SuiteHandlerTemplate.h | 63 + External/AE SDK/Headers/AEFX_SuiteHelper.c | 139 + External/AE SDK/Headers/AEFX_SuiteHelper.h | 157 + External/AE SDK/Headers/AEGP_SuiteHandler.cpp | 66 + External/AE SDK/Headers/AEGP_SuiteHandler.h | 601 ++ External/AE SDK/Headers/AEGP_Utils.cpp | 37 + External/AE SDK/Headers/AEGP_Utils.h | 9 + External/AE SDK/Headers/AE_AdvEffectSuites.h | 343 + External/AE SDK/Headers/AE_CacheOnLoadSuite.h | 39 + External/AE SDK/Headers/AE_ChannelSuites.h | 509 + .../AE SDK/Headers/AE_ComputeCacheSuite.h | 175 + External/AE SDK/Headers/AE_CreatorInfo.h | 1 + External/AE SDK/Headers/AE_Effect.h | 3049 ++++++ External/AE SDK/Headers/AE_EffectCB.h | 1223 +++ External/AE SDK/Headers/AE_EffectCBSuites.h | 914 ++ External/AE SDK/Headers/AE_EffectGPUSuites.h | 221 + .../AE SDK/Headers/AE_EffectPixelFormat.h | 110 + External/AE SDK/Headers/AE_EffectSuites.h | 728 ++ .../AE SDK/Headers/AE_EffectSuitesHelper.h | 152 + External/AE SDK/Headers/AE_EffectSuitesOld.h | 283 + External/AE SDK/Headers/AE_EffectUI.h | 580 ++ External/AE SDK/Headers/AE_EffectVers.h | 17 + External/AE SDK/Headers/AE_GeneralPlug.h | 5779 +++++++++++ External/AE SDK/Headers/AE_GeneralPlugOld.h | 9125 +++++++++++++++++ .../AE SDK/Headers/AE_GeneralPlugPanels.h | 134 + External/AE SDK/Headers/AE_GeneralPlugPost.h | 16 + External/AE SDK/Headers/AE_GeneralPlugPre.h | 15 + External/AE SDK/Headers/AE_HashSuite.h | 52 + External/AE SDK/Headers/AE_Hook.h | 155 + External/AE SDK/Headers/AE_IO.h | 789 ++ External/AE SDK/Headers/AE_IO_FileExt.h | 32 + External/AE SDK/Headers/AE_Macros.h | 102 + External/AE SDK/Headers/AE_PluginData.h | 84 + External/AE SDK/Headers/DuckSuite.h | 13 + External/AE SDK/Headers/FIEL_Public.h | 81 + External/AE SDK/Headers/Mach-O_prefix.h | 1 + External/AE SDK/Headers/MissingSuiteError.cpp | 43 + External/AE SDK/Headers/PF_Masks.h | 49 + External/AE SDK/Headers/PR_Public.h | 424 + External/AE SDK/Headers/PT_Public.h | 120 + External/AE SDK/Headers/Param_Utils.h | 343 + External/AE SDK/Headers/PrSDKAESupport.h | 547 + External/AE SDK/Headers/PrSDKPixelFormat.h | 160 + External/AE SDK/Headers/SP/PSIntTypes.h | 79 + External/AE SDK/Headers/SP/SPAccess.h | 387 + External/AE SDK/Headers/SP/SPAdapts.h | 406 + External/AE SDK/Headers/SP/SPBasic.h | 184 + External/AE SDK/Headers/SP/SPBckDbg.h | 118 + External/AE SDK/Headers/SP/SPBlocks.h | 118 + External/AE SDK/Headers/SP/SPCOM.h | 9 + External/AE SDK/Headers/SP/SPCaches.h | 128 + External/AE SDK/Headers/SP/SPConfig.h | 76 + External/AE SDK/Headers/SP/SPEDebug.c | 2 + External/AE SDK/Headers/SP/SPErrorCodes.h | 172 + External/AE SDK/Headers/SP/SPErrors.h | 34 + External/AE SDK/Headers/SP/SPFiles.h | 511 + External/AE SDK/Headers/SP/SPHost.h | 176 + External/AE SDK/Headers/SP/SPInterf.h | 180 + External/AE SDK/Headers/SP/SPMData.h | 66 + External/AE SDK/Headers/SP/SPObject.h | 15 + External/AE SDK/Headers/SP/SPPiPL.h | 302 + External/AE SDK/Headers/SP/SPPlugs.h | 631 ++ External/AE SDK/Headers/SP/SPProps.h | 316 + External/AE SDK/Headers/SP/SPRuntme.h | 500 + External/AE SDK/Headers/SP/SPSTSPrp.h | 52 + External/AE SDK/Headers/SP/SPStrngs.h | 132 + External/AE SDK/Headers/SP/SPSuites.h | 284 + External/AE SDK/Headers/SP/SPTypes.h | 175 + .../Headers/SP/artemis/config/platform.hpp | 114 + .../Headers/SP/photoshop/config/platform.hpp | 95 + External/AE SDK/Headers/Smart_Utils.cpp | 62 + External/AE SDK/Headers/Smart_Utils.h | 34 + External/AE SDK/Headers/String_Utils.c | 6 + External/AE SDK/Headers/String_Utils.h | 48 + External/AE SDK/Headers/SuiteHelper.h | 97 + .../AE SDK/Headers/adobesdk/DrawbotSuite.h | 660 ++ .../Headers/adobesdk/config/AdobesdkTypes.h | 54 + .../Headers/adobesdk/config/PostConfig.h | 2 + .../Headers/adobesdk/config/PreConfig.h | 23 + .../adobesdk/drawbotsuite/DrawbotSuiteTypes.h | 148 + External/AE SDK/Headers/entry.h | 53 + External/AE SDK/Resources/AE_General.r | 548 + External/AE SDK/Resources/Mach-O_prefix.h | 1 + External/AE SDK/Resources/PiPLtool.exe | 3 + External/AE SDK/Util/AEFX_ArbParseHelper.c | 174 + External/AE SDK/Util/AEFX_ArbParseHelper.h | 75 + External/AE SDK/Util/AEFX_ChannelDepthTpl.h | 59 + External/AE SDK/Util/AEFX_SuiteHelper.c | 139 + External/AE SDK/Util/AEFX_SuiteHelper.h | 157 + External/AE SDK/Util/AEGP_SuiteHandler.cpp | 66 + External/AE SDK/Util/AEGP_SuiteHandler.h | 601 ++ External/AE SDK/Util/AEGP_Utils.cpp | 38 + External/AE SDK/Util/AEGP_Utils.h | 9 + External/AE SDK/Util/DuckSuite.h | 13 + External/AE SDK/Util/MissingSuiteError.cpp | 43 + External/AE SDK/Util/Param_Utils.h | 343 + External/AE SDK/Util/Smart_Utils.cpp | 62 + External/AE SDK/Util/Smart_Utils.h | 34 + External/AE SDK/Util/String_Utils.h | 48 + External/AE SDK/Util/entry.h | 53 + External/popcornfx.qt/Qt5Core.dll | 3 + External/popcornfx.qt/Qt5Gui.dll | 3 + External/popcornfx.qt/Qt5Widgets.dll | 3 + External/popcornfx.qt/popcornfx.qt.manifest | 9 + External/popcornfx.qt/qwindows.dll | 3 + Native/debugger/PopcornFX.natvis | 409 + Native/debugger/qt5.natvis | 683 ++ PopcornFX/CHANGELOG.md | 3 + PopcornFX/LICENSE.md | 14 + PopcornFX/PK-ShaderTool_r.exe | 3 + .../PopcornFXInternals/Meshes/default.pkmm | 3 + ....0C443080A9914F8E3821857B39F3B3F6.metallib | Bin 0 -> 69574 bytes ....comp.3C55D2DBBDE67D3B05E91E33AA424D4A.cso | Bin 0 -> 32052 bytes ...p.3C55D2DBBDE67D3B05E91E33AA424D4A.cso.pdb | 3 + ....frag.3777E0C4C3850AF4730B699288C64A32.cso | Bin 0 -> 20372 bytes ...g.3777E0C4C3850AF4730B699288C64A32.cso.pdb | 3 + ....DBCFC7E098405CD8ABAFBFE666F38717.metallib | Bin 0 -> 68478 bytes ....frag.1CFFFE56845EBA06EDCF9E5C8278FEE3.cso | Bin 0 -> 24300 bytes ...g.1CFFFE56845EBA06EDCF9E5C8278FEE3.cso.pdb | 3 + ....C5813AF3B0DA61049FC61318A52A0039.metallib | Bin 0 -> 67730 bytes ....08B780C3B4A4A9B95239BE4725C155E3.metallib | Bin 0 -> 68274 bytes ....2BF4FFEBF18FD2317E7196CCB179BBD1.metallib | Bin 0 -> 68114 bytes ....comp.ACF5EA8A26A387527C94AE3CADBEEFE0.cso | Bin 0 -> 17656 bytes ...p.ACF5EA8A26A387527C94AE3CADBEEFE0.cso.pdb | 3 + ....comp.FADA9FB998752BB17F58A80A5F9E1569.cso | Bin 0 -> 20892 bytes ...p.FADA9FB998752BB17F58A80A5F9E1569.cso.pdb | 3 + ....12DC1B81F40BCA0B86B8977219474DA2.metallib | Bin 0 -> 67818 bytes ....comp.227B4305DA369E84D660CF7D0F95A7B1.cso | Bin 0 -> 19552 bytes ...p.227B4305DA369E84D660CF7D0F95A7B1.cso.pdb | 3 + ....comp.3041E5075421B7BEDB64891F34806B09.cso | Bin 0 -> 20104 bytes ...p.3041E5075421B7BEDB64891F34806B09.cso.pdb | 3 + ....3F9F670175C1E9A2721D86BF200E8992.metallib | Bin 0 -> 68042 bytes ....47AFC4B8F363592BAB2CB2B7450DC6CB.metallib | Bin 0 -> 66746 bytes ....comp.68D7368ADF463DA7672D728718850C05.cso | Bin 0 -> 19704 bytes ...p.68D7368ADF463DA7672D728718850C05.cso.pdb | 3 + ....comp.ADF077D22B698F0058CD269AB3B307F6.cso | Bin 0 -> 17168 bytes ...p.ADF077D22B698F0058CD269AB3B307F6.cso.pdb | 3 + ....E6559EF41DF4A3259DE7762E070648DE.metallib | Bin 0 -> 67050 bytes ....4FB8AAE1AE744B6A08826A79EB921BC5.metallib | Bin 0 -> 68134 bytes ....comp.B71DE41E8684A6AE211AB8D5CC66868D.cso | Bin 0 -> 22496 bytes ...p.B71DE41E8684A6AE211AB8D5CC66868D.cso.pdb | 3 + ....comp.77033778233ABE1F8DF4DC10896A9D54.cso | Bin 0 -> 16960 bytes ...p.77033778233ABE1F8DF4DC10896A9D54.cso.pdb | 3 + ....C9C782D1BBE13E453755EC081421DED8.metallib | Bin 0 -> 66942 bytes ....comp.369D88A577A88042FF66C8A4DB9A4FFF.cso | Bin 0 -> 17428 bytes ...p.369D88A577A88042FF66C8A4DB9A4FFF.cso.pdb | 3 + ....comp.392E08DB2C8E05308B151D1DA50C5FD0.cso | Bin 0 -> 20016 bytes ...p.392E08DB2C8E05308B151D1DA50C5FD0.cso.pdb | 3 + ....5105918DD8BE389C150428D89E1DC2A5.metallib | Bin 0 -> 67702 bytes ....comp.51CA73B06455A1B1FE3E7645C1E97A2C.cso | Bin 0 -> 17568 bytes ...p.51CA73B06455A1B1FE3E7645C1E97A2C.cso.pdb | 3 + ....87A39CD991750E4B6AA82597D1D6999F.metallib | Bin 0 -> 66742 bytes ....AE073ACCCC101E16160223DC2E63E101.metallib | Bin 0 -> 67942 bytes ....comp.C8248FD11EC1733B4966D0AD2A176353.cso | Bin 0 -> 19880 bytes ...p.C8248FD11EC1733B4966D0AD2A176353.cso.pdb | 3 + ....DF3F5EC676EAEE69B51393B80926E694.metallib | Bin 0 -> 67766 bytes ....2616FB8E13640920939266A5AB69B20D.metallib | Bin 0 -> 66830 bytes ....comp.5193D9B98F2643DCDDD49DEB24A0B7BF.cso | Bin 0 -> 19656 bytes ...p.5193D9B98F2643DCDDD49DEB24A0B7BF.cso.pdb | 3 + ....1176896EBBA00E7091A5D3AB0E2EBB79.metallib | Bin 0 -> 66454 bytes ....comp.22E56629C521714CE47CDCC8E03CCD62.cso | Bin 0 -> 20560 bytes ...p.22E56629C521714CE47CDCC8E03CCD62.cso.pdb | 3 + ....comp.3048D89D90DE3FE53B72E0B170415B00.cso | Bin 0 -> 20300 bytes ...p.3048D89D90DE3FE53B72E0B170415B00.cso.pdb | 3 + ....52AF64226113D111C7C55923680D03E7.metallib | Bin 0 -> 66662 bytes ....6D4F2B8F547360DC2A71F660E3706939.metallib | Bin 0 -> 67494 bytes ....comp.82765548E48F470AE2C324FD1DD1DF19.cso | Bin 0 -> 17248 bytes ...p.82765548E48F470AE2C324FD1DD1DF19.cso.pdb | 3 + ....comp.BF85DD78B470A799944AD5A0F0323B0C.cso | Bin 0 -> 19584 bytes ...p.BF85DD78B470A799944AD5A0F0323B0C.cso.pdb | 3 + ....EEC67DE904429E8E712062FB728CA7E7.metallib | Bin 0 -> 67286 bytes ....frag.002AC7D0B7F236B81143408D73D581F8.cso | Bin 0 -> 14900 bytes ...g.002AC7D0B7F236B81143408D73D581F8.cso.pdb | 3 + ....frag.008D18448C772DC164148A23DB8594EA.cso | Bin 0 -> 14940 bytes ...g.008D18448C772DC164148A23DB8594EA.cso.pdb | 3 + ....0AD45649F32641AAA69A3A9C079BDDBC.metallib | Bin 0 -> 69306 bytes ....frag.18BB2ED0068256FAC47DC4810295F65B.cso | Bin 0 -> 14620 bytes ...g.18BB2ED0068256FAC47DC4810295F65B.cso.pdb | 3 + ....3AEC42EAC916E5302A5879B5E0480E46.metallib | Bin 0 -> 66298 bytes ....42142CB169269EB33A0A31A418C939A6.metallib | Bin 0 -> 66314 bytes ....frag.48B033222FD1BD594675302F045A38A7.cso | Bin 0 -> 20092 bytes ...g.48B033222FD1BD594675302F045A38A7.cso.pdb | 3 + ....frag.4B0896B385CFE32F521EF3625ECD7CE6.cso | Bin 0 -> 14588 bytes ...g.4B0896B385CFE32F521EF3625ECD7CE6.cso.pdb | 3 + ....570374695D2EDE03975F3ACEEF142B8A.metallib | Bin 0 -> 66522 bytes ....5BCF450E7AAEB04EFE81950BC64E3F24.metallib | Bin 0 -> 66266 bytes ....6B6958101DFBCC2D44E480C8108B4531.metallib | Bin 0 -> 66314 bytes ....724B5E7F9D5F2C642BBADBF98BCE6122.metallib | Bin 0 -> 66666 bytes ....frag.7D3D408F4D90CC373A284D34F9B71F98.cso | Bin 0 -> 14708 bytes ...g.7D3D408F4D90CC373A284D34F9B71F98.cso.pdb | 3 + ....frag.842841B5F4FFDF9CF56BEF4C0A6C5C2D.cso | Bin 0 -> 14628 bytes ...g.842841B5F4FFDF9CF56BEF4C0A6C5C2D.cso.pdb | 3 + ....frag.87D14E5B2AF4072ABF40B5A743B01133.cso | Bin 0 -> 14588 bytes ...g.87D14E5B2AF4072ABF40B5A743B01133.cso.pdb | 3 + ....8EB0F8ED9C71D976C3914CE541D3AFC7.metallib | Bin 0 -> 67418 bytes ....9868960EE5BAA4542CE68A32E3F82EAB.metallib | Bin 0 -> 66618 bytes ....BD068B89B4F2CBB0E292F53BC3714F9D.metallib | Bin 0 -> 66314 bytes ....frag.CBB6451884404E44D465B01DF5A806BE.cso | Bin 0 -> 27776 bytes ...g.CBB6451884404E44D465B01DF5A806BE.cso.pdb | 3 + ....frag.F0E2F0F689387705D12CB9970013F51D.cso | Bin 0 -> 14560 bytes ...g.F0E2F0F689387705D12CB9970013F51D.cso.pdb | 3 + ....vert.01D890EA6B89BCCBE76EB1FEC30F851E.cso | Bin 0 -> 14600 bytes ...t.01D890EA6B89BCCBE76EB1FEC30F851E.cso.pdb | 3 + ....01D890EA6B89BCCBE76EB1FEC30F851E.metallib | Bin 0 -> 65539 bytes ....vert.140F4C3CE57F202DE2DE8B945704F1F0.cso | Bin 0 -> 18096 bytes ...t.140F4C3CE57F202DE2DE8B945704F1F0.cso.pdb | 3 + ....vert.1DCA9D50DC853C86C4F97DC839A9325E.cso | Bin 0 -> 17916 bytes ...t.1DCA9D50DC853C86C4F97DC839A9325E.cso.pdb | 3 + ....vert.2FF984AB185BE7E8637187AC34C0981A.cso | Bin 0 -> 17816 bytes ...t.2FF984AB185BE7E8637187AC34C0981A.cso.pdb | 3 + ....3348F0F53DE2A58A3FAD84C6699E871C.metallib | Bin 0 -> 65898 bytes ....vert.58AAEEAE9F43BBE34D312BD53914D01A.cso | Bin 0 -> 14744 bytes ...t.58AAEEAE9F43BBE34D312BD53914D01A.cso.pdb | 3 + ....5AE82EFD5FB29F367E0D45BA786D928A.metallib | Bin 0 -> 66579 bytes ....7DDABF541F1046F394F9BD2476CB5992.metallib | Bin 0 -> 66991 bytes ....E77F6D2C2CCEA5FD8F910DA990E10013.metallib | Bin 0 -> 66698 bytes ....frag.4DD1C89DF8002B409E089089CE8F24E7.cso | Bin 0 -> 14416 bytes ...g.4DD1C89DF8002B409E089089CE8F24E7.cso.pdb | 3 + ....4DD1C89DF8002B409E089089CE8F24E7.metallib | Bin 0 -> 65394 bytes ....5DF351B082B2DAEB6EA8D2B69FF8CE75.metallib | Bin 0 -> 66226 bytes ....frag.7CF9397E238069F29B5AD306936DC2E1.cso | Bin 0 -> 14416 bytes ...g.7CF9397E238069F29B5AD306936DC2E1.cso.pdb | 3 + ....7F37BB3F141BE207B89B42BD7E923FBA.metallib | Bin 0 -> 66226 bytes ....9E055DD95BFFEC03321947DE0EB82637.metallib | Bin 0 -> 66226 bytes ....DAB1785A8432D17D3A9633C69AC4C0BF.metallib | Bin 0 -> 66226 bytes ....EF723B81A7A0BF6787FDDD555588FDAA.metallib | Bin 0 -> 66226 bytes ....frag.7CF9397E238069F29B5AD306936DC2E1.cso | Bin 0 -> 14416 bytes ...g.7CF9397E238069F29B5AD306936DC2E1.cso.pdb | 3 + ....EF723B81A7A0BF6787FDDD555588FDAA.metallib | Bin 0 -> 66222 bytes ....vert.2FF984AB185BE7E8637187AC34C0981A.cso | Bin 0 -> 17816 bytes ...t.2FF984AB185BE7E8637187AC34C0981A.cso.pdb | 3 + ....5AE82EFD5FB29F367E0D45BA786D928A.metallib | Bin 0 -> 66595 bytes ....8DBEE0AA3D769A49703B7DD05C82CFA3.metallib | Bin 0 -> 69602 bytes ....frag.C1B07717CD6E335BA0719719B22FAFE3.cso | Bin 0 -> 31676 bytes ...g.C1B07717CD6E335BA0719719B22FAFE3.cso.pdb | 3 + ....29EB9B0EAE29F9736E833F3E1F035C27.metallib | Bin 0 -> 70111 bytes ....vert.75A6F16850E5D3B8E8B7368097463B42.cso | Bin 0 -> 34608 bytes ...t.75A6F16850E5D3B8E8B7368097463B42.cso.pdb | 3 + ....vert.03430199D846164B6B0612A9B2AB28EA.cso | Bin 0 -> 25100 bytes ...t.03430199D846164B6B0612A9B2AB28EA.cso.pdb | 3 + ....40C070F9811750AE211F3378926ED3B0.metallib | Bin 0 -> 69034 bytes ....9D7F4A290A88D708B9D8641A2177BBE3.metallib | Bin 0 -> 69386 bytes ....vert.AA13DF163AA5F83DF77B65270B739A08.cso | Bin 0 -> 25376 bytes ...t.AA13DF163AA5F83DF77B65270B739A08.cso.pdb | 3 + ....ABB1D1D062F10893CD085B71E73BA1FB.metallib | Bin 0 -> 69075 bytes ....vert.BB070F836ADD72A3E65E350E4F68AAFE.cso | Bin 0 -> 25100 bytes ...t.BB070F836ADD72A3E65E350E4F68AAFE.cso.pdb | 3 + ....vert.BB420670B55EEABBBB80947E171765E6.cso | Bin 0 -> 25124 bytes ...t.BB420670B55EEABBBB80947E171765E6.cso.pdb | 3 + ....vert.C0FACB4FBDE6B9C944D0F6B61E5515FE.cso | Bin 0 -> 25264 bytes ...t.C0FACB4FBDE6B9C944D0F6B61E5515FE.cso.pdb | 3 + ....F6238D8991D40344B66C2ABAF21B2B5A.metallib | Bin 0 -> 69194 bytes ....FE53A6036CA4635A540C1FEA2D189F45.metallib | Bin 0 -> 69034 bytes ....vert.05E05A32B897F2006A110EB2D80A4548.cso | Bin 0 -> 18096 bytes ...t.05E05A32B897F2006A110EB2D80A4548.cso.pdb | 3 + ....vert.0E8B137E61B073CBAAAB0C24A2C4CEF9.cso | Bin 0 -> 17792 bytes ...t.0E8B137E61B073CBAAAB0C24A2C4CEF9.cso.pdb | 3 + ....vert.266E4511F0C4068B851B075051BA543B.cso | Bin 0 -> 17900 bytes ...t.266E4511F0C4068B851B075051BA543B.cso.pdb | 3 + ....vert.2FF984AB185BE7E8637187AC34C0981A.cso | Bin 0 -> 17816 bytes ...t.2FF984AB185BE7E8637187AC34C0981A.cso.pdb | 3 + ....35C1E2A66FBFA2887558AC3636CCA6EB.metallib | Bin 0 -> 66854 bytes ....vert.38A9BD92AA3A1500ADA3082B18F935F4.cso | Bin 0 -> 18072 bytes ...t.38A9BD92AA3A1500ADA3082B18F935F4.cso.pdb | 3 + ....3DC0E88754F11D4478F7B7D881ADF28E.metallib | Bin 0 -> 66586 bytes ....473011F7B55118D4409E7A91C4CA0C06.metallib | Bin 0 -> 66720 bytes ....53C5FFB4F1F65014E9D8CE139E165C06.metallib | Bin 0 -> 66837 bytes ....vert.5A4DDE443DFF866A0B6F7E709735D7AB.cso | Bin 0 -> 20328 bytes ...t.5A4DDE443DFF866A0B6F7E709735D7AB.cso.pdb | 3 + ....5AE82EFD5FB29F367E0D45BA786D928A.metallib | Bin 0 -> 66595 bytes ....vert.5C6447565A432691A52405F2D1A50012.cso | Bin 0 -> 18000 bytes ...t.5C6447565A432691A52405F2D1A50012.cso.pdb | 3 + ....620373BC462CC9D98E9DAE33EC0EF03D.metallib | Bin 0 -> 66586 bytes ....vert.65E266EB404652FA1212BBD1F985A6AC.cso | Bin 0 -> 17900 bytes ...t.65E266EB404652FA1212BBD1F985A6AC.cso.pdb | 3 + ....66F6E1229EB0784EFA3F715B73E43D2B.metallib | Bin 0 -> 66695 bytes ....6CE9330E31EBBC32AE8E316A8C0EE277.metallib | Bin 0 -> 66996 bytes ....vert.8BD5661BC011A36608F82548C23FB052.cso | Bin 0 -> 18072 bytes ...t.8BD5661BC011A36608F82548C23FB052.cso.pdb | 3 + ....8D18B0A6A0838F6914203A391288C860.metallib | Bin 0 -> 66695 bytes ....A7855B18F4958E7E1B7D9B72701C3720.metallib | Bin 0 -> 66728 bytes ....vert.ADDF91CE486A3BFBC7564616DE170ABA.cso | Bin 0 -> 17924 bytes ...t.ADDF91CE486A3BFBC7564616DE170ABA.cso.pdb | 3 + ....B745EB05721137F2AE8C910D1BE17F25.metallib | Bin 0 -> 66854 bytes ....vert.C7EED909597A865FF430CA2885C69439.cso | Bin 0 -> 17792 bytes ...t.C7EED909597A865FF430CA2885C69439.cso.pdb | 3 + ....vert.DC15E12AB500EAEE4B0F9A2C8075E8E1.cso | Bin 0 -> 20156 bytes ...t.DC15E12AB500EAEE4B0F9A2C8075E8E1.cso.pdb | 3 + ....FDDCD4D907DA9A03ACCD42C140A776A4.metallib | Bin 0 -> 66863 bytes ....geom.11A3F59B29869268E24243BE4EABD116.cso | Bin 0 -> 41928 bytes ...m.11A3F59B29869268E24243BE4EABD116.cso.pdb | 3 + ....geom.125C4FCD6DC29A9F6B47ACC988C0162F.cso | Bin 0 -> 41956 bytes ...m.125C4FCD6DC29A9F6B47ACC988C0162F.cso.pdb | 3 + ....geom.1873B621D321CE82AA536C28DCE3C58D.cso | Bin 0 -> 49712 bytes ...m.1873B621D321CE82AA536C28DCE3C58D.cso.pdb | 3 + ....geom.1A146F33833BE9EEA65C6C0C0CBE799D.cso | Bin 0 -> 42016 bytes ...m.1A146F33833BE9EEA65C6C0C0CBE799D.cso.pdb | 3 + ....geom.1B816B245295CA5D5327E96BFE6301F6.cso | Bin 0 -> 36624 bytes ...m.1B816B245295CA5D5327E96BFE6301F6.cso.pdb | 3 + ....geom.1C0F0C96333B91901C06D1175A16E1DE.cso | Bin 0 -> 40836 bytes ...m.1C0F0C96333B91901C06D1175A16E1DE.cso.pdb | 3 + ....geom.2ACA21574A23B0D0074098285F176749.cso | Bin 0 -> 49712 bytes ...m.2ACA21574A23B0D0074098285F176749.cso.pdb | 3 + ....geom.2C8009173B59A839A8E4FF2BC5B85094.cso | Bin 0 -> 49740 bytes ...m.2C8009173B59A839A8E4FF2BC5B85094.cso.pdb | 3 + ....geom.2CEEC2A138B6BB946C7E5836CC5E37E0.cso | Bin 0 -> 40924 bytes ...m.2CEEC2A138B6BB946C7E5836CC5E37E0.cso.pdb | 3 + ....geom.377370747DA9B2908354049AAC2D30FA.cso | Bin 0 -> 40924 bytes ...m.377370747DA9B2908354049AAC2D30FA.cso.pdb | 3 + ....geom.38E2D27FF7046D8A00290708435B3AC5.cso | Bin 0 -> 42016 bytes ...m.38E2D27FF7046D8A00290708435B3AC5.cso.pdb | 3 + ....geom.40452A858BDF0DD351CAAC7CAD4D75AC.cso | Bin 0 -> 40956 bytes ...m.40452A858BDF0DD351CAAC7CAD4D75AC.cso.pdb | 3 + ....geom.455299EAF18CA9285CFB885E58CDC6D0.cso | Bin 0 -> 36712 bytes ...m.455299EAF18CA9285CFB885E58CDC6D0.cso.pdb | 3 + ....geom.494F248863E815B635F86B4C4A2B9878.cso | Bin 0 -> 41956 bytes ...m.494F248863E815B635F86B4C4A2B9878.cso.pdb | 3 + ....geom.4A6E9FDAA1CE421286BA2A3A30A6658A.cso | Bin 0 -> 42044 bytes ...m.4A6E9FDAA1CE421286BA2A3A30A6658A.cso.pdb | 3 + ....geom.566A5829015B608CF29A39550DEF77DC.cso | Bin 0 -> 49624 bytes ...m.566A5829015B608CF29A39550DEF77DC.cso.pdb | 3 + ....geom.5E305102DF74F937A763A780239EC2AB.cso | Bin 0 -> 49652 bytes ...m.5E305102DF74F937A763A780239EC2AB.cso.pdb | 3 + ....geom.5F5DF159396A6B8FE4C4A0F97D78924B.cso | Bin 0 -> 36624 bytes ...m.5F5DF159396A6B8FE4C4A0F97D78924B.cso.pdb | 3 + ....geom.7B8359347B0DEF37AA39A05B62E5CBC1.cso | Bin 0 -> 36740 bytes ...m.7B8359347B0DEF37AA39A05B62E5CBC1.cso.pdb | 3 + ....geom.7EEA6AF74A7E1398CE4B70E260147AF0.cso | Bin 0 -> 36652 bytes ...m.7EEA6AF74A7E1398CE4B70E260147AF0.cso.pdb | 3 + ....geom.7F33C027EBB191F2059BE1A8839D31F5.cso | Bin 0 -> 40868 bytes ...m.7F33C027EBB191F2059BE1A8839D31F5.cso.pdb | 3 + ....geom.893C3B31AEB4B56E07A0C0112A35B626.cso | Bin 0 -> 49740 bytes ...m.893C3B31AEB4B56E07A0C0112A35B626.cso.pdb | 3 + ....geom.8DDF66C3535F05343B6E0711A2F5EDE9.cso | Bin 0 -> 40868 bytes ...m.8DDF66C3535F05343B6E0711A2F5EDE9.cso.pdb | 3 + ....geom.9EBF63F0CECB121FB08C73258F424154.cso | Bin 0 -> 49624 bytes ...m.9EBF63F0CECB121FB08C73258F424154.cso.pdb | 3 + ....geom.9F151426D3A5187075EB122B45099E95.cso | Bin 0 -> 49652 bytes ...m.9F151426D3A5187075EB122B45099E95.cso.pdb | 3 + ....geom.C1D8B1B3F659E4754B02859930024C34.cso | Bin 0 -> 41928 bytes ...m.C1D8B1B3F659E4754B02859930024C34.cso.pdb | 3 + ....geom.CD3CD6C95FE00B70F3CB44712C4E6F6F.cso | Bin 0 -> 40956 bytes ...m.CD3CD6C95FE00B70F3CB44712C4E6F6F.cso.pdb | 3 + ....geom.DBAB50AF656C0B77BE3EACFA872A4107.cso | Bin 0 -> 36712 bytes ...m.DBAB50AF656C0B77BE3EACFA872A4107.cso.pdb | 3 + ....geom.E46C7BF11C16009DAD26F2E52BCA71ED.cso | Bin 0 -> 36740 bytes ...m.E46C7BF11C16009DAD26F2E52BCA71ED.cso.pdb | 3 + ....geom.EDC05431FEB536B2137D9C70A18E0E85.cso | Bin 0 -> 40836 bytes ...m.EDC05431FEB536B2137D9C70A18E0E85.cso.pdb | 3 + ....geom.F43E932D41866B4751D2AAAA122C0DF8.cso | Bin 0 -> 36652 bytes ...m.F43E932D41866B4751D2AAAA122C0DF8.cso.pdb | 3 + ....geom.FD048825BBE1F9EEFF9AF105929E49F9.cso | Bin 0 -> 42044 bytes ...m.FD048825BBE1F9EEFF9AF105929E49F9.cso.pdb | 3 + ....vert.0491B9E5DB4146F6039DB5A1028E068F.cso | Bin 0 -> 19056 bytes ...t.0491B9E5DB4146F6039DB5A1028E068F.cso.pdb | 3 + ....vert.089C1A93F75623C5625465ADC48162D9.cso | Bin 0 -> 19080 bytes ...t.089C1A93F75623C5625465ADC48162D9.cso.pdb | 3 + ....vert.2CBCDD973DD8785D8ED96E438B732020.cso | Bin 0 -> 19088 bytes ...t.2CBCDD973DD8785D8ED96E438B732020.cso.pdb | 3 + ....vert.2EBB1E214294B7250FB31039A38D6AC5.cso | Bin 0 -> 16848 bytes ...t.2EBB1E214294B7250FB31039A38D6AC5.cso.pdb | 3 + ....vert.38E30D094B028C691653A728362634B2.cso | Bin 0 -> 16824 bytes ...t.38E30D094B028C691653A728362634B2.cso.pdb | 3 + ....vert.45152D6B551F36103EA55B435AD0C462.cso | Bin 0 -> 16824 bytes ...t.45152D6B551F36103EA55B435AD0C462.cso.pdb | 3 + ....vert.57701C60E841F468867561F9335BDAB3.cso | Bin 0 -> 19056 bytes ...t.57701C60E841F468867561F9335BDAB3.cso.pdb | 3 + ....vert.630652A3268DE6E9BDE38BC918841E62.cso | Bin 0 -> 19088 bytes ...t.630652A3268DE6E9BDE38BC918841E62.cso.pdb | 3 + ....vert.77B31999700322078CF970FEB7407F9C.cso | Bin 0 -> 16824 bytes ...t.77B31999700322078CF970FEB7407F9C.cso.pdb | 3 + ....vert.7D65653E05F3CFD999E0CFE63FA6E06D.cso | Bin 0 -> 16848 bytes ...t.7D65653E05F3CFD999E0CFE63FA6E06D.cso.pdb | 3 + ....vert.AA7A6E402DA45EA1877F3864059BB328.cso | Bin 0 -> 19056 bytes ...t.AA7A6E402DA45EA1877F3864059BB328.cso.pdb | 3 + ....vert.ABC8329C82EFC7A175A670CD89AFCF15.cso | Bin 0 -> 19088 bytes ...t.ABC8329C82EFC7A175A670CD89AFCF15.cso.pdb | 3 + ....vert.AF299C4F5A88FF41BB134DEBBD221243.cso | Bin 0 -> 16824 bytes ...t.AF299C4F5A88FF41BB134DEBBD221243.cso.pdb | 3 + ....vert.B73B1CA9CB013890A989873EBD811678.cso | Bin 0 -> 16824 bytes ...t.B73B1CA9CB013890A989873EBD811678.cso.pdb | 3 + ....vert.BB1894D2E83C03A44A1F4C0ACFAC5941.cso | Bin 0 -> 16848 bytes ...t.BB1894D2E83C03A44A1F4C0ACFAC5941.cso.pdb | 3 + ....vert.CF3846F9E7636FD9485E620D0B85EA7A.cso | Bin 0 -> 19272 bytes ...t.CF3846F9E7636FD9485E620D0B85EA7A.cso.pdb | 3 + ....vert.CFDCA74BBAE47557D9554F9C6994FFF5.cso | Bin 0 -> 16824 bytes ...t.CFDCA74BBAE47557D9554F9C6994FFF5.cso.pdb | 3 + ....vert.D1027BFD27F09759DCE21D6C3D0007E6.cso | Bin 0 -> 19056 bytes ...t.D1027BFD27F09759DCE21D6C3D0007E6.cso.pdb | 3 + ....vert.D11F440AEF887A61EE9AF025D5E23AB9.cso | Bin 0 -> 19088 bytes ...t.D11F440AEF887A61EE9AF025D5E23AB9.cso.pdb | 3 + ....vert.DF9214C22288F9B9A48D38F5B74524DE.cso | Bin 0 -> 16824 bytes ...t.DF9214C22288F9B9A48D38F5B74524DE.cso.pdb | 3 + ....vert.E085F93BEC7DF3EBA14A46B44E57CA65.cso | Bin 0 -> 19272 bytes ...t.E085F93BEC7DF3EBA14A46B44E57CA65.cso.pdb | 3 + ....vert.E439E2679AC92876BE93DB6F63E71BA4.cso | Bin 0 -> 16848 bytes ...t.E439E2679AC92876BE93DB6F63E71BA4.cso.pdb | 3 + ....vert.FD3064546B01E2F76BFF1BFDEB54CC81.cso | Bin 0 -> 16824 bytes ...t.FD3064546B01E2F76BFF1BFDEB54CC81.cso.pdb | 3 + ....vert.FF385EE49D348C3D94E3E75DDEC43EF1.cso | Bin 0 -> 19080 bytes ...t.FF385EE49D348C3D94E3E75DDEC43EF1.cso.pdb | 3 + ....vert.03A9039DF625A5CE430A52161825FB2E.cso | Bin 0 -> 16876 bytes ...t.03A9039DF625A5CE430A52161825FB2E.cso.pdb | 3 + ....vert.125702F176A5DC7DE52D9A2D09ACB336.cso | Bin 0 -> 16864 bytes ...t.125702F176A5DC7DE52D9A2D09ACB336.cso.pdb | 3 + ....vert.1ADEC6D7AA8D6B5FA2623A3803561740.cso | Bin 0 -> 16840 bytes ...t.1ADEC6D7AA8D6B5FA2623A3803561740.cso.pdb | 3 + ....vert.1B4EF1D1BFD046CEA6303A75D5A090DD.cso | Bin 0 -> 19084 bytes ...t.1B4EF1D1BFD046CEA6303A75D5A090DD.cso.pdb | 3 + ....vert.215E7FA2E1D915E575BF0D051FF57DAC.cso | Bin 0 -> 16864 bytes ...t.215E7FA2E1D915E575BF0D051FF57DAC.cso.pdb | 3 + ....vert.2CF9EB30E57EC06C260F1C994273BBB9.cso | Bin 0 -> 19300 bytes ...t.2CF9EB30E57EC06C260F1C994273BBB9.cso.pdb | 3 + ....vert.3830050E054524D9FB4B97B3C5795D74.cso | Bin 0 -> 16840 bytes ...t.3830050E054524D9FB4B97B3C5795D74.cso.pdb | 3 + ....vert.3FC5681EEA9466868BDE6277412A1602.cso | Bin 0 -> 19084 bytes ...t.3FC5681EEA9466868BDE6277412A1602.cso.pdb | 3 + ....vert.54CE329F05A57498A425EEE7FFB92A53.cso | Bin 0 -> 16840 bytes ...t.54CE329F05A57498A425EEE7FFB92A53.cso.pdb | 3 + ....vert.63E4E8675470AA49793AE6B8F2EFB412.cso | Bin 0 -> 16876 bytes ...t.63E4E8675470AA49793AE6B8F2EFB412.cso.pdb | 3 + ....vert.6EDA9FA1D0CE763321BA160FE1F69436.cso | Bin 0 -> 16852 bytes ...t.6EDA9FA1D0CE763321BA160FE1F69436.cso.pdb | 3 + ....vert.7B6CA6E5E319B7DCD804E51483B1560B.cso | Bin 0 -> 19288 bytes ...t.7B6CA6E5E319B7DCD804E51483B1560B.cso.pdb | 3 + ....vert.8041C676881D61780106102C13F8133C.cso | Bin 0 -> 19116 bytes ...t.8041C676881D61780106102C13F8133C.cso.pdb | 3 + ....vert.96BCBFB5543D4357E250741BD758D684.cso | Bin 0 -> 19104 bytes ...t.96BCBFB5543D4357E250741BD758D684.cso.pdb | 3 + ....vert.AAE2DCCA9E4429BEDF7F5C12A4918FBE.cso | Bin 0 -> 19096 bytes ...t.AAE2DCCA9E4429BEDF7F5C12A4918FBE.cso.pdb | 3 + ....vert.B7B90948D23B69401E4275BBBA5F6021.cso | Bin 0 -> 19072 bytes ...t.B7B90948D23B69401E4275BBBA5F6021.cso.pdb | 3 + ....vert.B959A091D6A562E3BB2A4A86D8938E3B.cso | Bin 0 -> 19116 bytes ...t.B959A091D6A562E3BB2A4A86D8938E3B.cso.pdb | 3 + ....vert.C631C6F1C848D8407BB4550427BFAFE5.cso | Bin 0 -> 19104 bytes ...t.C631C6F1C848D8407BB4550427BFAFE5.cso.pdb | 3 + ....vert.C7D9E2F6ACF45D7DCA8F8EB92111BCBC.cso | Bin 0 -> 19072 bytes ...t.C7D9E2F6ACF45D7DCA8F8EB92111BCBC.cso.pdb | 3 + ....vert.E757CD08237F5B4A4C260EE943E6A7BC.cso | Bin 0 -> 16852 bytes ...t.E757CD08237F5B4A4C260EE943E6A7BC.cso.pdb | 3 + ....vert.F0F89BC5650EEE995AA9D7357378D280.cso | Bin 0 -> 16840 bytes ...t.F0F89BC5650EEE995AA9D7357378D280.cso.pdb | 3 + ....vert.F2AC0D1822C5C821BF888C0AB7491E5E.cso | Bin 0 -> 16852 bytes ...t.F2AC0D1822C5C821BF888C0AB7491E5E.cso.pdb | 3 + ....vert.FA071B919FA56A0FB70F4ED2F802D474.cso | Bin 0 -> 16852 bytes ...t.FA071B919FA56A0FB70F4ED2F802D474.cso.pdb | 3 + ....vert.FEE5E6A661D8F4453A0120A78702157A.cso | Bin 0 -> 19108 bytes ...t.FEE5E6A661D8F4453A0120A78702157A.cso.pdb | 3 + ....vert.0323DA1D4D66DFFC422FD195212F40AC.cso | Bin 0 -> 40848 bytes ...t.0323DA1D4D66DFFC422FD195212F40AC.cso.pdb | 3 + ....08792B0244607751B94495BF11FEA6C3.metallib | Bin 0 -> 71979 bytes ....vert.0A7FA5C512F5E63FC77778DAD58C1444.cso | Bin 0 -> 38128 bytes ...t.0A7FA5C512F5E63FC77778DAD58C1444.cso.pdb | 3 + ....vert.0BD3C6312B7670505B943262A89C9294.cso | Bin 0 -> 40900 bytes ...t.0BD3C6312B7670505B943262A89C9294.cso.pdb | 3 + ....0C752CA2B0AA5C4F58A28B4FB4DBC067.metallib | Bin 0 -> 71131 bytes ....vert.0D2906E0F0B901297CEC98725443F6B8.cso | Bin 0 -> 32756 bytes ...t.0D2906E0F0B901297CEC98725443F6B8.cso.pdb | 3 + ....vert.0DC89CC6EF2BB651C434A448D67109E9.cso | Bin 0 -> 35536 bytes ...t.0DC89CC6EF2BB651C434A448D67109E9.cso.pdb | 3 + ....vert.1244F96A9F041AA77E0829FE15A81781.cso | Bin 0 -> 32588 bytes ...t.1244F96A9F041AA77E0829FE15A81781.cso.pdb | 3 + ....15BA3C3CB8B8717F4D80F5FEC204370F.metallib | Bin 0 -> 71979 bytes ....180EA62B9D1202547139A36A2D1C9FCC.metallib | Bin 0 -> 71003 bytes ....vert.1925F8BB8C5C6BD69F02FA2CD1B6D8F0.cso | Bin 0 -> 43448 bytes ...t.1925F8BB8C5C6BD69F02FA2CD1B6D8F0.cso.pdb | 3 + ....vert.19E6B3D25951E1F2F91F02467D1FB30F.cso | Bin 0 -> 32744 bytes ...t.19E6B3D25951E1F2F91F02467D1FB30F.cso.pdb | 3 + ....1A0AF4135571475AB793369A890D45CA.metallib | Bin 0 -> 70219 bytes ....vert.1A894823438A140EA9E04BF73CD2EAA5.cso | Bin 0 -> 32156 bytes ...t.1A894823438A140EA9E04BF73CD2EAA5.cso.pdb | 3 + ....vert.1B961C28B1FDF4C1823DAA29CE009487.cso | Bin 0 -> 43316 bytes ...t.1B961C28B1FDF4C1823DAA29CE009487.cso.pdb | 3 + ....1E6971511258F0A69158B0C15A49CFC7.metallib | Bin 0 -> 72203 bytes ....vert.21E51D63F6FD0658E746CAE70039F290.cso | Bin 0 -> 45444 bytes ...t.21E51D63F6FD0658E746CAE70039F290.cso.pdb | 3 + ....vert.22F4863734AAC59D6C9C66C631B23B6E.cso | Bin 0 -> 35536 bytes ...t.22F4863734AAC59D6C9C66C631B23B6E.cso.pdb | 3 + ....2CD2DBBA33D183ACE6CD7F2A42321467.metallib | Bin 0 -> 70379 bytes ....vert.2E6BE8AF0F44BC5CC7DA119DDBB43E98.cso | Bin 0 -> 48208 bytes ...t.2E6BE8AF0F44BC5CC7DA119DDBB43E98.cso.pdb | 3 + ....vert.2F8A55777C2632894CF6DBCA38D259A8.cso | Bin 0 -> 32300 bytes ...t.2F8A55777C2632894CF6DBCA38D259A8.cso.pdb | 3 + ....31F564DDF64897CE8D0D8575BA11EA13.metallib | Bin 0 -> 72203 bytes ....vert.323B3616109D749EF6D2A3CF51050BE6.cso | Bin 0 -> 41008 bytes ...t.323B3616109D749EF6D2A3CF51050BE6.cso.pdb | 3 + ....vert.3340D8F8BFE958B965936432A77D2811.cso | Bin 0 -> 43464 bytes ...t.3340D8F8BFE958B965936432A77D2811.cso.pdb | 3 + ....vert.34AC697454E7671946541CA5BDED791A.cso | Bin 0 -> 46016 bytes ...t.34AC697454E7671946541CA5BDED791A.cso.pdb | 3 + ....vert.3A79EBFB229E33A9A80C49E5140236DE.cso | Bin 0 -> 45432 bytes ...t.3A79EBFB229E33A9A80C49E5140236DE.cso.pdb | 3 + ....vert.3B0D4E708AD83ECD8CB195DDCB463524.cso | Bin 0 -> 37984 bytes ...t.3B0D4E708AD83ECD8CB195DDCB463524.cso.pdb | 3 + ....3B4B9C3BB8420D61B0C14B7C673D4312.metallib | Bin 0 -> 69995 bytes ....vert.40FE6F3B1F908655080943E7970B5923.cso | Bin 0 -> 46000 bytes ...t.40FE6F3B1F908655080943E7970B5923.cso.pdb | 3 + ....41CC71331EA3F4DF19C62447C3B4957D.metallib | Bin 0 -> 71003 bytes ....441699570AB850AD3DB81564F52B0908.metallib | Bin 0 -> 72139 bytes ....476DA901FEFBD9A0A3C70B45C3313D67.metallib | Bin 0 -> 70971 bytes ....495C0A9F8FB4194D8EF08AE9C350B23E.metallib | Bin 0 -> 70043 bytes ....vert.4B8021430CC3C9971C8BC859E0C8989D.cso | Bin 0 -> 46016 bytes ...t.4B8021430CC3C9971C8BC859E0C8989D.cso.pdb | 3 + ....50D311BEF26C71B333D271C49B078772.metallib | Bin 0 -> 70427 bytes ....5166BF50736369CD4E22FFBFC064DE76.metallib | Bin 0 -> 72315 bytes ....vert.56DD6FF54063679C76D12691EA79ED95.cso | Bin 0 -> 43304 bytes ...t.56DD6FF54063679C76D12691EA79ED95.cso.pdb | 3 + ....vert.6421B04960935975A09996C65CF0A478.cso | Bin 0 -> 43456 bytes ...t.6421B04960935975A09996C65CF0A478.cso.pdb | 3 + ....vert.654D257A8942334F737B4CF3DBED0F48.cso | Bin 0 -> 32588 bytes ...t.654D257A8942334F737B4CF3DBED0F48.cso.pdb | 3 + ....67F490450BA69DEBD5593D019A7EC0B6.metallib | Bin 0 -> 71339 bytes ....vert.6ABEABA3444031DF1A478CE27CADC998.cso | Bin 0 -> 34784 bytes ...t.6ABEABA3444031DF1A478CE27CADC998.cso.pdb | 3 + ....vert.6AF760A6E9E643069DB35D5D06BD6BA9.cso | Bin 0 -> 38144 bytes ...t.6AF760A6E9E643069DB35D5D06BD6BA9.cso.pdb | 3 + ....vert.6D377C6B02680802CD74BA81C639ED28.cso | Bin 0 -> 43236 bytes ...t.6D377C6B02680802CD74BA81C639ED28.cso.pdb | 3 + ....vert.6E949D72552C7F34F1E09D89F1E1C952.cso | Bin 0 -> 43248 bytes ...t.6E949D72552C7F34F1E09D89F1E1C952.cso.pdb | 3 + ....71D4C26BBE212B4D2A9608C1E34D86E4.metallib | Bin 0 -> 70971 bytes ....vert.7204742FB331648ED83573329D86D073.cso | Bin 0 -> 32604 bytes ...t.7204742FB331648ED83573329D86D073.cso.pdb | 3 + ....73CFC84CF655AC999324D43BDB1E4EB6.metallib | Bin 0 -> 72155 bytes ....vert.74380FFB48164FF6B35623BE8701B7EB.cso | Bin 0 -> 32140 bytes ...t.74380FFB48164FF6B35623BE8701B7EB.cso.pdb | 3 + ....7521DA417DCEAD1B47E7D7BE0B95AFE5.metallib | Bin 0 -> 70043 bytes ....7B8E55E72E6CA6ACF6F1D3A81B3BC9D2.metallib | Bin 0 -> 72539 bytes ....vert.7E7C2EBE718EBA32FB6282BC269E323D.cso | Bin 0 -> 40832 bytes ...t.7E7C2EBE718EBA32FB6282BC269E323D.cso.pdb | 3 + ....vert.80EF261D1CC4A59FCF572E60A2F410EF.cso | Bin 0 -> 32604 bytes ...t.80EF261D1CC4A59FCF572E60A2F410EF.cso.pdb | 3 + ....8206568794DB63EDFB28346F08717693.metallib | Bin 0 -> 70171 bytes ....vert.86BBDE2865C753261D68E62FEF5F2901.cso | Bin 0 -> 43248 bytes ...t.86BBDE2865C753261D68E62FEF5F2901.cso.pdb | 3 + ....vert.8ADA3DCDE80CB10E83BA6B98332AB60B.cso | Bin 0 -> 35520 bytes ...t.8ADA3DCDE80CB10E83BA6B98332AB60B.cso.pdb | 3 + ....vert.8B6EC10AD63C117AADC967DFF1835F04.cso | Bin 0 -> 46156 bytes ...t.8B6EC10AD63C117AADC967DFF1835F04.cso.pdb | 3 + ....vert.8D5882C7F4BE916035D8A2A19C6DF78A.cso | Bin 0 -> 43292 bytes ...t.8D5882C7F4BE916035D8A2A19C6DF78A.cso.pdb | 3 + ....vert.90E1EDC296925F67098F2D916779539D.cso | Bin 0 -> 32196 bytes ...t.90E1EDC296925F67098F2D916779539D.cso.pdb | 3 + ....vert.91F8A2067B8EA071695FF41B8B76AE97.cso | Bin 0 -> 37984 bytes ...t.91F8A2067B8EA071695FF41B8B76AE97.cso.pdb | 3 + ....vert.93D943F5A9C29E618797431F40796C35.cso | Bin 0 -> 35576 bytes ...t.93D943F5A9C29E618797431F40796C35.cso.pdb | 3 + ....vert.96DAC364F30C96759E77B529B883C028.cso | Bin 0 -> 35520 bytes ...t.96DAC364F30C96759E77B529B883C028.cso.pdb | 3 + ....vert.979416BB843C6F05F3845FFCC3ECD7D6.cso | Bin 0 -> 40848 bytes ...t.979416BB843C6F05F3845FFCC3ECD7D6.cso.pdb | 3 + ....vert.984E39E04658AF07687F9C17D33781DA.cso | Bin 0 -> 37996 bytes ...t.984E39E04658AF07687F9C17D33781DA.cso.pdb | 3 + ....vert.9AE9452EB8270BB640EA28FE04E85D12.cso | Bin 0 -> 40888 bytes ...t.9AE9452EB8270BB640EA28FE04E85D12.cso.pdb | 3 + ....vert.9C59ECCAF416177DA2B674CC26C4C7C6.cso | Bin 0 -> 43304 bytes ...t.9C59ECCAF416177DA2B674CC26C4C7C6.cso.pdb | 3 + ....9C9DC497EE8CB2A3010B8F5BE870A4AD.metallib | Bin 0 -> 72363 bytes ....A14339AF9BA1D695A2231452C7C125B1.metallib | Bin 0 -> 72107 bytes ....A416CC957DBBA6BB89F520075E9ED987.metallib | Bin 0 -> 71947 bytes ....vert.A911A0900D6EB7FD73E64020B22DC54D.cso | Bin 0 -> 43316 bytes ...t.A911A0900D6EB7FD73E64020B22DC54D.cso.pdb | 3 + ....vert.B0C01FFF068BBB8EC7C84EC464A263C6.cso | Bin 0 -> 40992 bytes ...t.B0C01FFF068BBB8EC7C84EC464A263C6.cso.pdb | 3 + ....vert.B33BD37027E2C6E47FBC917C8D1AD34C.cso | Bin 0 -> 38136 bytes ...t.B33BD37027E2C6E47FBC917C8D1AD34C.cso.pdb | 3 + ....vert.B815C5761C479B16EDEFA49DD71F5BEF.cso | Bin 0 -> 43236 bytes ...t.B815C5761C479B16EDEFA49DD71F5BEF.cso.pdb | 3 + ....vert.B95B5D8436DC9065FA2624B17C3A8F4A.cso | Bin 0 -> 46168 bytes ...t.B95B5D8436DC9065FA2624B17C3A8F4A.cso.pdb | 3 + ....BB64A8E44AB8BAEEC81BE23ACF911CBC.metallib | Bin 0 -> 71179 bytes ....vert.BBDA720FBCB03878657725DCB4070478.cso | Bin 0 -> 38148 bytes ...t.BBDA720FBCB03878657725DCB4070478.cso.pdb | 3 + ....vert.C15B7A17F66E5D27A740A3A3C1979581.cso | Bin 0 -> 46000 bytes ...t.C15B7A17F66E5D27A740A3A3C1979581.cso.pdb | 3 + ....C7B2BB2F20BE157E180C159EFD14D8DE.metallib | Bin 0 -> 69995 bytes ....vert.C98B044AB7848AFC025DE95581642A05.cso | Bin 0 -> 37996 bytes ...t.C98B044AB7848AFC025DE95581642A05.cso.pdb | 3 + ....vert.CB92CEE22B94959EEA2E37687128679E.cso | Bin 0 -> 32140 bytes ...t.CB92CEE22B94959EEA2E37687128679E.cso.pdb | 3 + ....vert.CC0D866961E5688D9882D28BF15A2DD1.cso | Bin 0 -> 48196 bytes ...t.CC0D866961E5688D9882D28BF15A2DD1.cso.pdb | 3 + ....vert.CDA1E3C0E334532F508888E67D4074B0.cso | Bin 0 -> 37744 bytes ...t.CDA1E3C0E334532F508888E67D4074B0.cso.pdb | 3 + ....vert.D1972016D72D5B585C503DFDD9ABA548.cso | Bin 0 -> 43468 bytes ...t.D1972016D72D5B585C503DFDD9ABA548.cso.pdb | 3 + ....vert.D580014BB3F0D7F3FB392B6DE11130DF.cso | Bin 0 -> 32208 bytes ...t.D580014BB3F0D7F3FB392B6DE11130DF.cso.pdb | 3 + ....D8BEC1C4205A6483977E29A6E5C0A924.metallib | Bin 0 -> 72139 bytes ....vert.DB334DF1BF578B4A345D78EACFC48EFD.cso | Bin 0 -> 32156 bytes ...t.DB334DF1BF578B4A345D78EACFC48EFD.cso.pdb | 3 + ....vert.DBF0DC4E7C492B8443906BDABAB124D6.cso | Bin 0 -> 34796 bytes ...t.DBF0DC4E7C492B8443906BDABAB124D6.cso.pdb | 3 + ....vert.DC6974CAEE2A36877F6F6ECC13BBAD7E.cso | Bin 0 -> 32288 bytes ...t.DC6974CAEE2A36877F6F6ECC13BBAD7E.cso.pdb | 3 + ....vert.DDEB5E46AE2974A0BD8EEF904023D7ED.cso | Bin 0 -> 40832 bytes ...t.DDEB5E46AE2974A0BD8EEF904023D7ED.cso.pdb | 3 + ....E21668FA3F80C375943DB33466B664B7.metallib | Bin 0 -> 72379 bytes ....vert.E2A6EFBB662583C8B826AB85395FBE8B.cso | Bin 0 -> 35588 bytes ...t.E2A6EFBB662583C8B826AB85395FBE8B.cso.pdb | 3 + ....vert.E2B113ED936BDA4068FB8C5E849E995C.cso | Bin 0 -> 37728 bytes ...t.E2B113ED936BDA4068FB8C5E849E995C.cso.pdb | 3 + ....E7704C9D770808997358C137DF29684D.metallib | Bin 0 -> 71387 bytes ....E7F82C90DC6E05851419E96B05BE71AC.metallib | Bin 0 -> 72587 bytes ....EB837A0928B395784434A7A111B53B5A.metallib | Bin 0 -> 71947 bytes ....F57F07EF6B6ED1C1CCD0B43033944746.metallib | Bin 0 -> 72315 bytes ....vert.FE9156D85DC490262296F717A3729F04.cso | Bin 0 -> 43304 bytes ...t.FE9156D85DC490262296F717A3729F04.cso.pdb | 3 + ....vert.3AA9FB07C369A60580272C87CD195B48.cso | Bin 0 -> 23024 bytes ...t.3AA9FB07C369A60580272C87CD195B48.cso.pdb | 3 + ....54B0DD8802234A5C2D1599668B7B9206.metallib | Bin 0 -> 68818 bytes ....vert.55B9ABEC1E3A57FF5B4B48F003CA9752.cso | Bin 0 -> 22732 bytes ...t.55B9ABEC1E3A57FF5B4B48F003CA9752.cso.pdb | 3 + ....E0A95D2F1F3EE6F204B740E133E167F9.metallib | Bin 0 -> 69122 bytes ....vert.E4DE4FF3AC2C78D948169907E0A73083.cso | Bin 0 -> 22788 bytes ...t.E4DE4FF3AC2C78D948169907E0A73083.cso.pdb | 3 + ....E82AF2A7438928C99FB4380BF1D38EEA.metallib | Bin 0 -> 67698 bytes ....vert.F5A70F5EA17C5E1466A4461A319A10E1.cso | Bin 0 -> 22732 bytes ...t.F5A70F5EA17C5E1466A4461A319A10E1.cso.pdb | 3 + ....FC5D8F71F6D3DF19E20E42FF6618F7D3.metallib | Bin 0 -> 67714 bytes ....frag.7D4CDE3609CAABADC704CA9E51BB9F61.cso | Bin 0 -> 84236 bytes ...g.7D4CDE3609CAABADC704CA9E51BB9F61.cso.pdb | 3 + ....B5C43DC2134A05755ADB00CA12BAF5C9.metallib | Bin 0 -> 82802 bytes ....frag.AA6AB5EFB19FD706650DFAFAA01D7D90.cso | Bin 0 -> 17080 bytes ...g.AA6AB5EFB19FD706650DFAFAA01D7D90.cso.pdb | 3 + ....F9A4E1FF18B4D49D16DE912FD8A20B3E.metallib | Bin 0 -> 67094 bytes ....2BFF67C6D3C7441503662DA3FF5A8E57.metallib | Bin 0 -> 66914 bytes ....frag.AFFAB2D8D5F189DCDB557A256A2F8D08.cso | Bin 0 -> 17372 bytes ...g.AFFAB2D8D5F189DCDB557A256A2F8D08.cso.pdb | 3 + ....3A86B375B47444ED50B241CB31E4DE69.metallib | Bin 0 -> 69066 bytes ....frag.4E1DEB657074C0BC7622F2752888C406.cso | Bin 0 -> 58280 bytes ...g.4E1DEB657074C0BC7622F2752888C406.cso.pdb | 3 + ....6FF25215FE2377D1A9D44CB228A6FDCC.metallib | Bin 0 -> 69610 bytes ....frag.A565FBDBEDF828A39BE5F7DB10013507.cso | Bin 0 -> 50644 bytes ...g.A565FBDBEDF828A39BE5F7DB10013507.cso.pdb | 3 + ....comp.48F96F1C309D71E7B09A68D687BCAF2B.cso | Bin 0 -> 35276 bytes ...p.48F96F1C309D71E7B09A68D687BCAF2B.cso.pdb | 3 + ....7D008C2220573C54554F7ECF45C09AE1.metallib | Bin 0 -> 70846 bytes ....06F70F70BEE3A7F2C9007828EAC27793.metallib | Bin 0 -> 66350 bytes ....vert.23547C37D36CF6F9E3E4E1A5EFFDA5D7.cso | Bin 0 -> 16692 bytes ...t.23547C37D36CF6F9E3E4E1A5EFFDA5D7.cso.pdb | 3 + ....vert.5458F29FA4CB16046183E24079014F66.cso | Bin 0 -> 18740 bytes ...t.5458F29FA4CB16046183E24079014F66.cso.pdb | 3 + ....vert.6820B8E6207A3B72C4104BBEBA6362A7.cso | Bin 0 -> 16692 bytes ...t.6820B8E6207A3B72C4104BBEBA6362A7.cso.pdb | 3 + ....vert.84F2CED1305C36A788150F98225EDB8E.cso | Bin 0 -> 14644 bytes ...t.84F2CED1305C36A788150F98225EDB8E.cso.pdb | 3 + ....84F2CED1305C36A788150F98225EDB8E.metallib | Bin 0 -> 65550 bytes ....AB34E7F5715922651FCAC50613AD2C84.metallib | Bin 0 -> 67550 bytes ....E9BEA09E84D5D4F71D5B417CB9E33C2B.metallib | Bin 0 -> 66158 bytes ....20F6C676AA4429ECE221D06C3579FE6E.metallib | Bin 0 -> 68166 bytes ....frag.39AB76CAE213E76DBA545C88E8BDE602.cso | Bin 0 -> 22612 bytes ...g.39AB76CAE213E76DBA545C88E8BDE602.cso.pdb | 3 + ....frag.504D71546723AF7F0E946069BF0BBDC1.cso | Bin 0 -> 20372 bytes ...g.504D71546723AF7F0E946069BF0BBDC1.cso.pdb | 3 + ....frag.621E6F8AB62D0530723E6071DD1AECAE.cso | Bin 0 -> 20500 bytes ...g.621E6F8AB62D0530723E6071DD1AECAE.cso.pdb | 3 + ....frag.6B3AB535C56AF8AAA886CB915A7DE392.cso | Bin 0 -> 20348 bytes ...g.6B3AB535C56AF8AAA886CB915A7DE392.cso.pdb | 3 + ....frag.835D4B0EE4352DFABEFBE67F99F03581.cso | Bin 0 -> 22732 bytes ...g.835D4B0EE4352DFABEFBE67F99F03581.cso.pdb | 3 + ....A9E805B45F4C48DB5EC5940F2DBB49EF.metallib | Bin 0 -> 69734 bytes ....AD528D11B24C3E9547BBC2755B99AF0D.metallib | Bin 0 -> 68310 bytes ....AE86D100987DC55AC4CD67341D850BC9.metallib | Bin 0 -> 69798 bytes ....BBC3FA3E5A6A9C8BD17B04A4C3C3131F.metallib | Bin 0 -> 67526 bytes ....C26A349E4B498C28CA45FDF2B358356D.metallib | Bin 0 -> 67510 bytes ....frag.C7D82581B244FE8E3E7FAD38CA9B4C30.cso | Bin 0 -> 25560 bytes ...g.C7D82581B244FE8E3E7FAD38CA9B4C30.cso.pdb | 3 + ....D12FD3934A8AEA8B731F0FFDEE6E4203.metallib | Bin 0 -> 68118 bytes ....frag.F024867C34EF3686655F5D8B96BD85AD.cso | Bin 0 -> 25496 bytes ...g.F024867C34EF3686655F5D8B96BD85AD.cso.pdb | 3 + ....0A585A8EE1FAF289D0FA00431292E74D.metallib | Bin 0 -> 67562 bytes ....196033BDAFEE16C2947AC8D3CBD9E464.metallib | Bin 0 -> 67498 bytes ....frag.44119E8A23CB98B578519BD7A8DD2D3A.cso | Bin 0 -> 23796 bytes ...g.44119E8A23CB98B578519BD7A8DD2D3A.cso.pdb | 3 + ....frag.4D18DB2E6615B37CE61ADA69E7CF80B7.cso | Bin 0 -> 26252 bytes ...g.4D18DB2E6615B37CE61ADA69E7CF80B7.cso.pdb | 3 + ....frag.6B1E1A9B04F783E5EF5AF1FA2DD7A8F0.cso | Bin 0 -> 26464 bytes ...g.6B1E1A9B04F783E5EF5AF1FA2DD7A8F0.cso.pdb | 3 + ....776C8F8C4765207534C2B33EE67BA844.metallib | Bin 0 -> 67850 bytes ....frag.A85F6F848367C44C2139ED7946A2DD41.cso | Bin 0 -> 26060 bytes ...g.A85F6F848367C44C2139ED7946A2DD41.cso.pdb | 3 + ....frag.C7B3E6FB6A02D2891A0BFE850ABA2E05.cso | Bin 0 -> 23612 bytes ...g.C7B3E6FB6A02D2891A0BFE850ABA2E05.cso.pdb | 3 + ....D4B8B59DC084AF08261271DE31BD80FB.metallib | Bin 0 -> 67658 bytes ....D6F2FD832CE84459152427CA78D65D28.metallib | Bin 0 -> 67306 bytes ....frag.E0C7B3E835DB79196070A24486ABF763.cso | Bin 0 -> 23828 bytes ...g.E0C7B3E835DB79196070A24486ABF763.cso.pdb | 3 + ....E8745B044C2DFE8709E100D425FD7E22.metallib | Bin 0 -> 67210 bytes ....frag.4DD1C89DF8002B409E089089CE8F24E7.cso | Bin 0 -> 14436 bytes ...g.4DD1C89DF8002B409E089089CE8F24E7.cso.pdb | 3 + ....4DD1C89DF8002B409E089089CE8F24E7.metallib | Bin 0 -> 65406 bytes ....vert.C992EAD4108528439F5ACC0580D33319.cso | Bin 0 -> 17244 bytes ...t.C992EAD4108528439F5ACC0580D33319.cso.pdb | 3 + ....EEDB02B1278B2566C0A24981ED8E295B.metallib | Bin 0 -> 66259 bytes ....9005CED6A719F4C5A6266F97BBFB476E.metallib | Bin 0 -> 66486 bytes ....frag.F811CE9BD360967E23FA73EFC790BF73.cso | Bin 0 -> 14772 bytes ...g.F811CE9BD360967E23FA73EFC790BF73.cso.pdb | 3 + ....87409A88665BA0A46F3F776DF2CA1206.metallib | Bin 0 -> 66366 bytes ....frag.F0E2F0F689387705D12CB9970013F51D.cso | Bin 0 -> 14632 bytes ...g.F0E2F0F689387705D12CB9970013F51D.cso.pdb | 3 + ....vert.13B53A2583576C2B028749CFE7A75DBA.cso | Bin 0 -> 17032 bytes ...t.13B53A2583576C2B028749CFE7A75DBA.cso.pdb | 3 + ....613A033E7F8C94916EEEB5D560FE454B.metallib | Bin 0 -> 66063 bytes ....comp.03B060E36BAC8979EBFFCD327F74AAF9.cso | Bin 0 -> 17052 bytes ...p.03B060E36BAC8979EBFFCD327F74AAF9.cso.pdb | 3 + ....0AE6A05A739437D201C8C1B2F93B8544.metallib | Bin 0 -> 66362 bytes ....comp.3C1C64A82544849508C4F7B5018CED35.cso | Bin 0 -> 17356 bytes ...p.3C1C64A82544849508C4F7B5018CED35.cso.pdb | 3 + ....712FE560E255C4424D1793FEF1498944.metallib | Bin 0 -> 66570 bytes ....95BBBD48996763573C91C6D61130ADC6.metallib | Bin 0 -> 66876 bytes ....vert.C69D1C8B63FD48E0C28A855BE4BC8C72.cso | Bin 0 -> 20180 bytes ...t.C69D1C8B63FD48E0C28A855BE4BC8C72.cso.pdb | 3 + ....01A367EBF8EF61BEB5BBD977C507AD5D.metallib | Bin 0 -> 69834 bytes ....comp.46FFC0AC778725D76C1B4B50B25D2820.cso | Bin 0 -> 40844 bytes ...p.46FFC0AC778725D76C1B4B50B25D2820.cso.pdb | 3 + ....01A367EBF8EF61BEB5BBD977C507AD5D.metallib | Bin 0 -> 67614 bytes ....comp.46FFC0AC778725D76C1B4B50B25D2820.cso | Bin 0 -> 22672 bytes ...p.46FFC0AC778725D76C1B4B50B25D2820.cso.pdb | 3 + ....40666DC8ABC0281162338BC37344400B.metallib | Bin 0 -> 69366 bytes ....frag.4AB7012A334144666A00F99BE4F8ABF5.cso | Bin 0 -> 30080 bytes ...g.4AB7012A334144666A00F99BE4F8ABF5.cso.pdb | 3 + ....frag.4DD1C89DF8002B409E089089CE8F24E7.cso | Bin 0 -> 14416 bytes ...g.4DD1C89DF8002B409E089089CE8F24E7.cso.pdb | 3 + ....4DD1C89DF8002B409E089089CE8F24E7.metallib | Bin 0 -> 65370 bytes ....607F7C9197328C04A914D3DB28E91B70.metallib | Bin 0 -> 66047 bytes ....vert.7421279F2283857C300D16BA4AC862F9.cso | Bin 0 -> 16928 bytes ...t.7421279F2283857C300D16BA4AC862F9.cso.pdb | 3 + ....frag.3F8899175EDEBECFC90A9FCF4189D177.cso | Bin 0 -> 17288 bytes ...g.3F8899175EDEBECFC90A9FCF4189D177.cso.pdb | 3 + ....3F8899175EDEBECFC90A9FCF4189D177.metallib | Bin 0 -> 65978 bytes ....frag.4DD1C89DF8002B409E089089CE8F24E7.cso | Bin 0 -> 14416 bytes ...g.4DD1C89DF8002B409E089089CE8F24E7.cso.pdb | 3 + ....4DD1C89DF8002B409E089089CE8F24E7.metallib | Bin 0 -> 65402 bytes ....vert.A0CB1C647BF9FDC5B765A1CD78BEA0C6.cso | Bin 0 -> 21708 bytes ...t.A0CB1C647BF9FDC5B765A1CD78BEA0C6.cso.pdb | 3 + ....vert.B1F47489E9CAD9F30B6E29EECDC49DC7.cso | Bin 0 -> 19380 bytes ...t.B1F47489E9CAD9F30B6E29EECDC49DC7.cso.pdb | 3 + ....C6E60C6043020672ADB3C28FE4231386.metallib | Bin 0 -> 66234 bytes ....E306BFB69B25E84A37254307D2194DE4.metallib | Bin 0 -> 66484 bytes ....comp.000E9EBE432F6B318E8869722FA96736.cso | Bin 0 -> 20188 bytes ...p.000E9EBE432F6B318E8869722FA96736.cso.pdb | 3 + ....6B0FF562C6B4E087E89ECFB854F4DF16.metallib | Bin 0 -> 68494 bytes ....00EEAD7565201E1D171906979186BFF4.metallib | Bin 0 -> 68473 bytes ....vert.194FBD4081C25D96A0D72764B5D2868C.cso | Bin 0 -> 21028 bytes ...t.194FBD4081C25D96A0D72764B5D2868C.cso.pdb | 3 + ....vert.5914DC24CB72BBC25D999BA4C1DB9B5A.cso | Bin 0 -> 23212 bytes ...t.5914DC24CB72BBC25D999BA4C1DB9B5A.cso.pdb | 3 + ....vert.A50757CC2A13C001045CDD9A011A0E78.cso | Bin 0 -> 23304 bytes ...t.A50757CC2A13C001045CDD9A011A0E78.cso.pdb | 3 + ....C771D47D0FD2493829F05C25BF23328F.metallib | Bin 0 -> 68548 bytes ....vert.C91A588C69123D5B74210A1169C0B7CB.cso | Bin 0 -> 23168 bytes ...t.C91A588C69123D5B74210A1169C0B7CB.cso.pdb | 3 + ....D2590CD60D4E66225883164A95636A82.metallib | Bin 0 -> 68443 bytes ....F1C2D218A3AFC30EF7F2C8297F4B8646.metallib | Bin 0 -> 68352 bytes ....frag.7CF9397E238069F29B5AD306936DC2E1.cso | Bin 0 -> 16528 bytes ...g.7CF9397E238069F29B5AD306936DC2E1.cso.pdb | 3 + ....9E055DD95BFFEC03321947DE0EB82637.metallib | Bin 0 -> 66278 bytes ....18162C7773971E53C43D7A0F15D8ECE4.metallib | Bin 0 -> 67890 bytes ....vert.6D34106F328960A07AB5DB0CBEBE05E5.cso | Bin 0 -> 18580 bytes ...t.6D34106F328960A07AB5DB0CBEBE05E5.cso.pdb | 3 + ....comp.36030C466ADE37AEB6B32358DC8DBAC7.cso | Bin 0 -> 109500 bytes ...p.36030C466ADE37AEB6B32358DC8DBAC7.cso.pdb | 3 + ....comp.5CFD62E25CEECDE84ED94155C845E9B2.cso | Bin 0 -> 124800 bytes ...p.5CFD62E25CEECDE84ED94155C845E9B2.cso.pdb | 3 + ....D224AE024F31A732967118BC1834D51D.metallib | Bin 0 -> 69022 bytes ....D53181CD829C7C2CC9A7D66D28AA2D06.metallib | Bin 0 -> 69230 bytes ....comp.001CEFA3E15B4064857DF52248F766BE.cso | Bin 0 -> 45760 bytes ...p.001CEFA3E15B4064857DF52248F766BE.cso.pdb | 3 + ....4C1B3D9DE2E2589090B928914DBDCA22.metallib | Bin 0 -> 69134 bytes ....comp.BC3EED1104C7A5A05486050D5E27A5CC.cso | Bin 0 -> 23052 bytes ...p.BC3EED1104C7A5A05486050D5E27A5CC.cso.pdb | 3 + ....E926B5F5F536A436919B0059B2A29EFC.metallib | Bin 0 -> 67334 bytes ....EDD9731E86E29E66F0807C2362C8B640.metallib | Bin 0 -> 67350 bytes ....comp.F3A85FB3B74B54E33EEF438D2BBA34A1.cso | Bin 0 -> 22940 bytes ...p.F3A85FB3B74B54E33EEF438D2BBA34A1.cso.pdb | 3 + .../Textures/DitheringPatterns.png | 3 + .../PopcornFXInternals/Textures/Overdraw.dds | 3 + .../PopcornFXInternals/Textures/TextAtlas.dds | 3 + .../Textures/TextAtlas.pkat | 98 + .../PopcornFXInternals/Textures/default.dds | 3 + PopcornFX/README.md | 31 + PopcornFX/Resources.rcc | Bin 0 -> 727957 bytes PopcornFX/Resources/Fonts/Consolas.ttf | 3 + PopcornFX/Resources/Fonts/Roboto-Bold.ttf | 3 + PopcornFX/Resources/Fonts/Roboto-Light.ttf | 3 + PopcornFX/Resources/Fonts/Roboto-Regular.ttf | 3 + .../Resources/Fonts/RobotoMono-Regular.ttf | 3 + PopcornFX/Resources/Icons/Reset.png | 3 + PopcornFX/Resources/Icons/branch-closed.png | 3 + PopcornFX/Resources/Icons/branch-open.png | 3 + PopcornFX/Stylesheet.qss | 146 + PopcornFX/WinPixEventRuntime.dll | 3 + .../documentation/debugger/PopcornFX.natvis | 409 + PopcornFX/fxc.exe | 3 + PopcornFX/popcornfx.qt/Qt5Core.dll | 3 + PopcornFX/popcornfx.qt/Qt5Gui.dll | 3 + PopcornFX/popcornfx.qt/Qt5Widgets.dll | 3 + PopcornFX/popcornfx.qt/popcornfx.qt.manifest | 9 + PopcornFX/popcornfx.qt/qwindows.dll | 3 + Samples/PK-MCPP/directive.cpp | 1713 ++++ Samples/PK-MCPP/eval.cpp | 1693 +++ Samples/PK-MCPP/expand.cpp | 2998 ++++++ Samples/PK-MCPP/internal.h | 478 + Samples/PK-MCPP/main.cpp | 903 ++ Samples/PK-MCPP/mbchar.cpp | 878 ++ Samples/PK-MCPP/mcpp_lib.h | 30 + Samples/PK-MCPP/mcpp_out.h | 13 + Samples/PK-MCPP/noconfig.h | 616 ++ Samples/PK-MCPP/pk_mcpp_bridge.cpp | 369 + Samples/PK-MCPP/pk_mcpp_bridge.h | 292 + Samples/PK-MCPP/pk_preprocessor.cpp | 257 + Samples/PK-MCPP/pk_preprocessor.h | 34 + Samples/PK-MCPP/precompiled.cpp | 1 + Samples/PK-MCPP/precompiled.h | 11 + Samples/PK-MCPP/support.cpp | 2831 +++++ Samples/PK-MCPP/system.cpp | 4783 +++++++++ Samples/PK-MCPP/system.h | 414 + .../ApiContext/D3D/D3D11Context.cpp | 550 + .../ApiContext/D3D/D3D11Context.h | 82 + .../ApiContext/D3D/D3D12Context.cpp | 899 ++ .../ApiContext/D3D/D3D12Context.h | 83 + Samples/PK-SampleLib/ApiContext/IApiContext.h | 46 + .../ApiContext/Metal/MetalContext.h | 103 + .../ApiContext/Metal/MetalContext.mm | 427 + .../ApiContext/Metal/MetalContextFactory.h | 21 + .../ApiContext/Metal/MetalContextFactory.mm | 35 + .../ApiContext/Metal/MetalFinalBlitShader.h | 587 ++ .../Metal/MetalFinalBlitShader.metal | 52 + .../ApiContext/OpenGL/EGLContext.cpp | 250 + .../ApiContext/OpenGL/EGLContext.h | 51 + .../ApiContext/OpenGL/GLContext.cpp | 321 + .../ApiContext/OpenGL/GLContext.h | 104 + .../ApiContext/OpenGL/GLXContext.cpp | 234 + .../ApiContext/OpenGL/GLXContext.h | 51 + .../ApiContext/OpenGL/NSGLContext.h | 51 + .../ApiContext/OpenGL/NSGLContext.mm | 135 + .../ApiContext/OpenGL/WGLContext.cpp | 246 + .../ApiContext/OpenGL/WGLContext.h | 52 + .../ApiContext/Vulkan/VulkanContext.cpp | 1506 +++ .../ApiContext/Vulkan/VulkanContext.h | 215 + Samples/PK-SampleLib/ApiContextConfig.h | 92 + .../PK-SampleLib/Assets/Meshes/default.fbx | 3 + .../Assets/ShaderIncludes/gen_shaders_header | 18 + .../ShaderIncludes/gen_shaders_header.cmd | 9 + .../ShaderIncludes/generated/Billboard.geom.h | 549 + .../ShaderIncludes/generated/Billboard.vert.h | 579 ++ ...SimInterface_GBuffer_ProjectToNormal.d3d.h | 58 + ...mInterface_GBuffer_ProjectToPosition.d3d.h | 48 + .../ShaderIncludes/generated/Ribbon.vert.h | 424 + .../ShaderIncludes/generated/Triangle.vert.h | 174 + .../ShaderIncludes/sources/Billboard.geom | 548 + .../ShaderIncludes/sources/Billboard.vert | 477 + ...PUSimInterface_GBuffer_ProjectToNormal.d3d | 40 + ...SimInterface_GBuffer_ProjectToPosition.d3d | 35 + .../Assets/ShaderIncludes/sources/Ribbon.vert | 341 + .../ShaderIncludes/sources/Triangle.vert | 137 + .../PK-SampleLib/Assets/Shaders/Gizmo.frag | 5 + .../PK-SampleLib/Assets/Shaders/Gizmo.vert | 14 + .../PK-SampleLib/Assets/Shaders/ImGui.frag | 5 + .../PK-SampleLib/Assets/Shaders/ImGui.vert | 7 + .../PK-SampleLib/Assets/Shaders/Profiler.frag | 5 + .../PK-SampleLib/Assets/Shaders/Profiler.vert | 6 + .../Assets/Shaders/ProfilerDrawNode.frag | 39 + .../Assets/Shaders/ProfilerDrawNode.vert | 56 + .../Assets/Textures/DitheringPatterns.png | 3 + .../PK-SampleLib/Assets/Textures/default.dds | 3 + Samples/PK-SampleLib/BRDFLUT.cpp | 210 + Samples/PK-SampleLib/BRDFLUT.h | 23 + Samples/PK-SampleLib/BlueNoise.cpp | 153 + Samples/PK-SampleLib/BlueNoise.h | 22 + Samples/PK-SampleLib/Camera.cpp | 297 + Samples/PK-SampleLib/Camera.h | 162 + Samples/PK-SampleLib/DebugHelper.cpp | 111 + Samples/PK-SampleLib/DebugHelper.h | 60 + Samples/PK-SampleLib/Gizmo.cpp | 1772 ++++ Samples/PK-SampleLib/Gizmo.h | 235 + Samples/PK-SampleLib/ImguiRhiImplem.cpp | 674 ++ Samples/PK-SampleLib/ImguiRhiImplem.h | 193 + Samples/PK-SampleLib/PKPix.cpp | 75 + Samples/PK-SampleLib/PKPix.h | 30 + Samples/PK-SampleLib/PKSample.h | 41 + Samples/PK-SampleLib/PKSampleInit.cpp | 101 + Samples/PK-SampleLib/PKSampleInit.h | 47 + Samples/PK-SampleLib/PipelineCacheHelper.cpp | 87 + Samples/PK-SampleLib/PipelineCacheHelper.h | 30 + .../PopcornStartup/PopcornStartup.cpp | 290 + .../PopcornStartup/PopcornStartup.h | 24 + Samples/PK-SampleLib/ProfilerRenderer.cpp | 998 ++ Samples/PK-SampleLib/ProfilerRenderer.h | 219 + .../RHIRenderParticleSceneHelpers.cpp | 3198 ++++++ .../RHIRenderParticleSceneHelpers.h | 664 ++ .../FeatureRenderingSettings.cpp | 191 + .../FeatureRenderingSettings.h | 129 + .../RenderIntegrationRHI/FrameCollector.cpp | 108 + .../RenderIntegrationRHI/FrameCollector.h | 50 + .../RenderIntegrationRHI/MaterialToRHI.cpp | 2319 +++++ .../RenderIntegrationRHI/MaterialToRHI.h | 266 + .../RHIBillboardingBatchPolicy.cpp | 3723 +++++++ .../RHIBillboardingBatchPolicy.h | 271 + .../RHIBillboardingBatchPolicy_Vertex.cpp | 2528 +++++ .../RHIBillboardingBatchPolicy_Vertex.h | 243 + .../RenderIntegrationRHI/RHICustomTasks.cpp | 717 ++ .../RenderIntegrationRHI/RHICustomTasks.h | 296 + .../RenderIntegrationRHI/RHIGPUSorter.cpp | 244 + .../RenderIntegrationRHI/RHIGPUSorter.h | 71 + .../RHIGraphicResources.cpp | 2298 +++++ .../RHIGraphicResources.h | 777 ++ .../RHIParticleRenderDataFactory.cpp | 314 + .../RHIParticleRenderDataFactory.h | 67 + .../RHIRenderIntegrationConfig.h | 21 + .../RenderIntegrationRHI/RHITypePolicy.h | 331 + .../RenderIntegrationRHI/RendererCache.cpp | 268 + .../RenderIntegrationRHI/RendererCache.h | 60 + .../RenderIntegrationRHI/SoundPoolCache.cpp | 201 + .../RenderIntegrationRHI/SoundPoolCache.h | 87 + .../RenderPasses/DirectionalShadows.cpp | 766 ++ .../RenderPasses/DirectionalShadows.h | 178 + .../RenderPasses/DownSampleTexture.cpp | 258 + .../RenderPasses/DownSampleTexture.h | 84 + Samples/PK-SampleLib/RenderPasses/GBuffer.cpp | 567 + Samples/PK-SampleLib/RenderPasses/GBuffer.h | 161 + .../PK-SampleLib/RenderPasses/PostFxBloom.cpp | 383 + .../PK-SampleLib/RenderPasses/PostFxBloom.h | 102 + .../RenderPasses/PostFxColorRemap.cpp | 231 + .../RenderPasses/PostFxColorRemap.h | 80 + .../RenderPasses/PostFxDistortion.cpp | 348 + .../RenderPasses/PostFxDistortion.h | 112 + .../PK-SampleLib/RenderPasses/PostFxFXAA.cpp | 196 + .../PK-SampleLib/RenderPasses/PostFxFXAA.h | 84 + .../RenderPasses/PostFxToneMapping.cpp | 231 + .../RenderPasses/PostFxToneMapping.h | 112 + .../SampleScene/AbstractGraphicScene.cpp | 501 + .../SampleScene/AbstractGraphicScene.h | 94 + .../SampleScene/DeferredScene.cpp | 1040 ++ .../PK-SampleLib/SampleScene/DeferredScene.h | 222 + .../Entities/EnvironmentMapEntity.cpp | 877 ++ .../Entities/EnvironmentMapEntity.h | 108 + .../SampleScene/Entities/LightEntity.cpp | 233 + .../SampleScene/Entities/LightEntity.h | 136 + .../SampleScene/Entities/MeshEntity.cpp | 453 + .../SampleScene/Entities/MeshEntity.h | 151 + Samples/PK-SampleLib/SampleUtils.cpp | 577 ++ Samples/PK-SampleLib/SampleUtils.h | 175 + .../BasicSceneShaderDefinitions.cpp | 377 + .../BasicSceneShaderDefinitions.h | 54 + .../EditorShaderDefinitions.cpp | 1159 +++ .../EditorShaderDefinitions.h | 97 + .../SampleLibShaderDefinitions.cpp | 1334 +++ .../SampleLibShaderDefinitions.h | 108 + .../ShaderDefinitions/ShaderDefinitions.cpp | 187 + .../ShaderDefinitions/ShaderDefinitions.h | 35 + .../UnitTestsShaderDefinitions.cpp | 1329 +++ .../UnitTestsShaderDefinitions.h | 210 + .../ShaderGenerator/GLSLShaderGenerator.cpp | 813 ++ .../ShaderGenerator/GLSLShaderGenerator.h | 80 + .../ShaderGenerator/HLSLShaderGenerator.cpp | 696 ++ .../ShaderGenerator/HLSLShaderGenerator.h | 63 + .../ShaderGenerator/MetalShaderGenerator.cpp | 803 ++ .../ShaderGenerator/MetalShaderGenerator.h | 72 + .../ParticleShaderGenerator.cpp | 568 + .../ShaderGenerator/ParticleShaderGenerator.h | 145 + .../ShaderGenerator/ShaderGenerator.cpp | 532 + .../ShaderGenerator/ShaderGenerator.h | 142 + .../ShaderGenerator/VulkanShaderGenerator.cpp | 749 ++ .../ShaderGenerator/VulkanShaderGenerator.h | 62 + Samples/PK-SampleLib/ShaderLoader.cpp | 348 + Samples/PK-SampleLib/ShaderLoader.h | 118 + .../SimInterface_GBufferSampling.cpp | 551 + .../SimInterfaces/SimInterfaces.h | 39 + .../WindowContext/AWindowContext.cpp | 64 + .../WindowContext/AWindowContext.h | 131 + .../OffscreenContext/OffscreenContext.cpp | 60 + .../OffscreenContext/OffscreenContext.h | 55 + .../WindowContext/SdlContext/SdlContext.cpp | 595 ++ .../WindowContext/SdlContext/SdlContext.h | 125 + Samples/PK-SampleLib/bin/mcpp.exe | 3 + Samples/precompiled/precompiled.cpp | 11 + Samples/precompiled/precompiled.h | 58 + download_3rd_party.bat | 40 + download_3rd_party.sh | 9 + .../AE_Effect_Attribute.make | 199 + .../AE_Effect_AttributeSampler.make | 199 + .../AE_Effect_Emitter.make | 199 + .../AfterEffects_macosx/AE_GeneralPlugin.make | 380 + .../AfterEffects_macosx/PK-AssetBaker.make | 192 + .../AfterEffects_macosx/PK-AssetBakerLib.make | 221 + .../PK-Discretizers_SDK1.make | 152 + projects/AfterEffects_macosx/PK-MCPP.make | 203 + .../AfterEffects_macosx/PK-MCPP_SDK1.make | 203 + .../PK-ParticlesToolbox_SDK1.make | 152 + projects/AfterEffects_macosx/PK-RHI.make | 768 ++ projects/AfterEffects_macosx/PK-RHI_SDK1.make | 162 + .../AfterEffects_macosx/PK-RenderHelpers.make | 436 + .../PK-RenderHelpers_SDK1.make | 152 + .../AfterEffects_macosx/PK-Runtime_SDK1.make | 151 + .../AfterEffects_macosx/PK-SampleLib.make | 492 + .../PK-Sample_01_BasicRendering.make | 200 + .../PK-Sample_01_BasicStartup.make | 175 + .../PK-Sample_02_BasicEvolve.make | 175 + .../PK-Sample_02_FullIntegration.make | 185 + .../PK-Sample_03_EngineHooks.make | 170 + .../PK-Sample_04_Baking.make | 177 + .../PK-Sample_04_EffectInterface.make | 230 + .../PK-Sample_05_Stats.make | 185 + .../PK-Sample_05_Upgrader.make | 172 + .../PK-Sample_06_SimInterface.make | 200 + .../PK-Sample_06_SimInterfaceGPU.make | 190 + .../AfterEffects_macosx/PK-Sample_07_LOD.make | 185 + .../PK-Sample_08_CustomCollision.make | 200 + .../PK-Sample_09_AsyncLoading.make | 190 + .../PK-Sample_10_AsyncRendering.make | 190 + .../PK-Sample_11_ThreadPool.make | 195 + .../PK-Sample_12_GBufferSampling.make | 185 + .../AfterEffects_macosx/PK-ShaderTool.make | 162 + projects/AfterEffects_macosx/PK-Upgrader.make | 172 + .../AfterEffects_macosx/PK-UpgraderLib.make | 1461 +++ .../PopcornFX_AfterEffectsPlugin.make | 168 + .../AfterEffects_macosx/PopcornFX_SDK1.make | 372 + .../moc_AEGP_GraphicalResourcesTreeModel.args | 53 + .../Qt/x64/Debug/moc_AEGP_PanelQT.args | 53 + .../moc_AEGP_GraphicalResourcesTreeModel.args | 54 + .../Qt/x64/Release/moc_AEGP_PanelQT.args | 54 + .../AE_Effect_Attribute.vcxproj | 199 + .../AE_Effect_Attribute.vcxproj.filters | 171 + .../AE_Effect_AttributeSampler.vcxproj | 199 + ...AE_Effect_AttributeSampler.vcxproj.filters | 171 + .../AE_Effect_Emitter.vcxproj | 199 + .../AE_Effect_Emitter.vcxproj.filters | 171 + .../AE_GeneralPlugin.vcxproj | 328 + .../AE_GeneralPlugin.vcxproj.filters | 473 + .../AE_GeneralPlugin.vcxproj.user | 11 + .../AfterEffects_vs2019/PK-AssetBaker.vcxproj | 179 + .../PK-AssetBaker.vcxproj.filters | 140 + .../PK-AssetBaker.vcxproj.user | 11 + .../PK-AssetBakerLib.vcxproj | 208 + .../PK-AssetBakerLib.vcxproj.filters | 98 + .../PK-Discretizers_SDK1.vcxproj | 180 + .../PK-Discretizers_SDK1.vcxproj.filters | 21 + projects/AfterEffects_vs2019/PK-MCPP.vcxproj | 196 + .../PK-MCPP.vcxproj.filters | 77 + .../AfterEffects_vs2019/PK-MCPP_SDK1.vcxproj | 196 + .../PK-MCPP_SDK1.vcxproj.filters | 77 + .../PK-ParticlesToolbox_SDK1.vcxproj | 196 + .../PK-ParticlesToolbox_SDK1.vcxproj.filters | 69 + projects/AfterEffects_vs2019/PK-RHI.vcxproj | 684 ++ .../PK-RHI.vcxproj.filters | 977 ++ .../AfterEffects_vs2019/PK-RHI_SDK1.vcxproj | 365 + .../PK-RHI_SDK1.vcxproj.filters | 650 ++ .../PK-RenderHelpers.vcxproj | 326 + .../PK-RenderHelpers.vcxproj.filters | 509 + .../PK-RenderHelpers_SDK1.vcxproj | 259 + .../PK-RenderHelpers_SDK1.vcxproj.filters | 285 + .../PK-Runtime_SDK1.vcxproj | 566 + .../PK-Runtime_SDK1.vcxproj.filters | 1335 +++ .../AfterEffects_vs2019/PK-SampleLib.vcxproj | 442 + .../PK-SampleLib.vcxproj.filters | 911 ++ .../PK-Sample_01_BasicRendering.vcxproj | 237 + ...K-Sample_01_BasicRendering.vcxproj.filters | 179 + .../PK-Sample_01_BasicRendering.vcxproj.user | 15 + .../PK-Sample_01_BasicStartup.vcxproj | 200 + .../PK-Sample_01_BasicStartup.vcxproj.filters | 50 + .../PK-Sample_01_BasicStartup.vcxproj.user | 15 + .../PK-Sample_02_BasicEvolve.vcxproj | 200 + .../PK-Sample_02_BasicEvolve.vcxproj.filters | 50 + .../PK-Sample_02_BasicEvolve.vcxproj.user | 15 + .../PK-Sample_02_FullIntegration.vcxproj | 306 + ...-Sample_02_FullIntegration.vcxproj.filters | 395 + .../PK-Sample_02_FullIntegration.vcxproj.user | 15 + .../PK-Sample_03_EngineHooks.vcxproj | 196 + .../PK-Sample_03_EngineHooks.vcxproj.filters | 44 + .../PK-Sample_03_EngineHooks.vcxproj.user | 15 + .../PK-Sample_04_Baking.vcxproj | 212 + .../PK-Sample_04_Baking.vcxproj.filters | 74 + .../PK-Sample_04_Baking.vcxproj.user | 15 + .../PK-Sample_04_EffectInterface.vcxproj | 322 + ...-Sample_04_EffectInterface.vcxproj.filters | 443 + .../PK-Sample_04_EffectInterface.vcxproj.user | 15 + .../PK-Sample_05_Stats.vcxproj | 306 + .../PK-Sample_05_Stats.vcxproj.filters | 395 + .../PK-Sample_05_Stats.vcxproj.user | 15 + .../PK-Sample_05_Upgrader.vcxproj | 211 + .../PK-Sample_05_Upgrader.vcxproj.filters | 77 + .../PK-Sample_05_Upgrader.vcxproj.user | 15 + .../PK-Sample_06_SimInterface.vcxproj | 312 + .../PK-Sample_06_SimInterface.vcxproj.filters | 413 + .../PK-Sample_06_SimInterface.vcxproj.user | 15 + .../PK-Sample_06_SimInterfaceGPU.vcxproj | 308 + ...-Sample_06_SimInterfaceGPU.vcxproj.filters | 401 + .../PK-Sample_06_SimInterfaceGPU.vcxproj.user | 15 + .../PK-Sample_07_LOD.vcxproj | 306 + .../PK-Sample_07_LOD.vcxproj.filters | 395 + .../PK-Sample_07_LOD.vcxproj.user | 15 + .../PK-Sample_08_CustomCollision.vcxproj | 312 + ...-Sample_08_CustomCollision.vcxproj.filters | 413 + .../PK-Sample_08_CustomCollision.vcxproj.user | 15 + .../PK-Sample_09_AsyncLoading.vcxproj | 307 + .../PK-Sample_09_AsyncLoading.vcxproj.filters | 398 + .../PK-Sample_09_AsyncLoading.vcxproj.user | 15 + .../PK-Sample_10_AsyncRendering.vcxproj | 307 + ...K-Sample_10_AsyncRendering.vcxproj.filters | 398 + .../PK-Sample_10_AsyncRendering.vcxproj.user | 15 + .../PK-Sample_11_ThreadPool.vcxproj | 308 + .../PK-Sample_11_ThreadPool.vcxproj.filters | 401 + .../PK-Sample_11_ThreadPool.vcxproj.user | 15 + .../PK-Sample_12_GBufferSampling.vcxproj | 306 + ...-Sample_12_GBufferSampling.vcxproj.filters | 395 + .../PK-Sample_12_GBufferSampling.vcxproj.user | 15 + .../AfterEffects_vs2019/PK-ShaderTool.vcxproj | 171 + .../PK-ShaderTool.vcxproj.filters | 137 + .../PK-ShaderTool.vcxproj.user | 11 + .../AfterEffects_vs2019/PK-Upgrader.vcxproj | 199 + .../PK-Upgrader.vcxproj.filters | 38 + .../PK-Upgrader.vcxproj.user | 18 + .../PK-UpgraderLib.vcxproj | 1312 +++ .../PK-UpgraderLib.vcxproj.filters | 3533 +++++++ .../PopcornFX_AfterEffectsPlugin.sln | 122 + .../AfterEffects_vs2019/PopcornFX_SDK1.sln | 293 + .../moc_AEGP_GraphicalResourcesTreeModel.args | 57 + .../Qt/x64/Debug/moc_AEGP_PanelQT.args | 57 + .../moc_AEGP_GraphicalResourcesTreeModel.args | 58 + .../Qt/x64/Release/moc_AEGP_PanelQT.args | 58 + qtoverride.dll.manifest | 15 + 1244 files changed, 176502 insertions(+) create mode 100644 .github/workflows/draft-release.yml create mode 100644 AE.code-workspace create mode 100644 AE_Effect_Attribute/Include/AEAttribute_Main.h create mode 100644 AE_Effect_Attribute/Include/AEAttribute_ParamDefine.h create mode 100644 AE_Effect_Attribute/Include/AEAttribute_PluginInterface.h create mode 100644 AE_Effect_Attribute/Include/AEAttribute_SequenceData.h create mode 100644 AE_Effect_Attribute/PkgInfo create mode 100644 AE_Effect_Attribute/Precompiled/ae_precompiled.cpp create mode 100644 AE_Effect_Attribute/Precompiled/ae_precompiled.h create mode 100644 AE_Effect_Attribute/Sources/AEAttribute_Main.cpp create mode 100644 AE_Effect_Attribute/Sources/AEAttribute_ParamDefine.cpp create mode 100644 AE_Effect_Attribute/Sources/AEAttribute_PluginInterface.cpp create mode 100644 AE_Effect_Attribute/Sources/AEAttribute_SequenceData.cpp create mode 100644 AE_Effect_Attribute/Sources/AE_Effect_Attribute.plugin-Info.plist create mode 100644 AE_Effect_Attribute/Sources/AE_Effect_Attribute_PiPL.r create mode 100644 AE_Effect_AttributeSampler/Include/AEAttributeSampler_Main.h create mode 100644 AE_Effect_AttributeSampler/Include/AEAttributeSampler_ParamDefine.h create mode 100644 AE_Effect_AttributeSampler/Include/AEAttributeSampler_PluginInterface.h create mode 100644 AE_Effect_AttributeSampler/Include/AEAttributeSampler_SequenceData.h create mode 100644 AE_Effect_AttributeSampler/PkgInfo create mode 100644 AE_Effect_AttributeSampler/Precompiled/ae_precompiled.cpp create mode 100644 AE_Effect_AttributeSampler/Precompiled/ae_precompiled.h create mode 100644 AE_Effect_AttributeSampler/Sources/AEAttributeSampler_Main.cpp create mode 100644 AE_Effect_AttributeSampler/Sources/AEAttributeSampler_ParamDefine.cpp create mode 100644 AE_Effect_AttributeSampler/Sources/AEAttributeSampler_PluginInterface.cpp create mode 100644 AE_Effect_AttributeSampler/Sources/AEAttributeSampler_SequenceData.cpp create mode 100644 AE_Effect_AttributeSampler/Sources/AE_Effect_AttributeSampler.plugin-Info.plist create mode 100644 AE_Effect_AttributeSampler/Sources/AE_Effect_AttributeSampler_PiPL.r create mode 100644 AE_Effect_Emitter/Include/AEEffect_Main.h create mode 100644 AE_Effect_Emitter/Include/AEEffect_ParamDefine.h create mode 100644 AE_Effect_Emitter/Include/AEEffect_PluginInterface.h create mode 100644 AE_Effect_Emitter/Include/AEEffect_SequenceData.h create mode 100644 AE_Effect_Emitter/PkgInfo create mode 100644 AE_Effect_Emitter/Precompiled/ae_precompiled.cpp create mode 100644 AE_Effect_Emitter/Precompiled/ae_precompiled.h create mode 100644 AE_Effect_Emitter/Sources/AEEffect_Main.cpp create mode 100644 AE_Effect_Emitter/Sources/AEEffect_ParamDefine.cpp create mode 100644 AE_Effect_Emitter/Sources/AEEffect_PluginInterface.cpp create mode 100644 AE_Effect_Emitter/Sources/AEEffect_SequenceData.cpp create mode 100644 AE_Effect_Emitter/Sources/AE_Effect_Emitter.plugin-Info.plist create mode 100644 AE_Effect_Emitter/Sources/AE_Effect_Emitter_PiPL.r create mode 100644 AE_GeneralPlugin/GeneralPlugin.manifest create mode 100644 AE_GeneralPlugin/Include/AEGP_AEPKConversion.h create mode 100644 AE_GeneralPlugin/Include/AEGP_AssetBaker.h create mode 100644 AE_GeneralPlugin/Include/AEGP_Attribute.h create mode 100644 AE_GeneralPlugin/Include/AEGP_Define.h create mode 100644 AE_GeneralPlugin/Include/AEGP_FileDialog.h create mode 100644 AE_GeneralPlugin/Include/AEGP_FileDialogMac.h create mode 100644 AE_GeneralPlugin/Include/AEGP_FileWatcher.h create mode 100644 AE_GeneralPlugin/Include/AEGP_FrameCollector.h create mode 100644 AE_GeneralPlugin/Include/AEGP_LayerHolder.h create mode 100644 AE_GeneralPlugin/Include/AEGP_Log.h create mode 100644 AE_GeneralPlugin/Include/AEGP_Main.h create mode 100644 AE_GeneralPlugin/Include/AEGP_PackExplorer.h create mode 100644 AE_GeneralPlugin/Include/AEGP_ParticleScene.h create mode 100644 AE_GeneralPlugin/Include/AEGP_PopcornFXPlugins.h create mode 100644 AE_GeneralPlugin/Include/AEGP_RenderContext.h create mode 100644 AE_GeneralPlugin/Include/AEGP_Scene.h create mode 100644 AE_GeneralPlugin/Include/AEGP_SkinnedMesh.h create mode 100644 AE_GeneralPlugin/Include/AEGP_SkinnedMeshInstance.h create mode 100644 AE_GeneralPlugin/Include/AEGP_System.h create mode 100644 AE_GeneralPlugin/Include/AEGP_UpdateAEState.h create mode 100644 AE_GeneralPlugin/Include/AEGP_VaultHandler.h create mode 100644 AE_GeneralPlugin/Include/AEGP_WinFileDialog.h create mode 100644 AE_GeneralPlugin/Include/AEGP_WinSystem.h create mode 100644 AE_GeneralPlugin/Include/AEGP_World.h create mode 100644 AE_GeneralPlugin/Include/Panels/AEGP_GraphicalResourcesTreeModel.h create mode 100644 AE_GeneralPlugin/Include/Panels/AEGP_PanelQT.h create mode 100644 AE_GeneralPlugin/Include/RenderApi/AEGP_BaseContext.h create mode 100644 AE_GeneralPlugin/Include/RenderApi/AEGP_CopyPixels.h create mode 100644 AE_GeneralPlugin/Include/RenderApi/AEGP_CopyTask.h create mode 100644 AE_GeneralPlugin/Include/RenderApi/AEGP_D3D11Context.h create mode 100644 AE_GeneralPlugin/Include/RenderApi/AEGP_D3D12Context.h create mode 100644 AE_GeneralPlugin/Include/RenderApi/AEGP_MetalContext.h create mode 100644 AE_GeneralPlugin/PkgInfo create mode 100644 AE_GeneralPlugin/Precompiled/ae_precompiled.cpp create mode 100644 AE_GeneralPlugin/Precompiled/ae_precompiled.h create mode 100644 AE_GeneralPlugin/Sources/AEGP_AEPKConversion.cpp create mode 100644 AE_GeneralPlugin/Sources/AEGP_AssetBaker.cpp create mode 100644 AE_GeneralPlugin/Sources/AEGP_Attribute.cpp create mode 100644 AE_GeneralPlugin/Sources/AEGP_FileDialog.cpp create mode 100644 AE_GeneralPlugin/Sources/AEGP_FileDialogMac.mm create mode 100644 AE_GeneralPlugin/Sources/AEGP_FileWatcher.cpp create mode 100644 AE_GeneralPlugin/Sources/AEGP_FrameCollector.cpp create mode 100644 AE_GeneralPlugin/Sources/AEGP_LayerHolder.cpp create mode 100644 AE_GeneralPlugin/Sources/AEGP_Log.cpp create mode 100644 AE_GeneralPlugin/Sources/AEGP_Main.cpp create mode 100644 AE_GeneralPlugin/Sources/AEGP_PackExplorer.cpp create mode 100644 AE_GeneralPlugin/Sources/AEGP_ParticleScene.cpp create mode 100644 AE_GeneralPlugin/Sources/AEGP_PopcornFXPlugins.cpp create mode 100644 AE_GeneralPlugin/Sources/AEGP_RenderContext.cpp create mode 100644 AE_GeneralPlugin/Sources/AEGP_Scene.cpp create mode 100644 AE_GeneralPlugin/Sources/AEGP_SkinnedMesh.cpp create mode 100644 AE_GeneralPlugin/Sources/AEGP_SkinnedMeshInstance.cpp create mode 100644 AE_GeneralPlugin/Sources/AEGP_System.cpp create mode 100644 AE_GeneralPlugin/Sources/AEGP_UpdateAEState.cpp create mode 100644 AE_GeneralPlugin/Sources/AEGP_VaultHandler.cpp create mode 100644 AE_GeneralPlugin/Sources/AEGP_WinFileDialog.cpp create mode 100644 AE_GeneralPlugin/Sources/AEGP_WinSystem.cpp create mode 100644 AE_GeneralPlugin/Sources/AEGP_World.cpp create mode 100644 AE_GeneralPlugin/Sources/AE_GeneralPlugin.plugin-Info.plist create mode 100644 AE_GeneralPlugin/Sources/AE_GeneralPlugin_PiPL.r create mode 100644 AE_GeneralPlugin/Sources/Panels/AEGP_GraphicalResourcesTreeModel.cpp create mode 100644 AE_GeneralPlugin/Sources/Panels/AEGP_PanelQT.cpp create mode 100644 AE_GeneralPlugin/Sources/RenderApi/AEGP_BaseContext.cpp create mode 100644 AE_GeneralPlugin/Sources/RenderApi/AEGP_CopyPixels.cpp create mode 100644 AE_GeneralPlugin/Sources/RenderApi/AEGP_D3D11Context.cpp create mode 100644 AE_GeneralPlugin/Sources/RenderApi/AEGP_D3D12Context.cpp create mode 100644 AE_GeneralPlugin/Sources/RenderApi/AEGP_MetalContext.mm create mode 100644 AE_Suites/PopcornFX_BasePluginInterface.h create mode 100644 AE_Suites/PopcornFX_Define.h create mode 100644 AE_Suites/PopcornFX_Define_Version.h create mode 100644 AE_Suites/PopcornFX_Suite.h create mode 100644 AE_Suites/PopcornFX_UID.h create mode 100644 CopyQTDllsForAE.py create mode 100644 External/AE SDK/Headers/A.h create mode 100644 External/AE SDK/Headers/AEConfig.h create mode 100644 External/AE SDK/Headers/AEFX_ArbParseHelper.c create mode 100644 External/AE SDK/Headers/AEFX_ArbParseHelper.h create mode 100644 External/AE SDK/Headers/AEFX_ChannelDepthTpl.h create mode 100644 External/AE SDK/Headers/AEFX_SuiteHandlerTemplate.h create mode 100644 External/AE SDK/Headers/AEFX_SuiteHelper.c create mode 100644 External/AE SDK/Headers/AEFX_SuiteHelper.h create mode 100644 External/AE SDK/Headers/AEGP_SuiteHandler.cpp create mode 100644 External/AE SDK/Headers/AEGP_SuiteHandler.h create mode 100644 External/AE SDK/Headers/AEGP_Utils.cpp create mode 100644 External/AE SDK/Headers/AEGP_Utils.h create mode 100644 External/AE SDK/Headers/AE_AdvEffectSuites.h create mode 100644 External/AE SDK/Headers/AE_CacheOnLoadSuite.h create mode 100644 External/AE SDK/Headers/AE_ChannelSuites.h create mode 100644 External/AE SDK/Headers/AE_ComputeCacheSuite.h create mode 100644 External/AE SDK/Headers/AE_CreatorInfo.h create mode 100644 External/AE SDK/Headers/AE_Effect.h create mode 100644 External/AE SDK/Headers/AE_EffectCB.h create mode 100644 External/AE SDK/Headers/AE_EffectCBSuites.h create mode 100644 External/AE SDK/Headers/AE_EffectGPUSuites.h create mode 100644 External/AE SDK/Headers/AE_EffectPixelFormat.h create mode 100644 External/AE SDK/Headers/AE_EffectSuites.h create mode 100644 External/AE SDK/Headers/AE_EffectSuitesHelper.h create mode 100644 External/AE SDK/Headers/AE_EffectSuitesOld.h create mode 100644 External/AE SDK/Headers/AE_EffectUI.h create mode 100644 External/AE SDK/Headers/AE_EffectVers.h create mode 100644 External/AE SDK/Headers/AE_GeneralPlug.h create mode 100644 External/AE SDK/Headers/AE_GeneralPlugOld.h create mode 100644 External/AE SDK/Headers/AE_GeneralPlugPanels.h create mode 100644 External/AE SDK/Headers/AE_GeneralPlugPost.h create mode 100644 External/AE SDK/Headers/AE_GeneralPlugPre.h create mode 100644 External/AE SDK/Headers/AE_HashSuite.h create mode 100644 External/AE SDK/Headers/AE_Hook.h create mode 100644 External/AE SDK/Headers/AE_IO.h create mode 100644 External/AE SDK/Headers/AE_IO_FileExt.h create mode 100644 External/AE SDK/Headers/AE_Macros.h create mode 100644 External/AE SDK/Headers/AE_PluginData.h create mode 100644 External/AE SDK/Headers/DuckSuite.h create mode 100644 External/AE SDK/Headers/FIEL_Public.h create mode 100644 External/AE SDK/Headers/Mach-O_prefix.h create mode 100644 External/AE SDK/Headers/MissingSuiteError.cpp create mode 100644 External/AE SDK/Headers/PF_Masks.h create mode 100644 External/AE SDK/Headers/PR_Public.h create mode 100644 External/AE SDK/Headers/PT_Public.h create mode 100644 External/AE SDK/Headers/Param_Utils.h create mode 100644 External/AE SDK/Headers/PrSDKAESupport.h create mode 100644 External/AE SDK/Headers/PrSDKPixelFormat.h create mode 100644 External/AE SDK/Headers/SP/PSIntTypes.h create mode 100644 External/AE SDK/Headers/SP/SPAccess.h create mode 100644 External/AE SDK/Headers/SP/SPAdapts.h create mode 100644 External/AE SDK/Headers/SP/SPBasic.h create mode 100644 External/AE SDK/Headers/SP/SPBckDbg.h create mode 100644 External/AE SDK/Headers/SP/SPBlocks.h create mode 100644 External/AE SDK/Headers/SP/SPCOM.h create mode 100644 External/AE SDK/Headers/SP/SPCaches.h create mode 100644 External/AE SDK/Headers/SP/SPConfig.h create mode 100644 External/AE SDK/Headers/SP/SPEDebug.c create mode 100644 External/AE SDK/Headers/SP/SPErrorCodes.h create mode 100644 External/AE SDK/Headers/SP/SPErrors.h create mode 100644 External/AE SDK/Headers/SP/SPFiles.h create mode 100644 External/AE SDK/Headers/SP/SPHost.h create mode 100644 External/AE SDK/Headers/SP/SPInterf.h create mode 100644 External/AE SDK/Headers/SP/SPMData.h create mode 100644 External/AE SDK/Headers/SP/SPObject.h create mode 100644 External/AE SDK/Headers/SP/SPPiPL.h create mode 100644 External/AE SDK/Headers/SP/SPPlugs.h create mode 100644 External/AE SDK/Headers/SP/SPProps.h create mode 100644 External/AE SDK/Headers/SP/SPRuntme.h create mode 100644 External/AE SDK/Headers/SP/SPSTSPrp.h create mode 100644 External/AE SDK/Headers/SP/SPStrngs.h create mode 100644 External/AE SDK/Headers/SP/SPSuites.h create mode 100644 External/AE SDK/Headers/SP/SPTypes.h create mode 100755 External/AE SDK/Headers/SP/artemis/config/platform.hpp create mode 100755 External/AE SDK/Headers/SP/photoshop/config/platform.hpp create mode 100644 External/AE SDK/Headers/Smart_Utils.cpp create mode 100644 External/AE SDK/Headers/Smart_Utils.h create mode 100644 External/AE SDK/Headers/String_Utils.c create mode 100644 External/AE SDK/Headers/String_Utils.h create mode 100644 External/AE SDK/Headers/SuiteHelper.h create mode 100644 External/AE SDK/Headers/adobesdk/DrawbotSuite.h create mode 100755 External/AE SDK/Headers/adobesdk/config/AdobesdkTypes.h create mode 100755 External/AE SDK/Headers/adobesdk/config/PostConfig.h create mode 100755 External/AE SDK/Headers/adobesdk/config/PreConfig.h create mode 100755 External/AE SDK/Headers/adobesdk/drawbotsuite/DrawbotSuiteTypes.h create mode 100644 External/AE SDK/Headers/entry.h create mode 100644 External/AE SDK/Resources/AE_General.r create mode 100644 External/AE SDK/Resources/Mach-O_prefix.h create mode 100755 External/AE SDK/Resources/PiPLtool.exe create mode 100644 External/AE SDK/Util/AEFX_ArbParseHelper.c create mode 100644 External/AE SDK/Util/AEFX_ArbParseHelper.h create mode 100644 External/AE SDK/Util/AEFX_ChannelDepthTpl.h create mode 100644 External/AE SDK/Util/AEFX_SuiteHelper.c create mode 100644 External/AE SDK/Util/AEFX_SuiteHelper.h create mode 100644 External/AE SDK/Util/AEGP_SuiteHandler.cpp create mode 100644 External/AE SDK/Util/AEGP_SuiteHandler.h create mode 100644 External/AE SDK/Util/AEGP_Utils.cpp create mode 100644 External/AE SDK/Util/AEGP_Utils.h create mode 100644 External/AE SDK/Util/DuckSuite.h create mode 100644 External/AE SDK/Util/MissingSuiteError.cpp create mode 100644 External/AE SDK/Util/Param_Utils.h create mode 100644 External/AE SDK/Util/Smart_Utils.cpp create mode 100644 External/AE SDK/Util/Smart_Utils.h create mode 100644 External/AE SDK/Util/String_Utils.h create mode 100644 External/AE SDK/Util/entry.h create mode 100644 External/popcornfx.qt/Qt5Core.dll create mode 100644 External/popcornfx.qt/Qt5Gui.dll create mode 100644 External/popcornfx.qt/Qt5Widgets.dll create mode 100644 External/popcornfx.qt/popcornfx.qt.manifest create mode 100644 External/popcornfx.qt/qwindows.dll create mode 100644 Native/debugger/PopcornFX.natvis create mode 100644 Native/debugger/qt5.natvis create mode 100644 PopcornFX/CHANGELOG.md create mode 100644 PopcornFX/LICENSE.md create mode 100755 PopcornFX/PK-ShaderTool_r.exe create mode 100644 PopcornFX/PopcornFXInternals/Meshes/default.pkmm create mode 100644 PopcornFX/PopcornFXInternals/Shaders/BlurCubemap.comp.0C443080A9914F8E3821857B39F3B3F6.metallib create mode 100644 PopcornFX/PopcornFXInternals/Shaders/BlurCubemap.comp.3C55D2DBBDE67D3B05E91E33AA424D4A.cso create mode 100644 PopcornFX/PopcornFXInternals/Shaders/BlurCubemap.comp.3C55D2DBBDE67D3B05E91E33AA424D4A.cso.pdb create mode 100644 PopcornFX/PopcornFXInternals/Shaders/BrushBackdrop.frag.3777E0C4C3850AF4730B699288C64A32.cso create mode 100644 PopcornFX/PopcornFXInternals/Shaders/BrushBackdrop.frag.3777E0C4C3850AF4730B699288C64A32.cso.pdb create mode 100644 PopcornFX/PopcornFXInternals/Shaders/BrushBackdrop.frag.DBCFC7E098405CD8ABAFBFE666F38717.metallib create mode 100644 PopcornFX/PopcornFXInternals/Shaders/ColorRemap.frag.1CFFFE56845EBA06EDCF9E5C8278FEE3.cso create mode 100644 PopcornFX/PopcornFXInternals/Shaders/ColorRemap.frag.1CFFFE56845EBA06EDCF9E5C8278FEE3.cso.pdb create mode 100644 PopcornFX/PopcornFXInternals/Shaders/ColorRemap.frag.C5813AF3B0DA61049FC61318A52A0039.metallib create mode 100644 PopcornFX/PopcornFXInternals/Shaders/ComputeCubemap.comp.08B780C3B4A4A9B95239BE4725C155E3.metallib create mode 100644 PopcornFX/PopcornFXInternals/Shaders/ComputeCubemap.comp.2BF4FFEBF18FD2317E7196CCB179BBD1.metallib create mode 100644 PopcornFX/PopcornFXInternals/Shaders/ComputeCubemap.comp.ACF5EA8A26A387527C94AE3CADBEEFE0.cso create mode 100644 PopcornFX/PopcornFXInternals/Shaders/ComputeCubemap.comp.ACF5EA8A26A387527C94AE3CADBEEFE0.cso.pdb create mode 100644 PopcornFX/PopcornFXInternals/Shaders/ComputeCubemap.comp.FADA9FB998752BB17F58A80A5F9E1569.cso create mode 100644 PopcornFX/PopcornFXInternals/Shaders/ComputeCubemap.comp.FADA9FB998752BB17F58A80A5F9E1569.cso.pdb create mode 100644 PopcornFX/PopcornFXInternals/Shaders/ComputeMeshIndirectionBuffer.comp.12DC1B81F40BCA0B86B8977219474DA2.metallib create mode 100644 PopcornFX/PopcornFXInternals/Shaders/ComputeMeshIndirectionBuffer.comp.227B4305DA369E84D660CF7D0F95A7B1.cso create mode 100644 PopcornFX/PopcornFXInternals/Shaders/ComputeMeshIndirectionBuffer.comp.227B4305DA369E84D660CF7D0F95A7B1.cso.pdb create mode 100644 PopcornFX/PopcornFXInternals/Shaders/ComputeMeshIndirectionBuffer.comp.3041E5075421B7BEDB64891F34806B09.cso create mode 100644 PopcornFX/PopcornFXInternals/Shaders/ComputeMeshIndirectionBuffer.comp.3041E5075421B7BEDB64891F34806B09.cso.pdb create mode 100644 PopcornFX/PopcornFXInternals/Shaders/ComputeMeshIndirectionBuffer.comp.3F9F670175C1E9A2721D86BF200E8992.metallib create mode 100644 PopcornFX/PopcornFXInternals/Shaders/ComputeMeshIndirectionBuffer.comp.47AFC4B8F363592BAB2CB2B7450DC6CB.metallib create mode 100644 PopcornFX/PopcornFXInternals/Shaders/ComputeMeshIndirectionBuffer.comp.68D7368ADF463DA7672D728718850C05.cso create mode 100644 PopcornFX/PopcornFXInternals/Shaders/ComputeMeshIndirectionBuffer.comp.68D7368ADF463DA7672D728718850C05.cso.pdb create mode 100644 PopcornFX/PopcornFXInternals/Shaders/ComputeMeshIndirectionBuffer.comp.ADF077D22B698F0058CD269AB3B307F6.cso create mode 100644 PopcornFX/PopcornFXInternals/Shaders/ComputeMeshIndirectionBuffer.comp.ADF077D22B698F0058CD269AB3B307F6.cso.pdb create mode 100644 PopcornFX/PopcornFXInternals/Shaders/ComputeMeshIndirectionBuffer.comp.E6559EF41DF4A3259DE7762E070648DE.metallib create mode 100644 PopcornFX/PopcornFXInternals/Shaders/ComputeMeshMatrices.comp.4FB8AAE1AE744B6A08826A79EB921BC5.metallib create mode 100644 PopcornFX/PopcornFXInternals/Shaders/ComputeMeshMatrices.comp.B71DE41E8684A6AE211AB8D5CC66868D.cso create mode 100644 PopcornFX/PopcornFXInternals/Shaders/ComputeMeshMatrices.comp.B71DE41E8684A6AE211AB8D5CC66868D.cso.pdb create mode 100644 PopcornFX/PopcornFXInternals/Shaders/ComputeMipMap.comp.77033778233ABE1F8DF4DC10896A9D54.cso create mode 100644 PopcornFX/PopcornFXInternals/Shaders/ComputeMipMap.comp.77033778233ABE1F8DF4DC10896A9D54.cso.pdb create mode 100644 PopcornFX/PopcornFXInternals/Shaders/ComputeMipMap.comp.C9C782D1BBE13E453755EC081421DED8.metallib create mode 100644 PopcornFX/PopcornFXInternals/Shaders/ComputeParticleCountPerMesh.comp.369D88A577A88042FF66C8A4DB9A4FFF.cso create mode 100644 PopcornFX/PopcornFXInternals/Shaders/ComputeParticleCountPerMesh.comp.369D88A577A88042FF66C8A4DB9A4FFF.cso.pdb create mode 100644 PopcornFX/PopcornFXInternals/Shaders/ComputeParticleCountPerMesh.comp.392E08DB2C8E05308B151D1DA50C5FD0.cso create mode 100644 PopcornFX/PopcornFXInternals/Shaders/ComputeParticleCountPerMesh.comp.392E08DB2C8E05308B151D1DA50C5FD0.cso.pdb create mode 100644 PopcornFX/PopcornFXInternals/Shaders/ComputeParticleCountPerMesh.comp.5105918DD8BE389C150428D89E1DC2A5.metallib create mode 100644 PopcornFX/PopcornFXInternals/Shaders/ComputeParticleCountPerMesh.comp.51CA73B06455A1B1FE3E7645C1E97A2C.cso create mode 100644 PopcornFX/PopcornFXInternals/Shaders/ComputeParticleCountPerMesh.comp.51CA73B06455A1B1FE3E7645C1E97A2C.cso.pdb create mode 100644 PopcornFX/PopcornFXInternals/Shaders/ComputeParticleCountPerMesh.comp.87A39CD991750E4B6AA82597D1D6999F.metallib create mode 100644 PopcornFX/PopcornFXInternals/Shaders/ComputeParticleCountPerMesh.comp.AE073ACCCC101E16160223DC2E63E101.metallib create mode 100644 PopcornFX/PopcornFXInternals/Shaders/ComputeParticleCountPerMesh.comp.C8248FD11EC1733B4966D0AD2A176353.cso create mode 100644 PopcornFX/PopcornFXInternals/Shaders/ComputeParticleCountPerMesh.comp.C8248FD11EC1733B4966D0AD2A176353.cso.pdb create mode 100644 PopcornFX/PopcornFXInternals/Shaders/ComputeParticleCountPerMesh.comp.DF3F5EC676EAEE69B51393B80926E694.metallib create mode 100644 PopcornFX/PopcornFXInternals/Shaders/ComputeRibbonSortKeys.comp.2616FB8E13640920939266A5AB69B20D.metallib create mode 100644 PopcornFX/PopcornFXInternals/Shaders/ComputeRibbonSortKeys.comp.5193D9B98F2643DCDDD49DEB24A0B7BF.cso create mode 100644 PopcornFX/PopcornFXInternals/Shaders/ComputeRibbonSortKeys.comp.5193D9B98F2643DCDDD49DEB24A0B7BF.cso.pdb create mode 100644 PopcornFX/PopcornFXInternals/Shaders/ComputeSortKeys.comp.1176896EBBA00E7091A5D3AB0E2EBB79.metallib create mode 100644 PopcornFX/PopcornFXInternals/Shaders/ComputeSortKeys.comp.22E56629C521714CE47CDCC8E03CCD62.cso create mode 100644 PopcornFX/PopcornFXInternals/Shaders/ComputeSortKeys.comp.22E56629C521714CE47CDCC8E03CCD62.cso.pdb create mode 100644 PopcornFX/PopcornFXInternals/Shaders/ComputeSortKeys.comp.3048D89D90DE3FE53B72E0B170415B00.cso create mode 100644 PopcornFX/PopcornFXInternals/Shaders/ComputeSortKeys.comp.3048D89D90DE3FE53B72E0B170415B00.cso.pdb create mode 100644 PopcornFX/PopcornFXInternals/Shaders/ComputeSortKeys.comp.52AF64226113D111C7C55923680D03E7.metallib create mode 100644 PopcornFX/PopcornFXInternals/Shaders/ComputeSortKeys.comp.6D4F2B8F547360DC2A71F660E3706939.metallib create mode 100644 PopcornFX/PopcornFXInternals/Shaders/ComputeSortKeys.comp.82765548E48F470AE2C324FD1DD1DF19.cso create mode 100644 PopcornFX/PopcornFXInternals/Shaders/ComputeSortKeys.comp.82765548E48F470AE2C324FD1DD1DF19.cso.pdb create mode 100644 PopcornFX/PopcornFXInternals/Shaders/ComputeSortKeys.comp.BF85DD78B470A799944AD5A0F0323B0C.cso create mode 100644 PopcornFX/PopcornFXInternals/Shaders/ComputeSortKeys.comp.BF85DD78B470A799944AD5A0F0323B0C.cso.pdb create mode 100644 PopcornFX/PopcornFXInternals/Shaders/ComputeSortKeys.comp.EEC67DE904429E8E712062FB728CA7E7.metallib create mode 100644 PopcornFX/PopcornFXInternals/Shaders/Copy.frag.002AC7D0B7F236B81143408D73D581F8.cso create mode 100644 PopcornFX/PopcornFXInternals/Shaders/Copy.frag.002AC7D0B7F236B81143408D73D581F8.cso.pdb create mode 100644 PopcornFX/PopcornFXInternals/Shaders/Copy.frag.008D18448C772DC164148A23DB8594EA.cso create mode 100644 PopcornFX/PopcornFXInternals/Shaders/Copy.frag.008D18448C772DC164148A23DB8594EA.cso.pdb create mode 100644 PopcornFX/PopcornFXInternals/Shaders/Copy.frag.0AD45649F32641AAA69A3A9C079BDDBC.metallib create mode 100644 PopcornFX/PopcornFXInternals/Shaders/Copy.frag.18BB2ED0068256FAC47DC4810295F65B.cso create mode 100644 PopcornFX/PopcornFXInternals/Shaders/Copy.frag.18BB2ED0068256FAC47DC4810295F65B.cso.pdb create mode 100644 PopcornFX/PopcornFXInternals/Shaders/Copy.frag.3AEC42EAC916E5302A5879B5E0480E46.metallib create mode 100644 PopcornFX/PopcornFXInternals/Shaders/Copy.frag.42142CB169269EB33A0A31A418C939A6.metallib create mode 100644 PopcornFX/PopcornFXInternals/Shaders/Copy.frag.48B033222FD1BD594675302F045A38A7.cso create mode 100644 PopcornFX/PopcornFXInternals/Shaders/Copy.frag.48B033222FD1BD594675302F045A38A7.cso.pdb create mode 100644 PopcornFX/PopcornFXInternals/Shaders/Copy.frag.4B0896B385CFE32F521EF3625ECD7CE6.cso create mode 100644 PopcornFX/PopcornFXInternals/Shaders/Copy.frag.4B0896B385CFE32F521EF3625ECD7CE6.cso.pdb create mode 100644 PopcornFX/PopcornFXInternals/Shaders/Copy.frag.570374695D2EDE03975F3ACEEF142B8A.metallib create mode 100644 PopcornFX/PopcornFXInternals/Shaders/Copy.frag.5BCF450E7AAEB04EFE81950BC64E3F24.metallib create mode 100644 PopcornFX/PopcornFXInternals/Shaders/Copy.frag.6B6958101DFBCC2D44E480C8108B4531.metallib create mode 100644 PopcornFX/PopcornFXInternals/Shaders/Copy.frag.724B5E7F9D5F2C642BBADBF98BCE6122.metallib create mode 100644 PopcornFX/PopcornFXInternals/Shaders/Copy.frag.7D3D408F4D90CC373A284D34F9B71F98.cso create mode 100644 PopcornFX/PopcornFXInternals/Shaders/Copy.frag.7D3D408F4D90CC373A284D34F9B71F98.cso.pdb create mode 100644 PopcornFX/PopcornFXInternals/Shaders/Copy.frag.842841B5F4FFDF9CF56BEF4C0A6C5C2D.cso create mode 100644 PopcornFX/PopcornFXInternals/Shaders/Copy.frag.842841B5F4FFDF9CF56BEF4C0A6C5C2D.cso.pdb create mode 100644 PopcornFX/PopcornFXInternals/Shaders/Copy.frag.87D14E5B2AF4072ABF40B5A743B01133.cso create mode 100644 PopcornFX/PopcornFXInternals/Shaders/Copy.frag.87D14E5B2AF4072ABF40B5A743B01133.cso.pdb create mode 100644 PopcornFX/PopcornFXInternals/Shaders/Copy.frag.8EB0F8ED9C71D976C3914CE541D3AFC7.metallib create mode 100644 PopcornFX/PopcornFXInternals/Shaders/Copy.frag.9868960EE5BAA4542CE68A32E3F82EAB.metallib create mode 100644 PopcornFX/PopcornFXInternals/Shaders/Copy.frag.BD068B89B4F2CBB0E292F53BC3714F9D.metallib create mode 100644 PopcornFX/PopcornFXInternals/Shaders/Copy.frag.CBB6451884404E44D465B01DF5A806BE.cso create mode 100644 PopcornFX/PopcornFXInternals/Shaders/Copy.frag.CBB6451884404E44D465B01DF5A806BE.cso.pdb create mode 100644 PopcornFX/PopcornFXInternals/Shaders/Copy.frag.F0E2F0F689387705D12CB9970013F51D.cso create mode 100644 PopcornFX/PopcornFXInternals/Shaders/Copy.frag.F0E2F0F689387705D12CB9970013F51D.cso.pdb create mode 100644 PopcornFX/PopcornFXInternals/Shaders/DebugDraw.vert.01D890EA6B89BCCBE76EB1FEC30F851E.cso create mode 100644 PopcornFX/PopcornFXInternals/Shaders/DebugDraw.vert.01D890EA6B89BCCBE76EB1FEC30F851E.cso.pdb create mode 100644 PopcornFX/PopcornFXInternals/Shaders/DebugDraw.vert.01D890EA6B89BCCBE76EB1FEC30F851E.metallib create mode 100644 PopcornFX/PopcornFXInternals/Shaders/DebugDraw.vert.140F4C3CE57F202DE2DE8B945704F1F0.cso create mode 100644 PopcornFX/PopcornFXInternals/Shaders/DebugDraw.vert.140F4C3CE57F202DE2DE8B945704F1F0.cso.pdb create mode 100644 PopcornFX/PopcornFXInternals/Shaders/DebugDraw.vert.1DCA9D50DC853C86C4F97DC839A9325E.cso create mode 100644 PopcornFX/PopcornFXInternals/Shaders/DebugDraw.vert.1DCA9D50DC853C86C4F97DC839A9325E.cso.pdb create mode 100644 PopcornFX/PopcornFXInternals/Shaders/DebugDraw.vert.2FF984AB185BE7E8637187AC34C0981A.cso create mode 100644 PopcornFX/PopcornFXInternals/Shaders/DebugDraw.vert.2FF984AB185BE7E8637187AC34C0981A.cso.pdb create mode 100644 PopcornFX/PopcornFXInternals/Shaders/DebugDraw.vert.3348F0F53DE2A58A3FAD84C6699E871C.metallib create mode 100644 PopcornFX/PopcornFXInternals/Shaders/DebugDraw.vert.58AAEEAE9F43BBE34D312BD53914D01A.cso create mode 100644 PopcornFX/PopcornFXInternals/Shaders/DebugDraw.vert.58AAEEAE9F43BBE34D312BD53914D01A.cso.pdb create mode 100644 PopcornFX/PopcornFXInternals/Shaders/DebugDraw.vert.5AE82EFD5FB29F367E0D45BA786D928A.metallib create mode 100644 PopcornFX/PopcornFXInternals/Shaders/DebugDraw.vert.7DDABF541F1046F394F9BD2476CB5992.metallib create mode 100644 PopcornFX/PopcornFXInternals/Shaders/DebugDraw.vert.E77F6D2C2CCEA5FD8F910DA990E10013.metallib create mode 100644 PopcornFX/PopcornFXInternals/Shaders/DebugDrawColor.frag.4DD1C89DF8002B409E089089CE8F24E7.cso create mode 100644 PopcornFX/PopcornFXInternals/Shaders/DebugDrawColor.frag.4DD1C89DF8002B409E089089CE8F24E7.cso.pdb create mode 100644 PopcornFX/PopcornFXInternals/Shaders/DebugDrawColor.frag.4DD1C89DF8002B409E089089CE8F24E7.metallib create mode 100644 PopcornFX/PopcornFXInternals/Shaders/DebugDrawColor.frag.5DF351B082B2DAEB6EA8D2B69FF8CE75.metallib create mode 100644 PopcornFX/PopcornFXInternals/Shaders/DebugDrawColor.frag.7CF9397E238069F29B5AD306936DC2E1.cso create mode 100644 PopcornFX/PopcornFXInternals/Shaders/DebugDrawColor.frag.7CF9397E238069F29B5AD306936DC2E1.cso.pdb create mode 100644 PopcornFX/PopcornFXInternals/Shaders/DebugDrawColor.frag.7F37BB3F141BE207B89B42BD7E923FBA.metallib create mode 100644 PopcornFX/PopcornFXInternals/Shaders/DebugDrawColor.frag.9E055DD95BFFEC03321947DE0EB82637.metallib create mode 100644 PopcornFX/PopcornFXInternals/Shaders/DebugDrawColor.frag.DAB1785A8432D17D3A9633C69AC4C0BF.metallib create mode 100644 PopcornFX/PopcornFXInternals/Shaders/DebugDrawColor.frag.EF723B81A7A0BF6787FDDD555588FDAA.metallib create mode 100644 PopcornFX/PopcornFXInternals/Shaders/DebugDrawLine.frag.7CF9397E238069F29B5AD306936DC2E1.cso create mode 100644 PopcornFX/PopcornFXInternals/Shaders/DebugDrawLine.frag.7CF9397E238069F29B5AD306936DC2E1.cso.pdb create mode 100644 PopcornFX/PopcornFXInternals/Shaders/DebugDrawLine.frag.EF723B81A7A0BF6787FDDD555588FDAA.metallib create mode 100644 PopcornFX/PopcornFXInternals/Shaders/DebugDrawLine.vert.2FF984AB185BE7E8637187AC34C0981A.cso create mode 100644 PopcornFX/PopcornFXInternals/Shaders/DebugDrawLine.vert.2FF984AB185BE7E8637187AC34C0981A.cso.pdb create mode 100644 PopcornFX/PopcornFXInternals/Shaders/DebugDrawLine.vert.5AE82EFD5FB29F367E0D45BA786D928A.metallib create mode 100644 PopcornFX/PopcornFXInternals/Shaders/DebugDrawValue.frag.8DBEE0AA3D769A49703B7DD05C82CFA3.metallib create mode 100644 PopcornFX/PopcornFXInternals/Shaders/DebugDrawValue.frag.C1B07717CD6E335BA0719719B22FAFE3.cso create mode 100644 PopcornFX/PopcornFXInternals/Shaders/DebugDrawValue.frag.C1B07717CD6E335BA0719719B22FAFE3.cso.pdb create mode 100644 PopcornFX/PopcornFXInternals/Shaders/DebugDrawValue.vert.29EB9B0EAE29F9736E833F3E1F035C27.metallib create mode 100644 PopcornFX/PopcornFXInternals/Shaders/DebugDrawValue.vert.75A6F16850E5D3B8E8B7368097463B42.cso create mode 100644 PopcornFX/PopcornFXInternals/Shaders/DebugDrawValue.vert.75A6F16850E5D3B8E8B7368097463B42.cso.pdb create mode 100644 PopcornFX/PopcornFXInternals/Shaders/DebugMesh_GPU.vert.03430199D846164B6B0612A9B2AB28EA.cso create mode 100644 PopcornFX/PopcornFXInternals/Shaders/DebugMesh_GPU.vert.03430199D846164B6B0612A9B2AB28EA.cso.pdb create mode 100644 PopcornFX/PopcornFXInternals/Shaders/DebugMesh_GPU.vert.40C070F9811750AE211F3378926ED3B0.metallib create mode 100644 PopcornFX/PopcornFXInternals/Shaders/DebugMesh_GPU.vert.9D7F4A290A88D708B9D8641A2177BBE3.metallib create mode 100644 PopcornFX/PopcornFXInternals/Shaders/DebugMesh_GPU.vert.AA13DF163AA5F83DF77B65270B739A08.cso create mode 100644 PopcornFX/PopcornFXInternals/Shaders/DebugMesh_GPU.vert.AA13DF163AA5F83DF77B65270B739A08.cso.pdb create mode 100644 PopcornFX/PopcornFXInternals/Shaders/DebugMesh_GPU.vert.ABB1D1D062F10893CD085B71E73BA1FB.metallib create mode 100644 PopcornFX/PopcornFXInternals/Shaders/DebugMesh_GPU.vert.BB070F836ADD72A3E65E350E4F68AAFE.cso create mode 100644 PopcornFX/PopcornFXInternals/Shaders/DebugMesh_GPU.vert.BB070F836ADD72A3E65E350E4F68AAFE.cso.pdb create mode 100644 PopcornFX/PopcornFXInternals/Shaders/DebugMesh_GPU.vert.BB420670B55EEABBBB80947E171765E6.cso create mode 100644 PopcornFX/PopcornFXInternals/Shaders/DebugMesh_GPU.vert.BB420670B55EEABBBB80947E171765E6.cso.pdb create mode 100644 PopcornFX/PopcornFXInternals/Shaders/DebugMesh_GPU.vert.C0FACB4FBDE6B9C944D0F6B61E5515FE.cso create mode 100644 PopcornFX/PopcornFXInternals/Shaders/DebugMesh_GPU.vert.C0FACB4FBDE6B9C944D0F6B61E5515FE.cso.pdb create mode 100644 PopcornFX/PopcornFXInternals/Shaders/DebugMesh_GPU.vert.F6238D8991D40344B66C2ABAF21B2B5A.metallib create mode 100644 PopcornFX/PopcornFXInternals/Shaders/DebugMesh_GPU.vert.FE53A6036CA4635A540C1FEA2D189F45.metallib create mode 100644 PopcornFX/PopcornFXInternals/Shaders/DebugParticle.vert.05E05A32B897F2006A110EB2D80A4548.cso create mode 100644 PopcornFX/PopcornFXInternals/Shaders/DebugParticle.vert.05E05A32B897F2006A110EB2D80A4548.cso.pdb create mode 100644 PopcornFX/PopcornFXInternals/Shaders/DebugParticle.vert.0E8B137E61B073CBAAAB0C24A2C4CEF9.cso create mode 100644 PopcornFX/PopcornFXInternals/Shaders/DebugParticle.vert.0E8B137E61B073CBAAAB0C24A2C4CEF9.cso.pdb create mode 100644 PopcornFX/PopcornFXInternals/Shaders/DebugParticle.vert.266E4511F0C4068B851B075051BA543B.cso create mode 100644 PopcornFX/PopcornFXInternals/Shaders/DebugParticle.vert.266E4511F0C4068B851B075051BA543B.cso.pdb create mode 100644 PopcornFX/PopcornFXInternals/Shaders/DebugParticle.vert.2FF984AB185BE7E8637187AC34C0981A.cso create mode 100644 PopcornFX/PopcornFXInternals/Shaders/DebugParticle.vert.2FF984AB185BE7E8637187AC34C0981A.cso.pdb create mode 100644 PopcornFX/PopcornFXInternals/Shaders/DebugParticle.vert.35C1E2A66FBFA2887558AC3636CCA6EB.metallib create mode 100644 PopcornFX/PopcornFXInternals/Shaders/DebugParticle.vert.38A9BD92AA3A1500ADA3082B18F935F4.cso create mode 100644 PopcornFX/PopcornFXInternals/Shaders/DebugParticle.vert.38A9BD92AA3A1500ADA3082B18F935F4.cso.pdb create mode 100644 PopcornFX/PopcornFXInternals/Shaders/DebugParticle.vert.3DC0E88754F11D4478F7B7D881ADF28E.metallib create mode 100644 PopcornFX/PopcornFXInternals/Shaders/DebugParticle.vert.473011F7B55118D4409E7A91C4CA0C06.metallib create mode 100644 PopcornFX/PopcornFXInternals/Shaders/DebugParticle.vert.53C5FFB4F1F65014E9D8CE139E165C06.metallib create mode 100644 PopcornFX/PopcornFXInternals/Shaders/DebugParticle.vert.5A4DDE443DFF866A0B6F7E709735D7AB.cso create mode 100644 PopcornFX/PopcornFXInternals/Shaders/DebugParticle.vert.5A4DDE443DFF866A0B6F7E709735D7AB.cso.pdb create mode 100644 PopcornFX/PopcornFXInternals/Shaders/DebugParticle.vert.5AE82EFD5FB29F367E0D45BA786D928A.metallib create mode 100644 PopcornFX/PopcornFXInternals/Shaders/DebugParticle.vert.5C6447565A432691A52405F2D1A50012.cso create mode 100644 PopcornFX/PopcornFXInternals/Shaders/DebugParticle.vert.5C6447565A432691A52405F2D1A50012.cso.pdb create mode 100644 PopcornFX/PopcornFXInternals/Shaders/DebugParticle.vert.620373BC462CC9D98E9DAE33EC0EF03D.metallib create mode 100644 PopcornFX/PopcornFXInternals/Shaders/DebugParticle.vert.65E266EB404652FA1212BBD1F985A6AC.cso create mode 100644 PopcornFX/PopcornFXInternals/Shaders/DebugParticle.vert.65E266EB404652FA1212BBD1F985A6AC.cso.pdb create mode 100644 PopcornFX/PopcornFXInternals/Shaders/DebugParticle.vert.66F6E1229EB0784EFA3F715B73E43D2B.metallib create mode 100644 PopcornFX/PopcornFXInternals/Shaders/DebugParticle.vert.6CE9330E31EBBC32AE8E316A8C0EE277.metallib create mode 100644 PopcornFX/PopcornFXInternals/Shaders/DebugParticle.vert.8BD5661BC011A36608F82548C23FB052.cso create mode 100644 PopcornFX/PopcornFXInternals/Shaders/DebugParticle.vert.8BD5661BC011A36608F82548C23FB052.cso.pdb create mode 100644 PopcornFX/PopcornFXInternals/Shaders/DebugParticle.vert.8D18B0A6A0838F6914203A391288C860.metallib create mode 100644 PopcornFX/PopcornFXInternals/Shaders/DebugParticle.vert.A7855B18F4958E7E1B7D9B72701C3720.metallib create mode 100644 PopcornFX/PopcornFXInternals/Shaders/DebugParticle.vert.ADDF91CE486A3BFBC7564616DE170ABA.cso create mode 100644 PopcornFX/PopcornFXInternals/Shaders/DebugParticle.vert.ADDF91CE486A3BFBC7564616DE170ABA.cso.pdb create mode 100644 PopcornFX/PopcornFXInternals/Shaders/DebugParticle.vert.B745EB05721137F2AE8C910D1BE17F25.metallib create mode 100644 PopcornFX/PopcornFXInternals/Shaders/DebugParticle.vert.C7EED909597A865FF430CA2885C69439.cso create mode 100644 PopcornFX/PopcornFXInternals/Shaders/DebugParticle.vert.C7EED909597A865FF430CA2885C69439.cso.pdb create mode 100644 PopcornFX/PopcornFXInternals/Shaders/DebugParticle.vert.DC15E12AB500EAEE4B0F9A2C8075E8E1.cso create mode 100644 PopcornFX/PopcornFXInternals/Shaders/DebugParticle.vert.DC15E12AB500EAEE4B0F9A2C8075E8E1.cso.pdb create mode 100644 PopcornFX/PopcornFXInternals/Shaders/DebugParticle.vert.FDDCD4D907DA9A03ACCD42C140A776A4.metallib create mode 100644 PopcornFX/PopcornFXInternals/Shaders/DebugParticleGeom.geom.11A3F59B29869268E24243BE4EABD116.cso create mode 100644 PopcornFX/PopcornFXInternals/Shaders/DebugParticleGeom.geom.11A3F59B29869268E24243BE4EABD116.cso.pdb create mode 100644 PopcornFX/PopcornFXInternals/Shaders/DebugParticleGeom.geom.125C4FCD6DC29A9F6B47ACC988C0162F.cso create mode 100644 PopcornFX/PopcornFXInternals/Shaders/DebugParticleGeom.geom.125C4FCD6DC29A9F6B47ACC988C0162F.cso.pdb create mode 100644 PopcornFX/PopcornFXInternals/Shaders/DebugParticleGeom.geom.1873B621D321CE82AA536C28DCE3C58D.cso create mode 100644 PopcornFX/PopcornFXInternals/Shaders/DebugParticleGeom.geom.1873B621D321CE82AA536C28DCE3C58D.cso.pdb create mode 100644 PopcornFX/PopcornFXInternals/Shaders/DebugParticleGeom.geom.1A146F33833BE9EEA65C6C0C0CBE799D.cso create mode 100644 PopcornFX/PopcornFXInternals/Shaders/DebugParticleGeom.geom.1A146F33833BE9EEA65C6C0C0CBE799D.cso.pdb create mode 100644 PopcornFX/PopcornFXInternals/Shaders/DebugParticleGeom.geom.1B816B245295CA5D5327E96BFE6301F6.cso create mode 100644 PopcornFX/PopcornFXInternals/Shaders/DebugParticleGeom.geom.1B816B245295CA5D5327E96BFE6301F6.cso.pdb create mode 100644 PopcornFX/PopcornFXInternals/Shaders/DebugParticleGeom.geom.1C0F0C96333B91901C06D1175A16E1DE.cso create mode 100644 PopcornFX/PopcornFXInternals/Shaders/DebugParticleGeom.geom.1C0F0C96333B91901C06D1175A16E1DE.cso.pdb create mode 100644 PopcornFX/PopcornFXInternals/Shaders/DebugParticleGeom.geom.2ACA21574A23B0D0074098285F176749.cso create mode 100644 PopcornFX/PopcornFXInternals/Shaders/DebugParticleGeom.geom.2ACA21574A23B0D0074098285F176749.cso.pdb create mode 100644 PopcornFX/PopcornFXInternals/Shaders/DebugParticleGeom.geom.2C8009173B59A839A8E4FF2BC5B85094.cso create mode 100644 PopcornFX/PopcornFXInternals/Shaders/DebugParticleGeom.geom.2C8009173B59A839A8E4FF2BC5B85094.cso.pdb create mode 100644 PopcornFX/PopcornFXInternals/Shaders/DebugParticleGeom.geom.2CEEC2A138B6BB946C7E5836CC5E37E0.cso create mode 100644 PopcornFX/PopcornFXInternals/Shaders/DebugParticleGeom.geom.2CEEC2A138B6BB946C7E5836CC5E37E0.cso.pdb create mode 100644 PopcornFX/PopcornFXInternals/Shaders/DebugParticleGeom.geom.377370747DA9B2908354049AAC2D30FA.cso create mode 100644 PopcornFX/PopcornFXInternals/Shaders/DebugParticleGeom.geom.377370747DA9B2908354049AAC2D30FA.cso.pdb create mode 100644 PopcornFX/PopcornFXInternals/Shaders/DebugParticleGeom.geom.38E2D27FF7046D8A00290708435B3AC5.cso create mode 100644 PopcornFX/PopcornFXInternals/Shaders/DebugParticleGeom.geom.38E2D27FF7046D8A00290708435B3AC5.cso.pdb create mode 100644 PopcornFX/PopcornFXInternals/Shaders/DebugParticleGeom.geom.40452A858BDF0DD351CAAC7CAD4D75AC.cso create mode 100644 PopcornFX/PopcornFXInternals/Shaders/DebugParticleGeom.geom.40452A858BDF0DD351CAAC7CAD4D75AC.cso.pdb create mode 100644 PopcornFX/PopcornFXInternals/Shaders/DebugParticleGeom.geom.455299EAF18CA9285CFB885E58CDC6D0.cso create mode 100644 PopcornFX/PopcornFXInternals/Shaders/DebugParticleGeom.geom.455299EAF18CA9285CFB885E58CDC6D0.cso.pdb create mode 100644 PopcornFX/PopcornFXInternals/Shaders/DebugParticleGeom.geom.494F248863E815B635F86B4C4A2B9878.cso create mode 100644 PopcornFX/PopcornFXInternals/Shaders/DebugParticleGeom.geom.494F248863E815B635F86B4C4A2B9878.cso.pdb create mode 100644 PopcornFX/PopcornFXInternals/Shaders/DebugParticleGeom.geom.4A6E9FDAA1CE421286BA2A3A30A6658A.cso create mode 100644 PopcornFX/PopcornFXInternals/Shaders/DebugParticleGeom.geom.4A6E9FDAA1CE421286BA2A3A30A6658A.cso.pdb create mode 100644 PopcornFX/PopcornFXInternals/Shaders/DebugParticleGeom.geom.566A5829015B608CF29A39550DEF77DC.cso create mode 100644 PopcornFX/PopcornFXInternals/Shaders/DebugParticleGeom.geom.566A5829015B608CF29A39550DEF77DC.cso.pdb create mode 100644 PopcornFX/PopcornFXInternals/Shaders/DebugParticleGeom.geom.5E305102DF74F937A763A780239EC2AB.cso create mode 100644 PopcornFX/PopcornFXInternals/Shaders/DebugParticleGeom.geom.5E305102DF74F937A763A780239EC2AB.cso.pdb create mode 100644 PopcornFX/PopcornFXInternals/Shaders/DebugParticleGeom.geom.5F5DF159396A6B8FE4C4A0F97D78924B.cso create mode 100644 PopcornFX/PopcornFXInternals/Shaders/DebugParticleGeom.geom.5F5DF159396A6B8FE4C4A0F97D78924B.cso.pdb create mode 100644 PopcornFX/PopcornFXInternals/Shaders/DebugParticleGeom.geom.7B8359347B0DEF37AA39A05B62E5CBC1.cso create mode 100644 PopcornFX/PopcornFXInternals/Shaders/DebugParticleGeom.geom.7B8359347B0DEF37AA39A05B62E5CBC1.cso.pdb create mode 100644 PopcornFX/PopcornFXInternals/Shaders/DebugParticleGeom.geom.7EEA6AF74A7E1398CE4B70E260147AF0.cso create mode 100644 PopcornFX/PopcornFXInternals/Shaders/DebugParticleGeom.geom.7EEA6AF74A7E1398CE4B70E260147AF0.cso.pdb create mode 100644 PopcornFX/PopcornFXInternals/Shaders/DebugParticleGeom.geom.7F33C027EBB191F2059BE1A8839D31F5.cso create mode 100644 PopcornFX/PopcornFXInternals/Shaders/DebugParticleGeom.geom.7F33C027EBB191F2059BE1A8839D31F5.cso.pdb create mode 100644 PopcornFX/PopcornFXInternals/Shaders/DebugParticleGeom.geom.893C3B31AEB4B56E07A0C0112A35B626.cso create mode 100644 PopcornFX/PopcornFXInternals/Shaders/DebugParticleGeom.geom.893C3B31AEB4B56E07A0C0112A35B626.cso.pdb create mode 100644 PopcornFX/PopcornFXInternals/Shaders/DebugParticleGeom.geom.8DDF66C3535F05343B6E0711A2F5EDE9.cso create mode 100644 PopcornFX/PopcornFXInternals/Shaders/DebugParticleGeom.geom.8DDF66C3535F05343B6E0711A2F5EDE9.cso.pdb create mode 100644 PopcornFX/PopcornFXInternals/Shaders/DebugParticleGeom.geom.9EBF63F0CECB121FB08C73258F424154.cso create mode 100644 PopcornFX/PopcornFXInternals/Shaders/DebugParticleGeom.geom.9EBF63F0CECB121FB08C73258F424154.cso.pdb create mode 100644 PopcornFX/PopcornFXInternals/Shaders/DebugParticleGeom.geom.9F151426D3A5187075EB122B45099E95.cso create mode 100644 PopcornFX/PopcornFXInternals/Shaders/DebugParticleGeom.geom.9F151426D3A5187075EB122B45099E95.cso.pdb create mode 100644 PopcornFX/PopcornFXInternals/Shaders/DebugParticleGeom.geom.C1D8B1B3F659E4754B02859930024C34.cso create mode 100644 PopcornFX/PopcornFXInternals/Shaders/DebugParticleGeom.geom.C1D8B1B3F659E4754B02859930024C34.cso.pdb create mode 100644 PopcornFX/PopcornFXInternals/Shaders/DebugParticleGeom.geom.CD3CD6C95FE00B70F3CB44712C4E6F6F.cso create mode 100644 PopcornFX/PopcornFXInternals/Shaders/DebugParticleGeom.geom.CD3CD6C95FE00B70F3CB44712C4E6F6F.cso.pdb create mode 100644 PopcornFX/PopcornFXInternals/Shaders/DebugParticleGeom.geom.DBAB50AF656C0B77BE3EACFA872A4107.cso create mode 100644 PopcornFX/PopcornFXInternals/Shaders/DebugParticleGeom.geom.DBAB50AF656C0B77BE3EACFA872A4107.cso.pdb create mode 100644 PopcornFX/PopcornFXInternals/Shaders/DebugParticleGeom.geom.E46C7BF11C16009DAD26F2E52BCA71ED.cso create mode 100644 PopcornFX/PopcornFXInternals/Shaders/DebugParticleGeom.geom.E46C7BF11C16009DAD26F2E52BCA71ED.cso.pdb create mode 100644 PopcornFX/PopcornFXInternals/Shaders/DebugParticleGeom.geom.EDC05431FEB536B2137D9C70A18E0E85.cso create mode 100644 PopcornFX/PopcornFXInternals/Shaders/DebugParticleGeom.geom.EDC05431FEB536B2137D9C70A18E0E85.cso.pdb create mode 100644 PopcornFX/PopcornFXInternals/Shaders/DebugParticleGeom.geom.F43E932D41866B4751D2AAAA122C0DF8.cso create mode 100644 PopcornFX/PopcornFXInternals/Shaders/DebugParticleGeom.geom.F43E932D41866B4751D2AAAA122C0DF8.cso.pdb create mode 100644 PopcornFX/PopcornFXInternals/Shaders/DebugParticleGeom.geom.FD048825BBE1F9EEFF9AF105929E49F9.cso create mode 100644 PopcornFX/PopcornFXInternals/Shaders/DebugParticleGeom.geom.FD048825BBE1F9EEFF9AF105929E49F9.cso.pdb create mode 100644 PopcornFX/PopcornFXInternals/Shaders/DebugParticleGeom_CPU.vert.0491B9E5DB4146F6039DB5A1028E068F.cso create mode 100644 PopcornFX/PopcornFXInternals/Shaders/DebugParticleGeom_CPU.vert.0491B9E5DB4146F6039DB5A1028E068F.cso.pdb create mode 100644 PopcornFX/PopcornFXInternals/Shaders/DebugParticleGeom_CPU.vert.089C1A93F75623C5625465ADC48162D9.cso create mode 100644 PopcornFX/PopcornFXInternals/Shaders/DebugParticleGeom_CPU.vert.089C1A93F75623C5625465ADC48162D9.cso.pdb create mode 100644 PopcornFX/PopcornFXInternals/Shaders/DebugParticleGeom_CPU.vert.2CBCDD973DD8785D8ED96E438B732020.cso create mode 100644 PopcornFX/PopcornFXInternals/Shaders/DebugParticleGeom_CPU.vert.2CBCDD973DD8785D8ED96E438B732020.cso.pdb create mode 100644 PopcornFX/PopcornFXInternals/Shaders/DebugParticleGeom_CPU.vert.2EBB1E214294B7250FB31039A38D6AC5.cso create mode 100644 PopcornFX/PopcornFXInternals/Shaders/DebugParticleGeom_CPU.vert.2EBB1E214294B7250FB31039A38D6AC5.cso.pdb create mode 100644 PopcornFX/PopcornFXInternals/Shaders/DebugParticleGeom_CPU.vert.38E30D094B028C691653A728362634B2.cso create mode 100644 PopcornFX/PopcornFXInternals/Shaders/DebugParticleGeom_CPU.vert.38E30D094B028C691653A728362634B2.cso.pdb create mode 100644 PopcornFX/PopcornFXInternals/Shaders/DebugParticleGeom_CPU.vert.45152D6B551F36103EA55B435AD0C462.cso create mode 100644 PopcornFX/PopcornFXInternals/Shaders/DebugParticleGeom_CPU.vert.45152D6B551F36103EA55B435AD0C462.cso.pdb create mode 100644 PopcornFX/PopcornFXInternals/Shaders/DebugParticleGeom_CPU.vert.57701C60E841F468867561F9335BDAB3.cso create mode 100644 PopcornFX/PopcornFXInternals/Shaders/DebugParticleGeom_CPU.vert.57701C60E841F468867561F9335BDAB3.cso.pdb create mode 100644 PopcornFX/PopcornFXInternals/Shaders/DebugParticleGeom_CPU.vert.630652A3268DE6E9BDE38BC918841E62.cso create mode 100644 PopcornFX/PopcornFXInternals/Shaders/DebugParticleGeom_CPU.vert.630652A3268DE6E9BDE38BC918841E62.cso.pdb create mode 100644 PopcornFX/PopcornFXInternals/Shaders/DebugParticleGeom_CPU.vert.77B31999700322078CF970FEB7407F9C.cso create mode 100644 PopcornFX/PopcornFXInternals/Shaders/DebugParticleGeom_CPU.vert.77B31999700322078CF970FEB7407F9C.cso.pdb create mode 100644 PopcornFX/PopcornFXInternals/Shaders/DebugParticleGeom_CPU.vert.7D65653E05F3CFD999E0CFE63FA6E06D.cso create mode 100644 PopcornFX/PopcornFXInternals/Shaders/DebugParticleGeom_CPU.vert.7D65653E05F3CFD999E0CFE63FA6E06D.cso.pdb create mode 100644 PopcornFX/PopcornFXInternals/Shaders/DebugParticleGeom_CPU.vert.AA7A6E402DA45EA1877F3864059BB328.cso create mode 100644 PopcornFX/PopcornFXInternals/Shaders/DebugParticleGeom_CPU.vert.AA7A6E402DA45EA1877F3864059BB328.cso.pdb create mode 100644 PopcornFX/PopcornFXInternals/Shaders/DebugParticleGeom_CPU.vert.ABC8329C82EFC7A175A670CD89AFCF15.cso create mode 100644 PopcornFX/PopcornFXInternals/Shaders/DebugParticleGeom_CPU.vert.ABC8329C82EFC7A175A670CD89AFCF15.cso.pdb create mode 100644 PopcornFX/PopcornFXInternals/Shaders/DebugParticleGeom_CPU.vert.AF299C4F5A88FF41BB134DEBBD221243.cso create mode 100644 PopcornFX/PopcornFXInternals/Shaders/DebugParticleGeom_CPU.vert.AF299C4F5A88FF41BB134DEBBD221243.cso.pdb create mode 100644 PopcornFX/PopcornFXInternals/Shaders/DebugParticleGeom_CPU.vert.B73B1CA9CB013890A989873EBD811678.cso create mode 100644 PopcornFX/PopcornFXInternals/Shaders/DebugParticleGeom_CPU.vert.B73B1CA9CB013890A989873EBD811678.cso.pdb create mode 100644 PopcornFX/PopcornFXInternals/Shaders/DebugParticleGeom_CPU.vert.BB1894D2E83C03A44A1F4C0ACFAC5941.cso create mode 100644 PopcornFX/PopcornFXInternals/Shaders/DebugParticleGeom_CPU.vert.BB1894D2E83C03A44A1F4C0ACFAC5941.cso.pdb create mode 100644 PopcornFX/PopcornFXInternals/Shaders/DebugParticleGeom_CPU.vert.CF3846F9E7636FD9485E620D0B85EA7A.cso create mode 100644 PopcornFX/PopcornFXInternals/Shaders/DebugParticleGeom_CPU.vert.CF3846F9E7636FD9485E620D0B85EA7A.cso.pdb create mode 100644 PopcornFX/PopcornFXInternals/Shaders/DebugParticleGeom_CPU.vert.CFDCA74BBAE47557D9554F9C6994FFF5.cso create mode 100644 PopcornFX/PopcornFXInternals/Shaders/DebugParticleGeom_CPU.vert.CFDCA74BBAE47557D9554F9C6994FFF5.cso.pdb create mode 100644 PopcornFX/PopcornFXInternals/Shaders/DebugParticleGeom_CPU.vert.D1027BFD27F09759DCE21D6C3D0007E6.cso create mode 100644 PopcornFX/PopcornFXInternals/Shaders/DebugParticleGeom_CPU.vert.D1027BFD27F09759DCE21D6C3D0007E6.cso.pdb create mode 100644 PopcornFX/PopcornFXInternals/Shaders/DebugParticleGeom_CPU.vert.D11F440AEF887A61EE9AF025D5E23AB9.cso create mode 100644 PopcornFX/PopcornFXInternals/Shaders/DebugParticleGeom_CPU.vert.D11F440AEF887A61EE9AF025D5E23AB9.cso.pdb create mode 100644 PopcornFX/PopcornFXInternals/Shaders/DebugParticleGeom_CPU.vert.DF9214C22288F9B9A48D38F5B74524DE.cso create mode 100644 PopcornFX/PopcornFXInternals/Shaders/DebugParticleGeom_CPU.vert.DF9214C22288F9B9A48D38F5B74524DE.cso.pdb create mode 100644 PopcornFX/PopcornFXInternals/Shaders/DebugParticleGeom_CPU.vert.E085F93BEC7DF3EBA14A46B44E57CA65.cso create mode 100644 PopcornFX/PopcornFXInternals/Shaders/DebugParticleGeom_CPU.vert.E085F93BEC7DF3EBA14A46B44E57CA65.cso.pdb create mode 100644 PopcornFX/PopcornFXInternals/Shaders/DebugParticleGeom_CPU.vert.E439E2679AC92876BE93DB6F63E71BA4.cso create mode 100644 PopcornFX/PopcornFXInternals/Shaders/DebugParticleGeom_CPU.vert.E439E2679AC92876BE93DB6F63E71BA4.cso.pdb create mode 100644 PopcornFX/PopcornFXInternals/Shaders/DebugParticleGeom_CPU.vert.FD3064546B01E2F76BFF1BFDEB54CC81.cso create mode 100644 PopcornFX/PopcornFXInternals/Shaders/DebugParticleGeom_CPU.vert.FD3064546B01E2F76BFF1BFDEB54CC81.cso.pdb create mode 100644 PopcornFX/PopcornFXInternals/Shaders/DebugParticleGeom_CPU.vert.FF385EE49D348C3D94E3E75DDEC43EF1.cso create mode 100644 PopcornFX/PopcornFXInternals/Shaders/DebugParticleGeom_CPU.vert.FF385EE49D348C3D94E3E75DDEC43EF1.cso.pdb create mode 100644 PopcornFX/PopcornFXInternals/Shaders/DebugParticleGeom_GPU.vert.03A9039DF625A5CE430A52161825FB2E.cso create mode 100644 PopcornFX/PopcornFXInternals/Shaders/DebugParticleGeom_GPU.vert.03A9039DF625A5CE430A52161825FB2E.cso.pdb create mode 100644 PopcornFX/PopcornFXInternals/Shaders/DebugParticleGeom_GPU.vert.125702F176A5DC7DE52D9A2D09ACB336.cso create mode 100644 PopcornFX/PopcornFXInternals/Shaders/DebugParticleGeom_GPU.vert.125702F176A5DC7DE52D9A2D09ACB336.cso.pdb create mode 100644 PopcornFX/PopcornFXInternals/Shaders/DebugParticleGeom_GPU.vert.1ADEC6D7AA8D6B5FA2623A3803561740.cso create mode 100644 PopcornFX/PopcornFXInternals/Shaders/DebugParticleGeom_GPU.vert.1ADEC6D7AA8D6B5FA2623A3803561740.cso.pdb create mode 100644 PopcornFX/PopcornFXInternals/Shaders/DebugParticleGeom_GPU.vert.1B4EF1D1BFD046CEA6303A75D5A090DD.cso create mode 100644 PopcornFX/PopcornFXInternals/Shaders/DebugParticleGeom_GPU.vert.1B4EF1D1BFD046CEA6303A75D5A090DD.cso.pdb create mode 100644 PopcornFX/PopcornFXInternals/Shaders/DebugParticleGeom_GPU.vert.215E7FA2E1D915E575BF0D051FF57DAC.cso create mode 100644 PopcornFX/PopcornFXInternals/Shaders/DebugParticleGeom_GPU.vert.215E7FA2E1D915E575BF0D051FF57DAC.cso.pdb create mode 100644 PopcornFX/PopcornFXInternals/Shaders/DebugParticleGeom_GPU.vert.2CF9EB30E57EC06C260F1C994273BBB9.cso create mode 100644 PopcornFX/PopcornFXInternals/Shaders/DebugParticleGeom_GPU.vert.2CF9EB30E57EC06C260F1C994273BBB9.cso.pdb create mode 100644 PopcornFX/PopcornFXInternals/Shaders/DebugParticleGeom_GPU.vert.3830050E054524D9FB4B97B3C5795D74.cso create mode 100644 PopcornFX/PopcornFXInternals/Shaders/DebugParticleGeom_GPU.vert.3830050E054524D9FB4B97B3C5795D74.cso.pdb create mode 100644 PopcornFX/PopcornFXInternals/Shaders/DebugParticleGeom_GPU.vert.3FC5681EEA9466868BDE6277412A1602.cso create mode 100644 PopcornFX/PopcornFXInternals/Shaders/DebugParticleGeom_GPU.vert.3FC5681EEA9466868BDE6277412A1602.cso.pdb create mode 100644 PopcornFX/PopcornFXInternals/Shaders/DebugParticleGeom_GPU.vert.54CE329F05A57498A425EEE7FFB92A53.cso create mode 100644 PopcornFX/PopcornFXInternals/Shaders/DebugParticleGeom_GPU.vert.54CE329F05A57498A425EEE7FFB92A53.cso.pdb create mode 100644 PopcornFX/PopcornFXInternals/Shaders/DebugParticleGeom_GPU.vert.63E4E8675470AA49793AE6B8F2EFB412.cso create mode 100644 PopcornFX/PopcornFXInternals/Shaders/DebugParticleGeom_GPU.vert.63E4E8675470AA49793AE6B8F2EFB412.cso.pdb create mode 100644 PopcornFX/PopcornFXInternals/Shaders/DebugParticleGeom_GPU.vert.6EDA9FA1D0CE763321BA160FE1F69436.cso create mode 100644 PopcornFX/PopcornFXInternals/Shaders/DebugParticleGeom_GPU.vert.6EDA9FA1D0CE763321BA160FE1F69436.cso.pdb create mode 100644 PopcornFX/PopcornFXInternals/Shaders/DebugParticleGeom_GPU.vert.7B6CA6E5E319B7DCD804E51483B1560B.cso create mode 100644 PopcornFX/PopcornFXInternals/Shaders/DebugParticleGeom_GPU.vert.7B6CA6E5E319B7DCD804E51483B1560B.cso.pdb create mode 100644 PopcornFX/PopcornFXInternals/Shaders/DebugParticleGeom_GPU.vert.8041C676881D61780106102C13F8133C.cso create mode 100644 PopcornFX/PopcornFXInternals/Shaders/DebugParticleGeom_GPU.vert.8041C676881D61780106102C13F8133C.cso.pdb create mode 100644 PopcornFX/PopcornFXInternals/Shaders/DebugParticleGeom_GPU.vert.96BCBFB5543D4357E250741BD758D684.cso create mode 100644 PopcornFX/PopcornFXInternals/Shaders/DebugParticleGeom_GPU.vert.96BCBFB5543D4357E250741BD758D684.cso.pdb create mode 100644 PopcornFX/PopcornFXInternals/Shaders/DebugParticleGeom_GPU.vert.AAE2DCCA9E4429BEDF7F5C12A4918FBE.cso create mode 100644 PopcornFX/PopcornFXInternals/Shaders/DebugParticleGeom_GPU.vert.AAE2DCCA9E4429BEDF7F5C12A4918FBE.cso.pdb create mode 100644 PopcornFX/PopcornFXInternals/Shaders/DebugParticleGeom_GPU.vert.B7B90948D23B69401E4275BBBA5F6021.cso create mode 100644 PopcornFX/PopcornFXInternals/Shaders/DebugParticleGeom_GPU.vert.B7B90948D23B69401E4275BBBA5F6021.cso.pdb create mode 100644 PopcornFX/PopcornFXInternals/Shaders/DebugParticleGeom_GPU.vert.B959A091D6A562E3BB2A4A86D8938E3B.cso create mode 100644 PopcornFX/PopcornFXInternals/Shaders/DebugParticleGeom_GPU.vert.B959A091D6A562E3BB2A4A86D8938E3B.cso.pdb create mode 100644 PopcornFX/PopcornFXInternals/Shaders/DebugParticleGeom_GPU.vert.C631C6F1C848D8407BB4550427BFAFE5.cso create mode 100644 PopcornFX/PopcornFXInternals/Shaders/DebugParticleGeom_GPU.vert.C631C6F1C848D8407BB4550427BFAFE5.cso.pdb create mode 100644 PopcornFX/PopcornFXInternals/Shaders/DebugParticleGeom_GPU.vert.C7D9E2F6ACF45D7DCA8F8EB92111BCBC.cso create mode 100644 PopcornFX/PopcornFXInternals/Shaders/DebugParticleGeom_GPU.vert.C7D9E2F6ACF45D7DCA8F8EB92111BCBC.cso.pdb create mode 100644 PopcornFX/PopcornFXInternals/Shaders/DebugParticleGeom_GPU.vert.E757CD08237F5B4A4C260EE943E6A7BC.cso create mode 100644 PopcornFX/PopcornFXInternals/Shaders/DebugParticleGeom_GPU.vert.E757CD08237F5B4A4C260EE943E6A7BC.cso.pdb create mode 100644 PopcornFX/PopcornFXInternals/Shaders/DebugParticleGeom_GPU.vert.F0F89BC5650EEE995AA9D7357378D280.cso create mode 100644 PopcornFX/PopcornFXInternals/Shaders/DebugParticleGeom_GPU.vert.F0F89BC5650EEE995AA9D7357378D280.cso.pdb create mode 100644 PopcornFX/PopcornFXInternals/Shaders/DebugParticleGeom_GPU.vert.F2AC0D1822C5C821BF888C0AB7491E5E.cso create mode 100644 PopcornFX/PopcornFXInternals/Shaders/DebugParticleGeom_GPU.vert.F2AC0D1822C5C821BF888C0AB7491E5E.cso.pdb create mode 100644 PopcornFX/PopcornFXInternals/Shaders/DebugParticleGeom_GPU.vert.FA071B919FA56A0FB70F4ED2F802D474.cso create mode 100644 PopcornFX/PopcornFXInternals/Shaders/DebugParticleGeom_GPU.vert.FA071B919FA56A0FB70F4ED2F802D474.cso.pdb create mode 100644 PopcornFX/PopcornFXInternals/Shaders/DebugParticleGeom_GPU.vert.FEE5E6A661D8F4453A0120A78702157A.cso create mode 100644 PopcornFX/PopcornFXInternals/Shaders/DebugParticleGeom_GPU.vert.FEE5E6A661D8F4453A0120A78702157A.cso.pdb create mode 100644 PopcornFX/PopcornFXInternals/Shaders/DebugParticleVertexBB.vert.0323DA1D4D66DFFC422FD195212F40AC.cso create mode 100644 PopcornFX/PopcornFXInternals/Shaders/DebugParticleVertexBB.vert.0323DA1D4D66DFFC422FD195212F40AC.cso.pdb create mode 100644 PopcornFX/PopcornFXInternals/Shaders/DebugParticleVertexBB.vert.08792B0244607751B94495BF11FEA6C3.metallib create mode 100644 PopcornFX/PopcornFXInternals/Shaders/DebugParticleVertexBB.vert.0A7FA5C512F5E63FC77778DAD58C1444.cso create mode 100644 PopcornFX/PopcornFXInternals/Shaders/DebugParticleVertexBB.vert.0A7FA5C512F5E63FC77778DAD58C1444.cso.pdb create mode 100644 PopcornFX/PopcornFXInternals/Shaders/DebugParticleVertexBB.vert.0BD3C6312B7670505B943262A89C9294.cso create mode 100644 PopcornFX/PopcornFXInternals/Shaders/DebugParticleVertexBB.vert.0BD3C6312B7670505B943262A89C9294.cso.pdb create mode 100644 PopcornFX/PopcornFXInternals/Shaders/DebugParticleVertexBB.vert.0C752CA2B0AA5C4F58A28B4FB4DBC067.metallib create mode 100644 PopcornFX/PopcornFXInternals/Shaders/DebugParticleVertexBB.vert.0D2906E0F0B901297CEC98725443F6B8.cso create mode 100644 PopcornFX/PopcornFXInternals/Shaders/DebugParticleVertexBB.vert.0D2906E0F0B901297CEC98725443F6B8.cso.pdb create mode 100644 PopcornFX/PopcornFXInternals/Shaders/DebugParticleVertexBB.vert.0DC89CC6EF2BB651C434A448D67109E9.cso create mode 100644 PopcornFX/PopcornFXInternals/Shaders/DebugParticleVertexBB.vert.0DC89CC6EF2BB651C434A448D67109E9.cso.pdb create mode 100644 PopcornFX/PopcornFXInternals/Shaders/DebugParticleVertexBB.vert.1244F96A9F041AA77E0829FE15A81781.cso create mode 100644 PopcornFX/PopcornFXInternals/Shaders/DebugParticleVertexBB.vert.1244F96A9F041AA77E0829FE15A81781.cso.pdb create mode 100644 PopcornFX/PopcornFXInternals/Shaders/DebugParticleVertexBB.vert.15BA3C3CB8B8717F4D80F5FEC204370F.metallib create mode 100644 PopcornFX/PopcornFXInternals/Shaders/DebugParticleVertexBB.vert.180EA62B9D1202547139A36A2D1C9FCC.metallib create mode 100644 PopcornFX/PopcornFXInternals/Shaders/DebugParticleVertexBB.vert.1925F8BB8C5C6BD69F02FA2CD1B6D8F0.cso create mode 100644 PopcornFX/PopcornFXInternals/Shaders/DebugParticleVertexBB.vert.1925F8BB8C5C6BD69F02FA2CD1B6D8F0.cso.pdb create mode 100644 PopcornFX/PopcornFXInternals/Shaders/DebugParticleVertexBB.vert.19E6B3D25951E1F2F91F02467D1FB30F.cso create mode 100644 PopcornFX/PopcornFXInternals/Shaders/DebugParticleVertexBB.vert.19E6B3D25951E1F2F91F02467D1FB30F.cso.pdb create mode 100644 PopcornFX/PopcornFXInternals/Shaders/DebugParticleVertexBB.vert.1A0AF4135571475AB793369A890D45CA.metallib create mode 100644 PopcornFX/PopcornFXInternals/Shaders/DebugParticleVertexBB.vert.1A894823438A140EA9E04BF73CD2EAA5.cso create mode 100644 PopcornFX/PopcornFXInternals/Shaders/DebugParticleVertexBB.vert.1A894823438A140EA9E04BF73CD2EAA5.cso.pdb create mode 100644 PopcornFX/PopcornFXInternals/Shaders/DebugParticleVertexBB.vert.1B961C28B1FDF4C1823DAA29CE009487.cso create mode 100644 PopcornFX/PopcornFXInternals/Shaders/DebugParticleVertexBB.vert.1B961C28B1FDF4C1823DAA29CE009487.cso.pdb create mode 100644 PopcornFX/PopcornFXInternals/Shaders/DebugParticleVertexBB.vert.1E6971511258F0A69158B0C15A49CFC7.metallib create mode 100644 PopcornFX/PopcornFXInternals/Shaders/DebugParticleVertexBB.vert.21E51D63F6FD0658E746CAE70039F290.cso create mode 100644 PopcornFX/PopcornFXInternals/Shaders/DebugParticleVertexBB.vert.21E51D63F6FD0658E746CAE70039F290.cso.pdb create mode 100644 PopcornFX/PopcornFXInternals/Shaders/DebugParticleVertexBB.vert.22F4863734AAC59D6C9C66C631B23B6E.cso create mode 100644 PopcornFX/PopcornFXInternals/Shaders/DebugParticleVertexBB.vert.22F4863734AAC59D6C9C66C631B23B6E.cso.pdb create mode 100644 PopcornFX/PopcornFXInternals/Shaders/DebugParticleVertexBB.vert.2CD2DBBA33D183ACE6CD7F2A42321467.metallib create mode 100644 PopcornFX/PopcornFXInternals/Shaders/DebugParticleVertexBB.vert.2E6BE8AF0F44BC5CC7DA119DDBB43E98.cso create mode 100644 PopcornFX/PopcornFXInternals/Shaders/DebugParticleVertexBB.vert.2E6BE8AF0F44BC5CC7DA119DDBB43E98.cso.pdb create mode 100644 PopcornFX/PopcornFXInternals/Shaders/DebugParticleVertexBB.vert.2F8A55777C2632894CF6DBCA38D259A8.cso create mode 100644 PopcornFX/PopcornFXInternals/Shaders/DebugParticleVertexBB.vert.2F8A55777C2632894CF6DBCA38D259A8.cso.pdb create mode 100644 PopcornFX/PopcornFXInternals/Shaders/DebugParticleVertexBB.vert.31F564DDF64897CE8D0D8575BA11EA13.metallib create mode 100644 PopcornFX/PopcornFXInternals/Shaders/DebugParticleVertexBB.vert.323B3616109D749EF6D2A3CF51050BE6.cso create mode 100644 PopcornFX/PopcornFXInternals/Shaders/DebugParticleVertexBB.vert.323B3616109D749EF6D2A3CF51050BE6.cso.pdb create mode 100644 PopcornFX/PopcornFXInternals/Shaders/DebugParticleVertexBB.vert.3340D8F8BFE958B965936432A77D2811.cso create mode 100644 PopcornFX/PopcornFXInternals/Shaders/DebugParticleVertexBB.vert.3340D8F8BFE958B965936432A77D2811.cso.pdb create mode 100644 PopcornFX/PopcornFXInternals/Shaders/DebugParticleVertexBB.vert.34AC697454E7671946541CA5BDED791A.cso create mode 100644 PopcornFX/PopcornFXInternals/Shaders/DebugParticleVertexBB.vert.34AC697454E7671946541CA5BDED791A.cso.pdb create mode 100644 PopcornFX/PopcornFXInternals/Shaders/DebugParticleVertexBB.vert.3A79EBFB229E33A9A80C49E5140236DE.cso create mode 100644 PopcornFX/PopcornFXInternals/Shaders/DebugParticleVertexBB.vert.3A79EBFB229E33A9A80C49E5140236DE.cso.pdb create mode 100644 PopcornFX/PopcornFXInternals/Shaders/DebugParticleVertexBB.vert.3B0D4E708AD83ECD8CB195DDCB463524.cso create mode 100644 PopcornFX/PopcornFXInternals/Shaders/DebugParticleVertexBB.vert.3B0D4E708AD83ECD8CB195DDCB463524.cso.pdb create mode 100644 PopcornFX/PopcornFXInternals/Shaders/DebugParticleVertexBB.vert.3B4B9C3BB8420D61B0C14B7C673D4312.metallib create mode 100644 PopcornFX/PopcornFXInternals/Shaders/DebugParticleVertexBB.vert.40FE6F3B1F908655080943E7970B5923.cso create mode 100644 PopcornFX/PopcornFXInternals/Shaders/DebugParticleVertexBB.vert.40FE6F3B1F908655080943E7970B5923.cso.pdb create mode 100644 PopcornFX/PopcornFXInternals/Shaders/DebugParticleVertexBB.vert.41CC71331EA3F4DF19C62447C3B4957D.metallib create mode 100644 PopcornFX/PopcornFXInternals/Shaders/DebugParticleVertexBB.vert.441699570AB850AD3DB81564F52B0908.metallib create mode 100644 PopcornFX/PopcornFXInternals/Shaders/DebugParticleVertexBB.vert.476DA901FEFBD9A0A3C70B45C3313D67.metallib create mode 100644 PopcornFX/PopcornFXInternals/Shaders/DebugParticleVertexBB.vert.495C0A9F8FB4194D8EF08AE9C350B23E.metallib create mode 100644 PopcornFX/PopcornFXInternals/Shaders/DebugParticleVertexBB.vert.4B8021430CC3C9971C8BC859E0C8989D.cso create mode 100644 PopcornFX/PopcornFXInternals/Shaders/DebugParticleVertexBB.vert.4B8021430CC3C9971C8BC859E0C8989D.cso.pdb create mode 100644 PopcornFX/PopcornFXInternals/Shaders/DebugParticleVertexBB.vert.50D311BEF26C71B333D271C49B078772.metallib create mode 100644 PopcornFX/PopcornFXInternals/Shaders/DebugParticleVertexBB.vert.5166BF50736369CD4E22FFBFC064DE76.metallib create mode 100644 PopcornFX/PopcornFXInternals/Shaders/DebugParticleVertexBB.vert.56DD6FF54063679C76D12691EA79ED95.cso create mode 100644 PopcornFX/PopcornFXInternals/Shaders/DebugParticleVertexBB.vert.56DD6FF54063679C76D12691EA79ED95.cso.pdb create mode 100644 PopcornFX/PopcornFXInternals/Shaders/DebugParticleVertexBB.vert.6421B04960935975A09996C65CF0A478.cso create mode 100644 PopcornFX/PopcornFXInternals/Shaders/DebugParticleVertexBB.vert.6421B04960935975A09996C65CF0A478.cso.pdb create mode 100644 PopcornFX/PopcornFXInternals/Shaders/DebugParticleVertexBB.vert.654D257A8942334F737B4CF3DBED0F48.cso create mode 100644 PopcornFX/PopcornFXInternals/Shaders/DebugParticleVertexBB.vert.654D257A8942334F737B4CF3DBED0F48.cso.pdb create mode 100644 PopcornFX/PopcornFXInternals/Shaders/DebugParticleVertexBB.vert.67F490450BA69DEBD5593D019A7EC0B6.metallib create mode 100644 PopcornFX/PopcornFXInternals/Shaders/DebugParticleVertexBB.vert.6ABEABA3444031DF1A478CE27CADC998.cso create mode 100644 PopcornFX/PopcornFXInternals/Shaders/DebugParticleVertexBB.vert.6ABEABA3444031DF1A478CE27CADC998.cso.pdb create mode 100644 PopcornFX/PopcornFXInternals/Shaders/DebugParticleVertexBB.vert.6AF760A6E9E643069DB35D5D06BD6BA9.cso create mode 100644 PopcornFX/PopcornFXInternals/Shaders/DebugParticleVertexBB.vert.6AF760A6E9E643069DB35D5D06BD6BA9.cso.pdb create mode 100644 PopcornFX/PopcornFXInternals/Shaders/DebugParticleVertexBB.vert.6D377C6B02680802CD74BA81C639ED28.cso create mode 100644 PopcornFX/PopcornFXInternals/Shaders/DebugParticleVertexBB.vert.6D377C6B02680802CD74BA81C639ED28.cso.pdb create mode 100644 PopcornFX/PopcornFXInternals/Shaders/DebugParticleVertexBB.vert.6E949D72552C7F34F1E09D89F1E1C952.cso create mode 100644 PopcornFX/PopcornFXInternals/Shaders/DebugParticleVertexBB.vert.6E949D72552C7F34F1E09D89F1E1C952.cso.pdb create mode 100644 PopcornFX/PopcornFXInternals/Shaders/DebugParticleVertexBB.vert.71D4C26BBE212B4D2A9608C1E34D86E4.metallib create mode 100644 PopcornFX/PopcornFXInternals/Shaders/DebugParticleVertexBB.vert.7204742FB331648ED83573329D86D073.cso create mode 100644 PopcornFX/PopcornFXInternals/Shaders/DebugParticleVertexBB.vert.7204742FB331648ED83573329D86D073.cso.pdb create mode 100644 PopcornFX/PopcornFXInternals/Shaders/DebugParticleVertexBB.vert.73CFC84CF655AC999324D43BDB1E4EB6.metallib create mode 100644 PopcornFX/PopcornFXInternals/Shaders/DebugParticleVertexBB.vert.74380FFB48164FF6B35623BE8701B7EB.cso create mode 100644 PopcornFX/PopcornFXInternals/Shaders/DebugParticleVertexBB.vert.74380FFB48164FF6B35623BE8701B7EB.cso.pdb create mode 100644 PopcornFX/PopcornFXInternals/Shaders/DebugParticleVertexBB.vert.7521DA417DCEAD1B47E7D7BE0B95AFE5.metallib create mode 100644 PopcornFX/PopcornFXInternals/Shaders/DebugParticleVertexBB.vert.7B8E55E72E6CA6ACF6F1D3A81B3BC9D2.metallib create mode 100644 PopcornFX/PopcornFXInternals/Shaders/DebugParticleVertexBB.vert.7E7C2EBE718EBA32FB6282BC269E323D.cso create mode 100644 PopcornFX/PopcornFXInternals/Shaders/DebugParticleVertexBB.vert.7E7C2EBE718EBA32FB6282BC269E323D.cso.pdb create mode 100644 PopcornFX/PopcornFXInternals/Shaders/DebugParticleVertexBB.vert.80EF261D1CC4A59FCF572E60A2F410EF.cso create mode 100644 PopcornFX/PopcornFXInternals/Shaders/DebugParticleVertexBB.vert.80EF261D1CC4A59FCF572E60A2F410EF.cso.pdb create mode 100644 PopcornFX/PopcornFXInternals/Shaders/DebugParticleVertexBB.vert.8206568794DB63EDFB28346F08717693.metallib create mode 100644 PopcornFX/PopcornFXInternals/Shaders/DebugParticleVertexBB.vert.86BBDE2865C753261D68E62FEF5F2901.cso create mode 100644 PopcornFX/PopcornFXInternals/Shaders/DebugParticleVertexBB.vert.86BBDE2865C753261D68E62FEF5F2901.cso.pdb create mode 100644 PopcornFX/PopcornFXInternals/Shaders/DebugParticleVertexBB.vert.8ADA3DCDE80CB10E83BA6B98332AB60B.cso create mode 100644 PopcornFX/PopcornFXInternals/Shaders/DebugParticleVertexBB.vert.8ADA3DCDE80CB10E83BA6B98332AB60B.cso.pdb create mode 100644 PopcornFX/PopcornFXInternals/Shaders/DebugParticleVertexBB.vert.8B6EC10AD63C117AADC967DFF1835F04.cso create mode 100644 PopcornFX/PopcornFXInternals/Shaders/DebugParticleVertexBB.vert.8B6EC10AD63C117AADC967DFF1835F04.cso.pdb create mode 100644 PopcornFX/PopcornFXInternals/Shaders/DebugParticleVertexBB.vert.8D5882C7F4BE916035D8A2A19C6DF78A.cso create mode 100644 PopcornFX/PopcornFXInternals/Shaders/DebugParticleVertexBB.vert.8D5882C7F4BE916035D8A2A19C6DF78A.cso.pdb create mode 100644 PopcornFX/PopcornFXInternals/Shaders/DebugParticleVertexBB.vert.90E1EDC296925F67098F2D916779539D.cso create mode 100644 PopcornFX/PopcornFXInternals/Shaders/DebugParticleVertexBB.vert.90E1EDC296925F67098F2D916779539D.cso.pdb create mode 100644 PopcornFX/PopcornFXInternals/Shaders/DebugParticleVertexBB.vert.91F8A2067B8EA071695FF41B8B76AE97.cso create mode 100644 PopcornFX/PopcornFXInternals/Shaders/DebugParticleVertexBB.vert.91F8A2067B8EA071695FF41B8B76AE97.cso.pdb create mode 100644 PopcornFX/PopcornFXInternals/Shaders/DebugParticleVertexBB.vert.93D943F5A9C29E618797431F40796C35.cso create mode 100644 PopcornFX/PopcornFXInternals/Shaders/DebugParticleVertexBB.vert.93D943F5A9C29E618797431F40796C35.cso.pdb create mode 100644 PopcornFX/PopcornFXInternals/Shaders/DebugParticleVertexBB.vert.96DAC364F30C96759E77B529B883C028.cso create mode 100644 PopcornFX/PopcornFXInternals/Shaders/DebugParticleVertexBB.vert.96DAC364F30C96759E77B529B883C028.cso.pdb create mode 100644 PopcornFX/PopcornFXInternals/Shaders/DebugParticleVertexBB.vert.979416BB843C6F05F3845FFCC3ECD7D6.cso create mode 100644 PopcornFX/PopcornFXInternals/Shaders/DebugParticleVertexBB.vert.979416BB843C6F05F3845FFCC3ECD7D6.cso.pdb create mode 100644 PopcornFX/PopcornFXInternals/Shaders/DebugParticleVertexBB.vert.984E39E04658AF07687F9C17D33781DA.cso create mode 100644 PopcornFX/PopcornFXInternals/Shaders/DebugParticleVertexBB.vert.984E39E04658AF07687F9C17D33781DA.cso.pdb create mode 100644 PopcornFX/PopcornFXInternals/Shaders/DebugParticleVertexBB.vert.9AE9452EB8270BB640EA28FE04E85D12.cso create mode 100644 PopcornFX/PopcornFXInternals/Shaders/DebugParticleVertexBB.vert.9AE9452EB8270BB640EA28FE04E85D12.cso.pdb create mode 100644 PopcornFX/PopcornFXInternals/Shaders/DebugParticleVertexBB.vert.9C59ECCAF416177DA2B674CC26C4C7C6.cso create mode 100644 PopcornFX/PopcornFXInternals/Shaders/DebugParticleVertexBB.vert.9C59ECCAF416177DA2B674CC26C4C7C6.cso.pdb create mode 100644 PopcornFX/PopcornFXInternals/Shaders/DebugParticleVertexBB.vert.9C9DC497EE8CB2A3010B8F5BE870A4AD.metallib create mode 100644 PopcornFX/PopcornFXInternals/Shaders/DebugParticleVertexBB.vert.A14339AF9BA1D695A2231452C7C125B1.metallib create mode 100644 PopcornFX/PopcornFXInternals/Shaders/DebugParticleVertexBB.vert.A416CC957DBBA6BB89F520075E9ED987.metallib create mode 100644 PopcornFX/PopcornFXInternals/Shaders/DebugParticleVertexBB.vert.A911A0900D6EB7FD73E64020B22DC54D.cso create mode 100644 PopcornFX/PopcornFXInternals/Shaders/DebugParticleVertexBB.vert.A911A0900D6EB7FD73E64020B22DC54D.cso.pdb create mode 100644 PopcornFX/PopcornFXInternals/Shaders/DebugParticleVertexBB.vert.B0C01FFF068BBB8EC7C84EC464A263C6.cso create mode 100644 PopcornFX/PopcornFXInternals/Shaders/DebugParticleVertexBB.vert.B0C01FFF068BBB8EC7C84EC464A263C6.cso.pdb create mode 100644 PopcornFX/PopcornFXInternals/Shaders/DebugParticleVertexBB.vert.B33BD37027E2C6E47FBC917C8D1AD34C.cso create mode 100644 PopcornFX/PopcornFXInternals/Shaders/DebugParticleVertexBB.vert.B33BD37027E2C6E47FBC917C8D1AD34C.cso.pdb create mode 100644 PopcornFX/PopcornFXInternals/Shaders/DebugParticleVertexBB.vert.B815C5761C479B16EDEFA49DD71F5BEF.cso create mode 100644 PopcornFX/PopcornFXInternals/Shaders/DebugParticleVertexBB.vert.B815C5761C479B16EDEFA49DD71F5BEF.cso.pdb create mode 100644 PopcornFX/PopcornFXInternals/Shaders/DebugParticleVertexBB.vert.B95B5D8436DC9065FA2624B17C3A8F4A.cso create mode 100644 PopcornFX/PopcornFXInternals/Shaders/DebugParticleVertexBB.vert.B95B5D8436DC9065FA2624B17C3A8F4A.cso.pdb create mode 100644 PopcornFX/PopcornFXInternals/Shaders/DebugParticleVertexBB.vert.BB64A8E44AB8BAEEC81BE23ACF911CBC.metallib create mode 100644 PopcornFX/PopcornFXInternals/Shaders/DebugParticleVertexBB.vert.BBDA720FBCB03878657725DCB4070478.cso create mode 100644 PopcornFX/PopcornFXInternals/Shaders/DebugParticleVertexBB.vert.BBDA720FBCB03878657725DCB4070478.cso.pdb create mode 100644 PopcornFX/PopcornFXInternals/Shaders/DebugParticleVertexBB.vert.C15B7A17F66E5D27A740A3A3C1979581.cso create mode 100644 PopcornFX/PopcornFXInternals/Shaders/DebugParticleVertexBB.vert.C15B7A17F66E5D27A740A3A3C1979581.cso.pdb create mode 100644 PopcornFX/PopcornFXInternals/Shaders/DebugParticleVertexBB.vert.C7B2BB2F20BE157E180C159EFD14D8DE.metallib create mode 100644 PopcornFX/PopcornFXInternals/Shaders/DebugParticleVertexBB.vert.C98B044AB7848AFC025DE95581642A05.cso create mode 100644 PopcornFX/PopcornFXInternals/Shaders/DebugParticleVertexBB.vert.C98B044AB7848AFC025DE95581642A05.cso.pdb create mode 100644 PopcornFX/PopcornFXInternals/Shaders/DebugParticleVertexBB.vert.CB92CEE22B94959EEA2E37687128679E.cso create mode 100644 PopcornFX/PopcornFXInternals/Shaders/DebugParticleVertexBB.vert.CB92CEE22B94959EEA2E37687128679E.cso.pdb create mode 100644 PopcornFX/PopcornFXInternals/Shaders/DebugParticleVertexBB.vert.CC0D866961E5688D9882D28BF15A2DD1.cso create mode 100644 PopcornFX/PopcornFXInternals/Shaders/DebugParticleVertexBB.vert.CC0D866961E5688D9882D28BF15A2DD1.cso.pdb create mode 100644 PopcornFX/PopcornFXInternals/Shaders/DebugParticleVertexBB.vert.CDA1E3C0E334532F508888E67D4074B0.cso create mode 100644 PopcornFX/PopcornFXInternals/Shaders/DebugParticleVertexBB.vert.CDA1E3C0E334532F508888E67D4074B0.cso.pdb create mode 100644 PopcornFX/PopcornFXInternals/Shaders/DebugParticleVertexBB.vert.D1972016D72D5B585C503DFDD9ABA548.cso create mode 100644 PopcornFX/PopcornFXInternals/Shaders/DebugParticleVertexBB.vert.D1972016D72D5B585C503DFDD9ABA548.cso.pdb create mode 100644 PopcornFX/PopcornFXInternals/Shaders/DebugParticleVertexBB.vert.D580014BB3F0D7F3FB392B6DE11130DF.cso create mode 100644 PopcornFX/PopcornFXInternals/Shaders/DebugParticleVertexBB.vert.D580014BB3F0D7F3FB392B6DE11130DF.cso.pdb create mode 100644 PopcornFX/PopcornFXInternals/Shaders/DebugParticleVertexBB.vert.D8BEC1C4205A6483977E29A6E5C0A924.metallib create mode 100644 PopcornFX/PopcornFXInternals/Shaders/DebugParticleVertexBB.vert.DB334DF1BF578B4A345D78EACFC48EFD.cso create mode 100644 PopcornFX/PopcornFXInternals/Shaders/DebugParticleVertexBB.vert.DB334DF1BF578B4A345D78EACFC48EFD.cso.pdb create mode 100644 PopcornFX/PopcornFXInternals/Shaders/DebugParticleVertexBB.vert.DBF0DC4E7C492B8443906BDABAB124D6.cso create mode 100644 PopcornFX/PopcornFXInternals/Shaders/DebugParticleVertexBB.vert.DBF0DC4E7C492B8443906BDABAB124D6.cso.pdb create mode 100644 PopcornFX/PopcornFXInternals/Shaders/DebugParticleVertexBB.vert.DC6974CAEE2A36877F6F6ECC13BBAD7E.cso create mode 100644 PopcornFX/PopcornFXInternals/Shaders/DebugParticleVertexBB.vert.DC6974CAEE2A36877F6F6ECC13BBAD7E.cso.pdb create mode 100644 PopcornFX/PopcornFXInternals/Shaders/DebugParticleVertexBB.vert.DDEB5E46AE2974A0BD8EEF904023D7ED.cso create mode 100644 PopcornFX/PopcornFXInternals/Shaders/DebugParticleVertexBB.vert.DDEB5E46AE2974A0BD8EEF904023D7ED.cso.pdb create mode 100644 PopcornFX/PopcornFXInternals/Shaders/DebugParticleVertexBB.vert.E21668FA3F80C375943DB33466B664B7.metallib create mode 100644 PopcornFX/PopcornFXInternals/Shaders/DebugParticleVertexBB.vert.E2A6EFBB662583C8B826AB85395FBE8B.cso create mode 100644 PopcornFX/PopcornFXInternals/Shaders/DebugParticleVertexBB.vert.E2A6EFBB662583C8B826AB85395FBE8B.cso.pdb create mode 100644 PopcornFX/PopcornFXInternals/Shaders/DebugParticleVertexBB.vert.E2B113ED936BDA4068FB8C5E849E995C.cso create mode 100644 PopcornFX/PopcornFXInternals/Shaders/DebugParticleVertexBB.vert.E2B113ED936BDA4068FB8C5E849E995C.cso.pdb create mode 100644 PopcornFX/PopcornFXInternals/Shaders/DebugParticleVertexBB.vert.E7704C9D770808997358C137DF29684D.metallib create mode 100644 PopcornFX/PopcornFXInternals/Shaders/DebugParticleVertexBB.vert.E7F82C90DC6E05851419E96B05BE71AC.metallib create mode 100644 PopcornFX/PopcornFXInternals/Shaders/DebugParticleVertexBB.vert.EB837A0928B395784434A7A111B53B5A.metallib create mode 100644 PopcornFX/PopcornFXInternals/Shaders/DebugParticleVertexBB.vert.F57F07EF6B6ED1C1CCD0B43033944746.metallib create mode 100644 PopcornFX/PopcornFXInternals/Shaders/DebugParticleVertexBB.vert.FE9156D85DC490262296F717A3729F04.cso create mode 100644 PopcornFX/PopcornFXInternals/Shaders/DebugParticleVertexBB.vert.FE9156D85DC490262296F717A3729F04.cso.pdb create mode 100644 PopcornFX/PopcornFXInternals/Shaders/DebugParticleVertexTri.vert.3AA9FB07C369A60580272C87CD195B48.cso create mode 100644 PopcornFX/PopcornFXInternals/Shaders/DebugParticleVertexTri.vert.3AA9FB07C369A60580272C87CD195B48.cso.pdb create mode 100644 PopcornFX/PopcornFXInternals/Shaders/DebugParticleVertexTri.vert.54B0DD8802234A5C2D1599668B7B9206.metallib create mode 100644 PopcornFX/PopcornFXInternals/Shaders/DebugParticleVertexTri.vert.55B9ABEC1E3A57FF5B4B48F003CA9752.cso create mode 100644 PopcornFX/PopcornFXInternals/Shaders/DebugParticleVertexTri.vert.55B9ABEC1E3A57FF5B4B48F003CA9752.cso.pdb create mode 100644 PopcornFX/PopcornFXInternals/Shaders/DebugParticleVertexTri.vert.E0A95D2F1F3EE6F204B740E133E167F9.metallib create mode 100644 PopcornFX/PopcornFXInternals/Shaders/DebugParticleVertexTri.vert.E4DE4FF3AC2C78D948169907E0A73083.cso create mode 100644 PopcornFX/PopcornFXInternals/Shaders/DebugParticleVertexTri.vert.E4DE4FF3AC2C78D948169907E0A73083.cso.pdb create mode 100644 PopcornFX/PopcornFXInternals/Shaders/DebugParticleVertexTri.vert.E82AF2A7438928C99FB4380BF1D38EEA.metallib create mode 100644 PopcornFX/PopcornFXInternals/Shaders/DebugParticleVertexTri.vert.F5A70F5EA17C5E1466A4461A319A10E1.cso create mode 100644 PopcornFX/PopcornFXInternals/Shaders/DebugParticleVertexTri.vert.F5A70F5EA17C5E1466A4461A319A10E1.cso.pdb create mode 100644 PopcornFX/PopcornFXInternals/Shaders/DebugParticleVertexTri.vert.FC5D8F71F6D3DF19E20E42FF6618F7D3.metallib create mode 100644 PopcornFX/PopcornFXInternals/Shaders/DeferredLights.frag.7D4CDE3609CAABADC704CA9E51BB9F61.cso create mode 100644 PopcornFX/PopcornFXInternals/Shaders/DeferredLights.frag.7D4CDE3609CAABADC704CA9E51BB9F61.cso.pdb create mode 100644 PopcornFX/PopcornFXInternals/Shaders/DeferredLights.frag.B5C43DC2134A05755ADB00CA12BAF5C9.metallib create mode 100644 PopcornFX/PopcornFXInternals/Shaders/DeferredMerging.frag.AA6AB5EFB19FD706650DFAFAA01D7D90.cso create mode 100644 PopcornFX/PopcornFXInternals/Shaders/DeferredMerging.frag.AA6AB5EFB19FD706650DFAFAA01D7D90.cso.pdb create mode 100644 PopcornFX/PopcornFXInternals/Shaders/DeferredMerging.frag.F9A4E1FF18B4D49D16DE912FD8A20B3E.metallib create mode 100644 PopcornFX/PopcornFXInternals/Shaders/Distortion.frag.2BFF67C6D3C7441503662DA3FF5A8E57.metallib create mode 100644 PopcornFX/PopcornFXInternals/Shaders/Distortion.frag.AFFAB2D8D5F189DCDB557A256A2F8D08.cso create mode 100644 PopcornFX/PopcornFXInternals/Shaders/Distortion.frag.AFFAB2D8D5F189DCDB557A256A2F8D08.cso.pdb create mode 100644 PopcornFX/PopcornFXInternals/Shaders/FXAA.frag.3A86B375B47444ED50B241CB31E4DE69.metallib create mode 100644 PopcornFX/PopcornFXInternals/Shaders/FXAA.frag.4E1DEB657074C0BC7622F2752888C406.cso create mode 100644 PopcornFX/PopcornFXInternals/Shaders/FXAA.frag.4E1DEB657074C0BC7622F2752888C406.cso.pdb create mode 100644 PopcornFX/PopcornFXInternals/Shaders/FXAA.frag.6FF25215FE2377D1A9D44CB228A6FDCC.metallib create mode 100644 PopcornFX/PopcornFXInternals/Shaders/FXAA.frag.A565FBDBEDF828A39BE5F7DB10013507.cso create mode 100644 PopcornFX/PopcornFXInternals/Shaders/FXAA.frag.A565FBDBEDF828A39BE5F7DB10013507.cso.pdb create mode 100644 PopcornFX/PopcornFXInternals/Shaders/FilterCubemap.comp.48F96F1C309D71E7B09A68D687BCAF2B.cso create mode 100644 PopcornFX/PopcornFXInternals/Shaders/FilterCubemap.comp.48F96F1C309D71E7B09A68D687BCAF2B.cso.pdb create mode 100644 PopcornFX/PopcornFXInternals/Shaders/FilterCubemap.comp.7D008C2220573C54554F7ECF45C09AE1.metallib create mode 100644 PopcornFX/PopcornFXInternals/Shaders/FullScreenQuad.vert.06F70F70BEE3A7F2C9007828EAC27793.metallib create mode 100644 PopcornFX/PopcornFXInternals/Shaders/FullScreenQuad.vert.23547C37D36CF6F9E3E4E1A5EFFDA5D7.cso create mode 100644 PopcornFX/PopcornFXInternals/Shaders/FullScreenQuad.vert.23547C37D36CF6F9E3E4E1A5EFFDA5D7.cso.pdb create mode 100644 PopcornFX/PopcornFXInternals/Shaders/FullScreenQuad.vert.5458F29FA4CB16046183E24079014F66.cso create mode 100644 PopcornFX/PopcornFXInternals/Shaders/FullScreenQuad.vert.5458F29FA4CB16046183E24079014F66.cso.pdb create mode 100644 PopcornFX/PopcornFXInternals/Shaders/FullScreenQuad.vert.6820B8E6207A3B72C4104BBEBA6362A7.cso create mode 100644 PopcornFX/PopcornFXInternals/Shaders/FullScreenQuad.vert.6820B8E6207A3B72C4104BBEBA6362A7.cso.pdb create mode 100644 PopcornFX/PopcornFXInternals/Shaders/FullScreenQuad.vert.84F2CED1305C36A788150F98225EDB8E.cso create mode 100644 PopcornFX/PopcornFXInternals/Shaders/FullScreenQuad.vert.84F2CED1305C36A788150F98225EDB8E.cso.pdb create mode 100644 PopcornFX/PopcornFXInternals/Shaders/FullScreenQuad.vert.84F2CED1305C36A788150F98225EDB8E.metallib create mode 100644 PopcornFX/PopcornFXInternals/Shaders/FullScreenQuad.vert.AB34E7F5715922651FCAC50613AD2C84.metallib create mode 100644 PopcornFX/PopcornFXInternals/Shaders/FullScreenQuad.vert.E9BEA09E84D5D4F71D5B417CB9E33C2B.metallib create mode 100644 PopcornFX/PopcornFXInternals/Shaders/GBuffer.frag.20F6C676AA4429ECE221D06C3579FE6E.metallib create mode 100644 PopcornFX/PopcornFXInternals/Shaders/GBuffer.frag.39AB76CAE213E76DBA545C88E8BDE602.cso create mode 100644 PopcornFX/PopcornFXInternals/Shaders/GBuffer.frag.39AB76CAE213E76DBA545C88E8BDE602.cso.pdb create mode 100644 PopcornFX/PopcornFXInternals/Shaders/GBuffer.frag.504D71546723AF7F0E946069BF0BBDC1.cso create mode 100644 PopcornFX/PopcornFXInternals/Shaders/GBuffer.frag.504D71546723AF7F0E946069BF0BBDC1.cso.pdb create mode 100644 PopcornFX/PopcornFXInternals/Shaders/GBuffer.frag.621E6F8AB62D0530723E6071DD1AECAE.cso create mode 100644 PopcornFX/PopcornFXInternals/Shaders/GBuffer.frag.621E6F8AB62D0530723E6071DD1AECAE.cso.pdb create mode 100644 PopcornFX/PopcornFXInternals/Shaders/GBuffer.frag.6B3AB535C56AF8AAA886CB915A7DE392.cso create mode 100644 PopcornFX/PopcornFXInternals/Shaders/GBuffer.frag.6B3AB535C56AF8AAA886CB915A7DE392.cso.pdb create mode 100644 PopcornFX/PopcornFXInternals/Shaders/GBuffer.frag.835D4B0EE4352DFABEFBE67F99F03581.cso create mode 100644 PopcornFX/PopcornFXInternals/Shaders/GBuffer.frag.835D4B0EE4352DFABEFBE67F99F03581.cso.pdb create mode 100644 PopcornFX/PopcornFXInternals/Shaders/GBuffer.frag.A9E805B45F4C48DB5EC5940F2DBB49EF.metallib create mode 100644 PopcornFX/PopcornFXInternals/Shaders/GBuffer.frag.AD528D11B24C3E9547BBC2755B99AF0D.metallib create mode 100644 PopcornFX/PopcornFXInternals/Shaders/GBuffer.frag.AE86D100987DC55AC4CD67341D850BC9.metallib create mode 100644 PopcornFX/PopcornFXInternals/Shaders/GBuffer.frag.BBC3FA3E5A6A9C8BD17B04A4C3C3131F.metallib create mode 100644 PopcornFX/PopcornFXInternals/Shaders/GBuffer.frag.C26A349E4B498C28CA45FDF2B358356D.metallib create mode 100644 PopcornFX/PopcornFXInternals/Shaders/GBuffer.frag.C7D82581B244FE8E3E7FAD38CA9B4C30.cso create mode 100644 PopcornFX/PopcornFXInternals/Shaders/GBuffer.frag.C7D82581B244FE8E3E7FAD38CA9B4C30.cso.pdb create mode 100644 PopcornFX/PopcornFXInternals/Shaders/GBuffer.frag.D12FD3934A8AEA8B731F0FFDEE6E4203.metallib create mode 100644 PopcornFX/PopcornFXInternals/Shaders/GBuffer.frag.F024867C34EF3686655F5D8B96BD85AD.cso create mode 100644 PopcornFX/PopcornFXInternals/Shaders/GBuffer.frag.F024867C34EF3686655F5D8B96BD85AD.cso.pdb create mode 100644 PopcornFX/PopcornFXInternals/Shaders/GaussianBlur.frag.0A585A8EE1FAF289D0FA00431292E74D.metallib create mode 100644 PopcornFX/PopcornFXInternals/Shaders/GaussianBlur.frag.196033BDAFEE16C2947AC8D3CBD9E464.metallib create mode 100644 PopcornFX/PopcornFXInternals/Shaders/GaussianBlur.frag.44119E8A23CB98B578519BD7A8DD2D3A.cso create mode 100644 PopcornFX/PopcornFXInternals/Shaders/GaussianBlur.frag.44119E8A23CB98B578519BD7A8DD2D3A.cso.pdb create mode 100644 PopcornFX/PopcornFXInternals/Shaders/GaussianBlur.frag.4D18DB2E6615B37CE61ADA69E7CF80B7.cso create mode 100644 PopcornFX/PopcornFXInternals/Shaders/GaussianBlur.frag.4D18DB2E6615B37CE61ADA69E7CF80B7.cso.pdb create mode 100644 PopcornFX/PopcornFXInternals/Shaders/GaussianBlur.frag.6B1E1A9B04F783E5EF5AF1FA2DD7A8F0.cso create mode 100644 PopcornFX/PopcornFXInternals/Shaders/GaussianBlur.frag.6B1E1A9B04F783E5EF5AF1FA2DD7A8F0.cso.pdb create mode 100644 PopcornFX/PopcornFXInternals/Shaders/GaussianBlur.frag.776C8F8C4765207534C2B33EE67BA844.metallib create mode 100644 PopcornFX/PopcornFXInternals/Shaders/GaussianBlur.frag.A85F6F848367C44C2139ED7946A2DD41.cso create mode 100644 PopcornFX/PopcornFXInternals/Shaders/GaussianBlur.frag.A85F6F848367C44C2139ED7946A2DD41.cso.pdb create mode 100644 PopcornFX/PopcornFXInternals/Shaders/GaussianBlur.frag.C7B3E6FB6A02D2891A0BFE850ABA2E05.cso create mode 100644 PopcornFX/PopcornFXInternals/Shaders/GaussianBlur.frag.C7B3E6FB6A02D2891A0BFE850ABA2E05.cso.pdb create mode 100644 PopcornFX/PopcornFXInternals/Shaders/GaussianBlur.frag.D4B8B59DC084AF08261271DE31BD80FB.metallib create mode 100644 PopcornFX/PopcornFXInternals/Shaders/GaussianBlur.frag.D6F2FD832CE84459152427CA78D65D28.metallib create mode 100644 PopcornFX/PopcornFXInternals/Shaders/GaussianBlur.frag.E0C7B3E835DB79196070A24486ABF763.cso create mode 100644 PopcornFX/PopcornFXInternals/Shaders/GaussianBlur.frag.E0C7B3E835DB79196070A24486ABF763.cso.pdb create mode 100644 PopcornFX/PopcornFXInternals/Shaders/GaussianBlur.frag.E8745B044C2DFE8709E100D425FD7E22.metallib create mode 100644 PopcornFX/PopcornFXInternals/Shaders/Gizmo.frag.4DD1C89DF8002B409E089089CE8F24E7.cso create mode 100644 PopcornFX/PopcornFXInternals/Shaders/Gizmo.frag.4DD1C89DF8002B409E089089CE8F24E7.cso.pdb create mode 100644 PopcornFX/PopcornFXInternals/Shaders/Gizmo.frag.4DD1C89DF8002B409E089089CE8F24E7.metallib create mode 100644 PopcornFX/PopcornFXInternals/Shaders/Gizmo.vert.C992EAD4108528439F5ACC0580D33319.cso create mode 100644 PopcornFX/PopcornFXInternals/Shaders/Gizmo.vert.C992EAD4108528439F5ACC0580D33319.cso.pdb create mode 100644 PopcornFX/PopcornFXInternals/Shaders/Gizmo.vert.EEDB02B1278B2566C0A24981ED8E295B.metallib create mode 100644 PopcornFX/PopcornFXInternals/Shaders/Heatmap.frag.9005CED6A719F4C5A6266F97BBFB476E.metallib create mode 100644 PopcornFX/PopcornFXInternals/Shaders/Heatmap.frag.F811CE9BD360967E23FA73EFC790BF73.cso create mode 100644 PopcornFX/PopcornFXInternals/Shaders/Heatmap.frag.F811CE9BD360967E23FA73EFC790BF73.cso.pdb create mode 100644 PopcornFX/PopcornFXInternals/Shaders/ImGui.frag.87409A88665BA0A46F3F776DF2CA1206.metallib create mode 100644 PopcornFX/PopcornFXInternals/Shaders/ImGui.frag.F0E2F0F689387705D12CB9970013F51D.cso create mode 100644 PopcornFX/PopcornFXInternals/Shaders/ImGui.frag.F0E2F0F689387705D12CB9970013F51D.cso.pdb create mode 100644 PopcornFX/PopcornFXInternals/Shaders/ImGui.vert.13B53A2583576C2B028749CFE7A75DBA.cso create mode 100644 PopcornFX/PopcornFXInternals/Shaders/ImGui.vert.13B53A2583576C2B028749CFE7A75DBA.cso.pdb create mode 100644 PopcornFX/PopcornFXInternals/Shaders/ImGui.vert.613A033E7F8C94916EEEB5D560FE454B.metallib create mode 100644 PopcornFX/PopcornFXInternals/Shaders/InitIndirectionOffsetsBuffer.comp.03B060E36BAC8979EBFFCD327F74AAF9.cso create mode 100644 PopcornFX/PopcornFXInternals/Shaders/InitIndirectionOffsetsBuffer.comp.03B060E36BAC8979EBFFCD327F74AAF9.cso.pdb create mode 100644 PopcornFX/PopcornFXInternals/Shaders/InitIndirectionOffsetsBuffer.comp.0AE6A05A739437D201C8C1B2F93B8544.metallib create mode 100644 PopcornFX/PopcornFXInternals/Shaders/InitIndirectionOffsetsBuffer.comp.3C1C64A82544849508C4F7B5018CED35.cso create mode 100644 PopcornFX/PopcornFXInternals/Shaders/InitIndirectionOffsetsBuffer.comp.3C1C64A82544849508C4F7B5018CED35.cso.pdb create mode 100644 PopcornFX/PopcornFXInternals/Shaders/InitIndirectionOffsetsBuffer.comp.712FE560E255C4424D1793FEF1498944.metallib create mode 100644 PopcornFX/PopcornFXInternals/Shaders/LightInstanced.vert.95BBBD48996763573C91C6D61130ADC6.metallib create mode 100644 PopcornFX/PopcornFXInternals/Shaders/LightInstanced.vert.C69D1C8B63FD48E0C28A855BE4BC8C72.cso create mode 100644 PopcornFX/PopcornFXInternals/Shaders/LightInstanced.vert.C69D1C8B63FD48E0C28A855BE4BC8C72.cso.pdb create mode 100644 PopcornFX/PopcornFXInternals/Shaders/ParticleSelector.comp.01A367EBF8EF61BEB5BBD977C507AD5D.metallib create mode 100644 PopcornFX/PopcornFXInternals/Shaders/ParticleSelector.comp.46FFC0AC778725D76C1B4B50B25D2820.cso create mode 100644 PopcornFX/PopcornFXInternals/Shaders/ParticleSelector.comp.46FFC0AC778725D76C1B4B50B25D2820.cso.pdb create mode 100644 PopcornFX/PopcornFXInternals/Shaders/ParticleSelectorCycle.comp.01A367EBF8EF61BEB5BBD977C507AD5D.metallib create mode 100644 PopcornFX/PopcornFXInternals/Shaders/ParticleSelectorCycle.comp.46FFC0AC778725D76C1B4B50B25D2820.cso create mode 100644 PopcornFX/PopcornFXInternals/Shaders/ParticleSelectorCycle.comp.46FFC0AC778725D76C1B4B50B25D2820.cso.pdb create mode 100644 PopcornFX/PopcornFXInternals/Shaders/PointLightInstanced.frag.40666DC8ABC0281162338BC37344400B.metallib create mode 100644 PopcornFX/PopcornFXInternals/Shaders/PointLightInstanced.frag.4AB7012A334144666A00F99BE4F8ABF5.cso create mode 100644 PopcornFX/PopcornFXInternals/Shaders/PointLightInstanced.frag.4AB7012A334144666A00F99BE4F8ABF5.cso.pdb create mode 100644 PopcornFX/PopcornFXInternals/Shaders/Profiler.frag.4DD1C89DF8002B409E089089CE8F24E7.cso create mode 100644 PopcornFX/PopcornFXInternals/Shaders/Profiler.frag.4DD1C89DF8002B409E089089CE8F24E7.cso.pdb create mode 100644 PopcornFX/PopcornFXInternals/Shaders/Profiler.frag.4DD1C89DF8002B409E089089CE8F24E7.metallib create mode 100644 PopcornFX/PopcornFXInternals/Shaders/Profiler.vert.607F7C9197328C04A914D3DB28E91B70.metallib create mode 100644 PopcornFX/PopcornFXInternals/Shaders/Profiler.vert.7421279F2283857C300D16BA4AC862F9.cso create mode 100644 PopcornFX/PopcornFXInternals/Shaders/Profiler.vert.7421279F2283857C300D16BA4AC862F9.cso.pdb create mode 100644 PopcornFX/PopcornFXInternals/Shaders/ProfilerDrawNode.frag.3F8899175EDEBECFC90A9FCF4189D177.cso create mode 100644 PopcornFX/PopcornFXInternals/Shaders/ProfilerDrawNode.frag.3F8899175EDEBECFC90A9FCF4189D177.cso.pdb create mode 100644 PopcornFX/PopcornFXInternals/Shaders/ProfilerDrawNode.frag.3F8899175EDEBECFC90A9FCF4189D177.metallib create mode 100644 PopcornFX/PopcornFXInternals/Shaders/ProfilerDrawNode.frag.4DD1C89DF8002B409E089089CE8F24E7.cso create mode 100644 PopcornFX/PopcornFXInternals/Shaders/ProfilerDrawNode.frag.4DD1C89DF8002B409E089089CE8F24E7.cso.pdb create mode 100644 PopcornFX/PopcornFXInternals/Shaders/ProfilerDrawNode.frag.4DD1C89DF8002B409E089089CE8F24E7.metallib create mode 100644 PopcornFX/PopcornFXInternals/Shaders/ProfilerDrawNode.vert.A0CB1C647BF9FDC5B765A1CD78BEA0C6.cso create mode 100644 PopcornFX/PopcornFXInternals/Shaders/ProfilerDrawNode.vert.A0CB1C647BF9FDC5B765A1CD78BEA0C6.cso.pdb create mode 100644 PopcornFX/PopcornFXInternals/Shaders/ProfilerDrawNode.vert.B1F47489E9CAD9F30B6E29EECDC49DC7.cso create mode 100644 PopcornFX/PopcornFXInternals/Shaders/ProfilerDrawNode.vert.B1F47489E9CAD9F30B6E29EECDC49DC7.cso.pdb create mode 100644 PopcornFX/PopcornFXInternals/Shaders/ProfilerDrawNode.vert.C6E60C6043020672ADB3C28FE4231386.metallib create mode 100644 PopcornFX/PopcornFXInternals/Shaders/ProfilerDrawNode.vert.E306BFB69B25E84A37254307D2194DE4.metallib create mode 100644 PopcornFX/PopcornFXInternals/Shaders/RenderCubemapFace.comp.000E9EBE432F6B318E8869722FA96736.cso create mode 100644 PopcornFX/PopcornFXInternals/Shaders/RenderCubemapFace.comp.000E9EBE432F6B318E8869722FA96736.cso.pdb create mode 100644 PopcornFX/PopcornFXInternals/Shaders/RenderCubemapFace.comp.6B0FF562C6B4E087E89ECFB854F4DF16.metallib create mode 100644 PopcornFX/PopcornFXInternals/Shaders/SolidMesh.vert.00EEAD7565201E1D171906979186BFF4.metallib create mode 100644 PopcornFX/PopcornFXInternals/Shaders/SolidMesh.vert.194FBD4081C25D96A0D72764B5D2868C.cso create mode 100644 PopcornFX/PopcornFXInternals/Shaders/SolidMesh.vert.194FBD4081C25D96A0D72764B5D2868C.cso.pdb create mode 100644 PopcornFX/PopcornFXInternals/Shaders/SolidMesh.vert.5914DC24CB72BBC25D999BA4C1DB9B5A.cso create mode 100644 PopcornFX/PopcornFXInternals/Shaders/SolidMesh.vert.5914DC24CB72BBC25D999BA4C1DB9B5A.cso.pdb create mode 100644 PopcornFX/PopcornFXInternals/Shaders/SolidMesh.vert.A50757CC2A13C001045CDD9A011A0E78.cso create mode 100644 PopcornFX/PopcornFXInternals/Shaders/SolidMesh.vert.A50757CC2A13C001045CDD9A011A0E78.cso.pdb create mode 100644 PopcornFX/PopcornFXInternals/Shaders/SolidMesh.vert.C771D47D0FD2493829F05C25BF23328F.metallib create mode 100644 PopcornFX/PopcornFXInternals/Shaders/SolidMesh.vert.C91A588C69123D5B74210A1169C0B7CB.cso create mode 100644 PopcornFX/PopcornFXInternals/Shaders/SolidMesh.vert.C91A588C69123D5B74210A1169C0B7CB.cso.pdb create mode 100644 PopcornFX/PopcornFXInternals/Shaders/SolidMesh.vert.D2590CD60D4E66225883164A95636A82.metallib create mode 100644 PopcornFX/PopcornFXInternals/Shaders/SolidMesh.vert.F1C2D218A3AFC30EF7F2C8297F4B8646.metallib create mode 100644 PopcornFX/PopcornFXInternals/Shaders/SolidMeshShadow.frag.7CF9397E238069F29B5AD306936DC2E1.cso create mode 100644 PopcornFX/PopcornFXInternals/Shaders/SolidMeshShadow.frag.7CF9397E238069F29B5AD306936DC2E1.cso.pdb create mode 100644 PopcornFX/PopcornFXInternals/Shaders/SolidMeshShadow.frag.9E055DD95BFFEC03321947DE0EB82637.metallib create mode 100644 PopcornFX/PopcornFXInternals/Shaders/SolidMeshShadow.vert.18162C7773971E53C43D7A0F15D8ECE4.metallib create mode 100644 PopcornFX/PopcornFXInternals/Shaders/SolidMeshShadow.vert.6D34106F328960A07AB5DB0CBEBE05E5.cso create mode 100644 PopcornFX/PopcornFXInternals/Shaders/SolidMeshShadow.vert.6D34106F328960A07AB5DB0CBEBE05E5.cso.pdb create mode 100644 PopcornFX/PopcornFXInternals/Shaders/SortDownSweep.comp.36030C466ADE37AEB6B32358DC8DBAC7.cso create mode 100644 PopcornFX/PopcornFXInternals/Shaders/SortDownSweep.comp.36030C466ADE37AEB6B32358DC8DBAC7.cso.pdb create mode 100644 PopcornFX/PopcornFXInternals/Shaders/SortDownSweep.comp.5CFD62E25CEECDE84ED94155C845E9B2.cso create mode 100644 PopcornFX/PopcornFXInternals/Shaders/SortDownSweep.comp.5CFD62E25CEECDE84ED94155C845E9B2.cso.pdb create mode 100644 PopcornFX/PopcornFXInternals/Shaders/SortDownSweep.comp.D224AE024F31A732967118BC1834D51D.metallib create mode 100644 PopcornFX/PopcornFXInternals/Shaders/SortDownSweep.comp.D53181CD829C7C2CC9A7D66D28AA2D06.metallib create mode 100644 PopcornFX/PopcornFXInternals/Shaders/SortPrefixSum.comp.001CEFA3E15B4064857DF52248F766BE.cso create mode 100644 PopcornFX/PopcornFXInternals/Shaders/SortPrefixSum.comp.001CEFA3E15B4064857DF52248F766BE.cso.pdb create mode 100644 PopcornFX/PopcornFXInternals/Shaders/SortPrefixSum.comp.4C1B3D9DE2E2589090B928914DBDCA22.metallib create mode 100644 PopcornFX/PopcornFXInternals/Shaders/SortUpSweep.comp.BC3EED1104C7A5A05486050D5E27A5CC.cso create mode 100644 PopcornFX/PopcornFXInternals/Shaders/SortUpSweep.comp.BC3EED1104C7A5A05486050D5E27A5CC.cso.pdb create mode 100644 PopcornFX/PopcornFXInternals/Shaders/SortUpSweep.comp.E926B5F5F536A436919B0059B2A29EFC.metallib create mode 100644 PopcornFX/PopcornFXInternals/Shaders/SortUpSweep.comp.EDD9731E86E29E66F0807C2362C8B640.metallib create mode 100644 PopcornFX/PopcornFXInternals/Shaders/SortUpSweep.comp.F3A85FB3B74B54E33EEF438D2BBA34A1.cso create mode 100644 PopcornFX/PopcornFXInternals/Shaders/SortUpSweep.comp.F3A85FB3B74B54E33EEF438D2BBA34A1.cso.pdb create mode 100644 PopcornFX/PopcornFXInternals/Textures/DitheringPatterns.png create mode 100644 PopcornFX/PopcornFXInternals/Textures/Overdraw.dds create mode 100644 PopcornFX/PopcornFXInternals/Textures/TextAtlas.dds create mode 100644 PopcornFX/PopcornFXInternals/Textures/TextAtlas.pkat create mode 100644 PopcornFX/PopcornFXInternals/Textures/default.dds create mode 100644 PopcornFX/README.md create mode 100644 PopcornFX/Resources.rcc create mode 100644 PopcornFX/Resources/Fonts/Consolas.ttf create mode 100644 PopcornFX/Resources/Fonts/Roboto-Bold.ttf create mode 100644 PopcornFX/Resources/Fonts/Roboto-Light.ttf create mode 100644 PopcornFX/Resources/Fonts/Roboto-Regular.ttf create mode 100644 PopcornFX/Resources/Fonts/RobotoMono-Regular.ttf create mode 100644 PopcornFX/Resources/Icons/Reset.png create mode 100644 PopcornFX/Resources/Icons/branch-closed.png create mode 100644 PopcornFX/Resources/Icons/branch-open.png create mode 100644 PopcornFX/Stylesheet.qss create mode 100644 PopcornFX/WinPixEventRuntime.dll create mode 100644 PopcornFX/documentation/debugger/PopcornFX.natvis create mode 100644 PopcornFX/fxc.exe create mode 100644 PopcornFX/popcornfx.qt/Qt5Core.dll create mode 100644 PopcornFX/popcornfx.qt/Qt5Gui.dll create mode 100644 PopcornFX/popcornfx.qt/Qt5Widgets.dll create mode 100644 PopcornFX/popcornfx.qt/popcornfx.qt.manifest create mode 100644 PopcornFX/popcornfx.qt/qwindows.dll create mode 100644 Samples/PK-MCPP/directive.cpp create mode 100644 Samples/PK-MCPP/eval.cpp create mode 100644 Samples/PK-MCPP/expand.cpp create mode 100644 Samples/PK-MCPP/internal.h create mode 100644 Samples/PK-MCPP/main.cpp create mode 100644 Samples/PK-MCPP/mbchar.cpp create mode 100644 Samples/PK-MCPP/mcpp_lib.h create mode 100644 Samples/PK-MCPP/mcpp_out.h create mode 100644 Samples/PK-MCPP/noconfig.h create mode 100644 Samples/PK-MCPP/pk_mcpp_bridge.cpp create mode 100644 Samples/PK-MCPP/pk_mcpp_bridge.h create mode 100644 Samples/PK-MCPP/pk_preprocessor.cpp create mode 100644 Samples/PK-MCPP/pk_preprocessor.h create mode 100644 Samples/PK-MCPP/precompiled.cpp create mode 100644 Samples/PK-MCPP/precompiled.h create mode 100644 Samples/PK-MCPP/support.cpp create mode 100644 Samples/PK-MCPP/system.cpp create mode 100644 Samples/PK-MCPP/system.h create mode 100644 Samples/PK-SampleLib/ApiContext/D3D/D3D11Context.cpp create mode 100644 Samples/PK-SampleLib/ApiContext/D3D/D3D11Context.h create mode 100644 Samples/PK-SampleLib/ApiContext/D3D/D3D12Context.cpp create mode 100644 Samples/PK-SampleLib/ApiContext/D3D/D3D12Context.h create mode 100644 Samples/PK-SampleLib/ApiContext/IApiContext.h create mode 100644 Samples/PK-SampleLib/ApiContext/Metal/MetalContext.h create mode 100644 Samples/PK-SampleLib/ApiContext/Metal/MetalContext.mm create mode 100644 Samples/PK-SampleLib/ApiContext/Metal/MetalContextFactory.h create mode 100644 Samples/PK-SampleLib/ApiContext/Metal/MetalContextFactory.mm create mode 100644 Samples/PK-SampleLib/ApiContext/Metal/MetalFinalBlitShader.h create mode 100644 Samples/PK-SampleLib/ApiContext/Metal/MetalFinalBlitShader.metal create mode 100644 Samples/PK-SampleLib/ApiContext/OpenGL/EGLContext.cpp create mode 100644 Samples/PK-SampleLib/ApiContext/OpenGL/EGLContext.h create mode 100644 Samples/PK-SampleLib/ApiContext/OpenGL/GLContext.cpp create mode 100644 Samples/PK-SampleLib/ApiContext/OpenGL/GLContext.h create mode 100644 Samples/PK-SampleLib/ApiContext/OpenGL/GLXContext.cpp create mode 100644 Samples/PK-SampleLib/ApiContext/OpenGL/GLXContext.h create mode 100644 Samples/PK-SampleLib/ApiContext/OpenGL/NSGLContext.h create mode 100644 Samples/PK-SampleLib/ApiContext/OpenGL/NSGLContext.mm create mode 100644 Samples/PK-SampleLib/ApiContext/OpenGL/WGLContext.cpp create mode 100644 Samples/PK-SampleLib/ApiContext/OpenGL/WGLContext.h create mode 100644 Samples/PK-SampleLib/ApiContext/Vulkan/VulkanContext.cpp create mode 100644 Samples/PK-SampleLib/ApiContext/Vulkan/VulkanContext.h create mode 100644 Samples/PK-SampleLib/ApiContextConfig.h create mode 100644 Samples/PK-SampleLib/Assets/Meshes/default.fbx create mode 100755 Samples/PK-SampleLib/Assets/ShaderIncludes/gen_shaders_header create mode 100644 Samples/PK-SampleLib/Assets/ShaderIncludes/gen_shaders_header.cmd create mode 100755 Samples/PK-SampleLib/Assets/ShaderIncludes/generated/Billboard.geom.h create mode 100644 Samples/PK-SampleLib/Assets/ShaderIncludes/generated/Billboard.vert.h create mode 100644 Samples/PK-SampleLib/Assets/ShaderIncludes/generated/GPUSimInterface_GBuffer_ProjectToNormal.d3d.h create mode 100644 Samples/PK-SampleLib/Assets/ShaderIncludes/generated/GPUSimInterface_GBuffer_ProjectToPosition.d3d.h create mode 100644 Samples/PK-SampleLib/Assets/ShaderIncludes/generated/Ribbon.vert.h create mode 100644 Samples/PK-SampleLib/Assets/ShaderIncludes/generated/Triangle.vert.h create mode 100644 Samples/PK-SampleLib/Assets/ShaderIncludes/sources/Billboard.geom create mode 100644 Samples/PK-SampleLib/Assets/ShaderIncludes/sources/Billboard.vert create mode 100644 Samples/PK-SampleLib/Assets/ShaderIncludes/sources/GPUSimInterfaces/GPUSimInterface_GBuffer_ProjectToNormal.d3d create mode 100644 Samples/PK-SampleLib/Assets/ShaderIncludes/sources/GPUSimInterfaces/GPUSimInterface_GBuffer_ProjectToPosition.d3d create mode 100644 Samples/PK-SampleLib/Assets/ShaderIncludes/sources/Ribbon.vert create mode 100644 Samples/PK-SampleLib/Assets/ShaderIncludes/sources/Triangle.vert create mode 100644 Samples/PK-SampleLib/Assets/Shaders/Gizmo.frag create mode 100644 Samples/PK-SampleLib/Assets/Shaders/Gizmo.vert create mode 100644 Samples/PK-SampleLib/Assets/Shaders/ImGui.frag create mode 100644 Samples/PK-SampleLib/Assets/Shaders/ImGui.vert create mode 100644 Samples/PK-SampleLib/Assets/Shaders/Profiler.frag create mode 100644 Samples/PK-SampleLib/Assets/Shaders/Profiler.vert create mode 100644 Samples/PK-SampleLib/Assets/Shaders/ProfilerDrawNode.frag create mode 100644 Samples/PK-SampleLib/Assets/Shaders/ProfilerDrawNode.vert create mode 100644 Samples/PK-SampleLib/Assets/Textures/DitheringPatterns.png create mode 100644 Samples/PK-SampleLib/Assets/Textures/default.dds create mode 100644 Samples/PK-SampleLib/BRDFLUT.cpp create mode 100644 Samples/PK-SampleLib/BRDFLUT.h create mode 100644 Samples/PK-SampleLib/BlueNoise.cpp create mode 100644 Samples/PK-SampleLib/BlueNoise.h create mode 100644 Samples/PK-SampleLib/Camera.cpp create mode 100644 Samples/PK-SampleLib/Camera.h create mode 100644 Samples/PK-SampleLib/DebugHelper.cpp create mode 100644 Samples/PK-SampleLib/DebugHelper.h create mode 100644 Samples/PK-SampleLib/Gizmo.cpp create mode 100644 Samples/PK-SampleLib/Gizmo.h create mode 100644 Samples/PK-SampleLib/ImguiRhiImplem.cpp create mode 100644 Samples/PK-SampleLib/ImguiRhiImplem.h create mode 100644 Samples/PK-SampleLib/PKPix.cpp create mode 100644 Samples/PK-SampleLib/PKPix.h create mode 100644 Samples/PK-SampleLib/PKSample.h create mode 100644 Samples/PK-SampleLib/PKSampleInit.cpp create mode 100644 Samples/PK-SampleLib/PKSampleInit.h create mode 100644 Samples/PK-SampleLib/PipelineCacheHelper.cpp create mode 100644 Samples/PK-SampleLib/PipelineCacheHelper.h create mode 100644 Samples/PK-SampleLib/PopcornStartup/PopcornStartup.cpp create mode 100644 Samples/PK-SampleLib/PopcornStartup/PopcornStartup.h create mode 100644 Samples/PK-SampleLib/ProfilerRenderer.cpp create mode 100644 Samples/PK-SampleLib/ProfilerRenderer.h create mode 100644 Samples/PK-SampleLib/RHIRenderParticleSceneHelpers.cpp create mode 100644 Samples/PK-SampleLib/RHIRenderParticleSceneHelpers.h create mode 100644 Samples/PK-SampleLib/RenderIntegrationRHI/FeatureRenderingSettings.cpp create mode 100644 Samples/PK-SampleLib/RenderIntegrationRHI/FeatureRenderingSettings.h create mode 100644 Samples/PK-SampleLib/RenderIntegrationRHI/FrameCollector.cpp create mode 100644 Samples/PK-SampleLib/RenderIntegrationRHI/FrameCollector.h create mode 100644 Samples/PK-SampleLib/RenderIntegrationRHI/MaterialToRHI.cpp create mode 100644 Samples/PK-SampleLib/RenderIntegrationRHI/MaterialToRHI.h create mode 100644 Samples/PK-SampleLib/RenderIntegrationRHI/RHIBillboardingBatchPolicy.cpp create mode 100644 Samples/PK-SampleLib/RenderIntegrationRHI/RHIBillboardingBatchPolicy.h create mode 100644 Samples/PK-SampleLib/RenderIntegrationRHI/RHIBillboardingBatchPolicy_Vertex.cpp create mode 100644 Samples/PK-SampleLib/RenderIntegrationRHI/RHIBillboardingBatchPolicy_Vertex.h create mode 100644 Samples/PK-SampleLib/RenderIntegrationRHI/RHICustomTasks.cpp create mode 100644 Samples/PK-SampleLib/RenderIntegrationRHI/RHICustomTasks.h create mode 100644 Samples/PK-SampleLib/RenderIntegrationRHI/RHIGPUSorter.cpp create mode 100644 Samples/PK-SampleLib/RenderIntegrationRHI/RHIGPUSorter.h create mode 100644 Samples/PK-SampleLib/RenderIntegrationRHI/RHIGraphicResources.cpp create mode 100644 Samples/PK-SampleLib/RenderIntegrationRHI/RHIGraphicResources.h create mode 100644 Samples/PK-SampleLib/RenderIntegrationRHI/RHIParticleRenderDataFactory.cpp create mode 100644 Samples/PK-SampleLib/RenderIntegrationRHI/RHIParticleRenderDataFactory.h create mode 100644 Samples/PK-SampleLib/RenderIntegrationRHI/RHIRenderIntegrationConfig.h create mode 100644 Samples/PK-SampleLib/RenderIntegrationRHI/RHITypePolicy.h create mode 100644 Samples/PK-SampleLib/RenderIntegrationRHI/RendererCache.cpp create mode 100644 Samples/PK-SampleLib/RenderIntegrationRHI/RendererCache.h create mode 100644 Samples/PK-SampleLib/RenderIntegrationRHI/SoundPoolCache.cpp create mode 100644 Samples/PK-SampleLib/RenderIntegrationRHI/SoundPoolCache.h create mode 100644 Samples/PK-SampleLib/RenderPasses/DirectionalShadows.cpp create mode 100644 Samples/PK-SampleLib/RenderPasses/DirectionalShadows.h create mode 100644 Samples/PK-SampleLib/RenderPasses/DownSampleTexture.cpp create mode 100644 Samples/PK-SampleLib/RenderPasses/DownSampleTexture.h create mode 100644 Samples/PK-SampleLib/RenderPasses/GBuffer.cpp create mode 100644 Samples/PK-SampleLib/RenderPasses/GBuffer.h create mode 100644 Samples/PK-SampleLib/RenderPasses/PostFxBloom.cpp create mode 100644 Samples/PK-SampleLib/RenderPasses/PostFxBloom.h create mode 100644 Samples/PK-SampleLib/RenderPasses/PostFxColorRemap.cpp create mode 100644 Samples/PK-SampleLib/RenderPasses/PostFxColorRemap.h create mode 100644 Samples/PK-SampleLib/RenderPasses/PostFxDistortion.cpp create mode 100644 Samples/PK-SampleLib/RenderPasses/PostFxDistortion.h create mode 100644 Samples/PK-SampleLib/RenderPasses/PostFxFXAA.cpp create mode 100644 Samples/PK-SampleLib/RenderPasses/PostFxFXAA.h create mode 100644 Samples/PK-SampleLib/RenderPasses/PostFxToneMapping.cpp create mode 100644 Samples/PK-SampleLib/RenderPasses/PostFxToneMapping.h create mode 100644 Samples/PK-SampleLib/SampleScene/AbstractGraphicScene.cpp create mode 100644 Samples/PK-SampleLib/SampleScene/AbstractGraphicScene.h create mode 100644 Samples/PK-SampleLib/SampleScene/DeferredScene.cpp create mode 100644 Samples/PK-SampleLib/SampleScene/DeferredScene.h create mode 100644 Samples/PK-SampleLib/SampleScene/Entities/EnvironmentMapEntity.cpp create mode 100644 Samples/PK-SampleLib/SampleScene/Entities/EnvironmentMapEntity.h create mode 100644 Samples/PK-SampleLib/SampleScene/Entities/LightEntity.cpp create mode 100644 Samples/PK-SampleLib/SampleScene/Entities/LightEntity.h create mode 100644 Samples/PK-SampleLib/SampleScene/Entities/MeshEntity.cpp create mode 100644 Samples/PK-SampleLib/SampleScene/Entities/MeshEntity.h create mode 100644 Samples/PK-SampleLib/SampleUtils.cpp create mode 100644 Samples/PK-SampleLib/SampleUtils.h create mode 100644 Samples/PK-SampleLib/ShaderDefinitions/BasicSceneShaderDefinitions.cpp create mode 100644 Samples/PK-SampleLib/ShaderDefinitions/BasicSceneShaderDefinitions.h create mode 100644 Samples/PK-SampleLib/ShaderDefinitions/EditorShaderDefinitions.cpp create mode 100644 Samples/PK-SampleLib/ShaderDefinitions/EditorShaderDefinitions.h create mode 100644 Samples/PK-SampleLib/ShaderDefinitions/SampleLibShaderDefinitions.cpp create mode 100644 Samples/PK-SampleLib/ShaderDefinitions/SampleLibShaderDefinitions.h create mode 100644 Samples/PK-SampleLib/ShaderDefinitions/ShaderDefinitions.cpp create mode 100644 Samples/PK-SampleLib/ShaderDefinitions/ShaderDefinitions.h create mode 100644 Samples/PK-SampleLib/ShaderDefinitions/UnitTestsShaderDefinitions.cpp create mode 100644 Samples/PK-SampleLib/ShaderDefinitions/UnitTestsShaderDefinitions.h create mode 100644 Samples/PK-SampleLib/ShaderGenerator/GLSLShaderGenerator.cpp create mode 100644 Samples/PK-SampleLib/ShaderGenerator/GLSLShaderGenerator.h create mode 100644 Samples/PK-SampleLib/ShaderGenerator/HLSLShaderGenerator.cpp create mode 100644 Samples/PK-SampleLib/ShaderGenerator/HLSLShaderGenerator.h create mode 100644 Samples/PK-SampleLib/ShaderGenerator/MetalShaderGenerator.cpp create mode 100644 Samples/PK-SampleLib/ShaderGenerator/MetalShaderGenerator.h create mode 100644 Samples/PK-SampleLib/ShaderGenerator/ParticleShaderGenerator.cpp create mode 100644 Samples/PK-SampleLib/ShaderGenerator/ParticleShaderGenerator.h create mode 100644 Samples/PK-SampleLib/ShaderGenerator/ShaderGenerator.cpp create mode 100644 Samples/PK-SampleLib/ShaderGenerator/ShaderGenerator.h create mode 100644 Samples/PK-SampleLib/ShaderGenerator/VulkanShaderGenerator.cpp create mode 100644 Samples/PK-SampleLib/ShaderGenerator/VulkanShaderGenerator.h create mode 100644 Samples/PK-SampleLib/ShaderLoader.cpp create mode 100644 Samples/PK-SampleLib/ShaderLoader.h create mode 100644 Samples/PK-SampleLib/SimInterfaces/SimInterface_GBufferSampling.cpp create mode 100644 Samples/PK-SampleLib/SimInterfaces/SimInterfaces.h create mode 100644 Samples/PK-SampleLib/WindowContext/AWindowContext.cpp create mode 100644 Samples/PK-SampleLib/WindowContext/AWindowContext.h create mode 100644 Samples/PK-SampleLib/WindowContext/OffscreenContext/OffscreenContext.cpp create mode 100644 Samples/PK-SampleLib/WindowContext/OffscreenContext/OffscreenContext.h create mode 100644 Samples/PK-SampleLib/WindowContext/SdlContext/SdlContext.cpp create mode 100644 Samples/PK-SampleLib/WindowContext/SdlContext/SdlContext.h create mode 100644 Samples/PK-SampleLib/bin/mcpp.exe create mode 100644 Samples/precompiled/precompiled.cpp create mode 100644 Samples/precompiled/precompiled.h create mode 100644 download_3rd_party.bat create mode 100644 download_3rd_party.sh create mode 100644 projects/AfterEffects_macosx/AE_Effect_Attribute.make create mode 100644 projects/AfterEffects_macosx/AE_Effect_AttributeSampler.make create mode 100644 projects/AfterEffects_macosx/AE_Effect_Emitter.make create mode 100644 projects/AfterEffects_macosx/AE_GeneralPlugin.make create mode 100644 projects/AfterEffects_macosx/PK-AssetBaker.make create mode 100644 projects/AfterEffects_macosx/PK-AssetBakerLib.make create mode 100644 projects/AfterEffects_macosx/PK-Discretizers_SDK1.make create mode 100644 projects/AfterEffects_macosx/PK-MCPP.make create mode 100644 projects/AfterEffects_macosx/PK-MCPP_SDK1.make create mode 100644 projects/AfterEffects_macosx/PK-ParticlesToolbox_SDK1.make create mode 100644 projects/AfterEffects_macosx/PK-RHI.make create mode 100644 projects/AfterEffects_macosx/PK-RHI_SDK1.make create mode 100644 projects/AfterEffects_macosx/PK-RenderHelpers.make create mode 100644 projects/AfterEffects_macosx/PK-RenderHelpers_SDK1.make create mode 100644 projects/AfterEffects_macosx/PK-Runtime_SDK1.make create mode 100644 projects/AfterEffects_macosx/PK-SampleLib.make create mode 100644 projects/AfterEffects_macosx/PK-Sample_01_BasicRendering.make create mode 100644 projects/AfterEffects_macosx/PK-Sample_01_BasicStartup.make create mode 100644 projects/AfterEffects_macosx/PK-Sample_02_BasicEvolve.make create mode 100644 projects/AfterEffects_macosx/PK-Sample_02_FullIntegration.make create mode 100644 projects/AfterEffects_macosx/PK-Sample_03_EngineHooks.make create mode 100644 projects/AfterEffects_macosx/PK-Sample_04_Baking.make create mode 100644 projects/AfterEffects_macosx/PK-Sample_04_EffectInterface.make create mode 100644 projects/AfterEffects_macosx/PK-Sample_05_Stats.make create mode 100644 projects/AfterEffects_macosx/PK-Sample_05_Upgrader.make create mode 100644 projects/AfterEffects_macosx/PK-Sample_06_SimInterface.make create mode 100644 projects/AfterEffects_macosx/PK-Sample_06_SimInterfaceGPU.make create mode 100644 projects/AfterEffects_macosx/PK-Sample_07_LOD.make create mode 100644 projects/AfterEffects_macosx/PK-Sample_08_CustomCollision.make create mode 100644 projects/AfterEffects_macosx/PK-Sample_09_AsyncLoading.make create mode 100644 projects/AfterEffects_macosx/PK-Sample_10_AsyncRendering.make create mode 100644 projects/AfterEffects_macosx/PK-Sample_11_ThreadPool.make create mode 100644 projects/AfterEffects_macosx/PK-Sample_12_GBufferSampling.make create mode 100644 projects/AfterEffects_macosx/PK-ShaderTool.make create mode 100644 projects/AfterEffects_macosx/PK-Upgrader.make create mode 100644 projects/AfterEffects_macosx/PK-UpgraderLib.make create mode 100644 projects/AfterEffects_macosx/PopcornFX_AfterEffectsPlugin.make create mode 100644 projects/AfterEffects_macosx/PopcornFX_SDK1.make create mode 100644 projects/AfterEffects_macosx/Qt/x64/Debug/moc_AEGP_GraphicalResourcesTreeModel.args create mode 100644 projects/AfterEffects_macosx/Qt/x64/Debug/moc_AEGP_PanelQT.args create mode 100644 projects/AfterEffects_macosx/Qt/x64/Release/moc_AEGP_GraphicalResourcesTreeModel.args create mode 100644 projects/AfterEffects_macosx/Qt/x64/Release/moc_AEGP_PanelQT.args create mode 100644 projects/AfterEffects_vs2019/AE_Effect_Attribute.vcxproj create mode 100644 projects/AfterEffects_vs2019/AE_Effect_Attribute.vcxproj.filters create mode 100644 projects/AfterEffects_vs2019/AE_Effect_AttributeSampler.vcxproj create mode 100644 projects/AfterEffects_vs2019/AE_Effect_AttributeSampler.vcxproj.filters create mode 100644 projects/AfterEffects_vs2019/AE_Effect_Emitter.vcxproj create mode 100644 projects/AfterEffects_vs2019/AE_Effect_Emitter.vcxproj.filters create mode 100644 projects/AfterEffects_vs2019/AE_GeneralPlugin.vcxproj create mode 100644 projects/AfterEffects_vs2019/AE_GeneralPlugin.vcxproj.filters create mode 100644 projects/AfterEffects_vs2019/AE_GeneralPlugin.vcxproj.user create mode 100644 projects/AfterEffects_vs2019/PK-AssetBaker.vcxproj create mode 100644 projects/AfterEffects_vs2019/PK-AssetBaker.vcxproj.filters create mode 100644 projects/AfterEffects_vs2019/PK-AssetBaker.vcxproj.user create mode 100644 projects/AfterEffects_vs2019/PK-AssetBakerLib.vcxproj create mode 100644 projects/AfterEffects_vs2019/PK-AssetBakerLib.vcxproj.filters create mode 100644 projects/AfterEffects_vs2019/PK-Discretizers_SDK1.vcxproj create mode 100644 projects/AfterEffects_vs2019/PK-Discretizers_SDK1.vcxproj.filters create mode 100644 projects/AfterEffects_vs2019/PK-MCPP.vcxproj create mode 100644 projects/AfterEffects_vs2019/PK-MCPP.vcxproj.filters create mode 100644 projects/AfterEffects_vs2019/PK-MCPP_SDK1.vcxproj create mode 100644 projects/AfterEffects_vs2019/PK-MCPP_SDK1.vcxproj.filters create mode 100644 projects/AfterEffects_vs2019/PK-ParticlesToolbox_SDK1.vcxproj create mode 100644 projects/AfterEffects_vs2019/PK-ParticlesToolbox_SDK1.vcxproj.filters create mode 100644 projects/AfterEffects_vs2019/PK-RHI.vcxproj create mode 100644 projects/AfterEffects_vs2019/PK-RHI.vcxproj.filters create mode 100644 projects/AfterEffects_vs2019/PK-RHI_SDK1.vcxproj create mode 100644 projects/AfterEffects_vs2019/PK-RHI_SDK1.vcxproj.filters create mode 100644 projects/AfterEffects_vs2019/PK-RenderHelpers.vcxproj create mode 100644 projects/AfterEffects_vs2019/PK-RenderHelpers.vcxproj.filters create mode 100644 projects/AfterEffects_vs2019/PK-RenderHelpers_SDK1.vcxproj create mode 100644 projects/AfterEffects_vs2019/PK-RenderHelpers_SDK1.vcxproj.filters create mode 100644 projects/AfterEffects_vs2019/PK-Runtime_SDK1.vcxproj create mode 100644 projects/AfterEffects_vs2019/PK-Runtime_SDK1.vcxproj.filters create mode 100644 projects/AfterEffects_vs2019/PK-SampleLib.vcxproj create mode 100644 projects/AfterEffects_vs2019/PK-SampleLib.vcxproj.filters create mode 100644 projects/AfterEffects_vs2019/PK-Sample_01_BasicRendering.vcxproj create mode 100644 projects/AfterEffects_vs2019/PK-Sample_01_BasicRendering.vcxproj.filters create mode 100644 projects/AfterEffects_vs2019/PK-Sample_01_BasicRendering.vcxproj.user create mode 100644 projects/AfterEffects_vs2019/PK-Sample_01_BasicStartup.vcxproj create mode 100644 projects/AfterEffects_vs2019/PK-Sample_01_BasicStartup.vcxproj.filters create mode 100644 projects/AfterEffects_vs2019/PK-Sample_01_BasicStartup.vcxproj.user create mode 100644 projects/AfterEffects_vs2019/PK-Sample_02_BasicEvolve.vcxproj create mode 100644 projects/AfterEffects_vs2019/PK-Sample_02_BasicEvolve.vcxproj.filters create mode 100644 projects/AfterEffects_vs2019/PK-Sample_02_BasicEvolve.vcxproj.user create mode 100644 projects/AfterEffects_vs2019/PK-Sample_02_FullIntegration.vcxproj create mode 100644 projects/AfterEffects_vs2019/PK-Sample_02_FullIntegration.vcxproj.filters create mode 100644 projects/AfterEffects_vs2019/PK-Sample_02_FullIntegration.vcxproj.user create mode 100644 projects/AfterEffects_vs2019/PK-Sample_03_EngineHooks.vcxproj create mode 100644 projects/AfterEffects_vs2019/PK-Sample_03_EngineHooks.vcxproj.filters create mode 100644 projects/AfterEffects_vs2019/PK-Sample_03_EngineHooks.vcxproj.user create mode 100644 projects/AfterEffects_vs2019/PK-Sample_04_Baking.vcxproj create mode 100644 projects/AfterEffects_vs2019/PK-Sample_04_Baking.vcxproj.filters create mode 100644 projects/AfterEffects_vs2019/PK-Sample_04_Baking.vcxproj.user create mode 100644 projects/AfterEffects_vs2019/PK-Sample_04_EffectInterface.vcxproj create mode 100644 projects/AfterEffects_vs2019/PK-Sample_04_EffectInterface.vcxproj.filters create mode 100644 projects/AfterEffects_vs2019/PK-Sample_04_EffectInterface.vcxproj.user create mode 100644 projects/AfterEffects_vs2019/PK-Sample_05_Stats.vcxproj create mode 100644 projects/AfterEffects_vs2019/PK-Sample_05_Stats.vcxproj.filters create mode 100644 projects/AfterEffects_vs2019/PK-Sample_05_Stats.vcxproj.user create mode 100644 projects/AfterEffects_vs2019/PK-Sample_05_Upgrader.vcxproj create mode 100644 projects/AfterEffects_vs2019/PK-Sample_05_Upgrader.vcxproj.filters create mode 100644 projects/AfterEffects_vs2019/PK-Sample_05_Upgrader.vcxproj.user create mode 100644 projects/AfterEffects_vs2019/PK-Sample_06_SimInterface.vcxproj create mode 100644 projects/AfterEffects_vs2019/PK-Sample_06_SimInterface.vcxproj.filters create mode 100644 projects/AfterEffects_vs2019/PK-Sample_06_SimInterface.vcxproj.user create mode 100644 projects/AfterEffects_vs2019/PK-Sample_06_SimInterfaceGPU.vcxproj create mode 100644 projects/AfterEffects_vs2019/PK-Sample_06_SimInterfaceGPU.vcxproj.filters create mode 100644 projects/AfterEffects_vs2019/PK-Sample_06_SimInterfaceGPU.vcxproj.user create mode 100644 projects/AfterEffects_vs2019/PK-Sample_07_LOD.vcxproj create mode 100644 projects/AfterEffects_vs2019/PK-Sample_07_LOD.vcxproj.filters create mode 100644 projects/AfterEffects_vs2019/PK-Sample_07_LOD.vcxproj.user create mode 100644 projects/AfterEffects_vs2019/PK-Sample_08_CustomCollision.vcxproj create mode 100644 projects/AfterEffects_vs2019/PK-Sample_08_CustomCollision.vcxproj.filters create mode 100644 projects/AfterEffects_vs2019/PK-Sample_08_CustomCollision.vcxproj.user create mode 100644 projects/AfterEffects_vs2019/PK-Sample_09_AsyncLoading.vcxproj create mode 100644 projects/AfterEffects_vs2019/PK-Sample_09_AsyncLoading.vcxproj.filters create mode 100644 projects/AfterEffects_vs2019/PK-Sample_09_AsyncLoading.vcxproj.user create mode 100644 projects/AfterEffects_vs2019/PK-Sample_10_AsyncRendering.vcxproj create mode 100644 projects/AfterEffects_vs2019/PK-Sample_10_AsyncRendering.vcxproj.filters create mode 100644 projects/AfterEffects_vs2019/PK-Sample_10_AsyncRendering.vcxproj.user create mode 100644 projects/AfterEffects_vs2019/PK-Sample_11_ThreadPool.vcxproj create mode 100644 projects/AfterEffects_vs2019/PK-Sample_11_ThreadPool.vcxproj.filters create mode 100644 projects/AfterEffects_vs2019/PK-Sample_11_ThreadPool.vcxproj.user create mode 100644 projects/AfterEffects_vs2019/PK-Sample_12_GBufferSampling.vcxproj create mode 100644 projects/AfterEffects_vs2019/PK-Sample_12_GBufferSampling.vcxproj.filters create mode 100644 projects/AfterEffects_vs2019/PK-Sample_12_GBufferSampling.vcxproj.user create mode 100644 projects/AfterEffects_vs2019/PK-ShaderTool.vcxproj create mode 100644 projects/AfterEffects_vs2019/PK-ShaderTool.vcxproj.filters create mode 100644 projects/AfterEffects_vs2019/PK-ShaderTool.vcxproj.user create mode 100644 projects/AfterEffects_vs2019/PK-Upgrader.vcxproj create mode 100644 projects/AfterEffects_vs2019/PK-Upgrader.vcxproj.filters create mode 100644 projects/AfterEffects_vs2019/PK-Upgrader.vcxproj.user create mode 100644 projects/AfterEffects_vs2019/PK-UpgraderLib.vcxproj create mode 100644 projects/AfterEffects_vs2019/PK-UpgraderLib.vcxproj.filters create mode 100644 projects/AfterEffects_vs2019/PopcornFX_AfterEffectsPlugin.sln create mode 100644 projects/AfterEffects_vs2019/PopcornFX_SDK1.sln create mode 100644 projects/AfterEffects_vs2019/Qt/x64/Debug/moc_AEGP_GraphicalResourcesTreeModel.args create mode 100644 projects/AfterEffects_vs2019/Qt/x64/Debug/moc_AEGP_PanelQT.args create mode 100644 projects/AfterEffects_vs2019/Qt/x64/Release/moc_AEGP_GraphicalResourcesTreeModel.args create mode 100644 projects/AfterEffects_vs2019/Qt/x64/Release/moc_AEGP_PanelQT.args create mode 100644 qtoverride.dll.manifest diff --git a/.github/workflows/draft-release.yml b/.github/workflows/draft-release.yml new file mode 100644 index 00000000..2afd7e80 --- /dev/null +++ b/.github/workflows/draft-release.yml @@ -0,0 +1,30 @@ +on: + push: + tags: + - v*.*.* + +jobs: + release-on-tag: + runs-on: ubuntu-latest + permissions: + contents: write + + steps: + - uses: actions/checkout@v3 + + - uses: jungwinter/split@master + id: split + with: + msg: ${{ github.ref_name }} + separator: "." + + - name: Set environment + run: echo "VERSION=$(echo "${GITHUB_REF_NAME#v}" | sed 's/-LTS//g')" >> $GITHUB_ENV && echo "MINOR_VERSION=${{ steps.split.outputs._0 }}.${{ steps.split.outputs._1 }}" >> $GITHUB_ENV + + - uses: ncipollo/release-action@v1 + with: + draft: true + name: "After Effects Plugin: ${{ github.ref_name }}" + body: "PopcornFX Plugin ${{ github.ref_name }} for After Effects\n\n + You can download the PopcornFX Editor and find the full changelog here:\n + https://wiki.popcornfx.com/index.php?title=PK-Editor_${{ env.MINOR_VERSION }}#Changelog_${{ env.VERSION }}" \ No newline at end of file diff --git a/AE.code-workspace b/AE.code-workspace new file mode 100644 index 00000000..f439dfde --- /dev/null +++ b/AE.code-workspace @@ -0,0 +1,65 @@ +{ + "folders": [ + { + "path": "." + } + ], + "settings": { + "C_Cpp.default.defines": [ "PK_BUILD_WITH_METAL_SUPPORT=1" ], + "C_Cpp.default.includePath": [ + "../../Runtime", + "../../Runtime/include", + "../../Runtime/include/license/AfterEffects", + "../../Integrations/AfterEffects/PK-AfterEffects__Main/Sources", + "../../Integrations/AfterEffects/PK-AfterEffects__Main/Include", + "../../Integrations/AfterEffects/PK-AfterEffects__Main/Precompiled", + "../../Integrations/AfterEffects/AE_Suites", + "../../Integrations/AfterEffects/External/AE SDK/Util", + "../../Integrations/AfterEffects/External/AE SDK/Resources", + "../../Integrations/AfterEffects/External/AE SDK/Headers", + "../../Integrations/AfterEffects/External/AE SDK/Headers/SP", + "../../Integrations/AfterEffects/External/AE SDK/Headers/adobesdk", + "../../Integrations/AfterEffects/External/AE SDK/Headers/adobesdk/config", + "../../Integrations/AfterEffects/External/AE SDK/Headers/adobesdk/drawbotsuite", + "../../SDK/Samples/PK-Samples", + "../../SDK/Samples/External/imgui", + "../../SDK/Samples/External/GL/include", + "/usr/local/include/SDL2", + ], + "lldb.launch.env": { + "AEBin": "\"/Applications/Adobe After Effects 2022/Adobe After Effects 2022.app/Contents/MacOS/After Effects\"" + }, + "terminal.integrated.env.osx": { + "AEBin": "\"/Applications/Adobe After Effects 2022/Adobe After Effects 2022.app/Contents/MacOS/After Effects\"" + }, + "files.associations": { + "array": "cpp", + "iterator": "cpp", + "string": "cpp", + "string_view": "cpp", + "vector": "cpp", + "__locale": "cpp" + }, + }, + "launch": { + // Use IntelliSense to learn about possible attributes. + // Hover to view descriptions of existing attributes. + // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 + "version": "0.2.0", + "configurations": [ + { + "name": "(lldb) Launch", + "type": "cppdbg", + "request": "launch", + "program": "/Applications/Adobe After Effects 2022/Adobe After Effects 2022.app/Contents/MacOS/After Effects", + "args": ["--debug"], + "stopAtEntry": false, + "cwd": "${workspaceFolder}", + "environment": [], + "externalConsole": false, + "MIMode": "lldb", + "visualizerFile": "${workspaceRoot}/../../../configurations/visual studio/debugger/PopcornFX.natvis", + } + ] + } +} diff --git a/AE_Effect_Attribute/Include/AEAttribute_Main.h b/AE_Effect_Attribute/Include/AEAttribute_Main.h new file mode 100644 index 00000000..e44dc60c --- /dev/null +++ b/AE_Effect_Attribute/Include/AEAttribute_Main.h @@ -0,0 +1,39 @@ +//---------------------------------------------------------------------------- +// Copyright Persistant Studios, SARL. All Rights Reserved. https://www.popcornfx.com/terms-and-conditions/ +//---------------------------------------------------------------------------- +#pragma once + +#ifndef __FX_AEATTRIBUTE_MAIN_H__ +#define __FX_AEATTRIBUTE_MAIN_H__ + +#include + +#ifdef AE_OS_WIN + typedef unsigned short PixelType; + #include +#endif + +#include +#include + +#include "PopcornFX_Define.h" + +//---------------------------------------------------------------------------- + +extern "C" { + DllExport + PF_Err + EffectMain( + PF_Cmd cmd, + PF_InData *in_data, + PF_OutData *out_data, + PF_ParamDef *params[], + PF_LayerDef *output, + void *extra); + +} + +//---------------------------------------------------------------------------- + +#endif + diff --git a/AE_Effect_Attribute/Include/AEAttribute_ParamDefine.h b/AE_Effect_Attribute/Include/AEAttribute_ParamDefine.h new file mode 100644 index 00000000..780622ba --- /dev/null +++ b/AE_Effect_Attribute/Include/AEAttribute_ParamDefine.h @@ -0,0 +1,58 @@ +//---------------------------------------------------------------------------- +// Copyright Persistant Studios, SARL. All Rights Reserved. https://www.popcornfx.com/terms-and-conditions/ +//---------------------------------------------------------------------------- +#pragma once + +#include +#include + +#include + +__AAEPK_BEGIN + +//---------------------------------------------------------------------------- + +enum EPKParams +{ + ATTRIBUTE_INPUT = 0, + ATTRIBUTE_PARAM, + ATTRIBUTE_NUM_PARAMS +}; + +//---------------------------------------------------------------------------- + +enum EStrIDType +{ + StrID_NONE = 0, + StrID_Name, + StrID_Description, + StrID_Generic_Bool1, + StrID_Generic_Bool2, + StrID_Generic_Bool3, + StrID_Generic_Bool4, + StrID_Generic_Int1, + StrID_Generic_Int2, + StrID_Generic_Int3, + StrID_Generic_Int4, + StrID_Generic_Float1, + StrID_Generic_Float2, + StrID_Generic_Float3, + StrID_Generic_Float4, + StrID_Generic_Quaternion, + + StrID_Generic_Infernal_Uuid, + StrID_Scale_Checkbox, + StrID_Generic_Infernal_Name, + + StrID_Generic_Color_RGB, + StrID_Generic_Color_A, + + StrID_Parameters_Reset, + StrID_Parameters_Reset_Button, + + StrID_NUMTYPES +}; + +//---------------------------------------------------------------------------- + +__AAEPK_END diff --git a/AE_Effect_Attribute/Include/AEAttribute_PluginInterface.h b/AE_Effect_Attribute/Include/AEAttribute_PluginInterface.h new file mode 100644 index 00000000..6adef44b --- /dev/null +++ b/AE_Effect_Attribute/Include/AEAttribute_PluginInterface.h @@ -0,0 +1,99 @@ +//---------------------------------------------------------------------------- +// Copyright Persistant Studios, SARL. All Rights Reserved. https://www.popcornfx.com/terms-and-conditions/ +//---------------------------------------------------------------------------- +#pragma once + +#ifndef __FX_CPluginInterface_H__ +#define __FX_CPluginInterface_H__ + +#include "PopcornFX_Define.h" +#include "PopcornFX_BasePluginInterface.h" + +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include +#include + +__AAEPK_BEGIN + +struct SAAEIOData; +struct SAttributeDesc; +struct SAttributeSequenceDataFlat; + +//---------------------------------------------------------------------------- + +class CPluginInterface : public CBasePluginInterface +{ + struct SAttributeData + { + //Memory Owned by effect + SAttributeDesc *m_DescAttribute; + + bool m_UIVisibility[__Attribute_Parameters_Count]; + bool m_IsDefault; + + SAttributeData() + : m_DescAttribute(nullptr) + , m_IsDefault(true) + { + } + ~SAttributeData() + { + m_DescAttribute = nullptr; + } + }; +public: + ~CPluginInterface(); + static CPluginInterface &Instance(); + + PF_Err About(SAAEIOData &AAEData, PF_ParamDef *params[], PF_LayerDef *output); + PF_Err GlobalSetup(SAAEIOData &AAEData, PF_ParamDef *params[], PF_LayerDef *output); + PF_Err ParamsSetup(SAAEIOData &AAEData, PF_ParamDef *params[], PF_LayerDef *output); + PF_Err GlobalSetdown(SAAEIOData &AAEData, PF_ParamDef *params[], PF_LayerDef *output); + + PF_Err SequenceSetup(SAAEIOData &AAEData, PF_ParamDef *params[], PF_LayerDef *output); + PF_Err SequenceReSetup(SAAEIOData &AAEData, PF_ParamDef *params[], PF_LayerDef *output); + PF_Err SequenceFlatten(SAAEIOData &AAEData, PF_ParamDef *params[], PF_LayerDef *output); + PF_Err SequenceShutdown(SAAEIOData &AAEData, PF_ParamDef *params[], PF_LayerDef *output); + + PF_Err PreRender(SAAEIOData &AAEData); + PF_Err SmartRender(SAAEIOData &AAEData); + PF_Err UpdateParams(SAAEIOData &AAEData, PF_ParamDef *params[]); + PF_Err UpdateParamsUI(SAAEIOData &AAEData, PF_ParamDef *params[]); + + PF_Err SetDefaultValueIFN(SAAEIOData &AAEData, PF_ParamDef *params[], SAttributeData *AttrData); + + PF_Err HandleDataFromAEGP(SAAEIOData &AAEData, PF_ParamDef *params[]); + + void UpdateBoolAttribute(SAAEIOData &AAEData, SAttributeDesc *descriptor, bool *uiVisibility); + void UpdateIntAttribute(SAAEIOData &AAEData, SAttributeDesc *descriptor, bool *uiVisibility); + void UpdateFloatAttribute(SAAEIOData &AAEData, SAttributeDesc *descriptor, bool *uiVisibility); + +private: + CPluginInterface(); + static CPluginInterface *m_Instance; + static uint32_t m_AttrUID; + + bool _GetAttributeSequenceUID(SAAEIOData &AAEData, std::string &out); + + PF_Err _RegisterAttributeInstancePlugin(SAAEIOData &AAEData, PF_ParamDef *params[], SAttributeSequenceDataFlat *sequenceData, bool setup); + + std::unordered_map m_AttributeData; + + std::thread::id m_MainThreadID; +}; + +//---------------------------------------------------------------------------- + +__AAEPK_END + +#endif diff --git a/AE_Effect_Attribute/Include/AEAttribute_SequenceData.h b/AE_Effect_Attribute/Include/AEAttribute_SequenceData.h new file mode 100644 index 00000000..e74600f2 --- /dev/null +++ b/AE_Effect_Attribute/Include/AEAttribute_SequenceData.h @@ -0,0 +1,52 @@ +//---------------------------------------------------------------------------- +// Copyright Persistant Studios, SARL. All Rights Reserved. https://www.popcornfx.com/terms-and-conditions/ +//---------------------------------------------------------------------------- +#pragma once + +#ifndef __AEATTRIBUTE_SEQUENCEDATA_H__ +#define __AEATTRIBUTE_SEQUENCEDATA_H__ + +#include +#include +#include + +__AAEPK_BEGIN + +//---------------------------------------------------------------------------- + +namespace SequenceCST +{ + static const size_t MAX_PATH_LEN = 1024; + static const size_t MAX_NAME_LEN = 100; + static const size_t UUID_LEN = 64; +}; + +//---------------------------------------------------------------------------- + +struct SAttributeSequenceDataFlat +{ + bool m_IsFlat = true; + + char m_AttributeUUID[SequenceCST::UUID_LEN]; + size_t m_AttributeUUIDLen; + + char m_AttributeName[SequenceCST::MAX_NAME_LEN]; + size_t m_AttributeNameLen; + + bool m_IsDefault = true; + + A_long m_LayerID; + + void CopyFrom(SAttributeSequenceDataFlat* src); + + void SetIsDefaultValue(bool value); + bool SetUUID(const char *uuid); + bool SetName(const char *name); + bool SetLayerID(bool value); +}; + +//---------------------------------------------------------------------------- + +__AAEPK_END + +#endif // !__AAEFFECT_SEQUENCEDATA_H__ diff --git a/AE_Effect_Attribute/PkgInfo b/AE_Effect_Attribute/PkgInfo new file mode 100644 index 00000000..31cf1f41 --- /dev/null +++ b/AE_Effect_Attribute/PkgInfo @@ -0,0 +1 @@ +eFKTFXTC \ No newline at end of file diff --git a/AE_Effect_Attribute/Precompiled/ae_precompiled.cpp b/AE_Effect_Attribute/Precompiled/ae_precompiled.cpp new file mode 100644 index 00000000..84e52276 --- /dev/null +++ b/AE_Effect_Attribute/Precompiled/ae_precompiled.cpp @@ -0,0 +1 @@ +#include "ae_precompiled.h" diff --git a/AE_Effect_Attribute/Precompiled/ae_precompiled.h b/AE_Effect_Attribute/Precompiled/ae_precompiled.h new file mode 100644 index 00000000..5b1746dd --- /dev/null +++ b/AE_Effect_Attribute/Precompiled/ae_precompiled.h @@ -0,0 +1,13 @@ +#pragma once + +#undef PV_MODULE_NAME +#undef PV_MODULE_SYM +#define PV_MODULE_NAME "AEPlugin" +#define PV_MODULE_SYM AEPlugin + +#include + +#if defined(PK_WINDOWS) +#define WIN32_LEAN_AND_MEAN +#include +#endif diff --git a/AE_Effect_Attribute/Sources/AEAttribute_Main.cpp b/AE_Effect_Attribute/Sources/AEAttribute_Main.cpp new file mode 100644 index 00000000..a442da88 --- /dev/null +++ b/AE_Effect_Attribute/Sources/AEAttribute_Main.cpp @@ -0,0 +1,172 @@ +//---------------------------------------------------------------------------- +// Copyright Persistant Studios, SARL. All Rights Reserved. https://www.popcornfx.com/terms-and-conditions/ +//---------------------------------------------------------------------------- +#include "ae_precompiled.h" + +#include "AEAttribute_Main.h" + +#include "AEAttribute_PluginInterface.h" +#include "PopcornFX_Suite.h" + +#include + +#include + +//---------------------------------------------------------------------------- + +extern "C" +{ + DllExport PF_Err PluginDataEntryFunction( PF_PluginDataPtr inPtr, + PF_PluginDataCB inPluginDataCallBackPtr, + SPBasicSuite *inSPBasicSuitePtr, + const char *inHostName, + const char *inHostVersion) + { + (void)inSPBasicSuitePtr; + (void)inHostName; + (void)inHostVersion; + + PF_Err result = PF_Err_INVALID_CALLBACK; + + result = PF_REGISTER_EFFECT( + inPtr, // Infos must match the PopcornFXPiPL.r + inPluginDataCallBackPtr, // + "Attribute", // Name + "ADBE PopcornFX Attribute", // Match Name + "PopcornFX", // Category + AE_RESERVED_INFO); // Reserved Info + return result; + } +} + +//---------------------------------------------------------------------------- + +PF_Err EffectMain( PF_Cmd cmd, + PF_InData *in_data, + PF_OutData *out_data, + PF_ParamDef *params[], + PF_LayerDef *output, + void *extra) +{ + PF_Err result = PF_Err_NONE; + AAePk::CPluginInterface &AEPlugin = AAePk::CPluginInterface::Instance(); + AAePk::SAAEIOData AAEData{ cmd, in_data, out_data, extra, AEPlugin.GetParametersIndexes() }; + +#if _DEBUG + try + { +#endif + + assert(in_data != nullptr); + assert(out_data != nullptr); + if (in_data == nullptr) + return PF_Err_BAD_CALLBACK_PARAM; + //Force Render + //AAEData.m_OutData->out_flags &= PF_OutFlag_FORCE_RERENDER + + if (AAEData.m_InData->appl_id == 'PrMr') + { + //User Tried to load plugin in Premiere Pro. + //There is surely a better way to handle this. + return PF_Err_UNRECOGNIZED_PARAM_TYPE; + } + + switch (cmd) + { + // Called once + case PF_Cmd_ABOUT: + //Mandatory + //Version and General Infos about the plugin + result = AEPlugin.About(AAEData, params, output); + break; + case PF_Cmd_GLOBAL_SETUP: + //Mandatory + //Startup run + result = AEPlugin.GlobalSetup(AAEData, params, output); + break; + case PF_Cmd_PARAMS_SETUP: + //Mandatory + //Setup AAE UI. + result = AEPlugin.ParamsSetup(AAEData, params, output); + break; + case PF_Cmd_GLOBAL_SETDOWN: + //Mandatory + result = AEPlugin.GlobalSetdown(AAEData, params, output); + break; + // Sequence Handling + //UI thread + case PF_Cmd_SEQUENCE_SETUP: + //Each time the user adds the effect to a layer + result = AEPlugin.SequenceSetup(AAEData, params, output); + break; + case PF_Cmd_SEQUENCE_RESETUP: + //Load or Duplicate + //UI/Render thread + result = AEPlugin.SequenceReSetup(AAEData, params, output); + break; + case PF_Cmd_SEQUENCE_FLATTEN: + //Effect Saved, copied, duplicated.. + //UI/Render thread + result = AEPlugin.SequenceFlatten(AAEData, params, output); + break; + case PF_Cmd_SEQUENCE_SETDOWN: + //Effect Deleted + result = AEPlugin.SequenceShutdown(AAEData, params, output); + break; + case PF_Cmd_GET_FLATTENED_SEQUENCE_DATA: + break; + + // Called each Frame + case PF_Cmd_AUDIO_SETUP: + case PF_Cmd_AUDIO_RENDER: + case PF_Cmd_AUDIO_SETDOWN: + break; + case PF_Cmd_FRAME_SETUP: + //Allow resizing of drawing area + break; + case PF_Cmd_SMART_PRE_RENDER: + result = AEPlugin.PreRender(AAEData); + //Can be called several times for one render + break; + case PF_Cmd_SMART_RENDER: + result = AEPlugin.SmartRender(AAEData); + break; + case PF_Cmd_FRAME_SETDOWN: + //Allow resizing of drawing area + break; + + // Messaging + case PF_Cmd_EVENT: + break; + case PF_Cmd_USER_CHANGED_PARAM: + AEPlugin.UpdateParams(AAEData, params); + //If PF_ParamFlag_SUPERVIZE if set when adding param, PF_Cmd_USER_CHANGED_PARAM is called when value change + break; + case PF_Cmd_UPDATE_PARAMS_UI: + result = AEPlugin.UpdateParamsUI(AAEData, params); + break; + case PF_Cmd_ARBITRARY_CALLBACK: + case PF_Cmd_GET_EXTERNAL_DEPENDENCIES: + break; + case PF_Cmd_COMPLETELY_GENERAL: + result = AEPlugin.HandleDataFromAEGP(AAEData, params); + break; + case PF_Cmd_DO_DIALOG: + //Send when user click on Options + //Received if PF_OutFlag_I_DO_DIALOG is set in PF_Cmd_GLOBAL_SETUP + break; + case PF_Cmd_QUERY_DYNAMIC_FLAGS: + break; + default: + break; + } + +#if _DEBUG + } + catch (...) + { + assert(false); + } +#endif + return result; +} diff --git a/AE_Effect_Attribute/Sources/AEAttribute_ParamDefine.cpp b/AE_Effect_Attribute/Sources/AEAttribute_ParamDefine.cpp new file mode 100644 index 00000000..19ba1ce2 --- /dev/null +++ b/AE_Effect_Attribute/Sources/AEAttribute_ParamDefine.cpp @@ -0,0 +1,66 @@ +//---------------------------------------------------------------------------- +// Copyright Persistant Studios, SARL. All Rights Reserved. https://www.popcornfx.com/terms-and-conditions/ +//---------------------------------------------------------------------------- +#include "ae_precompiled.h" + +#include "AEAttribute_ParamDefine.h" + +__AAEPK_BEGIN + +//---------------------------------------------------------------------------- + +struct STableString +{ + A_u_long index; + A_char str[256]; +} ; + +//---------------------------------------------------------------------------- + +STableString g_strs[StrID_NUMTYPES] = +{ + { StrID_NONE, "" }, + { StrID_Name, "Attribute" }, + { StrID_Description, "PopcornFX Plugin." }, + { StrID_Generic_Bool1, "Attribute bool" }, + { StrID_Generic_Bool2, "Attribute bool 2" }, + { StrID_Generic_Bool3, "Attribute bool 3" }, + { StrID_Generic_Bool4, "Attribute bool 4" }, + { StrID_Generic_Int1, "Attribute int" }, + { StrID_Generic_Int2, "Attribute int 2" }, + { StrID_Generic_Int3, "Attribute int 3" }, + { StrID_Generic_Int4, "Attribute int 4" }, + { StrID_Generic_Float1, "Attribute float" }, + { StrID_Generic_Float2, "Attribute float 2" }, + { StrID_Generic_Float3, "Attribute float 3" }, + { StrID_Generic_Float4, "Attribute float 4" }, + { StrID_Generic_Quaternion, "Attribute Quaternion" }, + { StrID_Generic_Infernal_Uuid, "AttributeKey" }, + { StrID_Scale_Checkbox, "Affected by scale" }, + { StrID_Generic_Infernal_Name, "AttributeName" }, + { StrID_Generic_Color_RGB, "RGB" }, + { StrID_Generic_Color_A, "Alpha" }, + { StrID_Parameters_Reset, "" }, + { StrID_Parameters_Reset_Button, "Reset Value" }, +}; + +//---------------------------------------------------------------------------- + +__AAEPK_END + +//---------------------------------------------------------------------------- + +#ifdef __cplusplus +extern "C" +{ +#endif + +A_char *GetStringPtr(int strNum) +{ + return AAePk::g_strs[strNum].str; +} + +#ifdef __cplusplus +} +#endif + diff --git a/AE_Effect_Attribute/Sources/AEAttribute_PluginInterface.cpp b/AE_Effect_Attribute/Sources/AEAttribute_PluginInterface.cpp new file mode 100644 index 00000000..a6ac028b --- /dev/null +++ b/AE_Effect_Attribute/Sources/AEAttribute_PluginInterface.cpp @@ -0,0 +1,928 @@ +//---------------------------------------------------------------------------- +// Copyright Persistant Studios, SARL. All Rights Reserved. https://www.popcornfx.com/terms-and-conditions/ +//---------------------------------------------------------------------------- +#include "ae_precompiled.h" + +#include "AEAttribute_PluginInterface.h" +#include "AEAttribute_SequenceData.h" +#include "AEAttribute_ParamDefine.h" + +#include "PopcornFX_UID.h" + +//AE +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +//AAE Plugin code +#include +#include + +#include +#include + +__AAEPK_BEGIN + +//---------------------------------------------------------------------------- + +CPluginInterface *CPluginInterface::m_Instance = nullptr; +uint32_t CPluginInterface::m_AttrUID = 1; + +//---------------------------------------------------------------------------- + +CPluginInterface::CPluginInterface() +{ +} + +//---------------------------------------------------------------------------- + +CPluginInterface::~CPluginInterface() +{ + for (auto& it : m_AttributeData) + { + delete(it.second); + } + m_AttributeData.clear(); +} + +//---------------------------------------------------------------------------- + +CPluginInterface &CPluginInterface::Instance() +{ + if (CPluginInterface::m_Instance == nullptr) + { + m_Instance = new CPluginInterface(); + } + return *m_Instance; +} + +//---------------------------------------------------------------------------- + +PF_Err CPluginInterface::About( SAAEIOData &AAEData, + PF_ParamDef *params[], + PF_LayerDef *output) +{ + (void)output; + (void)params; + + AEGP_SuiteHandler suites(AAEData.m_InData->pica_basicP); + suites.ANSICallbacksSuite1()->sprintf(AAEData.m_OutData->return_msg, + "%s v%d.%d.%d\r%s", + STR(StrID_Name), + AEPOPCORNFX_MAJOR_VERSION, + AEPOPCORNFX_MINOR_VERSION, + AEPOPCORNFX_BUG_VERSION, + STR(StrID_Description)); + return PF_Err_NONE; +} + +//---------------------------------------------------------------------------- + +PF_Err CPluginInterface::GlobalSetup( SAAEIOData &AAEData, + PF_ParamDef *params[], + PF_LayerDef *output) +{ + (void)output; + (void)params; + m_MainThreadID = std::this_thread::get_id(); + + AEFX_SuiteScoper popcornFXSuite = AEFX_SuiteScoper( AAEData.m_InData, + kPopcornFXSuite1, + kPopcornFXSuiteVersion1, + AAEData.m_OutData, + "PopcornFX suite was not found."); + AEGP_SuiteHandler suites(AAEData.m_InData->pica_basicP); + + AAEData.m_OutData->my_version = PF_VERSION( AEPOPCORNFX_MAJOR_VERSION, + AEPOPCORNFX_MINOR_VERSION, + AEPOPCORNFX_BUG_VERSION, + AEPOPCORNFX_STAGE_VERSION, + AEPOPCORNFX_BUILD_VERSION); + + //PF_OutFlag_DEEP_COLOR_AWARE -> To support 16bit per chan format. + //PF_OutFlag_I_AM_OBSOLETE -> Do not show in menu. We do not want user to create this effect manually. + //PF_OutFlag_SEND_UPDATE_PARAMS_UI -> To be notified when PF_ParamFlag_SUPERVISE is set on parameters + AAEData.m_OutData->out_flags = PF_OutFlag_DEEP_COLOR_AWARE | PF_OutFlag_I_AM_OBSOLETE | PF_OutFlag_SEND_UPDATE_PARAMS_UI; + //PF_OutFlag2_SUPPORTS_QUERY_DYNAMIC_FLAGS -> To be able to change dynamicly some out_flags. see doc. + //PF_OutFlag2_FLOAT_COLOR_AWARE -> To support 32bit per chan format. Need PF_OutFlag2_SUPPORTS_SMART_RENDER + //PF_OutFlag2_SUPPORTS_SMART_RENDER -> Necessary for new render pipeline. + //PF_OutFlag2_I_USE_3D_CAMERA -> Can query 3D camera information, Not sure if necessery in Attribute or just on Effect. + AAEData.m_OutData->out_flags2 = PF_OutFlag2_SUPPORTS_QUERY_DYNAMIC_FLAGS | PF_OutFlag2_FLOAT_COLOR_AWARE | PF_OutFlag2_SUPPORTS_SMART_RENDER | PF_OutFlag2_I_USE_3D_CAMERA | + PF_OutFlag2_SUPPORTS_THREADED_RENDERING;// | PF_OutFlag2_MUTABLE_RENDER_SEQUENCE_DATA_SLOWER;; + + suites.UtilitySuite3()->AEGP_RegisterWithAEGP(nullptr, STR(StrID_Name), &m_AAEID); + + return popcornFXSuite->InitializePopcornFXIFN(AAEData); +} + +//---------------------------------------------------------------------------- + +PF_Err CPluginInterface::ParamsSetup( SAAEIOData &AAEData, + PF_ParamDef *params[], + PF_LayerDef *output) +{ + (void)output; + (void)params; + + AEFX_SuiteScoper popcornFXSuite = AEFX_SuiteScoper( AAEData.m_InData, + kPopcornFXSuite1, + kPopcornFXSuiteVersion1, + AAEData.m_OutData, + "PopcornFX suite was not found."); + PF_Err result = PF_Err_NONE; + //TMP Used in Macros + PF_InData *in_data = AAEData.m_InData; + PF_ParamDef def; + + m_ParametersIndexes = new int[__Attribute_Parameters_Count]; + for (unsigned int i = 0; i < __Attribute_Parameters_Count; ++i) + m_ParametersIndexes[i] = -1; + m_ParametersIndexes[0] = 0; // First Parameter is reserved to AE + + AddCheckBoxParameter(in_data, STR(StrID_Generic_Bool1), Attribute_Parameters_Bool1); + AddCheckBoxParameter(in_data, STR(StrID_Generic_Bool2), Attribute_Parameters_Bool2); + AddCheckBoxParameter(in_data, STR(StrID_Generic_Bool3), Attribute_Parameters_Bool3); + AddCheckBoxParameter(in_data, STR(StrID_Generic_Bool4), Attribute_Parameters_Bool4); + + AddFloatParameterUnbound(in_data, STR(StrID_Generic_Int1), Attribute_Parameters_Int1, 0.0f, PF_ValueDisplayFlag_NONE | PF_ParamFlag_SUPERVISE | PF_ParamFlag_COLLAPSE_TWIRLY); + AddFloatParameterUnbound(in_data, STR(StrID_Generic_Int2), Attribute_Parameters_Int2, 0.0f, PF_ValueDisplayFlag_NONE | PF_ParamFlag_SUPERVISE | PF_ParamFlag_COLLAPSE_TWIRLY); + AddFloatParameterUnbound(in_data, STR(StrID_Generic_Int3), Attribute_Parameters_Int3, 0.0f, PF_ValueDisplayFlag_NONE | PF_ParamFlag_SUPERVISE | PF_ParamFlag_COLLAPSE_TWIRLY); + AddFloatParameterUnbound(in_data, STR(StrID_Generic_Int4), Attribute_Parameters_Int4, 0.0f, PF_ValueDisplayFlag_NONE | PF_ParamFlag_SUPERVISE | PF_ParamFlag_COLLAPSE_TWIRLY); + + AddFloatParameterUnbound(in_data, STR(StrID_Generic_Float1), Attribute_Parameters_Float1, 0.0f, PF_ValueDisplayFlag_NONE | PF_ParamFlag_SUPERVISE | PF_ParamFlag_COLLAPSE_TWIRLY); + AddFloatParameterUnbound(in_data, STR(StrID_Generic_Float2), Attribute_Parameters_Float2, 0.0f, PF_ValueDisplayFlag_NONE | PF_ParamFlag_SUPERVISE | PF_ParamFlag_COLLAPSE_TWIRLY); + AddFloatParameterUnbound(in_data, STR(StrID_Generic_Float3), Attribute_Parameters_Float3, 0.0f, PF_ValueDisplayFlag_NONE | PF_ParamFlag_SUPERVISE | PF_ParamFlag_COLLAPSE_TWIRLY); + AddFloatParameterUnbound(in_data, STR(StrID_Generic_Float4), Attribute_Parameters_Float4, 0.0f, PF_ValueDisplayFlag_NONE | PF_ParamFlag_SUPERVISE | PF_ParamFlag_COLLAPSE_TWIRLY); + + //To do add Quaternion + //PF_ADD_POINT_3D(STR(StrID_Generic_Quaternion), 50, 50, 0, AttributeType_Quaternion) + + AddCheckBoxParameter(in_data, STR(StrID_Generic_Infernal_Uuid), Attribute_Parameters_Infernal_Uuid, false, 0, PF_PUI_INVISIBLE); + + AddCheckBoxParameter(in_data, STR(StrID_Scale_Checkbox), Attribute_Parameters_AffectedByScale, false, PF_ParamFlag_CANNOT_TIME_VARY | PF_ParamFlag_CANNOT_INTERP); + + AddCheckBoxParameter(in_data, STR(StrID_Generic_Infernal_Name), Attribute_Parameters_Infernal_Name, false, 0, PF_PUI_INVISIBLE); + + + AEFX_CLR_STRUCT(def); + PF_ADD_COLOR(STR(StrID_Generic_Color_RGB), + (char)(0.0f), + (char)(0.0f), + (char)(0.0f), + Attribute_Parameters_Color_RGB); + m_ParametersIndexes[Attribute_Parameters_Color_RGB] = ++m_CurrentIndex; + + AddPercentParameter(in_data, STR(StrID_Generic_Color_A), Attribute_Parameters_Color_A, 100); + + AEFX_CLR_STRUCT(def); + PF_ADD_BUTTON(STR(StrID_Parameters_Reset), STR(StrID_Parameters_Reset_Button), 0, PF_ParamFlag_SUPERVISE, Attribute_Parameters_Reset); + m_ParametersIndexes[Attribute_Parameters_Reset] = ++m_CurrentIndex; + + AAEData.m_OutData->num_params = __Attribute_Parameters_Count; + + popcornFXSuite->SetParametersIndexes(m_ParametersIndexes, EPKChildPlugins::ATTRIBUTE); + + return result; +} + +//---------------------------------------------------------------------------- + +PF_Err CPluginInterface::GlobalSetdown( SAAEIOData &AAEData, + PF_ParamDef *params[], + PF_LayerDef *output) +{ + (void)output; + (void)params; + + AEFX_SuiteScoper PopcornFXSuite = AEFX_SuiteScoper( AAEData.m_InData, + kPopcornFXSuite1, + kPopcornFXSuiteVersion1, + AAEData.m_OutData, + "PopcornFX suite was not found."); + + + if (m_ParametersIndexes != nullptr) + delete[] m_ParametersIndexes; + m_ParametersIndexes = nullptr; + for (auto it = m_AttributeData.begin(); it != m_AttributeData.end(); ++it) + { + if (it->second != nullptr) + { + delete (it->second); + it->second = nullptr; + } + } + return PF_Err_NONE; +} + +//---------------------------------------------------------------------------- + +PF_Err CPluginInterface::SequenceSetup(SAAEIOData &AAEData, PF_ParamDef *params[], PF_LayerDef *output) +{ + (void)output; + + A_Err result = A_Err_NONE; + SAttributeSequenceDataFlat *sequenceData = nullptr; + AEGP_SuiteHandler suites(AAEData.m_InData->pica_basicP); + PF_Handle sequenceDataHandle = suites.HandleSuite1()->host_new_handle(sizeof(SAttributeSequenceDataFlat)); + + if (!sequenceDataHandle) + return PF_Err_OUT_OF_MEMORY; + sequenceData = static_cast(suites.HandleSuite1()->host_lock_handle(sequenceDataHandle)); + if (sequenceData != nullptr) + { + AEFX_CLR_STRUCT(*sequenceData); + + sequenceData->m_IsDefault = true; + sequenceData->m_IsFlat = true; + sequenceData->SetUUID(CUUIDGenerator::Get16().data()); + sequenceData->SetName("AttributeName"); + + AEGP_LayerH layerH; + A_long dstID = 0; + + result |= suites.PFInterfaceSuite1()->AEGP_GetEffectLayer(AAEData.m_InData->effect_ref, &layerH); + result |= suites.LayerSuite8()->AEGP_GetLayerID(layerH, &dstID); + + if (result == A_Err_NONE) + sequenceData->SetLayerID(dstID); + + _RegisterAttributeInstancePlugin(AAEData, params, sequenceData, true); + + AAEData.m_OutData->sequence_data = sequenceDataHandle; + suites.HandleSuite1()->host_unlock_handle(sequenceDataHandle); + } + return PF_Err_NONE; +} + +//---------------------------------------------------------------------------- + +PF_Err CPluginInterface::SequenceReSetup(SAAEIOData &AAEData, PF_ParamDef *params[], PF_LayerDef *output) +{ + (void)output; + (void)params; + + AEGP_SuiteHandler suites(AAEData.m_InData->pica_basicP); + PF_Err result = PF_Err_NONE; + + if (AAEData.m_InData->sequence_data) + { + PF_Handle sequenceDataFlatHandle = AAEData.m_InData->sequence_data; + SAttributeSequenceDataFlat *sequenceDataFlat = static_cast(suites.HandleSuite1()->host_lock_handle(sequenceDataFlatHandle)); + + if (sequenceDataFlat) + { + _RegisterAttributeInstancePlugin(AAEData, params, sequenceDataFlat, false); + AAEData.m_OutData->sequence_data = sequenceDataFlatHandle; + + suites.HandleSuite1()->host_unlock_handle(sequenceDataFlatHandle); + } + } + else + { + result = SequenceSetup(AAEData, params, output); + } + return result; +} + +//---------------------------------------------------------------------------- + +PF_Err CPluginInterface::SequenceFlatten(SAAEIOData &AAEData, PF_ParamDef *params[], PF_LayerDef *output) +{ + (void)output; + (void)params; + + AEGP_SuiteHandler suites(AAEData.m_InData->pica_basicP); + PF_Err result = PF_Err_NONE; + + if (!AAEData.m_InData->sequence_data) + return result; + + PF_Handle sequenceDataHandle = AAEData.m_InData->sequence_data; + SAttributeSequenceDataFlat *sequenceData = static_cast(suites.HandleSuite1()->host_lock_handle(sequenceDataHandle)); + + if (sequenceData) + { + std::string uuid; + //Check Layer ID to determine if its a duplicate. if so, update LayerID and regenerate UUID + AEGP_LayerH layerH; + A_long dstID = 0; + + result |= suites.PFInterfaceSuite1()->AEGP_GetEffectLayer(AAEData.m_InData->effect_ref, &layerH); + result |= suites.LayerSuite8()->AEGP_GetLayerID(layerH, &dstID); + + if (result == A_Err_NONE) + { + if (sequenceData->m_LayerID != dstID) + { + sequenceData->m_LayerID = dstID; + sequenceData->SetUUID(CUUIDGenerator::Get16().data()); + } + } + _RegisterAttributeInstancePlugin(AAEData, params, sequenceData, false); + + if (GetParamsSequenceUID(AAEData, uuid, m_ParametersIndexes[Attribute_Parameters_Infernal_Uuid]) != A_Err_NONE) + return result; + + if (m_AttributeData.count(uuid) == 0) + return result; + + SAttributeDesc *descriptor = m_AttributeData[uuid]->m_DescAttribute; + + if (descriptor == nullptr) + return result; + + sequenceData->m_IsFlat = true; + sequenceData->SetIsDefaultValue(descriptor->m_IsDefaultValue); + sequenceData->SetName(descriptor->GetAttributePKKey().c_str()); + + AAEData.m_OutData->sequence_data = sequenceDataHandle; + suites.HandleSuite1()->host_unlock_handle(sequenceDataHandle); + } + else + result = PF_Err_INTERNAL_STRUCT_DAMAGED; + return result; +} + +//---------------------------------------------------------------------------- + +PF_Err CPluginInterface::SequenceShutdown(SAAEIOData &AAEData, PF_ParamDef *params[], PF_LayerDef *output) +{ + (void)output; + (void)params; + + AEGP_SuiteHandler suites(AAEData.m_InData->pica_basicP); + + if (AAEData.m_InData->sequence_data != nullptr) + { + PF_Handle sequenceDataHandle = AAEData.m_InData->sequence_data; + suites.HandleSuite1()->host_dispose_handle(sequenceDataHandle); + } + AAEData.m_InData->sequence_data = nullptr; + AAEData.m_OutData->sequence_data = nullptr; + + return PF_Err_NONE; + +} + +//---------------------------------------------------------------------------- + +PF_Err CPluginInterface::PreRender(SAAEIOData &AAEData) +{ + PF_RenderRequest req = AAEData.m_ExtraData.m_PreRenderData->input->output_request; + PF_CheckoutResult in_result; + + AE_VERIFY(AAEData.m_ExtraData.m_PreRenderData != nullptr); + AE_VERIFY(AAEData.m_ExtraData.m_PreRenderData->cb != nullptr); + + AAEData.m_ExtraData.m_PreRenderData->cb->checkout_layer(AAEData.m_InData->effect_ref, + ATTRIBUTE_INPUT, + ATTRIBUTE_INPUT, + &req, + AAEData.m_InData->current_time, + AAEData.m_InData->local_time_step, + AAEData.m_InData->time_scale, + &in_result); + + UnionLRect(&in_result.result_rect, &AAEData.m_ExtraData.m_PreRenderData->output->result_rect); + UnionLRect(&in_result.max_result_rect, &AAEData.m_ExtraData.m_PreRenderData->output->max_result_rect); + return PF_Err_NONE; +} + +//---------------------------------------------------------------------------- + +void CPluginInterface::UpdateBoolAttribute(SAAEIOData &AAEData, SAttributeDesc *descriptor, bool *uiVisibility) +{ + bool value[4]; + + for (uint32_t i = 0; i < 4; ++i) + { + if (uiVisibility[i + Attribute_Parameters_Bool1]) + { + SAAEScopedParams params{ AAEData, i + Attribute_Parameters_Bool1 }; + + value[i] = params.GetCheckBoxValue(); + } + } + descriptor->SetValue(&value); +} + +//---------------------------------------------------------------------------- + +void CPluginInterface::UpdateIntAttribute(SAAEIOData &AAEData, SAttributeDesc *descriptor, bool *uiVisibility) +{ + int value[4]; + + if (descriptor->m_AttributeSemantic == AttributeSemantic_Color) + { + SAAEScopedParams color{ AAEData, Attribute_Parameters_Color_RGB }; + SAAEScopedParams alpha{ AAEData, Attribute_Parameters_Color_A }; + + A_FloatPoint3 AEColor = color.GetColor(); + + value[0] = (int)AEColor.x * 255; + value[1] = (int)AEColor.y * 255; + value[2] = (int)AEColor.z * 255; + value[3] = (int)alpha.GetPercent() *255; + } + else + { + for (uint32_t i = 0; i < 4; ++i) + { + if (uiVisibility[i + Attribute_Parameters_Int1]) + { + SAAEScopedParams params{ AAEData, i + Attribute_Parameters_Int1 }; + + value[i] = params.GetInt(); + } + } + } + descriptor->SetValue(&value); +} + +//---------------------------------------------------------------------------- + +void CPluginInterface::UpdateFloatAttribute(SAAEIOData &AAEData, SAttributeDesc *descriptor, bool *uiVisibility) +{ + float value[4]; + + if (descriptor->m_AttributeSemantic == AttributeSemantic_Color) + { + SAAEScopedParams color{ AAEData, Attribute_Parameters_Color_RGB }; + SAAEScopedParams alpha{ AAEData, Attribute_Parameters_Color_A }; + + A_FloatPoint3 AEColor = color.GetColor(); + + value[0] = (float)AEColor.x; + value[1] = (float)AEColor.y; + value[2] = (float)AEColor.z; + value[3] = alpha.GetPercent(); + } + else + { + for (uint32_t i = 0; i < 4; ++i) + { + if (uiVisibility[i + Attribute_Parameters_Float1]) + { + SAAEScopedParams params{ AAEData, i + Attribute_Parameters_Float1 }; + value[i] = params.GetFloat(); + } + } + } + descriptor->SetValue(&value); +} + +//---------------------------------------------------------------------------- + +PF_Err CPluginInterface::SmartRender(SAAEIOData &AAEData) +{ + AEGP_SuiteHandler suites(AAEData.m_InData->pica_basicP); + PF_EffectWorld *inputWorld = nullptr; + PF_EffectWorld *outputWorld = nullptr; + PF_Err err = PF_Err_NONE; + + std::string uuid; + + AAEData.m_ExtraData.m_SmartRenderData->cb->checkout_layer_pixels(AAEData.m_InData->effect_ref, ATTRIBUTE_INPUT, &inputWorld); + AAEData.m_ExtraData.m_SmartRenderData->cb->checkout_output(AAEData.m_InData->effect_ref, &outputWorld); + + if (inputWorld == nullptr || outputWorld == nullptr) + return PF_Err_BAD_CALLBACK_PARAM; + outputWorld->data = inputWorld->data; + + if (GetParamsSequenceUID(AAEData, uuid, m_ParametersIndexes[Attribute_Parameters_Infernal_Uuid]) != PF_Err_NONE) + return PF_Err_BAD_CALLBACK_PARAM; + if ( m_AttributeData.count(uuid) == 0) + return err; + + SAttributeDesc *descriptor = m_AttributeData[uuid]->m_DescAttribute; + bool *uiVisibility = m_AttributeData[uuid]->m_UIVisibility; + + if (descriptor != nullptr) + { + switch (descriptor->m_Type) + { + case Attribute_Parameters_Bool1: + case Attribute_Parameters_Bool2: + case Attribute_Parameters_Bool3: + case Attribute_Parameters_Bool4: + UpdateBoolAttribute(AAEData, descriptor, uiVisibility); + break; + case Attribute_Parameters_Int1: + case Attribute_Parameters_Int2: + case Attribute_Parameters_Int3: + case Attribute_Parameters_Int4: + UpdateIntAttribute(AAEData, descriptor, uiVisibility); + break; + case Attribute_Parameters_Float1: + case Attribute_Parameters_Float2: + case Attribute_Parameters_Float3: + case Attribute_Parameters_Float4: + UpdateFloatAttribute(AAEData, descriptor, uiVisibility); + break; + } + { + SAAEScopedParams affectedByScale{ AAEData, Attribute_Parameters_AffectedByScale }; + + descriptor->m_IsAffectedByScale = affectedByScale.GetCheckBoxValue(); + } + } + + AAEData.m_ExtraData.m_SmartRenderData->cb->checkin_layer_pixels(AAEData.m_InData->effect_ref, ATTRIBUTE_INPUT); + + return err; +} + +//---------------------------------------------------------------------------- + +PF_Err CPluginInterface::UpdateParams(SAAEIOData &AAEData, PF_ParamDef *params[]) +{ + (void)AAEData; + (void)params; + + PF_Err result = PF_Err_NONE; +#if 1 + std::string uuid; + + if (GetParamsSequenceUID(AAEData, uuid, m_ParametersIndexes[Attribute_Parameters_Infernal_Uuid]) != A_Err_NONE) + return PF_Err_BAD_CALLBACK_PARAM; + if (m_AttributeData.count(uuid) == 0) + return result; + + AEGP_SuiteHandler suites(AAEData.m_InData->pica_basicP); + SAttributeDesc *descriptor = m_AttributeData[uuid]->m_DescAttribute; + + if (descriptor == nullptr) + return result; + + if (descriptor != nullptr) + { + if (AAEData.m_ExtraData.m_ChangeParamData->param_index == m_ParametersIndexes[Attribute_Parameters_Reset]) + { + descriptor->ResetValues(); + m_AttributeData[uuid]->m_IsDefault = true; + SetDefaultValueIFN(AAEData, params, m_AttributeData[uuid]); + } + } +#endif + return result; +} + +//---------------------------------------------------------------------------- + +bool CPluginInterface::_GetAttributeSequenceUID(SAAEIOData &AAEData, std::string &out) +{ + AEGP_SuiteHandler suites(AAEData.m_InData->pica_basicP); + AEFX_SuiteScoper seqdata_suite = AEFX_SuiteScoper(AAEData.m_InData, kPFEffectSequenceDataSuite, kPFEffectSequenceDataSuiteVersion1, AAEData.m_OutData); + PF_ConstHandle constSeq; + seqdata_suite->PF_GetConstSequenceData(AAEData.m_InData->effect_ref, &constSeq); + + const SAttributeSequenceDataFlat *sequenceDataFlat = static_cast(suites.HandleSuite1()->host_lock_handle((PF_Handle)constSeq)); + + out.clear(); + if (sequenceDataFlat && sequenceDataFlat->m_IsFlat == true) + { + out.append(sequenceDataFlat->m_AttributeUUID, strlen(sequenceDataFlat->m_AttributeUUID)); + suites.HandleSuite1()->host_unlock_handle((PF_Handle)constSeq); + return true; + } + if (sequenceDataFlat) + suites.HandleSuite1()->host_unlock_handle((PF_Handle)constSeq); + return false; +} + +//---------------------------------------------------------------------------- + +bool Debug_IsInterfaceRelevant(EAttributeParameterType current, EAttributeType attribute, EAttributeSemantic semantic) +{ + if (semantic == AttributeSemantic_Color) + { + if (current == Attribute_Parameters_Color_RGB) + return true; + else if (current == Attribute_Parameters_Color_A && + (attribute == AttributeType_Int4 || attribute == AttributeType_Float4)) + return true; + else + return false; + } + if (attribute >= AttributeType_Bool1 && attribute <= AttributeType_Bool4) + { + return (current >= AttributeType_Bool1 && current <= attribute); + } + if (attribute >= AttributeType_Int1 && attribute <= AttributeType_Int4) + { + return (current >= AttributeType_Int1 && current <= attribute); + } + if (attribute >= AttributeType_Float1 && attribute <= AttributeType_Float4) + { + return (current >= AttributeType_Float1 && current <= attribute); + } + return false; +} + +//---------------------------------------------------------------------------- + +PF_Err CPluginInterface::SetDefaultValueIFN(SAAEIOData &AAEData, PF_ParamDef *params[], SAttributeData *AttrData) +{ + (void)params; + + PF_Err err = PF_Err_NONE; + AEGP_SuiteHandler suites(AAEData.m_InData->pica_basicP); + AEGP_StreamRefH streamRef = nullptr; + AEGP_EffectRefH effectRef = nullptr; + bool *uiVisibility = AttrData->m_UIVisibility; + SAttributeDesc *desc = AttrData->m_DescAttribute; + + err = suites.PFInterfaceSuite1()->AEGP_GetNewEffectForEffect(m_AAEID, AAEData.m_InData->effect_ref, &effectRef); + if (!AE_VERIFY(err == A_Err_NONE)) + return err; + + for (int i = 1; i < __Attribute_Parameters_Count; ++i) // Start at 1, first params is reserved. + { + if (i == Attribute_Parameters_Infernal_Uuid || + i == Attribute_Parameters_AffectedByScale || + i == Attribute_Parameters_Infernal_Name || + i == Attribute_Parameters_Reset) + continue; + err |= suites.StreamSuite2()->AEGP_GetNewEffectStreamByIndex(m_AAEID, effectRef, m_ParametersIndexes[i], &streamRef); + if (!AE_VERIFY(err == A_Err_NONE)) + return err; + + if (Debug_IsInterfaceRelevant((EAttributeParameterType)i, desc->m_Type, desc->m_AttributeSemantic) == false) // Disable + { + uiVisibility[i] = false; + } + else // Enable and Update name + { + uiVisibility[i] = true; + } + // Toggle visibility of parameter + err |= suites.DynamicStreamSuite2()->AEGP_SetDynamicStreamFlag(streamRef, AEGP_DynStreamFlag_HIDDEN, FALSE, !uiVisibility[i]); + + // Set Default Value + if (uiVisibility[i] && AttrData->m_IsDefault) + { + AEGP_StreamValue streamValue; + if (i < __AttributeType_Count) + { + AttrData->m_DescAttribute->GetValueAsStreamValue((EAttributeType)i, &streamValue); + err |= suites.StreamSuite2()->AEGP_SetStreamValue(m_AAEID, streamRef, &streamValue); + } + else if (desc->m_AttributeSemantic == AttributeSemantic_Color) + { + float color[4]; + float mult = 1.0f; + + if (desc->m_Type >= AttributeType_Int1 && desc->m_Type <= AttributeType_Int4) + mult = 255.0f; + + AttrData->m_DescAttribute->GetValue(color); + if (i == Attribute_Parameters_Color_RGB) + { + streamValue.val.color.redF = color[0] / mult; + streamValue.val.color.greenF = color[1] / mult; + streamValue.val.color.blueF = color[2] / mult; + err |= suites.StreamSuite2()->AEGP_SetStreamValue(m_AAEID, streamRef, &streamValue); + } + else if (i == Attribute_Parameters_Color_A) + { + streamValue.val.one_d = color[3] * 100.0f / mult; + err |= suites.StreamSuite2()->AEGP_SetStreamValue(m_AAEID, streamRef, &streamValue); + } + } + } + + err |= suites.StreamSuite2()->AEGP_DisposeStream(streamRef); + streamRef = nullptr; + } + AAEData.m_OutData->out_flags |= PF_OutFlag_REFRESH_UI; + err |= suites.EffectSuite4()->AEGP_DisposeEffect(effectRef); + + if (!AE_VERIFY(err == A_Err_NONE)) + return err; + return err; +} + +//---------------------------------------------------------------------------- + +PF_Err CPluginInterface::HandleDataFromAEGP(SAAEIOData &AAEData, + PF_ParamDef *params[]) +{ + PF_Err err = PF_Err_NONE; + void *extraData = AAEData.m_ExtraData.m_UndefinedData; + SAttributeDesc *desc = reinterpret_cast(extraData); + AEGP_SuiteHandler suites(AAEData.m_InData->pica_basicP); + + if (desc != nullptr) + { + if (desc->m_IsDeleted) + { + std::string uuid; + + if (_GetAttributeSequenceUID(AAEData, uuid) == false) + { + AE_VERIFY(false); + return PF_Err_BAD_CALLBACK_PARAM; + } + if (m_AttributeData.count(uuid) == 0) + return PF_Err_BAD_CALLBACK_PARAM; + + SAttributeData *AttrData = m_AttributeData[uuid]; + + if (AttrData) + { + m_AttributeData.erase(uuid); + + AttrData->m_DescAttribute = nullptr; + delete desc; + delete AttrData; + return PF_Err_NONE; + } + } + else + { + m_AttrUID += 1; + + std::string pkKey; + std::string uuid; + SAttributeData *AttrData = nullptr; + + if (_GetAttributeSequenceUID(AAEData, uuid) == false) + { + AE_VERIFY(false); + return PF_Err_BAD_CALLBACK_PARAM; + } + if (m_AttributeData.count(uuid) == 0) + { + AttrData = new SAttributeData{}; + } + AttrData = m_AttributeData[uuid]; + AttrData->m_DescAttribute = desc; + + pkKey = AttrData->m_DescAttribute->GetAttributePKKey(); + + AttrData->m_DescAttribute->m_IsDefaultValue = AttrData->m_IsDefault; + + err |= SetDefaultValueIFN(AAEData, params, AttrData); + + AEGP_EffectRefH effectRef = nullptr; + + err = suites.PFInterfaceSuite1()->AEGP_GetNewEffectForEffect(m_AAEID, AAEData.m_InData->effect_ref, &effectRef); + if (!AE_VERIFY(err == A_Err_NONE)) + return err; + + err |= SetEffectName(AAEData, pkKey, effectRef); + err |= SetParameterStreamName(AAEData, uuid, m_ParametersIndexes[Attribute_Parameters_Infernal_Uuid] , effectRef); + err |= SetParameterStreamName(AAEData, pkKey, m_ParametersIndexes[Attribute_Parameters_Infernal_Name], effectRef); + + params[m_ParametersIndexes[Attribute_Parameters_Infernal_Name]]->ui_flags |= PF_PUI_INVISIBLE; + params[m_ParametersIndexes[Attribute_Parameters_Infernal_Name]]->ui_flags |= PF_PUI_DISABLED; + + err |= suites.EffectSuite4()->AEGP_DisposeEffect(effectRef); + + AAEData.m_OutData->out_flags |= PF_OutFlag_REFRESH_UI; + effectRef = nullptr; + } + } + AAEData.m_OutData->out_flags |= PF_OutFlag_FORCE_RERENDER; + AE_VERIFY(err == A_Err_NONE); + return err; +} + +//---------------------------------------------------------------------------- + +PF_Err CPluginInterface::UpdateParamsUI(SAAEIOData &AAEData, PF_ParamDef *params[]) +{ + std::string uuid; + + if (GetParamsSequenceUID(AAEData, uuid, m_ParametersIndexes[Attribute_Parameters_Infernal_Uuid]) != A_Err_NONE) + return PF_Err_BAD_CALLBACK_PARAM; + if (m_AttributeData.count(uuid) == 0) + return A_Err_NONE; + + PF_Err err = PF_Err_NONE; + AEGP_SuiteHandler suites(AAEData.m_InData->pica_basicP); + SAttributeDesc *descriptor = m_AttributeData[uuid]->m_DescAttribute; + bool *uiVisibility = m_AttributeData[uuid]->m_UIVisibility; + + if (descriptor == nullptr) + return PF_Err_NONE; + + if (descriptor != nullptr && descriptor->m_IsDeleted) + { + m_AttributeData.erase(uuid); + delete descriptor; + return PF_Err_NONE; + } + PF_ParamDef paramCopy[__Attribute_Parameters_Count]; + + MakeParamCopy(params, paramCopy, __Attribute_Parameters_Count); + for (int i = 1; i < __Attribute_Parameters_Count; ++i) // Start at 1, first params is reserved. + { + if (i == Attribute_Parameters_Infernal_Uuid || + i == Attribute_Parameters_AffectedByScale || + i == Attribute_Parameters_Infernal_Name) + continue; + if (uiVisibility[i] == false) // Disable + { + paramCopy[m_ParametersIndexes[i]].ui_flags |= PF_PUI_DISABLED; + } + else // Enable + { + if ((paramCopy[m_ParametersIndexes[i]].ui_flags & PF_PUI_DISABLED) != 0) + { + paramCopy[m_ParametersIndexes[i]].ui_flags &= ~PF_PUI_DISABLED; + } + //Should set min and max value. + if (paramCopy[m_ParametersIndexes[i]].param_type == PF_Param_FLOAT_SLIDER) + { + float value; + descriptor->GetDefaultValueByType((EAttributeType)i, &value); + paramCopy[m_ParametersIndexes[i]].u.fs_d.dephault = static_cast(value); + + if (descriptor->m_HasMax || descriptor->m_HasMin) + { + if (descriptor->m_HasMin) + { + descriptor->GetMinValueByType((EAttributeType)i, &value); + paramCopy[m_ParametersIndexes[i]].u.fs_d.slider_min = static_cast(value); + } + if (descriptor->m_HasMax) + { + descriptor->GetMaxValueByType((EAttributeType)i, &value); + paramCopy[m_ParametersIndexes[i]].u.fs_d.slider_max = static_cast(value); + } + if ((paramCopy[m_ParametersIndexes[i]].flags & PF_ParamFlag_COLLAPSE_TWIRLY) != 0) + paramCopy[m_ParametersIndexes[i]].flags &= ~PF_ParamFlag_COLLAPSE_TWIRLY; + } + else + { + paramCopy[m_ParametersIndexes[i]].flags |= PF_ParamFlag_COLLAPSE_TWIRLY; + } + + paramCopy[m_ParametersIndexes[i]].uu.change_flags = PF_ChangeFlag_CHANGED_VALUE; + } + } + //Apply Change on param + err |= suites.ParamUtilsSuite3()->PF_UpdateParamUI(AAEData.m_InData->effect_ref, m_ParametersIndexes[i], ¶mCopy[m_ParametersIndexes[i]]); + } + AE_VERIFY(err == A_Err_NONE); + return err; +} + +//---------------------------------------------------------------------------- + +A_Err CPluginInterface::_RegisterAttributeInstancePlugin(SAAEIOData &AAEData, PF_ParamDef *params[], SAttributeSequenceDataFlat *sequenceData, bool setup) +{ + (void)params; + + PF_Err err = PF_Err_NONE; + std::string id; + + if (sequenceData != nullptr) + id = sequenceData->m_AttributeUUID; + else if (_GetAttributeSequenceUID(AAEData, id) == false) + return A_Err_NONE; + + if (m_AttributeData.count(id) == 0) + { + SAttributeData *AttrData = new SAttributeData{}; + + if (!AE_VERIFY(AttrData != nullptr)) + return A_Err_ALLOC; + + if (!setup) + { + if (m_MainThreadID == std::this_thread::get_id()) + { + AEGP_SuiteHandler suites(AAEData.m_InData->pica_basicP); + AEGP_EffectRefH effectRef = nullptr; + + err |= suites.PFInterfaceSuite1()->AEGP_GetNewEffectForEffect(m_AAEID, AAEData.m_InData->effect_ref, &effectRef); + + std::string uuid(sequenceData->m_AttributeUUID); + std::string name(sequenceData->m_AttributeName); + err |= SetParameterStreamName(AAEData, uuid, m_ParametersIndexes[Attribute_Parameters_Infernal_Uuid], effectRef); + err |= SetParameterStreamName(AAEData, name, m_ParametersIndexes[Attribute_Parameters_Infernal_Name], effectRef); + err |= suites.EffectSuite4()->AEGP_DisposeEffect(effectRef); + } + } + m_AttributeData[id] = AttrData; + } + if (sequenceData != nullptr) + { + m_AttributeData[id]->m_IsDefault = sequenceData->m_IsDefault; + } + return A_Err_NONE;; +} + +//---------------------------------------------------------------------------- + +__AAEPK_END diff --git a/AE_Effect_Attribute/Sources/AEAttribute_SequenceData.cpp b/AE_Effect_Attribute/Sources/AEAttribute_SequenceData.cpp new file mode 100644 index 00000000..3007a780 --- /dev/null +++ b/AE_Effect_Attribute/Sources/AEAttribute_SequenceData.cpp @@ -0,0 +1,59 @@ +//---------------------------------------------------------------------------- +// Copyright Persistant Studios, SARL. All Rights Reserved. https://www.popcornfx.com/terms-and-conditions/ +//---------------------------------------------------------------------------- +#include "ae_precompiled.h" + +#include "AEAttribute_SequenceData.h" + +#include +#include + +__AAEPK_BEGIN + +//---------------------------------------------------------------------------- + +void SAttributeSequenceDataFlat::CopyFrom(SAttributeSequenceDataFlat *src) +{ + m_IsFlat = true; + SetUUID(src->m_AttributeUUID); + SetName(src->m_AttributeName); + SetIsDefaultValue(src->m_IsDefault); +} + +//---------------------------------------------------------------------------- + +void SAttributeSequenceDataFlat::SetIsDefaultValue(bool value) +{ + m_IsDefault = value; +} + +//---------------------------------------------------------------------------- + +bool SAttributeSequenceDataFlat::SetUUID(const char *uuid) +{ + m_AttributeUUIDLen = strlen(uuid) + 1; + + strncpy(m_AttributeUUID, uuid, SequenceCST::UUID_LEN); + return true; +} + +//---------------------------------------------------------------------------- + +bool SAttributeSequenceDataFlat::SetName(const char *name) +{ + m_AttributeNameLen = strlen(name) + 1; + + strncpy(m_AttributeName, name, SequenceCST::MAX_NAME_LEN); + return true; +} + +//---------------------------------------------------------------------------- + +bool SAttributeSequenceDataFlat::SetLayerID(bool value) +{ + m_LayerID = value; + return true; +} + +//---------------------------------------------------------------------------- +__AAEPK_END diff --git a/AE_Effect_Attribute/Sources/AE_Effect_Attribute.plugin-Info.plist b/AE_Effect_Attribute/Sources/AE_Effect_Attribute.plugin-Info.plist new file mode 100644 index 00000000..3299ec2f --- /dev/null +++ b/AE_Effect_Attribute/Sources/AE_Effect_Attribute.plugin-Info.plist @@ -0,0 +1,24 @@ + + + + + CFBundleExecutable + Attribute + CFBundleIdentifier + com.PersistantStudio.PopcornFX.Attribute + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + AE_Effect_Attribute + CFBundlePackageType + eFKT + CFBundleSignature + FXTC + LSRequiresCarbon + + NSAppleScriptEnabled + No + NSHumanReadableCopyright + © PersistantStudio PopcornFX + + diff --git a/AE_Effect_Attribute/Sources/AE_Effect_Attribute_PiPL.r b/AE_Effect_Attribute/Sources/AE_Effect_Attribute_PiPL.r new file mode 100644 index 00000000..0fe45ea0 --- /dev/null +++ b/AE_Effect_Attribute/Sources/AE_Effect_Attribute_PiPL.r @@ -0,0 +1,73 @@ +#include "AEConfig.h" +#include "AE_EffectVers.h" + +#ifndef AE_OS_WIN + #include +#endif + + +#ifdef AE_OS_WIN +#include "../../AE_Suites/PopcornFX_Define_Version.h" +#endif +#ifdef AE_OS_MAC +#include "PopcornFX_Define_Version.h" +#endif + +resource 'PiPL' (16000) { + { /* array properties: 12 elements */ + /* [1] */ + Kind { + AEEffect + }, + /* [2] */ + Name { + "Attribute" + }, + /* [3] */ + Category { + "PopcornFX" + }, +#ifdef AE_OS_WIN + #ifdef AE_PROC_INTELx64 + CodeWin64X86 {"EffectMain"}, + #endif +#else + #ifdef AE_OS_MAC + CodeMacIntel64 {"EffectMain"}, + #endif +#endif + /* [6] */ + AE_PiPL_Version { + 2, + 0 + }, + /* [7] */ + AE_Effect_Spec_Version { + PF_PLUG_IN_VERSION, + PF_PLUG_IN_SUBVERS + }, + /* [8] */ + AE_Effect_Version { + AEPOPCORNFX_PIPL_VERSION + }, + /* [9] */ + AE_Effect_Info_Flags { + 0 + }, + /* [10] */ + AE_Effect_Global_OutFlags { + 0x06200000 + }, + AE_Effect_Global_OutFlags_2 { + 0x08001403 + }, + /* [11] */ + AE_Effect_Match_Name { + "ADBE PopcornFX Attribute" + }, + /* [12] */ + AE_Reserved_Info { + 8 + } + } +}; diff --git a/AE_Effect_AttributeSampler/Include/AEAttributeSampler_Main.h b/AE_Effect_AttributeSampler/Include/AEAttributeSampler_Main.h new file mode 100644 index 00000000..48128c83 --- /dev/null +++ b/AE_Effect_AttributeSampler/Include/AEAttributeSampler_Main.h @@ -0,0 +1,39 @@ +//---------------------------------------------------------------------------- +// Copyright Persistant Studios, SARL. All Rights Reserved. https://www.popcornfx.com/terms-and-conditions/ +//---------------------------------------------------------------------------- +#pragma once + +#ifndef __FX_AEATTRIBUTESAMPLER_MAIN_H__ +#define __FX_AEATTRIBUTESAMPLER_MAIN_H__ + +#include + +#ifdef AE_OS_WIN + typedef unsigned short PixelType; + #include +#endif + +#include +#include + +#include "PopcornFX_Define.h" + +//---------------------------------------------------------------------------- + +extern "C" { + DllExport + PF_Err + EffectMain( + PF_Cmd cmd, + PF_InData *in_data, + PF_OutData *out_data, + PF_ParamDef *params[], + PF_LayerDef *output, + void *extra); + +} + +//---------------------------------------------------------------------------- + +#endif + diff --git a/AE_Effect_AttributeSampler/Include/AEAttributeSampler_ParamDefine.h b/AE_Effect_AttributeSampler/Include/AEAttributeSampler_ParamDefine.h new file mode 100644 index 00000000..f47ca41b --- /dev/null +++ b/AE_Effect_AttributeSampler/Include/AEAttributeSampler_ParamDefine.h @@ -0,0 +1,105 @@ +//---------------------------------------------------------------------------- +// Copyright Persistant Studios, SARL. All Rights Reserved. https://www.popcornfx.com/terms-and-conditions/ +//---------------------------------------------------------------------------- +#pragma once + +#ifndef __FX_AEATTRIBUTESAMPLER_PARAM_DEFINE_H__ +#define __FX_AEATTRIBUTESAMPLER_PARAM_DEFINE_H__ + +#include +#include + +#include + +__AAEPK_BEGIN + + +//---------------------------------------------------------------------------- + +enum EPKParams +{ + ATTRIBUTESAMPLER_INPUT = 0, + ATTRIBUTESAMPLER_PARAM, + ATTRIBUTESAMPLER_NUM_PARAMS +}; + +//---------------------------------------------------------------------------- + +enum EStrIDType +{ + StrID_NONE = 0, + StrID_Name, + StrID_Description, + StrID_Generic_Infernal_Uuid, + StrID_Generic_Infernal_Name, + StrID_Parameters_Shapes, + StrID_Parameters_Shapes_Combobox, + + StrID_Topic_Shape_Start, + + StrID_Topic_Shape_Box_Start, + StrID_Parameters_Box_Size_X, + StrID_Parameters_Box_Size_Y, + StrID_Parameters_Box_Size_Z, + + StrID_Topic_Shape_Sphere_Start, + StrID_Parameters_Sphere_Radius, + StrID_Parameters_Sphere_InnerRadius, + + StrID_Topic_Shape_Ellipsoid_Start, + StrID_Parameters_Ellipsoid_Radius, + StrID_Parameters_Ellipsoid_InnerRadius, + + StrID_Topic_Shape_Cylinder_Start, + StrID_Parameters_Cylinder_Radius, + StrID_Parameters_Cylinder_Height, + StrID_Parameters_Cylinder_InnerRadius, + + StrID_Topic_Shape_Capsule_Start, + StrID_Parameters_Capsule_Radius, + StrID_Parameters_Capsule_Height, + StrID_Parameters_Capsule_InnerRadius, + + StrID_Topic_Shape_Cone_Start, + StrID_Parameters_Cone_Radius, + StrID_Parameters_Cone_Height, + + StrID_Topic_Shape_Mesh_Start, + StrID_Parameters_Mesh_Scale, + + StrID_Parameters_Mesh_Path, + StrID_Parameters_Mesh_Path_Button, + + StrID_Parameters_Mesh_Bind_Backdrop, + StrID_Parameters_Mesh_Bind_Backdrop_Weight_Enabled, + StrID_Parameters_Mesh_Bind_Backdrop_ColorStreamID, + StrID_Parameters_Mesh_Bind_Backdrop_WeightStreamID, + + StrID_Parameters_Layer_Pick, + + StrID_Parameters_Layer_Sample_Once, + StrID_Parameters_Layer_Sample_Seeking, + + StrID_Parameters_VectorField_Path, + StrID_Parameters_VectorField_Path_Button, + StrID_Parameters_VectorField_Strength, + StrID_Parameters_VectorField_Position, + StrID_Parameters_VectorField_Interpolation, + StrID_Parameters_VectorField_Interpolation_Combobox, + + StrID_Parameters_Layer_Sample_Downsampling_X, + StrID_Parameters_Layer_Sample_Downsampling_Y, + + StrID_NUMTYPES +}; + +//---------------------------------------------------------------------------- + +__AAEPK_END + +//---------------------------------------------------------------------------- + +bool GetParamsVisibility(int num, AAePk::EAttributeSamplerType type); + +#endif + diff --git a/AE_Effect_AttributeSampler/Include/AEAttributeSampler_PluginInterface.h b/AE_Effect_AttributeSampler/Include/AEAttributeSampler_PluginInterface.h new file mode 100644 index 00000000..9e330073 --- /dev/null +++ b/AE_Effect_AttributeSampler/Include/AEAttributeSampler_PluginInterface.h @@ -0,0 +1,107 @@ +//---------------------------------------------------------------------------- +// Copyright Persistant Studios, SARL. All Rights Reserved. https://www.popcornfx.com/terms-and-conditions/ +//---------------------------------------------------------------------------- +#pragma once + + +#ifndef __FX_AEATTRIBUTESAMPLER_PLUGIN_INTERFACE_H__ +#define __FX_AEATTRIBUTESAMPLER_PLUGIN_INTERFACE_H__ + + +#include "PopcornFX_Define.h" +#include "PopcornFX_BasePluginInterface.h" + +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include +#include + +__AAEPK_BEGIN + +//---------------------------------------------------------------------------- + +struct SAAEIOData; +struct SAttributeSamplerDesc; +struct SAttributeSamplerSequenceDataFlat; + +//---------------------------------------------------------------------------- + +class CPluginInterface : public CBasePluginInterface +{ + struct SAttributeSamplerData + { + //Memory Owned by effect + SAttributeSamplerDesc *m_DescAttribute; + + std::string m_ResourcePath; + bool m_IsDefault; + + SAttributeSamplerData() + : m_DescAttribute(nullptr) + , m_ResourcePath("") + , m_IsDefault(true) + { + } + ~SAttributeSamplerData() + { + m_DescAttribute = nullptr; + } + }; +public: + ~CPluginInterface(); + static CPluginInterface &Instance(); + + PF_Err About(SAAEIOData &AAEData, PF_ParamDef *params[], PF_LayerDef *output); + PF_Err GlobalSetup(SAAEIOData &AAEData, PF_ParamDef *params[], PF_LayerDef *output); + PF_Err ParamsSetup(SAAEIOData &AAEData, PF_ParamDef *params[], PF_LayerDef *output); + PF_Err GlobalSetdown(SAAEIOData &AAEData, PF_ParamDef *params[], PF_LayerDef *output); + + PF_Err SequenceSetup(SAAEIOData &AAEData, PF_ParamDef *params[], PF_LayerDef *output); + PF_Err SequenceReSetup(SAAEIOData &AAEData, PF_ParamDef *params[], PF_LayerDef *output); + PF_Err SequenceFlatten(SAAEIOData &AAEData, PF_ParamDef *params[], PF_LayerDef *output); + PF_Err SequenceShutdown(SAAEIOData &AAEData, PF_ParamDef *params[], PF_LayerDef *output); + + PF_Err PreRender(SAAEIOData &AAEData); + PF_Err SmartRender(SAAEIOData &AAEData); + PF_Err UpdateParams(SAAEIOData &AAEData, PF_ParamDef *params[]); + PF_Err UpdateParamsUI(SAAEIOData &AAEData, PF_ParamDef *params[]); + + PF_Err HandleDataFromAEGP(SAAEIOData &AAEData, PF_ParamDef *params[]); + +private: + CPluginInterface(); + + PF_Err _UpdateParamsVisibility(SAAEIOData &AAEData, SAttributeSamplerData *AttrData); + + bool _GetAttributeSequenceUID(SAAEIOData &AAEData, std::string &out); + + PF_Err _RegisterAttributeInstancePlugin(SAAEIOData &AAEData, PF_ParamDef *params[], SAttributeSamplerSequenceDataFlat *sequenceData, bool setup); + + + void UpdateSamplerGeometry(SAAEIOData &AAEData, SAttributeSamplerDesc *descriptor); + void UpdateSamplerText(SAAEIOData &AAEData, SAttributeSamplerDesc *descriptor); + void UpdateSamplerImage(SAAEIOData &AAEData, SAttributeSamplerDesc *descriptor); + void UpdateSamplerVectorField(SAAEIOData &AAEData, SAttributeSamplerDesc *descriptor); + + static CPluginInterface *m_Instance; + static uint32_t m_AttrUID; + + std::unordered_map m_AttributeData; + + std::thread::id m_MainThreadID; +}; + +//---------------------------------------------------------------------------- + +__AAEPK_END + +#endif diff --git a/AE_Effect_AttributeSampler/Include/AEAttributeSampler_SequenceData.h b/AE_Effect_AttributeSampler/Include/AEAttributeSampler_SequenceData.h new file mode 100644 index 00000000..7ad1dde2 --- /dev/null +++ b/AE_Effect_AttributeSampler/Include/AEAttributeSampler_SequenceData.h @@ -0,0 +1,52 @@ +//---------------------------------------------------------------------------- +// Copyright Persistant Studios, SARL. All Rights Reserved. https://www.popcornfx.com/terms-and-conditions/ +//---------------------------------------------------------------------------- +#pragma once + +#ifndef __AEATTRIBUTESAMPLER_SEQUENCEDATA_H__ +#define __AEATTRIBUTESAMPLER_SEQUENCEDATA_H__ + +#include +#include +#include + +__AAEPK_BEGIN + +//---------------------------------------------------------------------------- + +namespace SequenceCST +{ + static const size_t MAX_PATH_LEN = 4096; + static const size_t MAX_NAME_LEN = 100; + static const size_t UUID_LEN = 64; +} + +//---------------------------------------------------------------------------- + +struct SAttributeSamplerSequenceDataFlat +{ + bool m_IsFlat = true; + + char m_AttributeUUID[SequenceCST::UUID_LEN]; + size_t m_AttributeUUIDLen; + + char m_AttributeName[SequenceCST::MAX_NAME_LEN]; + size_t m_AttributeNameLen; + + char m_ResourcePath[SequenceCST::MAX_PATH_LEN]; + size_t m_ResourcePathLen; + + A_long m_LayerID; + + bool SetUUID(const char *uuid); + bool SetName(const char *name); + bool SetResourcePath(const char * path); + bool SetLayerID(A_long id); +}; + +//---------------------------------------------------------------------------- + +__AAEPK_END + +#endif // !__AAEFFECT_SEQUENCEDATA_H__ + diff --git a/AE_Effect_AttributeSampler/PkgInfo b/AE_Effect_AttributeSampler/PkgInfo new file mode 100644 index 00000000..31cf1f41 --- /dev/null +++ b/AE_Effect_AttributeSampler/PkgInfo @@ -0,0 +1 @@ +eFKTFXTC \ No newline at end of file diff --git a/AE_Effect_AttributeSampler/Precompiled/ae_precompiled.cpp b/AE_Effect_AttributeSampler/Precompiled/ae_precompiled.cpp new file mode 100644 index 00000000..84e52276 --- /dev/null +++ b/AE_Effect_AttributeSampler/Precompiled/ae_precompiled.cpp @@ -0,0 +1 @@ +#include "ae_precompiled.h" diff --git a/AE_Effect_AttributeSampler/Precompiled/ae_precompiled.h b/AE_Effect_AttributeSampler/Precompiled/ae_precompiled.h new file mode 100644 index 00000000..ee643f3d --- /dev/null +++ b/AE_Effect_AttributeSampler/Precompiled/ae_precompiled.h @@ -0,0 +1,8 @@ +#pragma once + +#undef PV_MODULE_NAME +#undef PV_MODULE_SYM +#define PV_MODULE_NAME "AEPlugin" +#define PV_MODULE_SYM AEPlugin + +#include diff --git a/AE_Effect_AttributeSampler/Sources/AEAttributeSampler_Main.cpp b/AE_Effect_AttributeSampler/Sources/AEAttributeSampler_Main.cpp new file mode 100644 index 00000000..b4bdd532 --- /dev/null +++ b/AE_Effect_AttributeSampler/Sources/AEAttributeSampler_Main.cpp @@ -0,0 +1,170 @@ +//---------------------------------------------------------------------------- +// Copyright Persistant Studios, SARL. All Rights Reserved. https://www.popcornfx.com/terms-and-conditions/ +//---------------------------------------------------------------------------- +#include "ae_precompiled.h" + +#include "AEAttributeSampler_Main.h" + +#include "AEAttributeSampler_PluginInterface.h" +#include "PopcornFX_Suite.h" + +#include + +#include + +//---------------------------------------------------------------------------- + +extern "C" +{ + DllExport PF_Err PluginDataEntryFunction( PF_PluginDataPtr inPtr, + PF_PluginDataCB inPluginDataCallBackPtr, + SPBasicSuite *inSPBasicSuitePtr, + const char *inHostName, + const char *inHostVersion) + { + (void)inSPBasicSuitePtr; + (void)inHostName; + (void)inHostVersion; + + PF_Err result = PF_Err_INVALID_CALLBACK; + + result = PF_REGISTER_EFFECT( + inPtr, // Infos must match the PopcornFXPiPL.r + inPluginDataCallBackPtr, // + "Attribute Sampler", // Name + "ADBE PopcornFX Sampler", // Match Name + "PopcornFX", // Category + AE_RESERVED_INFO); // Reserved Info + return result; + } +} + +//---------------------------------------------------------------------------- + +PF_Err EffectMain( PF_Cmd cmd, + PF_InData *in_data, + PF_OutData *out_data, + PF_ParamDef *params[], + PF_LayerDef *output, + void *extra) +{ + PF_Err result = PF_Err_NONE; + AAePk::CPluginInterface &AEPlugin = AAePk::CPluginInterface::Instance(); + AAePk::SAAEIOData AAEData{ cmd, in_data, out_data, extra, AEPlugin.GetParametersIndexes() }; + +#if _DEBUG + try + { +#endif + + assert(in_data != nullptr); + assert(out_data != nullptr); + if (in_data == nullptr) + return PF_Err_BAD_CALLBACK_PARAM; + + if (AAEData.m_InData->appl_id == 'PrMr') + { + //User Tried to load plugin in Premiere Pro. + //There is surely a better way to handle this. + return PF_Err_UNRECOGNIZED_PARAM_TYPE; + } + + switch (cmd) + { + // Called once + case PF_Cmd_ABOUT: + //Mandatory + //Version and General Infos about the plugin + result = AEPlugin.About(AAEData, params, output); + break; + case PF_Cmd_GLOBAL_SETUP: + //Mandatory + //Startup run + result = AEPlugin.GlobalSetup(AAEData, params, output); + break; + case PF_Cmd_PARAMS_SETUP: + //Mandatory + //Setup AAE UI. + result = AEPlugin.ParamsSetup(AAEData, params, output); + break; + case PF_Cmd_GLOBAL_SETDOWN: + //Mandatory + result = AEPlugin.GlobalSetdown(AAEData, params, output); + break; + // Sequence Handling + //UI thread + case PF_Cmd_SEQUENCE_SETUP: + //Each time the user adds the effect to a layer + result = AEPlugin.SequenceSetup(AAEData, params, output); + break; + case PF_Cmd_SEQUENCE_RESETUP: + //Load or Duplicate + result = AEPlugin.SequenceReSetup(AAEData, params, output); + break; + //UI thread + case PF_Cmd_SEQUENCE_FLATTEN: + //Effect Saved, copied, duplicated.. + result = AEPlugin.SequenceFlatten(AAEData, params, output); + break; + case PF_Cmd_SEQUENCE_SETDOWN: + //Effect Deleted + result = AEPlugin.SequenceShutdown(AAEData, params, output); + break; + case PF_Cmd_GET_FLATTENED_SEQUENCE_DATA: + break; + // Called each Frame + case PF_Cmd_AUDIO_SETUP: + case PF_Cmd_AUDIO_RENDER: + case PF_Cmd_AUDIO_SETDOWN: + break; + case PF_Cmd_FRAME_SETUP: + //Allow resizing of drawing area + break; + case PF_Cmd_SMART_PRE_RENDER: + result = AEPlugin.PreRender(AAEData); + //Can be called several times for one render + break; + case PF_Cmd_SMART_RENDER: + result = AEPlugin.SmartRender(AAEData); + break; + case PF_Cmd_FRAME_SETDOWN: + //Allow resizing of drawing area + break; + // Messaging + case PF_Cmd_EVENT: + break; + case PF_Cmd_USER_CHANGED_PARAM: + AEPlugin.UpdateParams(AAEData, params); + //If PF_ParamFlag_SUPERVIZE if set when adding param, PF_Cmd_USER_CHANGED_PARAM is called when value change + break; + case PF_Cmd_UPDATE_PARAMS_UI: + result = AEPlugin.UpdateParamsUI(AAEData, params); + break; + case PF_Cmd_ARBITRARY_CALLBACK: + case PF_Cmd_GET_EXTERNAL_DEPENDENCIES: + break; + case PF_Cmd_COMPLETELY_GENERAL: + result = AEPlugin.HandleDataFromAEGP(AAEData, params); + break; + case PF_Cmd_DO_DIALOG: + //Send when user click on Options + //Received if PF_OutFlag_I_DO_DIALOG is set in PF_Cmd_GLOBAL_SETUP + break; + case PF_Cmd_QUERY_DYNAMIC_FLAGS: + break; + default: + break; + } + +#if _DEBUG + } + catch (...) + { + assert(false); + } +#endif + return result; +} + +//---------------------------------------------------------------------------- + diff --git a/AE_Effect_AttributeSampler/Sources/AEAttributeSampler_ParamDefine.cpp b/AE_Effect_AttributeSampler/Sources/AEAttributeSampler_ParamDefine.cpp new file mode 100644 index 00000000..2c3b9e3f --- /dev/null +++ b/AE_Effect_AttributeSampler/Sources/AEAttributeSampler_ParamDefine.cpp @@ -0,0 +1,169 @@ +//---------------------------------------------------------------------------- +// Copyright Persistant Studios, SARL. All Rights Reserved. https://www.popcornfx.com/terms-and-conditions/ +//---------------------------------------------------------------------------- +#include "ae_precompiled.h" + +#include "AEAttributeSampler_ParamDefine.h" + +#include "PopcornFX_Suite.h" + +__AAEPK_BEGIN + +//---------------------------------------------------------------------------- + +struct STableString +{ + A_u_long index; + A_char str[256]; +} ; + +//---------------------------------------------------------------------------- + +STableString g_strs[StrID_NUMTYPES] = +{ + { StrID_NONE, "" }, + { StrID_Name, "Attribute Sampler" }, + { StrID_Description, "PopcornFX Plugin." }, + { StrID_Generic_Infernal_Uuid, "AttributeKey" }, + { StrID_Generic_Infernal_Name, "AttributeSamplerName" }, + { StrID_Parameters_Shapes, "Geometry" }, + { StrID_Parameters_Shapes_Combobox, "Box|Sphere|Ellipsoid|Cylinder|Capsule|Cone|Mesh" }, + { StrID_Topic_Shape_Start, "Shapes Properties" }, + { StrID_Topic_Shape_Box_Start, "Box" }, + { StrID_Parameters_Box_Size_X, "Width" }, + { StrID_Parameters_Box_Size_Y, "Height" }, + { StrID_Parameters_Box_Size_Z, "Depth" }, + { StrID_Topic_Shape_Sphere_Start, "Sphere" }, + { StrID_Parameters_Sphere_Radius, "Radius" }, + { StrID_Parameters_Sphere_InnerRadius, "Inner Radius" }, + { StrID_Topic_Shape_Ellipsoid_Start, "Complex Ellipsoid" }, + { StrID_Parameters_Ellipsoid_Radius, "Radius" }, + { StrID_Parameters_Ellipsoid_InnerRadius, "Inner Radius" }, + { StrID_Topic_Shape_Cylinder_Start, "Cylinder" }, + { StrID_Parameters_Cylinder_Radius, "Radius" }, + { StrID_Parameters_Cylinder_Height, "Height" }, + { StrID_Parameters_Cylinder_InnerRadius, "Inner Radius" }, + { StrID_Topic_Shape_Capsule_Start, "Capsule" }, + { StrID_Parameters_Capsule_Radius, "Radius" }, + { StrID_Parameters_Capsule_Height, "Height" }, + { StrID_Parameters_Capsule_InnerRadius, "Inner Radius" }, + { StrID_Topic_Shape_Cone_Start, "Cone" }, + { StrID_Parameters_Cone_Radius, "Radius" }, + { StrID_Parameters_Cone_Height, "Height" }, + { StrID_Topic_Shape_Mesh_Start, "Mesh" }, + { StrID_Parameters_Mesh_Scale, "Scale" }, + { StrID_Parameters_Mesh_Path, "Mesh Path" }, + { StrID_Parameters_Mesh_Path_Button, "Browse" }, + { StrID_Parameters_Mesh_Bind_Backdrop, "Bind to Backdrop" }, + { StrID_Parameters_Mesh_Bind_Backdrop_Weight_Enabled, "Weight Sampling" }, + { StrID_Parameters_Mesh_Bind_Backdrop_ColorStreamID, "Color Stream ID" }, + { StrID_Parameters_Mesh_Bind_Backdrop_WeightStreamID, "Weight Stream ID" }, + { StrID_Parameters_Layer_Pick, "Layer" }, + { StrID_Parameters_Layer_Sample_Once, "Sample once" }, + { StrID_Parameters_Layer_Sample_Seeking, "Sample while seeking" }, + { StrID_Parameters_VectorField_Path, "VectorField Path" }, + { StrID_Parameters_VectorField_Path_Button, "Browse" }, + { StrID_Parameters_VectorField_Strength, "Strength" }, + { StrID_Parameters_VectorField_Position, "Position" }, + { StrID_Parameters_VectorField_Interpolation, "Interpolation Type" }, + { StrID_Parameters_VectorField_Interpolation_Combobox, "Point|Trilinear|Quadrilinear" }, + { StrID_Parameters_Layer_Sample_Downsampling_X, "Downsample X" }, + { StrID_Parameters_Layer_Sample_Downsampling_Y, "Downsample Y" }, +}; + +//---------------------------------------------------------------------------- + +struct STableVisibility +{ + A_u_long index; + bool visibility[__AttributeSamplerType_Count]; +}; + +//---------------------------------------------------------------------------- + +STableVisibility g_attributeSamplerParamVisibility[__AttributeSamplerType_Parameters_Count] = +{ + // None , AT , Audio, Curve, Event, Geom , Img , ImgAT, Text , Vector + { 0,/*Padding*/ { false, false, false, false, false, false, false, false, false, false } },/*Padding*/ + { AttributeSamplerType_Parameters_Infernal_Uuid, { false, false, false, false, false, false, false, false, false, false } }, + { AttributeSamplerType_Parameters_Infernal_Name, { false, false, false, false, false, false, false, false, false, false } }, + { AttributeSamplerType_Parameters_Shapes, { false, false, false, false, false, TRUE, false, false, false, false } }, + { AttributeSamplerType_Topic_Shape_Start, { false, false, false, false, false, TRUE, false, false, false, false } }, + { AttributeSamplerType_Topic_Shape_Box_Start, { false, false, false, false, false, TRUE, false, false, false, false } }, + { AttributeSamplerType_Parameters_Box_Size_X, { false, false, false, false, false, TRUE, false, false, false, false } }, + { AttributeSamplerType_Parameters_Box_Size_Y, { false, false, false, false, false, TRUE, false, false, false, false } }, + { AttributeSamplerType_Parameters_Box_Size_Z, { false, false, false, false, false, TRUE, false, false, false, false } }, + { AttributeSamplerType_Topic_Shape_Box_End, { false, false, false, false, false, TRUE, false, false, false, false } }, + { AttributeSamplerType_Topic_Shape_Sphere_Start, { false, false, false, false, false, TRUE, false, false, false, false } }, + { AttributeSamplerType_Parameters_Sphere_Radius, { false, false, false, false, false, TRUE, false, false, false, false } }, + { AttributeSamplerType_Parameters_Sphere_InnerRadius, { false, false, false, false, false, TRUE, false, false, false, false } }, + { AttributeSamplerType_Topic_Shape_Sphere_End, { false, false, false, false, false, TRUE, false, false, false, false } }, + { AttributeSamplerType_Topic_Shape_Ellipsoid_Start, { false, false, false, false, false, TRUE, false, false, false, false } }, + { AttributeSamplerType_Parameters_Ellipsoid_Radius, { false, false, false, false, false, TRUE, false, false, false, false } }, + { AttributeSamplerType_Parameters_Ellipsoid_InnerRadius, { false, false, false, false, false, TRUE, false, false, false, false } }, + { AttributeSamplerType_Topic_Shape_Ellipsoid_End, { false, false, false, false, false, TRUE, false, false, false, false } }, + { AttributeSamplerType_Topic_Shape_Cylinder_Start, { false, false, false, false, false, TRUE, false, false, false, false } }, + { AttributeSamplerType_Parameters_Cylinder_Radius, { false, false, false, false, false, TRUE, false, false, false, false } }, + // None , AT , Audio, Curve, Event, Geom , Img , ImgAT, Text , Vector + { AttributeSamplerType_Parameters_Cylinder_Height, { false, false, false, false, false, TRUE, false, false, false, false } }, + { AttributeSamplerType_Parameters_Cylinder_InnerRadius, { false, false, false, false, false, TRUE, false, false, false, false } }, + { AttributeSamplerType_Topic_Shape_Cylinder_End, { false, false, false, false, false, TRUE, false, false, false, false } }, + { AttributeSamplerType_Topic_Shape_Capsule_Start, { false, false, false, false, false, TRUE, false, false, false, false } }, + { AttributeSamplerType_Parameters_Capsule_Radius, { false, false, false, false, false, TRUE, false, false, false, false } }, + { AttributeSamplerType_Parameters_Capsule_Height, { false, false, false, false, false, TRUE, false, false, false, false } }, + { AttributeSamplerType_Parameters_Capsule_InnerRadius, { false, false, false, false, false, TRUE, false, false, false, false } }, + { AttributeSamplerType_Topic_Shape_Capsule_End, { false, false, false, false, false, TRUE, false, false, false, false } }, + { AttributeSamplerType_Topic_Shape_Cone_Start, { false, false, false, false, false, TRUE, false, false, false, false } }, + { AttributeSamplerType_Parameters_Cone_Radius, { false, false, false, false, false, TRUE, false, false, false, false } }, + { AttributeSamplerType_Parameters_Cone_Height, { false, false, false, false, false, TRUE, false, false, false, false } }, + { AttributeSamplerType_Topic_Shape_Cone_End, { false, false, false, false, false, TRUE, false, false, false, false } }, + { AttributeSamplerType_Topic_Shape_Mesh_Start, { false, false, false, false, false, TRUE, false, false, false, false } }, + { AttributeSamplerType_Parameters_Mesh_Scale, { false, false, false, false, false, TRUE, false, false, false, false } }, + { AttributeSamplerType_Parameters_Mesh_Path, { false, false, false, false, false, TRUE, false, false, false, false } }, + { AttributeSamplerType_Parameters_Mesh_Bind_Backdrop, { false, false, false, false, false, TRUE, false, false, false, false } }, + { AttributeSamplerType_Parameters_Mesh_Bind_Backdrop_Weighted_Enabled, { false, false, false, false, false, TRUE, false, false, false, false } }, + { AttributeSamplerType_Parameters_Mesh_Bind_Backdrop_ColorStreamID, { false, false, false, false, false, TRUE, false, false, false, false } }, + { AttributeSamplerType_Parameters_Mesh_Bind_Backdrop_WeightStreamID, { false, false, false, false, false, TRUE, false, false, false, false } }, + { AttributeSamplerType_Topic_Shape_Mesh_End, { false, false, false, false, false, TRUE, false, false, false, false } }, + { AttributeSamplerType_Topic_Shape_End, { false, false, false, false, false, TRUE, false, false, false, false } }, + // None , AT , Audio, Curve, Event, Geom , Img , ImgAT, Text , Vector + { AttributeSamplerType_Layer_Pick, { false, false, TRUE, false, false, false, TRUE, false, TRUE, false } }, + { AttributeSamplerType_Layer_Sample_Once, { false, false, false, false, false, false, TRUE, false, TRUE, false } }, + { AttributeSamplerType_Layer_Sample_Seeking, { false, false, TRUE, false, false, false, TRUE, false, TRUE, false } }, + + { AttributeSamplerType_Parameters_VectorField_Path, { false, false, false, false, false, false, false, false, false, TRUE } }, + { AttributeSamplerType_Parameters_VectorField_Strength, { false, false, false, false, false, false, false, false, false, TRUE } }, + { AttributeSamplerType_Parameters_VectorField_Position, { false, false, false, false, false, false, false, false, false, TRUE } }, + { AttributeSamplerType_Parameters_VectorField_Interpolation, { false, false, false, false, false, false, false, false, false, TRUE } }, + + { AttributeSamplerType_Layer_Sample_Downsampling_X, { false, false, false, false, false, false, TRUE, false, false, false } }, + { AttributeSamplerType_Layer_Sample_Downsampling_Y, { false, false, false, false, false, false, TRUE, false, false, false } }, + // None , AT , Audio, Curve, Event, Geom , Img , ImgAT, Text , Vector +}; + +//---------------------------------------------------------------------------- + +__AAEPK_END + +//---------------------------------------------------------------------------- + +#ifdef __cplusplus +extern "C" +{ +#endif + +A_char *GetStringPtr(int strNum) +{ + return AAePk::g_strs[strNum].str; +} + +#ifdef __cplusplus +} +#endif + +//---------------------------------------------------------------------------- + +bool GetParamsVisibility(int num, AAePk::EAttributeSamplerType type) +{ + return AAePk::g_attributeSamplerParamVisibility[num].visibility[type]; +} diff --git a/AE_Effect_AttributeSampler/Sources/AEAttributeSampler_PluginInterface.cpp b/AE_Effect_AttributeSampler/Sources/AEAttributeSampler_PluginInterface.cpp new file mode 100644 index 00000000..7a85032b --- /dev/null +++ b/AE_Effect_AttributeSampler/Sources/AEAttributeSampler_PluginInterface.cpp @@ -0,0 +1,780 @@ +//---------------------------------------------------------------------------- +// Copyright Persistant Studios, SARL. All Rights Reserved. https://www.popcornfx.com/terms-and-conditions/ +//---------------------------------------------------------------------------- +#include "ae_precompiled.h" + +#include "AEAttributeSampler_PluginInterface.h" +#include "AEAttributeSampler_SequenceData.h" +#include "AEAttributeSampler_ParamDefine.h" + +#include "PopcornFX_UID.h" + +//AE +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +//AAE Plugin code +#include +#include + +#include +#include +#include + +__AAEPK_BEGIN + +//---------------------------------------------------------------------------- + +CPluginInterface *CPluginInterface::m_Instance = nullptr; +uint32_t CPluginInterface::m_AttrUID = 1; + +//---------------------------------------------------------------------------- + +CPluginInterface::CPluginInterface() +{ +} + +//---------------------------------------------------------------------------- + +CPluginInterface::~CPluginInterface() +{ + for (auto& it : m_AttributeData) + { + delete(it.second); + } + m_AttributeData.clear(); +} + +//---------------------------------------------------------------------------- + +CPluginInterface &CPluginInterface::Instance() +{ + if (CPluginInterface::m_Instance == nullptr) + { + m_Instance = new CPluginInterface(); + } + return *m_Instance; +} + +//---------------------------------------------------------------------------- + +PF_Err CPluginInterface::About( SAAEIOData &AAEData, + PF_ParamDef *params[], + PF_LayerDef *output) +{ + (void)output; + (void)params; + + AEGP_SuiteHandler suites(AAEData.m_InData->pica_basicP); + suites.ANSICallbacksSuite1()->sprintf(AAEData.m_OutData->return_msg, + "%s v%d.%d.%d\r%s", + STR(StrID_Name), + AEPOPCORNFX_MAJOR_VERSION, + AEPOPCORNFX_MINOR_VERSION, + AEPOPCORNFX_BUG_VERSION, + STR(StrID_Description)); + return PF_Err_NONE; +} + +//---------------------------------------------------------------------------- + +PF_Err CPluginInterface::GlobalSetup( SAAEIOData &AAEData, + PF_ParamDef *params[], + PF_LayerDef *output) +{ + (void)output; + (void)params; + m_MainThreadID = std::this_thread::get_id(); + + AEFX_SuiteScoper popcornFXSuite = AEFX_SuiteScoper( AAEData.m_InData, + kPopcornFXSuite1, + kPopcornFXSuiteVersion1, + AAEData.m_OutData, + "PopcornFX suite was not found."); + AEGP_SuiteHandler suites(AAEData.m_InData->pica_basicP); + + AAEData.m_OutData->my_version = PF_VERSION( AEPOPCORNFX_MAJOR_VERSION, + AEPOPCORNFX_MINOR_VERSION, + AEPOPCORNFX_BUG_VERSION, + AEPOPCORNFX_STAGE_VERSION, + AEPOPCORNFX_BUILD_VERSION); + + //PF_OutFlag_DEEP_COLOR_AWARE -> To support 16bit per chan format. + //PF_OutFlag_I_AM_OBSOLETE -> Do not show in menu. We do not want user to create this effect manually. + //PF_OutFlag_SEND_UPDATE_PARAMS_UI -> To be notified when PF_ParamFlag_SUPERVISE is set on parameters + AAEData.m_OutData->out_flags = PF_OutFlag_DEEP_COLOR_AWARE | + PF_OutFlag_I_AM_OBSOLETE | + PF_OutFlag_SEND_UPDATE_PARAMS_UI; + //PF_OutFlag2_SUPPORTS_QUERY_DYNAMIC_FLAGS -> To be able to change dynamicly some out_flags. see doc. + //PF_OutFlag2_FLOAT_COLOR_AWARE -> To support 32bit per chan format. Need PF_OutFlag2_SUPPORTS_SMART_RENDER + //PF_OutFlag2_SUPPORTS_SMART_RENDER -> Necessary for new render pipeline. + //PF_OutFlag2_I_USE_3D_CAMERA -> Can query 3D camera information, Not sure if necessery in Attribute or just on Effect. + AAEData.m_OutData->out_flags2 = PF_OutFlag2_SUPPORTS_QUERY_DYNAMIC_FLAGS | + PF_OutFlag2_FLOAT_COLOR_AWARE | + PF_OutFlag2_SUPPORTS_SMART_RENDER | + PF_OutFlag2_I_USE_3D_CAMERA | + PF_OutFlag2_SUPPORTS_THREADED_RENDERING; + + suites.UtilitySuite3()->AEGP_RegisterWithAEGP(nullptr, STR(StrID_Name), &m_AAEID); + + return popcornFXSuite->InitializePopcornFXIFN(AAEData); +} + +//---------------------------------------------------------------------------- + +PF_Err CPluginInterface::ParamsSetup( SAAEIOData &AAEData, + PF_ParamDef *params[], + PF_LayerDef *output) +{ + (void)output; + (void)params; + + AEFX_SuiteScoper popcornFXSuite = AEFX_SuiteScoper( AAEData.m_InData, + kPopcornFXSuite1, + kPopcornFXSuiteVersion1, + AAEData.m_OutData, + "PopcornFX suite was not found."); + PF_Err result = PF_Err_NONE; + PF_InData *in_data = AAEData.m_InData; //Used in AE Macros + PF_ParamDef def; + float minFloat = -100000.0f; //std::numeric_limits::min() crashes AfterFX, smashing his stack to pieces. + float maxFloat = 100000.0f; //same as above. + + m_ParametersIndexes = new int[__AttributeSamplerType_Parameters_Count]; + for (unsigned int i = 0; i < __AttributeSamplerType_Parameters_Count; ++i) + m_ParametersIndexes[i] = -1; + m_ParametersIndexes[0] = 0; // First Parameter is reserved to AE + + CBasePluginInterface::AddCheckBoxParameter(in_data, GetStringPtr(StrID_Generic_Infernal_Uuid), AttributeSamplerType_Parameters_Infernal_Uuid); + CBasePluginInterface::AddCheckBoxParameter(in_data, GetStringPtr(StrID_Generic_Infernal_Name), AttributeSamplerType_Parameters_Infernal_Name, false, 0, PF_PUI_INVISIBLE); + + AEFX_CLR_STRUCT(def); + def.flags = PF_ParamFlag_SUPERVISE | PF_ParamFlag_CANNOT_INTERP; + PF_ADD_POPUP( GetStringPtr(StrID_Parameters_Shapes), + __SamplerShapeType_Count, + SamplerShapeType_Box, + GetStringPtr(StrID_Parameters_Shapes_Combobox), + AttributeSamplerType_Parameters_Shapes); + m_ParametersIndexes[AttributeSamplerType_Parameters_Shapes] = ++m_CurrentIndex; + + CBasePluginInterface::StartParameterCategory(in_data, GetStringPtr(StrID_Topic_Shape_Start), AttributeSamplerType_Topic_Shape_Start); + { + CBasePluginInterface::StartParameterCategory(in_data, GetStringPtr(StrID_Topic_Shape_Box_Start), AttributeSamplerType_Topic_Shape_Box_Start); + { + CBasePluginInterface::AddFloatParameterUnbound(in_data, GetStringPtr(StrID_Parameters_Box_Size_X), AttributeSamplerType_Parameters_Box_Size_X, 0.5f); + CBasePluginInterface::AddFloatParameterUnbound(in_data, GetStringPtr(StrID_Parameters_Box_Size_Y), AttributeSamplerType_Parameters_Box_Size_Y, 0.5f); + CBasePluginInterface::AddFloatParameterUnbound(in_data, GetStringPtr(StrID_Parameters_Box_Size_Z), AttributeSamplerType_Parameters_Box_Size_Z, 0.5f); + } + CBasePluginInterface::EndParameterCategory(in_data, AttributeSamplerType_Topic_Shape_Box_End); + + StartParameterCategory(in_data, GetStringPtr(StrID_Topic_Shape_Sphere_Start), AttributeSamplerType_Topic_Shape_Sphere_Start); + { + AddFloatParameterUnbound(in_data, GetStringPtr(StrID_Parameters_Sphere_Radius), AttributeSamplerType_Parameters_Sphere_Radius, 1.0f); + AddFloatParameterUnbound(in_data, GetStringPtr(StrID_Parameters_Sphere_InnerRadius), AttributeSamplerType_Parameters_Sphere_InnerRadius, 0.0f); + } + EndParameterCategory(in_data, AttributeSamplerType_Topic_Shape_Sphere_End); + + StartParameterCategory(in_data, GetStringPtr(StrID_Topic_Shape_Ellipsoid_Start), AttributeSamplerType_Topic_Shape_Ellipsoid_Start); + { + AddFloatParameterUnbound(in_data, GetStringPtr(StrID_Parameters_Ellipsoid_Radius), AttributeSamplerType_Parameters_Ellipsoid_Radius, 1.0f); + AddFloatParameterUnbound(in_data, GetStringPtr(StrID_Parameters_Ellipsoid_InnerRadius), AttributeSamplerType_Parameters_Ellipsoid_InnerRadius, 0.0f); + } + EndParameterCategory(in_data, AttributeSamplerType_Topic_Shape_Ellipsoid_End); + + StartParameterCategory(in_data, GetStringPtr(StrID_Topic_Shape_Cylinder_Start), AttributeSamplerType_Topic_Shape_Cylinder_Start); + { + AddFloatParameterUnbound(in_data, GetStringPtr(StrID_Parameters_Cylinder_Radius), AttributeSamplerType_Parameters_Cylinder_Radius, 1.0f); + AddFloatParameterUnbound(in_data, GetStringPtr(StrID_Parameters_Cylinder_Height), AttributeSamplerType_Parameters_Cylinder_Height, 0.5f); + AddFloatParameterUnbound(in_data, GetStringPtr(StrID_Parameters_Cylinder_InnerRadius), AttributeSamplerType_Parameters_Cylinder_InnerRadius, 0.0f); + } + EndParameterCategory(in_data, AttributeSamplerType_Topic_Shape_Cylinder_End); + + StartParameterCategory(in_data, GetStringPtr(StrID_Topic_Shape_Capsule_Start), AttributeSamplerType_Topic_Shape_Capsule_Start); + { + AddFloatParameterUnbound(in_data, GetStringPtr(StrID_Parameters_Capsule_Radius), AttributeSamplerType_Parameters_Capsule_Radius, 1.0f); + AddFloatParameterUnbound(in_data, GetStringPtr(StrID_Parameters_Capsule_Height), AttributeSamplerType_Parameters_Capsule_Height, 0.5f); + AddFloatParameterUnbound(in_data, GetStringPtr(StrID_Parameters_Capsule_InnerRadius), AttributeSamplerType_Parameters_Capsule_InnerRadius, 0.0f); + } + EndParameterCategory(in_data, AttributeSamplerType_Topic_Shape_Capsule_End); + + StartParameterCategory(in_data, GetStringPtr(StrID_Topic_Shape_Cone_Start), AttributeSamplerType_Topic_Shape_Cone_Start); + { + AddFloatParameterUnbound(in_data, GetStringPtr(StrID_Parameters_Cone_Radius), AttributeSamplerType_Parameters_Cone_Radius, 1.0f); + AddFloatParameterUnbound(in_data, GetStringPtr(StrID_Parameters_Cone_Height), AttributeSamplerType_Parameters_Cone_Height, 0.5f); + } + EndParameterCategory(in_data, AttributeSamplerType_Topic_Shape_Cone_End); + + StartParameterCategory(in_data, GetStringPtr(StrID_Topic_Shape_Mesh_Start), AttributeSamplerType_Topic_Shape_Mesh_Start); + { + AEFX_CLR_STRUCT(def); + PF_ADD_FLOAT_SLIDERX(GetStringPtr(StrID_Parameters_Mesh_Scale), minFloat, maxFloat, minFloat, maxFloat, 1.0f/*default*/, 6, 0, 0, AttributeSamplerType_Parameters_Mesh_Scale); + m_ParametersIndexes[AttributeSamplerType_Parameters_Mesh_Scale] = ++m_CurrentIndex; + + AEFX_CLR_STRUCT(def); + PF_ADD_BUTTON(GetStringPtr(StrID_Parameters_Mesh_Path), GetStringPtr(StrID_Parameters_Mesh_Path_Button), 0, PF_ParamFlag_SUPERVISE, AttributeSamplerType_Parameters_Mesh_Path); + m_ParametersIndexes[AttributeSamplerType_Parameters_Mesh_Path] = ++m_CurrentIndex; + + AddCheckBoxParameter(in_data, GetStringPtr(StrID_Parameters_Mesh_Bind_Backdrop), AttributeSamplerType_Parameters_Mesh_Bind_Backdrop); + + AddCheckBoxParameter(in_data, GetStringPtr(StrID_Parameters_Mesh_Bind_Backdrop_Weight_Enabled), AttributeSamplerType_Parameters_Mesh_Bind_Backdrop_Weighted_Enabled); + + AddIntParameter(in_data, GetStringPtr(StrID_Parameters_Mesh_Bind_Backdrop_ColorStreamID), AttributeSamplerType_Parameters_Mesh_Bind_Backdrop_ColorStreamID, 0, 0, 100); + AddIntParameter(in_data, GetStringPtr(StrID_Parameters_Mesh_Bind_Backdrop_WeightStreamID), AttributeSamplerType_Parameters_Mesh_Bind_Backdrop_WeightStreamID, 0, 0, 100); + + } + EndParameterCategory(in_data, AttributeSamplerType_Topic_Shape_Mesh_End); + } + EndParameterCategory(in_data, AttributeSamplerType_Topic_Shape_End); + + AEFX_CLR_STRUCT(def); + def.flags = PF_ParamFlag_SUPERVISE; + PF_ADD_LAYER(GetStringPtr(StrID_Parameters_Layer_Pick), PF_LayerDefault_NONE, AttributeSamplerType_Layer_Pick); + m_ParametersIndexes[AttributeSamplerType_Layer_Pick] = ++m_CurrentIndex; + + AddCheckBoxParameter(in_data, GetStringPtr(StrID_Parameters_Layer_Sample_Once), AttributeSamplerType_Layer_Sample_Once); + + AddCheckBoxParameter(in_data, GetStringPtr(StrID_Parameters_Layer_Sample_Seeking), AttributeSamplerType_Layer_Sample_Seeking); + + AEFX_CLR_STRUCT(def); + PF_ADD_BUTTON(GetStringPtr(StrID_Parameters_VectorField_Path), GetStringPtr(StrID_Parameters_Mesh_Path_Button), 0, PF_ParamFlag_SUPERVISE, AttributeSamplerType_Parameters_VectorField_Path); + m_ParametersIndexes[AttributeSamplerType_Parameters_VectorField_Path] = ++m_CurrentIndex; + + AddFloatParameter(in_data, GetStringPtr(StrID_Parameters_VectorField_Strength), AttributeSamplerType_Parameters_VectorField_Strength, 0.1f, 0.0f, 10.0f); + + AEFX_CLR_STRUCT(def); + def.ui_flags = PF_PUI_INVISIBLE; + def.param_type = PF_Param_POINT_3D; + PF_STRCPY(def.name, (GetStringPtr(StrID_Parameters_VectorField_Position))); + def.u.point3d_d.x_value = def.u.point3d_d.x_dephault = 0; + def.u.point3d_d.y_value = def.u.point3d_d.y_dephault = 0; + def.u.point3d_d.z_value = def.u.point3d_d.z_dephault = 0; + def.uu.id = (AttributeSamplerType_Parameters_VectorField_Position); + PF_ADD_PARAM(in_data, -1, &def); + m_ParametersIndexes[AttributeSamplerType_Parameters_VectorField_Position] = ++m_CurrentIndex; + + AEFX_CLR_STRUCT(def); + def.flags = PF_ParamFlag_SUPERVISE | + PF_ParamFlag_CANNOT_TIME_VARY | + PF_ParamFlag_CANNOT_INTERP; + //def.ui_flags = PF_PUI_STD_CONTROL_ONLY; + PF_ADD_POPUP(GetStringPtr(StrID_Parameters_VectorField_Interpolation), + __EInterpolationType_Count, + EInterpolationType_Point, + GetStringPtr(StrID_Parameters_VectorField_Interpolation_Combobox), + AttributeSamplerType_Parameters_VectorField_Interpolation); + m_ParametersIndexes[AttributeSamplerType_Parameters_VectorField_Interpolation] = ++m_CurrentIndex; + + AddFloatParameter(in_data, GetStringPtr(StrID_Parameters_Layer_Sample_Downsampling_X), AttributeSamplerType_Layer_Sample_Downsampling_X, 1.0f, 1.0f, 100.0f); + AddFloatParameter(in_data, GetStringPtr(StrID_Parameters_Layer_Sample_Downsampling_Y), AttributeSamplerType_Layer_Sample_Downsampling_Y, 1.0f, 1.0f, 100.0f); + + AAEData.m_OutData->num_params = __AttributeSamplerType_Parameters_Count; + + popcornFXSuite->SetParametersIndexes(m_ParametersIndexes, EPKChildPlugins::SAMPLER); + return result; +} + +//---------------------------------------------------------------------------- + +PF_Err CPluginInterface::GlobalSetdown( SAAEIOData &AAEData, + PF_ParamDef *params[], + PF_LayerDef *output) +{ + (void)output; + (void)params; + + AEFX_SuiteScoper PopcornFXSuite = AEFX_SuiteScoper( AAEData.m_InData, + kPopcornFXSuite1, + kPopcornFXSuiteVersion1, + AAEData.m_OutData, + "PopcornFX suite was not found."); + + if (m_ParametersIndexes != nullptr) + delete[] m_ParametersIndexes; + m_ParametersIndexes = nullptr; + + for (auto it = m_AttributeData.begin(); it != m_AttributeData.end(); ++it) + { + if (it->second != nullptr) + { + delete (it->second); + it->second = nullptr; + } + } + return PF_Err_NONE; +} + +//---------------------------------------------------------------------------- + +PF_Err CPluginInterface::SequenceSetup(SAAEIOData &AAEData, PF_ParamDef *params[], PF_LayerDef *output) +{ + (void)output; + + A_Err result = A_Err_NONE; + SAttributeSamplerSequenceDataFlat *sequenceData = nullptr; + AEGP_SuiteHandler suites(AAEData.m_InData->pica_basicP); + PF_Handle sequenceDataHandle = suites.HandleSuite1()->host_new_handle(sizeof(SAttributeSamplerSequenceDataFlat)); + + if (!sequenceDataHandle) + return PF_Err_OUT_OF_MEMORY; + sequenceData = static_cast(suites.HandleSuite1()->host_lock_handle(sequenceDataHandle)); + if (sequenceData != nullptr) + { + AEFX_CLR_STRUCT(*sequenceData); + + sequenceData->m_IsFlat = true; + + sequenceData->SetUUID(CUUIDGenerator::Get16().data()); + sequenceData->SetName("AttributeSamplerName"); + sequenceData->SetResourcePath(""); + + AEGP_LayerH layerH; + A_long dstID = 0; + + result |= suites.PFInterfaceSuite1()->AEGP_GetEffectLayer(AAEData.m_InData->effect_ref, &layerH); + result |= suites.LayerSuite8()->AEGP_GetLayerID(layerH, &dstID); + + if (result == A_Err_NONE) + sequenceData->SetLayerID(dstID); + + _RegisterAttributeInstancePlugin(AAEData, params, sequenceData, true); + + AAEData.m_OutData->sequence_data = sequenceDataHandle; + suites.HandleSuite1()->host_unlock_handle(sequenceDataHandle); + } + return PF_Err_NONE; +} + +//---------------------------------------------------------------------------- + +PF_Err CPluginInterface::SequenceReSetup(SAAEIOData &AAEData, PF_ParamDef *params[], PF_LayerDef *output) +{ + (void)output; + (void)params; + + AEGP_SuiteHandler suites(AAEData.m_InData->pica_basicP); + PF_Err result = PF_Err_NONE; + + if (AAEData.m_InData->sequence_data) + { + PF_Handle sequenceDataFlatHandle = AAEData.m_InData->sequence_data; + SAttributeSamplerSequenceDataFlat *sequenceDataFlat = static_cast(suites.HandleSuite1()->host_lock_handle(sequenceDataFlatHandle)); + + if (sequenceDataFlat) + { + _RegisterAttributeInstancePlugin(AAEData, params, sequenceDataFlat, false); + AAEData.m_OutData->sequence_data = sequenceDataFlatHandle; + + suites.HandleSuite1()->host_unlock_handle(sequenceDataFlatHandle); + } + } + else + { + result = SequenceSetup(AAEData, params, output); + } + return result; +} + +//---------------------------------------------------------------------------- + +PF_Err CPluginInterface::SequenceFlatten(SAAEIOData &AAEData, PF_ParamDef *params[], PF_LayerDef *output) +{ + (void)output; + (void)params; + + AEGP_SuiteHandler suites(AAEData.m_InData->pica_basicP); + PF_Err result = PF_Err_NONE; + + if (!AAEData.m_InData->sequence_data) + return result; + + PF_Handle sequenceDataHandle = AAEData.m_InData->sequence_data; + SAttributeSamplerSequenceDataFlat *sequenceData = static_cast(suites.HandleSuite1()->host_lock_handle(sequenceDataHandle)); + + if (sequenceData) + { + std::string uuid; + //Check Layer ID to determine if its a duplicate. if so, update LayerID and regenerate UUID + AEGP_LayerH layerH; + A_long dstID = 0; + + result |= suites.PFInterfaceSuite1()->AEGP_GetEffectLayer(AAEData.m_InData->effect_ref, &layerH); + result |= suites.LayerSuite8()->AEGP_GetLayerID(layerH, &dstID); + + if (result == A_Err_NONE) + { + if (sequenceData->m_LayerID != dstID) + { + sequenceData->m_LayerID = dstID; + sequenceData->SetUUID(CUUIDGenerator::Get16().data()); + } + } + _RegisterAttributeInstancePlugin(AAEData, params, sequenceData, false); + + if (GetParamsSequenceUID(AAEData, uuid, m_ParametersIndexes[AttributeSamplerType_Parameters_Infernal_Uuid]) != PF_Err_NONE) + return result; + + if (m_AttributeData.count(uuid) == 0) + return result; + + SAttributeSamplerDesc *descriptor = m_AttributeData[uuid]->m_DescAttribute; + + if (descriptor == nullptr) + return result; + + sequenceData->m_IsFlat = true; + sequenceData->SetName(descriptor->GetAttributePKKey().c_str()); + sequenceData->SetResourcePath(descriptor->m_ResourcePath.c_str()); + + AAEData.m_OutData->sequence_data = sequenceDataHandle; + suites.HandleSuite1()->host_unlock_handle(sequenceDataHandle); + } + else + result = PF_Err_INTERNAL_STRUCT_DAMAGED; + return result; +} + +//---------------------------------------------------------------------------- + +PF_Err CPluginInterface::SequenceShutdown(SAAEIOData &AAEData, PF_ParamDef *params[], PF_LayerDef *output) +{ + (void)output; + (void)params; + + AEGP_SuiteHandler suites(AAEData.m_InData->pica_basicP); + + if (AAEData.m_InData->sequence_data != nullptr) + { + PF_Handle sequenceDataHandle = AAEData.m_InData->sequence_data; + suites.HandleSuite1()->host_dispose_handle(sequenceDataHandle); + } + AAEData.m_InData->sequence_data = nullptr; + AAEData.m_OutData->sequence_data = nullptr; + + return PF_Err_NONE; + +} + +//---------------------------------------------------------------------------- + +PF_Err CPluginInterface::PreRender(SAAEIOData &AAEData) +{ + PF_RenderRequest req = AAEData.m_ExtraData.m_PreRenderData->input->output_request; + PF_CheckoutResult in_result; + + AE_VERIFY(AAEData.m_ExtraData.m_PreRenderData != nullptr); + AE_VERIFY(AAEData.m_ExtraData.m_PreRenderData->cb != nullptr); + + AAEData.m_ExtraData.m_PreRenderData->cb->checkout_layer(AAEData.m_InData->effect_ref, + ATTRIBUTESAMPLER_INPUT, + ATTRIBUTESAMPLER_INPUT, + &req, + AAEData.m_InData->current_time, + AAEData.m_InData->local_time_step, + AAEData.m_InData->time_scale, + &in_result); + + UnionLRect(&in_result.result_rect, &AAEData.m_ExtraData.m_PreRenderData->output->result_rect); + UnionLRect(&in_result.max_result_rect, &AAEData.m_ExtraData.m_PreRenderData->output->max_result_rect); + return PF_Err_NONE; +} + +//---------------------------------------------------------------------------- + +PF_Err CPluginInterface::SmartRender(SAAEIOData &AAEData) +{ + AEGP_SuiteHandler suites(AAEData.m_InData->pica_basicP); + PF_EffectWorld *inputWorld = nullptr; + PF_EffectWorld *outputWorld = nullptr; + PF_Err err = PF_Err_NONE; + + std::string uuid; + + AAEData.m_ExtraData.m_SmartRenderData->cb->checkout_layer_pixels(AAEData.m_InData->effect_ref, ATTRIBUTESAMPLER_INPUT, &inputWorld); + AAEData.m_ExtraData.m_SmartRenderData->cb->checkout_output(AAEData.m_InData->effect_ref, &outputWorld); + + if (inputWorld == nullptr || outputWorld == nullptr) + { + return PF_Err_BAD_CALLBACK_PARAM; + } + outputWorld->data = inputWorld->data; + + AAEData.m_ExtraData.m_SmartRenderData->cb->checkin_layer_pixels(AAEData.m_InData->effect_ref, ATTRIBUTESAMPLER_INPUT); + + return err; +} + +//---------------------------------------------------------------------------- + +PF_Err CPluginInterface::UpdateParams(SAAEIOData &AAEData, PF_ParamDef *params[]) +{ + (void)AAEData; + (void)params; + + PF_Err result = PF_Err_NONE; + std::string uuid; + + if (AAEData.m_InData->appl_id == 'PrMr') + return result; + + if (_GetAttributeSequenceUID(AAEData, uuid) == false) + return PF_Err_BAD_CALLBACK_PARAM; + if (m_AttributeData.count(uuid) == 0) + return result; + + AEGP_SuiteHandler suites(AAEData.m_InData->pica_basicP); + SAttributeSamplerDesc *descriptor = m_AttributeData[uuid]->m_DescAttribute; + + if (descriptor == nullptr) + return result; + + if (descriptor != nullptr) + { + if (m_ParametersIndexes[AttributeSamplerType_Parameters_Mesh_Path] == (AAEData.m_ExtraData.m_ChangeParamData->param_index) || + m_ParametersIndexes[AttributeSamplerType_Parameters_VectorField_Path] == (AAEData.m_ExtraData.m_ChangeParamData->param_index)) + { + AEFX_SuiteScoper PopcornFXSuite = AEFX_SuiteScoper(AAEData.m_InData, kPopcornFXSuite1, kPopcornFXSuiteVersion1, AAEData.m_OutData, "PopcornFX suite was not found."); + result |= PopcornFXSuite->Display_AttributeSampler_BrowseMeshDialog(AAEData, descriptor); + AAEData.m_OutData->out_flags |= PF_OutFlag_FORCE_RERENDER; + } + else if (m_ParametersIndexes[AttributeSamplerType_Layer_Pick] == (AAEData.m_ExtraData.m_ChangeParamData->param_index)) + { + AAEData.m_OutData->out_flags |= PF_OutFlag_FORCE_RERENDER; + } + } + return result; +} + +//---------------------------------------------------------------------------- + +bool CPluginInterface::_GetAttributeSequenceUID(SAAEIOData &AAEData, std::string &out) +{ + AEGP_SuiteHandler suites(AAEData.m_InData->pica_basicP); + PF_Handle sequenceDataHandle = AAEData.m_InData->sequence_data; + SAttributeSamplerSequenceDataFlat *sequenceDataFlat = static_cast(suites.HandleSuite1()->host_lock_handle(sequenceDataHandle)); + + out.clear(); + if (sequenceDataFlat && sequenceDataFlat->m_IsFlat == true) + { + out.append(sequenceDataFlat->m_AttributeUUID, strlen(sequenceDataFlat->m_AttributeUUID)); + suites.HandleSuite1()->host_unlock_handle(sequenceDataHandle); + return true; + } + return false; +} + +//---------------------------------------------------------------------------- + +PF_Err CPluginInterface::_UpdateParamsVisibility(SAAEIOData &AAEData, SAttributeSamplerData *AttrData) +{ + AEGP_SuiteHandler suites(AAEData.m_InData->pica_basicP); + PF_Err err = PF_Err_NONE; + AEGP_EffectRefH effectRef = nullptr; + AEGP_StreamRefH streamRef = nullptr; + + AAEData.m_OutData->out_flags |= PF_OutFlag_REFRESH_UI; + + err = suites.PFInterfaceSuite1()->AEGP_GetNewEffectForEffect(m_AAEID, AAEData.m_InData->effect_ref, &effectRef); + if (!AE_VERIFY(err == A_Err_NONE)) + return err; + + for (int i = 1; i < __AttributeSamplerType_Parameters_Count; ++i) // Start at 1, first params is reserved. + { + err |= suites.StreamSuite2()->AEGP_GetNewEffectStreamByIndex(m_AAEID, effectRef, m_ParametersIndexes[i], &streamRef); + if (!AE_VERIFY(err == A_Err_NONE)) + { + err |= suites.EffectSuite4()->AEGP_DisposeEffect(effectRef); + return err; + + } + bool visibility = GetParamsVisibility(i, AttrData->m_DescAttribute->m_Type); + + // Toggle visibility of parameter + err |= suites.DynamicStreamSuite2()->AEGP_SetDynamicStreamFlag(streamRef, AEGP_DynStreamFlag_HIDDEN, FALSE, !visibility); + + err |= suites.StreamSuite2()->AEGP_DisposeStream(streamRef); + streamRef = nullptr; + if (!AE_VERIFY(err == A_Err_NONE)) + { + err |= suites.EffectSuite4()->AEGP_DisposeEffect(effectRef); + return err; + } + } + err |= suites.EffectSuite4()->AEGP_DisposeEffect(effectRef); + return err; +} + +//---------------------------------------------------------------------------- + +PF_Err CPluginInterface::HandleDataFromAEGP(SAAEIOData &AAEData, + PF_ParamDef *params[]) +{ + (void)params; + + PF_Err err = PF_Err_NONE; + void *extraData = AAEData.m_ExtraData.m_UndefinedData; + SAttributeSamplerDesc *desc = reinterpret_cast(extraData); + AEGP_SuiteHandler suites(AAEData.m_InData->pica_basicP); + + if (desc != nullptr) + { + if (desc->m_IsDeleted) + { + std::string uuid; + + if (_GetAttributeSequenceUID(AAEData, uuid) == false) + { + AE_VERIFY(false); + return PF_Err_BAD_CALLBACK_PARAM; + } + + if (m_AttributeData.count(uuid) == 0) + return PF_Err_BAD_CALLBACK_PARAM; + + SAttributeSamplerData *AttrData = m_AttributeData[uuid]; + + if (AttrData) + { + m_AttributeData.erase(uuid); + + AttrData->m_DescAttribute = nullptr; + if (desc->m_Descriptor != nullptr) + delete desc->m_Descriptor; + delete desc; + delete AttrData; + return PF_Err_NONE; + } + } + else + { + m_AttrUID += 1; + + std::string pkKey; + std::string uuid; + SAttributeSamplerData *AttrData = nullptr; + + if (_GetAttributeSequenceUID(AAEData, uuid) == false) + { + AE_VERIFY(false); + return PF_Err_BAD_CALLBACK_PARAM; + } + if (m_AttributeData.count(uuid) == 0) + { + AttrData = new SAttributeSamplerData{}; + } + AttrData = m_AttributeData[uuid]; + AttrData->m_DescAttribute = desc; + + pkKey = AttrData->m_DescAttribute->GetAttributePKKey(); + + AttrData->m_DescAttribute->m_IsDefaultValue = AttrData->m_IsDefault; + AttrData->m_DescAttribute->m_ResourcePath = AttrData->m_ResourcePath; + + AEGP_EffectRefH effectRef = nullptr; + + err = suites.PFInterfaceSuite1()->AEGP_GetNewEffectForEffect(m_AAEID, AAEData.m_InData->effect_ref, &effectRef); + if (!AE_VERIFY(err == A_Err_NONE)) + return err; + + err |= SetEffectName(AAEData, pkKey, effectRef); + err |= SetParameterStreamName(AAEData, uuid, m_ParametersIndexes[AttributeSamplerType_Parameters_Infernal_Uuid], effectRef); + err |= SetParameterStreamName(AAEData, pkKey, m_ParametersIndexes[AttributeSamplerType_Parameters_Infernal_Name], effectRef); + err |= suites.EffectSuite4()->AEGP_DisposeEffect(effectRef); + effectRef = nullptr; + + + _UpdateParamsVisibility(AAEData, AttrData); + } + + } + AAEData.m_OutData->out_flags |= PF_OutFlag_FORCE_RERENDER; + AE_VERIFY(err == A_Err_NONE); + return err; +} + +//---------------------------------------------------------------------------- + +PF_Err CPluginInterface::UpdateParamsUI(SAAEIOData &AAEData, PF_ParamDef *params[]) +{ + (void)params; + std::string uuid; + + if (GetParamsSequenceUID(AAEData, uuid, m_ParametersIndexes[AttributeSamplerType_Parameters_Infernal_Uuid]) != PF_Err_NONE) + return PF_Err_BAD_CALLBACK_PARAM; + if (m_AttributeData.count(uuid) == 0) + return A_Err_NONE; + + PF_Err err = PF_Err_NONE; + AEGP_SuiteHandler suites(AAEData.m_InData->pica_basicP); + SAttributeSamplerDesc *descriptor = m_AttributeData[uuid]->m_DescAttribute; + + if (descriptor == nullptr) + return PF_Err_NONE; + + if (descriptor != nullptr && descriptor->m_IsDeleted) + { + m_AttributeData.erase(uuid); + delete descriptor; + return PF_Err_NONE; + } + return err; +} + +//---------------------------------------------------------------------------- + +A_Err CPluginInterface::_RegisterAttributeInstancePlugin(SAAEIOData &AAEData, PF_ParamDef *params[], SAttributeSamplerSequenceDataFlat *sequenceData, bool setup) +{ + (void)params; + + PF_Err err = PF_Err_NONE; + std::string id; + + if (sequenceData != nullptr) + id = sequenceData->m_AttributeUUID; + else if (_GetAttributeSequenceUID(AAEData, id) == false) + return A_Err_NONE; + + if (m_AttributeData.count(id) == 0) + { + SAttributeSamplerData *AttrData = new SAttributeSamplerData{}; + + if (!AE_VERIFY(AttrData != nullptr)) + return A_Err_ALLOC; + + if (!setup) + { + if (m_MainThreadID == std::this_thread::get_id()) + { + AEGP_SuiteHandler suites(AAEData.m_InData->pica_basicP); + AEGP_EffectRefH effectRef = nullptr; + + err |= suites.PFInterfaceSuite1()->AEGP_GetNewEffectForEffect(m_AAEID, AAEData.m_InData->effect_ref, &effectRef); + + std::string uuid(sequenceData->m_AttributeUUID); + std::string name(sequenceData->m_AttributeName); + + err |= SetParameterStreamName(AAEData, uuid, m_ParametersIndexes[AttributeSamplerType_Parameters_Infernal_Uuid], effectRef); + err |= SetParameterStreamName(AAEData, name, m_ParametersIndexes[AttributeSamplerType_Parameters_Infernal_Name], effectRef); + err |= suites.EffectSuite4()->AEGP_DisposeEffect(effectRef); + } + } + m_AttributeData[id] = AttrData; + } + if (sequenceData != nullptr) + { + m_AttributeData[id]->m_ResourcePath = sequenceData->m_ResourcePath; + } + AE_VERIFY(err == A_Err_NONE); + return A_Err_NONE;; +} + +//---------------------------------------------------------------------------- + +__AAEPK_END diff --git a/AE_Effect_AttributeSampler/Sources/AEAttributeSampler_SequenceData.cpp b/AE_Effect_AttributeSampler/Sources/AEAttributeSampler_SequenceData.cpp new file mode 100644 index 00000000..4f13f72d --- /dev/null +++ b/AE_Effect_AttributeSampler/Sources/AEAttributeSampler_SequenceData.cpp @@ -0,0 +1,59 @@ +//---------------------------------------------------------------------------- +// Copyright Persistant Studios, SARL. All Rights Reserved. https://www.popcornfx.com/terms-and-conditions/ +//---------------------------------------------------------------------------- +#include "ae_precompiled.h" + +#include "AEAttributeSampler_SequenceData.h" + +#include +#include + +__AAEPK_BEGIN + +//---------------------------------------------------------------------------- + +bool SAttributeSamplerSequenceDataFlat::SetUUID(const char *uuid) +{ + m_AttributeUUIDLen = std::min(strlen(uuid) + 1, SequenceCST::UUID_LEN); + if (m_AttributeUUIDLen != 0) + { + strncpy(m_AttributeUUID, uuid, m_AttributeUUIDLen); + } + return true; +} + +//---------------------------------------------------------------------------- + +bool SAttributeSamplerSequenceDataFlat::SetName(const char *name) +{ + m_AttributeNameLen = std::min(strlen(name) + 1, SequenceCST::MAX_NAME_LEN); + if (m_AttributeNameLen != 0) + { + strncpy(m_AttributeName, name, m_AttributeNameLen); + } + return true; +} + +//---------------------------------------------------------------------------- + +bool SAttributeSamplerSequenceDataFlat::SetResourcePath(const char *path) +{ + m_ResourcePathLen = std::min(strlen(path) + 1, SequenceCST::MAX_PATH_LEN); + if (m_ResourcePathLen != 0) + { + strncpy(m_ResourcePath, path, m_ResourcePathLen); + } + return true; +} + +//---------------------------------------------------------------------------- + +bool SAttributeSamplerSequenceDataFlat::SetLayerID(A_long id) +{ + m_LayerID = id; + return true; +} + +//---------------------------------------------------------------------------- + +__AAEPK_END diff --git a/AE_Effect_AttributeSampler/Sources/AE_Effect_AttributeSampler.plugin-Info.plist b/AE_Effect_AttributeSampler/Sources/AE_Effect_AttributeSampler.plugin-Info.plist new file mode 100644 index 00000000..719de26a --- /dev/null +++ b/AE_Effect_AttributeSampler/Sources/AE_Effect_AttributeSampler.plugin-Info.plist @@ -0,0 +1,24 @@ + + + + + CFBundleExecutable + AttributeSampler + CFBundleIdentifier + com.PersistantStudio.PopcornFX.AttributeSampler + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + PK-AfterEffects_AttributeSampler + CFBundlePackageType + eFKT + CFBundleSignature + FXTC + LSRequiresCarbon + + NSAppleScriptEnabled + No + NSHumanReadableCopyright + © PersistantStudio PopcornFX + + diff --git a/AE_Effect_AttributeSampler/Sources/AE_Effect_AttributeSampler_PiPL.r b/AE_Effect_AttributeSampler/Sources/AE_Effect_AttributeSampler_PiPL.r new file mode 100644 index 00000000..bf73cd01 --- /dev/null +++ b/AE_Effect_AttributeSampler/Sources/AE_Effect_AttributeSampler_PiPL.r @@ -0,0 +1,73 @@ +#include "AEConfig.h" +#include "AE_EffectVers.h" + +#ifndef AE_OS_WIN + #include +#endif + +#ifdef AE_OS_WIN +#include "../../AE_Suites/PopcornFX_Define_Version.h" +#endif +#ifdef AE_OS_MAC +#include "PopcornFX_Define_Version.h" +#endif + +resource 'PiPL' (16000) { + { /* array properties: 12 elements */ + /* [1] */ + Kind { + AEEffect + }, + /* [2] */ + Name { + "Attribute Sampler" + }, + /* [3] */ + Category { + "PopcornFX" + }, +#ifdef AE_OS_WIN + #ifdef AE_PROC_INTELx64 + CodeWin64X86 {"EffectMain"}, + #endif +#else + #ifdef AE_OS_MAC + CodeMacIntel64 {"EffectMain"}, + #endif +#endif + /* [6] */ + AE_PiPL_Version { + 2, + 0 + }, + /* [7] */ + AE_Effect_Spec_Version { + PF_PLUG_IN_VERSION, + PF_PLUG_IN_SUBVERS + }, + /* [8] */ + AE_Effect_Version { + AEPOPCORNFX_PIPL_VERSION + }, + /* [9] */ + AE_Effect_Info_Flags { + 0 + }, + /* [10] */ + AE_Effect_Global_OutFlags { + 0x06200000 + }, + AE_Effect_Global_OutFlags_2 { + 0x08001403 + }, + /* [11] */ + AE_Effect_Match_Name { + "ADBE PopcornFX Sampler" + }, + /* [12] */ + AE_Reserved_Info { + 8 + } + } +}; + diff --git a/AE_Effect_Emitter/Include/AEEffect_Main.h b/AE_Effect_Emitter/Include/AEEffect_Main.h new file mode 100644 index 00000000..dac2331a --- /dev/null +++ b/AE_Effect_Emitter/Include/AEEffect_Main.h @@ -0,0 +1,39 @@ +//---------------------------------------------------------------------------- +// Copyright Persistant Studios, SARL. All Rights Reserved. https://www.popcornfx.com/terms-and-conditions/ +//---------------------------------------------------------------------------- +#pragma once + +#ifndef __FX_AEEFFECT_MAIN_H__ +#define __FX_AEEFFECT_MAIN_H__ + +#include + +#ifdef AE_OS_WIN + typedef unsigned short PixelType; + #include +#endif + +#include +#include + +#include "PopcornFX_Define.h" + +//---------------------------------------------------------------------------- + +extern "C" { + DllExport + PF_Err + EffectMain( + PF_Cmd cmd, + PF_InData *in_data, + PF_OutData *out_data, + PF_ParamDef *params[], + PF_LayerDef *output, + void *extra); + +} + +//---------------------------------------------------------------------------- + +#endif + diff --git a/AE_Effect_Emitter/Include/AEEffect_ParamDefine.h b/AE_Effect_Emitter/Include/AEEffect_ParamDefine.h new file mode 100644 index 00000000..86ab0a90 --- /dev/null +++ b/AE_Effect_Emitter/Include/AEEffect_ParamDefine.h @@ -0,0 +1,149 @@ +//---------------------------------------------------------------------------- +// Copyright Persistant Studios, SARL. All Rights Reserved. https://www.popcornfx.com/terms-and-conditions/ +//---------------------------------------------------------------------------- +#pragma once + +#include +#include + +__AAEPK_BEGIN + +//---------------------------------------------------------------------------- + +enum EStrIDType +{ + StrID_None_Param_Name, + StrID_Name_Param_Name, + StrID_Description_Param_Name, + + StrID_Generic_Infernal_Autorender_Param_Name, + + StrID_Parameters_Path, + StrID_Parameters_Path_Button, + + StrID_Parameters_Path_Reimport, + StrID_Parameters_Path_Reimport_Button, + + StrID_Generic_Infernal_Effect_Path_Hash, + + StrID_Topic_Transform_Start, + StrID_Parameters_Position, + StrID_Parameters_Rotation_X, + StrID_Parameters_Rotation_Y, + StrID_Parameters_Rotation_Z, + + StrID_Parameters_Seed, + + StrID_Topic_Rendering_Start, + + StrID_Parameters_Render_Background_Toggle, + StrID_Parameters_Render_Background_Opacity, + + StrID_Parameters_Render_Type, + StrID_Parameters_Render_Type_Combobox, + + StrID_Topic_Camera_Start, + StrID_Parameters_Camera, + StrID_Parameters_Camera_Combobox, + StrID_Parameters_Camera_Position, + StrID_Parameters_Camera_Rotation_X, + StrID_Parameters_Camera_Rotation_Y, + StrID_Parameters_Camera_Rotation_Z, + StrID_Parameters_Camera_FOV, + StrID_Parameters_Camera_Near, + StrID_Parameters_Camera_Far, + + StrID_Parameters_Receive_Light, + + StrID_Topic_PostFX_Start, + + StrID_Topic_Distortion_Start, + StrID_Parameters_Distortion_Enable, + + StrID_Topic_Bloom_Start, + StrID_Parameters_Bloom_Enable, + StrID_Parameters_Bloom_BrightPassValue, + StrID_Parameters_Bloom_Intensity, + StrID_Parameters_Bloom_Attenuation, + StrID_Parameters_Bloom_GaussianBlur, + StrID_Parameters_Bloom_GaussianBlur_Combobox, + StrID_Parameters_Bloom_RenderPassCount, + + StrID_Topic_ToneMapping_Start, + StrID_Parameters_ToneMapping_Enable, + StrID_Parameters_ToneMapping_Saturation, + StrID_Parameters_ToneMapping_Exposure, + + StrID_Topic_FXAA_Start, + StrID_Parameters_FXAA_Enable, + + StrID_Topic_BackdropMesh_Start, + + StrID_Parameters_BackdropMesh_Enable_Rendering, + StrID_Parameters_BackdropMesh_Enable_Collisions, + StrID_Parameters_BackdropMesh_Path, + StrID_Parameters_BackdropMesh_Path_Button, + + StrID_Parameters_BackdropMesh_Reset, + StrID_Parameters_BackdropMesh_Reset_Button, + + StrID_Topic_BackdropMesh_Transform_Start, + StrID_Parameters_BackdropMesh_Position, + StrID_Parameters_BackdropMesh_Rotation_X, + StrID_Parameters_BackdropMesh_Rotation_Y, + StrID_Parameters_BackdropMesh_Rotation_Z, + StrID_Parameters_BackdropMesh_Scale_X, + StrID_Parameters_BackdropMesh_Scale_Y, + StrID_Parameters_BackdropMesh_Scale_Z, + StrID_Parameters_BackdropMesh_Roughness, + StrID_Parameters_BackdropMesh_Metalness, + + StrID_Topic_BackdropAudio_Start, + StrID_Parameters_Audio, + + StrID_Topic_BackdropEnvMap_Start, + StrID_Parameters_BackdropEnvMap_Enable_Rendering, + StrID_Parameters_BackdropEnvMap_Path, + StrID_Parameters_BackdropEnvMap_Path_Button, + StrID_Parameters_BackdropEnvMap_Reset, + StrID_Parameters_BackdropEnvMap_Reset_Button, + StrID_Parameters_BackdropEnvMap_Intensity, + StrID_Parameters_BackdropEnvMap_Color, + + StrID_Topic_Light_Start, + StrID_Parameters_Light_Category, + StrID_Parameters_Light_Combobox, + StrID_Parameters_Light_Direction, + StrID_Parameters_Light_Intensity, + StrID_Parameters_Light_Color, + StrID_Parameters_Light_Ambient, + + StrID_Parameters_Scale_Factor, + StrID_Parameters_Refresh_Render, + StrID_Parameters_Render_Seeking_Toggle, + StrID_Parameters_Simulation_State, + + StrID_Parameters_BackdropMesh_Enable_Animation, + + StrID_Parameters_Path_Marketplace, + StrID_Parameters_Path_Marketplace_Button, + + StrID_Parameters_TransformType, + StrID_Parameters_TransformType_Combobox, + + StrID_Parameters_Position_2D, + StrID_Parameters_Position_2D_Distance, + + StrID_Parameters_BringEffectIntoView, + StrID_Parameters_BringEffectIntoView_Button, + + StrID_num_types +}; + +//---------------------------------------------------------------------------- + +char *GetParamsStringPtr(int strNum); + +//---------------------------------------------------------------------------- + +__AAEPK_END diff --git a/AE_Effect_Emitter/Include/AEEffect_PluginInterface.h b/AE_Effect_Emitter/Include/AEEffect_PluginInterface.h new file mode 100644 index 00000000..a8f64e06 --- /dev/null +++ b/AE_Effect_Emitter/Include/AEEffect_PluginInterface.h @@ -0,0 +1,98 @@ +//---------------------------------------------------------------------------- +// Copyright Persistant Studios, SARL. All Rights Reserved. https://www.popcornfx.com/terms-and-conditions/ +//---------------------------------------------------------------------------- +#pragma once + +#ifndef __FX_CPluginInterface_H__ +#define __FX_CPluginInterface_H__ + + +#include "PopcornFX_Define.h" +#include "PopcornFX_Suite.h" +#include "PopcornFX_BasePluginInterface.h" + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +__AAEPK_BEGIN + +//---------------------------------------------------------------------------- + +struct SEmitterDesc; +struct SEffectSequenceDataFlat; +struct SAAEIOData; + +//---------------------------------------------------------------------------- + +class CPluginInterface : public CBasePluginInterface +{ + struct SEffectData + { + //Memory Owned by effect + SEmitterDesc *m_Desc; + int m_LastRenderTime = -1; + + std::mutex m_Lock; + + SEffectData() + : m_Desc(nullptr) + { + + } + }; +public: + virtual ~CPluginInterface(); + static CPluginInterface &Instance(); + + PF_Err About(SAAEIOData &AAEData, PF_ParamDef *params[], PF_LayerDef *output); + PF_Err GlobalSetup(SAAEIOData &AAEData, PF_ParamDef *params[], PF_LayerDef *output); + PF_Err ParamsSetup(SAAEIOData &AAEData, PF_ParamDef *params[], PF_LayerDef *output); + PF_Err GlobalSetdown(SAAEIOData &AAEData, PF_ParamDef *params[], PF_LayerDef *output); + + PF_Err SequenceSetup(SAAEIOData &AAEData, PF_ParamDef *params[], PF_LayerDef *output); + PF_Err SequenceReSetup(SAAEIOData &AAEData, PF_ParamDef *params[], PF_LayerDef *output); + PF_Err SequenceFlatten(SAAEIOData &AAEData, PF_ParamDef *params[], PF_LayerDef *output); + PF_Err SequenceShutdown(SAAEIOData &AAEData, PF_ParamDef *params[], PF_LayerDef *output); + + PF_Err PreRender(SAAEIOData &AAEData); + PF_Err SmartRender(SAAEIOData &AAEData); + + PF_Err ParamValueChanged(SAAEIOData &AAEData, PF_ParamDef *params[]); + PF_Err UpdateParamsUI(SAAEIOData &AAEData, PF_ParamDef *params[]); + PF_Err HandleDataFromAEGP(SAAEIOData &AAEData, PF_ParamDef *params[]); + PF_Err QueryDynamicFlags(SAAEIOData &AAEData, PF_ParamDef *params[]); + + bool GetEffectSequenceUID(SAAEIOData &AAEData, std::string &out); + + +private: + CPluginInterface(); + static CPluginInterface *m_Instance; + static uint32_t m_AttrUID; + + //void _MakeParamCopy(PF_ParamDef *actual[], PF_ParamDef copy[]); + bool _RegisterEffectInstancePlugin(SAAEIOData &AAEData, PF_ParamDef *params[], SEffectSequenceDataFlat *sequenceData); + bool _UnRegisterEffectInstancePlugin(SAAEIOData &AAEData, PF_ParamDef *params[], SEffectSequenceDataFlat *sequenceData); + + //PF_Err _UpdateEmitterName(SAAEIOData &AAEData, SEmitterDesc* desc); + //PF_Err _UpdateBackdropMeshPath(SAAEIOData &AAEData, SEmitterDesc* desc); + + std::unordered_map m_EffectData; + std::vector m_QueuedEffectData; + +}; + +//---------------------------------------------------------------------------- + +__AAEPK_END + +#endif diff --git a/AE_Effect_Emitter/Include/AEEffect_SequenceData.h b/AE_Effect_Emitter/Include/AEEffect_SequenceData.h new file mode 100644 index 00000000..7867a5be --- /dev/null +++ b/AE_Effect_Emitter/Include/AEEffect_SequenceData.h @@ -0,0 +1,65 @@ +//---------------------------------------------------------------------------- +// Copyright Persistant Studios, SARL. All Rights Reserved. https://www.popcornfx.com/terms-and-conditions/ +//---------------------------------------------------------------------------- +#pragma once + +#ifndef __AAEFFECT_SEQUENCEDATA_H__ +#define __AAEFFECT_SEQUENCEDATA_H__ + +#include +#include +#include + +__AAEPK_BEGIN + +//---------------------------------------------------------------------------- + +namespace SequenceCST +{ + static const size_t MAX_PATH_LEN = 1024; + static const size_t MAX_NAME_LEN = 100; + static const size_t UUID_LEN = 32; +} + +//---------------------------------------------------------------------------- + +struct SEffectSequenceDataFlat +{ + //Set is useless, as we do not create directly the struct. Just a friendly reminder. + bool m_IsFlat = true; + + char m_EffectUUID[SequenceCST::UUID_LEN]; + + char m_EffectName[SequenceCST::MAX_NAME_LEN]; + size_t m_EffectNameLen; + + char m_EffectPath[SequenceCST::MAX_PATH_LEN]; + size_t m_EffectPathLen; + + char m_EffectPathSource[SequenceCST::MAX_PATH_LEN]; + size_t m_EffectPathSourceLen; + + char m_EffectBackdropMeshPath[SequenceCST::MAX_PATH_LEN]; + size_t m_EffectBackdropMeshPathLen; + + char m_EffectEnvironmentMapPath[SequenceCST::MAX_PATH_LEN]; + size_t m_EffectEnvironmentMapPathLen; + + A_long m_LayerID; + + bool SetEffectName(const char *name); + bool SetEffectPathSource(const char *name); + bool SetEffectBackdropMeshPath(const char *name); + bool SetEffectEnvironmentMapPath(const char *name); + bool SetUUID(const std::string &uuid); + bool SetUUID(const char *uuid); + void SetLayerID(A_long id); + bool CopyFrom(SEffectSequenceDataFlat *src); +}; + +//---------------------------------------------------------------------------- + +__AAEPK_END + +#endif // !__AAEFFECT_SEQUENCEDATA_H__ + diff --git a/AE_Effect_Emitter/PkgInfo b/AE_Effect_Emitter/PkgInfo new file mode 100644 index 00000000..31cf1f41 --- /dev/null +++ b/AE_Effect_Emitter/PkgInfo @@ -0,0 +1 @@ +eFKTFXTC \ No newline at end of file diff --git a/AE_Effect_Emitter/Precompiled/ae_precompiled.cpp b/AE_Effect_Emitter/Precompiled/ae_precompiled.cpp new file mode 100644 index 00000000..84e52276 --- /dev/null +++ b/AE_Effect_Emitter/Precompiled/ae_precompiled.cpp @@ -0,0 +1 @@ +#include "ae_precompiled.h" diff --git a/AE_Effect_Emitter/Precompiled/ae_precompiled.h b/AE_Effect_Emitter/Precompiled/ae_precompiled.h new file mode 100644 index 00000000..ee643f3d --- /dev/null +++ b/AE_Effect_Emitter/Precompiled/ae_precompiled.h @@ -0,0 +1,8 @@ +#pragma once + +#undef PV_MODULE_NAME +#undef PV_MODULE_SYM +#define PV_MODULE_NAME "AEPlugin" +#define PV_MODULE_SYM AEPlugin + +#include diff --git a/AE_Effect_Emitter/Sources/AEEffect_Main.cpp b/AE_Effect_Emitter/Sources/AEEffect_Main.cpp new file mode 100644 index 00000000..53906ab5 --- /dev/null +++ b/AE_Effect_Emitter/Sources/AEEffect_Main.cpp @@ -0,0 +1,169 @@ +//---------------------------------------------------------------------------- +// Copyright Persistant Studios, SARL. All Rights Reserved. https://www.popcornfx.com/terms-and-conditions/ +//---------------------------------------------------------------------------- +#include "ae_precompiled.h" + +#include "AEEffect_Main.h" + +#include "PopcornFX_Suite.h" +#include "AEEffect_PluginInterface.h" +#include "PopcornFX_Define.h" + +#include + +//---------------------------------------------------------------------------- + +extern "C" +{ + DllExport PF_Err PluginDataEntryFunction( PF_PluginDataPtr inPtr, + PF_PluginDataCB inPluginDataCallBackPtr, + SPBasicSuite *inSPBasicSuitePtr, + const char *inHostName, + const char *inHostVersion) + { + (void)inSPBasicSuitePtr; + (void)inHostName; + (void)inHostVersion; + + PF_Err result = PF_Err_INVALID_CALLBACK; + + result = PF_REGISTER_EFFECT( + inPtr, // Infos must match the PopcornFXPiPL.r + inPluginDataCallBackPtr, // + "Emitter", // Name + "ADBE PopcornFX Emitter", // Match Name + "PopcornFX", // Category + AE_RESERVED_INFO); // Reserved Info + return result; + } +} + +//---------------------------------------------------------------------------- + +PF_Err EffectMain( PF_Cmd cmd, + PF_InData *in_data, + PF_OutData *out_data, + PF_ParamDef *params[], + PF_LayerDef *output, + void *extra) +{ + PF_Err result = PF_Err_NONE; + AAePk::CPluginInterface &AEPlugin = AAePk::CPluginInterface::Instance(); + AAePk::SAAEIOData AAEData{ cmd, in_data, out_data, extra, AEPlugin.GetParametersIndexes() }; + + assert(in_data != nullptr); + assert(out_data != nullptr); + +#if _DEBUG + try + { +#endif + + if (AAEData.m_InData->appl_id == 'PrMr') + { + //User Tried to load plugin in Premiere Pro. + //There is surely a better way to handle this. + return PF_Err_UNRECOGNIZED_PARAM_TYPE; + } + + switch (cmd) + { + // Called once + case PF_Cmd_ABOUT: + //Mandatory + //Version and General Infos about the plugin + result = AEPlugin.About(AAEData, params, output); + break; + case PF_Cmd_GLOBAL_SETUP: + //Mandatory + //Startup run + result = AEPlugin.GlobalSetup(AAEData, params, output); + break; + case PF_Cmd_PARAMS_SETUP: + //Mandatory + //Setup AAE UI. + result = AEPlugin.ParamsSetup(AAEData, params, output); + break; + case PF_Cmd_GLOBAL_SETDOWN: + //Mandatory + result = AEPlugin.GlobalSetdown(AAEData, params, output); + break; + // Sequence Handling + //UI thread + case PF_Cmd_SEQUENCE_SETUP: + //Each time the user adds the effect to a layer + result = AEPlugin.SequenceSetup(AAEData, params, output); + break; + case PF_Cmd_SEQUENCE_RESETUP: + //Load or Duplicate + result = AEPlugin.SequenceReSetup(AAEData, params, output); + break; + //UI thread + case PF_Cmd_SEQUENCE_FLATTEN: + //Effect Saved, copied, duplicated.. + result = AEPlugin.SequenceFlatten(AAEData, params, output); + break; + case PF_Cmd_SEQUENCE_SETDOWN: + //Effect Deleted + result = AEPlugin.SequenceShutdown(AAEData, params, output); + break; + case PF_Cmd_GET_FLATTENED_SEQUENCE_DATA: + break; + // Audio + case PF_Cmd_AUDIO_SETUP: + case PF_Cmd_AUDIO_RENDER: + case PF_Cmd_AUDIO_SETDOWN: + break; + case PF_Cmd_SMART_PRE_RENDER: + //Can be called several times for one render + result = AEPlugin.PreRender(AAEData); + break; + case PF_Cmd_SMART_RENDER: + result = AEPlugin.SmartRender(AAEData); + break; + case PF_Cmd_FRAME_SETDOWN: + //Allow resizing of drawing area + break; + // Messaging + case PF_Cmd_EVENT: + break; + case PF_Cmd_USER_CHANGED_PARAM: + result = AEPlugin.ParamValueChanged(AAEData, params); + break; + //UI thread + //If PF_ParamFlag_SUPERVIZE if set when adding param, PF_Cmd_USER_CHANGED_PARAM is called when value change + case PF_Cmd_UPDATE_PARAMS_UI: + result = AEPlugin.UpdateParamsUI(AAEData, params); + break; + case PF_Cmd_ARBITRARY_CALLBACK: + case PF_Cmd_GET_EXTERNAL_DEPENDENCIES: + break; + case PF_Cmd_COMPLETELY_GENERAL: + result = AEPlugin.HandleDataFromAEGP(AAEData, params); + break; + case PF_Cmd_DO_DIALOG: + //UI thread + //Send when user click on Options + //Received if PF_OutFlag_I_DO_DIALOG is set in PF_Cmd_GLOBAL_SETUP + break; + case PF_Cmd_QUERY_DYNAMIC_FLAGS: + result = AEPlugin.QueryDynamicFlags(AAEData, params); + break; + default: + break; + } + +#if _DEBUG + } + catch (...) + { + assert(false); + } +#endif + if (AAEData.m_ReturnCode != PF_Err_NONE) + return AAEData.m_ReturnCode; + return result; +} + +//---------------------------------------------------------------------------- + diff --git a/AE_Effect_Emitter/Sources/AEEffect_ParamDefine.cpp b/AE_Effect_Emitter/Sources/AEEffect_ParamDefine.cpp new file mode 100644 index 00000000..77a65ab4 --- /dev/null +++ b/AE_Effect_Emitter/Sources/AEEffect_ParamDefine.cpp @@ -0,0 +1,155 @@ +//---------------------------------------------------------------------------- +// Copyright Persistant Studios, SARL. All Rights Reserved. https://www.popcornfx.com/terms-and-conditions/ +//---------------------------------------------------------------------------- +#include "ae_precompiled.h" + +#include "AEEffect_ParamDefine.h" + +__AAEPK_BEGIN + +//---------------------------------------------------------------------------- + +struct STableString +{ + A_u_long index; + A_char str[256]; +}; + +//---------------------------------------------------------------------------- + +STableString g_strs_params[StrID_num_types] = +{ + { StrID_None_Param_Name, "" }, + { StrID_Name_Param_Name, "Emitter" }, + { StrID_Description_Param_Name, "PopcornFX Emitter plugin" }, + + { StrID_Generic_Infernal_Autorender_Param_Name, "Internal Autorender" }, + + { StrID_Parameters_Path, "" }, + { StrID_Parameters_Path_Button, "Browse local files" }, + + { StrID_Parameters_Path_Reimport, "" }, + { StrID_Parameters_Path_Reimport_Button, "Reimport" }, + + { StrID_Generic_Infernal_Effect_Path_Hash, "Internal - Param Path Hash" }, + + { StrID_Topic_Transform_Start, "Transform" }, + { StrID_Parameters_Position, "Position" }, + { StrID_Parameters_Rotation_X, "Rotation X" }, + { StrID_Parameters_Rotation_Y, "Rotation Y" }, + { StrID_Parameters_Rotation_Z, "Rotation Z" }, + + { StrID_Parameters_Seed, "Seed" }, + + { StrID_Topic_Rendering_Start, "Rendering" }, + + { StrID_Parameters_Render_Background_Toggle, "Override background opacity" }, + { StrID_Parameters_Render_Background_Opacity, "Background opacity" }, + { StrID_Parameters_Render_Type, "Render Output" }, + { StrID_Parameters_Render_Type_Combobox, "Final|Emissive(Not impld)|Albedo(Not impld)|Normal|Depth" }, + + { StrID_Topic_Camera_Start, "Camera Options" }, + { StrID_Parameters_Camera, "Camera" }, + { StrID_Parameters_Camera_Combobox, "Default Composition|Custom Composition(Not impld)" }, + { StrID_Parameters_Camera_Position, "Position" }, + { StrID_Parameters_Camera_Rotation_X, "Rotation X" }, + { StrID_Parameters_Camera_Rotation_Y, "Rotation Y" }, + { StrID_Parameters_Camera_Rotation_Z, "Rotation Z" }, + { StrID_Parameters_Camera_FOV, "FOV" }, + { StrID_Parameters_Camera_Near, "Near" }, + { StrID_Parameters_Camera_Far, "Far" }, + + { StrID_Parameters_Receive_Light, "Receive Light(Not impld)" }, + + { StrID_Topic_PostFX_Start, "Post Effects" }, + + { StrID_Topic_Distortion_Start, "Distortion" }, + { StrID_Parameters_Distortion_Enable, "Enable" }, + + { StrID_Topic_Bloom_Start, "Bloom" }, + { StrID_Parameters_Bloom_Enable, "Enable" }, + { StrID_Parameters_Bloom_BrightPassValue, "Bright Pass Value" }, + { StrID_Parameters_Bloom_Intensity, "Intensity" }, + { StrID_Parameters_Bloom_Attenuation, "Attenuation" }, + { StrID_Parameters_Bloom_GaussianBlur, "Blur Pixel Radius" }, + { StrID_Parameters_Bloom_GaussianBlur_Combobox, "5|9|13" }, + { StrID_Parameters_Bloom_RenderPassCount, "Render Pass Count" }, + + { StrID_Topic_ToneMapping_Start, "Tone Mapping" }, + { StrID_Parameters_ToneMapping_Enable, "Enable" }, + { StrID_Parameters_ToneMapping_Saturation, "Saturation" }, + { StrID_Parameters_ToneMapping_Exposure, "Exposure" }, + + { StrID_Topic_FXAA_Start, "FXAA" }, + { StrID_Parameters_FXAA_Enable, "Enable" }, + + { StrID_Topic_BackdropMesh_Start, "Backdrop Mesh" }, + + { StrID_Parameters_BackdropMesh_Enable_Rendering, "Enable Rendering" }, + { StrID_Parameters_BackdropMesh_Enable_Collisions, "Enable Collisions" }, + { StrID_Parameters_BackdropMesh_Path, "Mesh Path" }, + { StrID_Parameters_BackdropMesh_Path_Button, "Browse" }, + { StrID_Parameters_BackdropMesh_Reset, "" }, + { StrID_Parameters_BackdropMesh_Reset_Button, "Reset" }, + + { StrID_Topic_BackdropMesh_Transform_Start, "Transform" }, + { StrID_Parameters_BackdropMesh_Position, "Position" }, + { StrID_Parameters_BackdropMesh_Rotation_X, "Rotation X" }, + { StrID_Parameters_BackdropMesh_Rotation_Y, "Rotation Y" }, + { StrID_Parameters_BackdropMesh_Rotation_Z, "Rotation Z" }, + { StrID_Parameters_BackdropMesh_Scale_X, "Scale X" }, + { StrID_Parameters_BackdropMesh_Scale_Y, "Scale Y" }, + { StrID_Parameters_BackdropMesh_Scale_Z, "Scale Z" }, + { StrID_Parameters_BackdropMesh_Roughness, "Roughness" }, + { StrID_Parameters_BackdropMesh_Metalness, "Metalness" }, + + { StrID_Topic_BackdropAudio_Start, "Backdrop Audio" }, + { StrID_Parameters_Audio, "Audio Layer" }, + + { StrID_Topic_BackdropEnvMap_Start, "Environment Map" }, + { StrID_Parameters_BackdropEnvMap_Enable_Rendering, "Enable Rendering" }, + { StrID_Parameters_BackdropEnvMap_Path, "Map Path" }, + { StrID_Parameters_BackdropEnvMap_Path_Button, "Browse" }, + { StrID_Parameters_BackdropEnvMap_Reset, "" }, + { StrID_Parameters_BackdropEnvMap_Reset_Button, "Reset" }, + { StrID_Parameters_BackdropEnvMap_Intensity, "Intensity" }, + { StrID_Parameters_BackdropEnvMap_Color, "Color" }, + + { StrID_Topic_Light_Start, "Light" }, + { StrID_Parameters_Light_Category, "Category" }, + { StrID_Parameters_Light_Combobox, "Internal|All in Composition" }, + { StrID_Parameters_Light_Direction, "Direction" }, + { StrID_Parameters_Light_Intensity, "Intensity" }, + { StrID_Parameters_Light_Color, "Color" }, + { StrID_Parameters_Light_Ambient, "Ambient" }, + + { StrID_Parameters_Scale_Factor, "Effect Scale Up Factor" }, + { StrID_Parameters_Refresh_Render, "Internal" }, + { StrID_Parameters_Render_Seeking_Toggle, "Seeking Simulation" }, + { StrID_Parameters_Simulation_State, "Simulation state" }, + + { StrID_Parameters_BackdropMesh_Enable_Animation, "Enable Animations" }, + + { StrID_Parameters_Path_Marketplace, "Emitter Effect" }, + { StrID_Parameters_Path_Marketplace_Button, "Browse Marketplace" }, + + { StrID_Parameters_TransformType, "Transform Type" }, + { StrID_Parameters_TransformType_Combobox, "3D|2D" }, + + { StrID_Parameters_Position_2D, "Position" }, + { StrID_Parameters_Position_2D_Distance, "Distance To camera" }, + + { StrID_Parameters_BringEffectIntoView, "" }, + { StrID_Parameters_BringEffectIntoView_Button, "Bring Effect to view" }, +}; + +//---------------------------------------------------------------------------- + +A_char *GetParamsStringPtr(int strNum) +{ + return AAePk::g_strs_params[strNum].str; +} + +//---------------------------------------------------------------------------- + +__AAEPK_END diff --git a/AE_Effect_Emitter/Sources/AEEffect_PluginInterface.cpp b/AE_Effect_Emitter/Sources/AEEffect_PluginInterface.cpp new file mode 100644 index 00000000..ee91d280 --- /dev/null +++ b/AE_Effect_Emitter/Sources/AEEffect_PluginInterface.cpp @@ -0,0 +1,1304 @@ +//---------------------------------------------------------------------------- +// Copyright Persistant Studios, SARL. All Rights Reserved. https://www.popcornfx.com/terms-and-conditions/ +//---------------------------------------------------------------------------- +#include "ae_precompiled.h" + +#include "AEEffect_PluginInterface.h" +#include "AEEffect_ParamDefine.h" +#include "AEEffect_SequenceData.h" + +//AE +#include +#include +#include +#include +#include +#include +#include +#include +#include + +//AAE Plugin code +#include "PopcornFX_Suite.h" +#include "PopcornFX_UID.h" + +#include +#include + +__AAEPK_BEGIN + +//---------------------------------------------------------------------------- + +int SEmitterDesc::s_ID = 0; + +CPluginInterface *CPluginInterface::m_Instance = nullptr; +uint32_t CPluginInterface::m_AttrUID = 1; + +//---------------------------------------------------------------------------- + +CPluginInterface::CPluginInterface() +{ +} + +//---------------------------------------------------------------------------- + +CPluginInterface::~CPluginInterface() +{ +} + +//---------------------------------------------------------------------------- + +CPluginInterface &CPluginInterface::Instance() +{ + if (CPluginInterface::m_Instance == nullptr) + { + m_Instance = new CPluginInterface(); + } + return *m_Instance; +} + +//---------------------------------------------------------------------------- + +PF_Err CPluginInterface::About( SAAEIOData &AAEData, + PF_ParamDef *params[], + PF_LayerDef *output) +{ + (void)output; + (void)params; + + AEGP_SuiteHandler suites(AAEData.m_InData->pica_basicP); + suites.ANSICallbacksSuite1()->sprintf(AAEData.m_OutData->return_msg, + "%s v%d.%d.%d\r%s", + GetParamsStringPtr(StrID_Name_Param_Name), + AEPOPCORNFX_MAJOR_VERSION, + AEPOPCORNFX_MINOR_VERSION, + AEPOPCORNFX_BUG_VERSION, + GetParamsStringPtr(StrID_Description_Param_Name)); + return PF_Err_NONE; +} + +//---------------------------------------------------------------------------- + +PF_Err CPluginInterface::GlobalSetup( SAAEIOData &AAEData, + PF_ParamDef *params[], + PF_LayerDef *output) +{ + (void)output; + (void)params; + + AEFX_SuiteScoper PopcornFXSuite = AEFX_SuiteScoper( AAEData.m_InData, + kPopcornFXSuite1, + kPopcornFXSuiteVersion1, + AAEData.m_OutData, + "PopcornFX suite was not found."); + + AAEData.m_OutData->my_version = PF_VERSION(AEPOPCORNFX_MAJOR_VERSION, AEPOPCORNFX_MINOR_VERSION, AEPOPCORNFX_BUG_VERSION, AEPOPCORNFX_STAGE_VERSION, AEPOPCORNFX_BUILD_VERSION); + + //PF_OutFlag_DEEP_COLOR_AWARE -> To support 16bit per chan format. + //PF_OutFlag_SEND_UPDATE_PARAMS_UI -> To be notified when PF_ParamFlag_SUPERVISE is set on parameters + AAEData.m_OutData->out_flags = PF_OutFlag_DEEP_COLOR_AWARE | + PF_OutFlag_SEND_UPDATE_PARAMS_UI | + PF_OutFlag_I_USE_SHUTTER_ANGLE; + //PF_OutFlag2_SUPPORTS_QUERY_DYNAMIC_FLAGS -> To be able to change dynamicly some out_flags. see doc. + //PF_OutFlag2_FLOAT_COLOR_AWARE -> To support 32bit per chan format. Need PF_OutFlag2_SUPPORTS_SMART_RENDER + //PF_OutFlag2_SUPPORTS_SMART_RENDER -> Necessary for new render pipeline. + //PF_OutFlag2_I_USE_3D_CAMERA -> Can query 3D camera information, Not sure if necessery in Attribute or just on Effect. + //PF_OutFlag2_I_USE_3D_LIGHTS -> Can query 3D LIGHT information, Not sure if necessery in Attribute or just on Effect. + AAEData.m_OutData->out_flags2 = PF_OutFlag2_SUPPORTS_QUERY_DYNAMIC_FLAGS | + PF_OutFlag2_FLOAT_COLOR_AWARE | + PF_OutFlag2_SUPPORTS_SMART_RENDER | + PF_OutFlag2_I_USE_3D_CAMERA | + PF_OutFlag2_I_USE_3D_LIGHTS | + PF_OutFlag2_SUPPORTS_THREADED_RENDERING; + + AEGP_SuiteHandler suites(AAEData.m_InData->pica_basicP); + suites.UtilitySuite3()->AEGP_RegisterWithAEGP(nullptr, GetParamsStringPtr(StrID_Name_Param_Name), &m_AAEID); + + return PopcornFXSuite->InitializePopcornFXIFN(AAEData); +} + +//---------------------------------------------------------------------------- + +PF_Err CPluginInterface::ParamsSetup( SAAEIOData &AAEData, + PF_ParamDef *params[], + PF_LayerDef *output) +{ + (void)output; + (void)params; + + + AEFX_SuiteScoper popcornFXSuite = AEFX_SuiteScoper( AAEData.m_InData, + kPopcornFXSuite1, + kPopcornFXSuiteVersion1, + AAEData.m_OutData, + "PopcornFX suite was not found."); + + PF_Err result = PF_Err_NONE; + PF_InData *in_data = AAEData.m_InData; + PF_ParamDef def; + + const float minFloat = -1000000.0f;//std::numeric_limits::min() crashes AfterFX, smashing his stack to pieces. + const float maxFloat = 1000000.0f;//same as above. + + m_ParametersIndexes = new int[__Effect_Parameters_Count]; + for (unsigned int i = 0; i < __Effect_Parameters_Count; ++i) + m_ParametersIndexes[i] = -1; + m_ParametersIndexes[0] = 0; // First Parameter is reserved to AE + + AddFloatParameterUnbound(in_data, GetParamsStringPtr(StrID_Generic_Infernal_Autorender_Param_Name), Effect_Parameters_Infernal_Autorender, 0.0f, PF_ValueDisplayFlag_NONE, PF_PUI_INVISIBLE); + + AEFX_CLR_STRUCT(def); + PF_ADD_BUTTON(GetParamsStringPtr(StrID_Parameters_Path_Marketplace), GetParamsStringPtr(StrID_Parameters_Path_Marketplace_Button), 0, PF_ParamFlag_SUPERVISE, Effect_Parameters_Path_Marketplace); + m_ParametersIndexes[Effect_Parameters_Path_Marketplace] = ++m_CurrentIndex; + + AEFX_CLR_STRUCT(def); + PF_ADD_BUTTON(GetParamsStringPtr(StrID_Parameters_Path), GetParamsStringPtr(StrID_Parameters_Path_Button), 0, PF_ParamFlag_SUPERVISE, Effect_Parameters_Path); + m_ParametersIndexes[Effect_Parameters_Path] = ++m_CurrentIndex; + + AEFX_CLR_STRUCT(def); + PF_ADD_BUTTON(GetParamsStringPtr(StrID_Parameters_Path_Reimport), GetParamsStringPtr(StrID_Parameters_Path_Reimport_Button), 0, PF_ParamFlag_SUPERVISE, Effect_Parameters_Path_Reimport); + m_ParametersIndexes[Effect_Parameters_Path_Reimport] = ++m_CurrentIndex; + + AddIntParameterUnbound(in_data, GetParamsStringPtr(StrID_Generic_Infernal_Effect_Path_Hash), Effect_Parameters_Infernal_Effect_Path_Hash, 0, PF_ValueDisplayFlag_NONE | PF_ParamFlag_CANNOT_TIME_VARY | PF_ParamFlag_CANNOT_INTERP, PF_PUI_INVISIBLE); + + StartParameterCategory(in_data, GetParamsStringPtr(StrID_Topic_Transform_Start), Effect_Topic_Transform_Start); + { + AEFX_CLR_STRUCT(def); + def.flags = PF_ParamFlag_SUPERVISE | + PF_ParamFlag_CANNOT_TIME_VARY | + PF_ParamFlag_CANNOT_INTERP; + //def.ui_flags = PF_PUI_STD_CONTROL_ONLY; + PF_ADD_POPUP(GetParamsStringPtr(StrID_Parameters_TransformType), + __ETransformType_Count, + ETransformType_3D, + GetParamsStringPtr(StrID_Parameters_TransformType_Combobox), + Effect_Parameters_TransformType); + m_ParametersIndexes[Effect_Parameters_TransformType] = ++m_CurrentIndex; + + AEFX_CLR_STRUCT(def); + def.param_type = PF_Param_POINT_3D; + PF_STRCPY(def.name, (GetParamsStringPtr(StrID_Parameters_Position))); + def.u.point3d_d.x_value = def.u.point3d_d.x_dephault = 50; + def.u.point3d_d.y_value = def.u.point3d_d.y_dephault = 50; + def.u.point3d_d.z_value = def.u.point3d_d.z_dephault = 0; + def.uu.id = (Effect_Parameters_Position); + PF_ADD_PARAM(in_data, -1, &def); + m_ParametersIndexes[Effect_Parameters_Position] = ++m_CurrentIndex; + + AEFX_CLR_STRUCT(def); + def.param_type = PF_Param_POINT; + PF_STRCPY(def.name, (GetParamsStringPtr(StrID_Parameters_Position_2D))); + def.u.td.x_value = def.u.td.x_dephault = 50; + def.u.td.y_value = def.u.td.y_dephault = 50; + def.uu.id = (Effect_Parameters_Position_2D); + PF_ADD_PARAM(in_data, -1, &def); + m_ParametersIndexes[Effect_Parameters_Position_2D] = ++m_CurrentIndex; + + AddFloatParameter(in_data, GetParamsStringPtr(StrID_Parameters_Position_2D_Distance), Effect_Parameters_Position_2D_Distance, 1.0f, -10.f, 500.0f, NULL); + + AddAngleParameter(in_data, GetParamsStringPtr(StrID_Parameters_Rotation_X), Effect_Parameters_Rotation_X, 0.0f); + AddAngleParameter(in_data, GetParamsStringPtr(StrID_Parameters_Rotation_Y), Effect_Parameters_Rotation_Y, 0.0f); + AddAngleParameter(in_data, GetParamsStringPtr(StrID_Parameters_Rotation_Z), Effect_Parameters_Rotation_Z, 0.0f); + + AddFloatParameter(in_data, GetParamsStringPtr(StrID_Parameters_Scale_Factor), Effect_Parameters_Scale_Factor, 1.0f, 0.001f, 10000.0f, PF_ParamFlag_CANNOT_TIME_VARY | PF_ParamFlag_CANNOT_INTERP); + + AEFX_CLR_STRUCT(def); + PF_ADD_BUTTON(GetParamsStringPtr(StrID_Parameters_BringEffectIntoView), GetParamsStringPtr(StrID_Parameters_BringEffectIntoView_Button), 0, PF_ParamFlag_SUPERVISE, Effect_Parameters_BringEffectIntoView); + m_ParametersIndexes[Effect_Parameters_BringEffectIntoView] = ++m_CurrentIndex; + + } + EndParameterCategory(in_data, Effect_Topic_Transform_End); + + AddIntParameterUnbound(in_data, GetParamsStringPtr(StrID_Parameters_Seed), Effect_Parameters_Seed, 0, PF_ParamFlag_CANNOT_TIME_VARY | PF_ParamFlag_CANNOT_INTERP); + + AddCheckBoxParameter(in_data, GetParamsStringPtr(StrID_Parameters_Simulation_State), Effect_Parameters_Simulation_State, true, PF_ParamFlag_SUPERVISE | PF_ParamFlag_CANNOT_INTERP); + + AddCheckBoxParameter(in_data, GetParamsStringPtr(StrID_Parameters_Render_Seeking_Toggle), Effect_Parameters_Seeking_Toggle, true, PF_ParamFlag_SUPERVISE | PF_ParamFlag_CANNOT_TIME_VARY | PF_ParamFlag_CANNOT_INTERP, PF_PUI_INVISIBLE); + + StartParameterCategory(in_data, GetParamsStringPtr(StrID_Topic_Rendering_Start), Effect_Topic_Rendering_Start); + { + AddCheckBoxParameter(in_data, GetParamsStringPtr(StrID_Parameters_Render_Background_Toggle), Effect_Parameters_Background_Toggle); + + AddPercentParameter(in_data, GetParamsStringPtr(StrID_Parameters_Render_Background_Opacity), Effect_Parameters_Background_Opacity, 0); + + AEFX_CLR_STRUCT(def); + def.flags = PF_ParamFlag_SUPERVISE | + PF_ParamFlag_CANNOT_TIME_VARY | + PF_ParamFlag_CANNOT_INTERP; + //def.ui_flags = PF_PUI_STD_CONTROL_ONLY; + PF_ADD_POPUP(GetParamsStringPtr(StrID_Parameters_Render_Type), + __RenderType_Count, + RenderType_FinalCompositing, + GetParamsStringPtr(StrID_Parameters_Render_Type_Combobox), + Effect_Parameters_Render_Type); + m_ParametersIndexes[Effect_Parameters_Render_Type] = ++m_CurrentIndex; + + StartParameterCategory(in_data, GetParamsStringPtr(StrID_Topic_Camera_Start), Effect_Topic_Camera_Start); + { + AEFX_CLR_STRUCT(def); + def.flags = PF_ParamFlag_SUPERVISE | + PF_ParamFlag_CANNOT_TIME_VARY | + PF_ParamFlag_CANNOT_INTERP; + //def.ui_flags = PF_PUI_STD_CONTROL_ONLY; + PF_ADD_POPUP(GetParamsStringPtr(StrID_Parameters_Camera), + __ECameraType_Count, + ECameraType_Compo_Default, + GetParamsStringPtr(StrID_Parameters_Camera_Combobox), + Effect_Parameters_Camera); + m_ParametersIndexes[Effect_Parameters_Camera] = ++m_CurrentIndex; + + AEFX_CLR_STRUCT(def); + def.ui_flags = PF_PUI_INVISIBLE; + def.param_type = PF_Param_POINT_3D; + PF_STRCPY(def.name, (GetParamsStringPtr(StrID_Parameters_Camera_Position))); + def.u.point3d_d.x_value = def.u.point3d_d.x_dephault = 50; + def.u.point3d_d.y_value = def.u.point3d_d.y_dephault = 50; + def.u.point3d_d.z_value = def.u.point3d_d.z_dephault = 1; + def.uu.id = (Effect_Parameters_Camera_Position); + PF_ADD_PARAM(in_data, -1, &def); + m_ParametersIndexes[Effect_Parameters_Camera_Position] = ++m_CurrentIndex; + + AddAngleParameter(in_data, GetParamsStringPtr(StrID_Parameters_Camera_Rotation_X), Effect_Parameters_Camera_Rotation_X, 0, 0, PF_PUI_INVISIBLE); + AddAngleParameter(in_data, GetParamsStringPtr(StrID_Parameters_Camera_Rotation_Y), Effect_Parameters_Camera_Rotation_Y, 0, 0, PF_PUI_INVISIBLE); + AddAngleParameter(in_data, GetParamsStringPtr(StrID_Parameters_Camera_Rotation_Z), Effect_Parameters_Camera_Rotation_Z, 0, 0, PF_PUI_INVISIBLE); + + AddFloatParameter(in_data, GetParamsStringPtr(StrID_Parameters_Camera_FOV), Effect_Parameters_Camera_FOV, 90.0f, 1.0f, 179.0f, 0, PF_PUI_INVISIBLE); + + AddFloatParameter(in_data, GetParamsStringPtr(StrID_Parameters_Camera_Near), Effect_Parameters_Camera_Near, 0.01f, 0.0001f, 1.0f); + AddFloatParameter(in_data, GetParamsStringPtr(StrID_Parameters_Camera_Far), Effect_Parameters_Camera_Far, 1000.0f, 1.0f, 100000.0f); + } + EndParameterCategory(in_data, Effect_Topic_Camera_End); + + AddCheckBoxParameter(in_data, GetParamsStringPtr(StrID_Parameters_Receive_Light), Effect_Parameters_Receive_Light, false, PF_ParamFlag_SUPERVISE | PF_ParamFlag_CANNOT_TIME_VARY | PF_ParamFlag_CANNOT_INTERP, PF_PUI_DISABLED | PF_PUI_INVISIBLE); + + StartParameterCategory(in_data, GetParamsStringPtr(StrID_Topic_PostFX_Start), Effect_Topic_PostFX_Start); + { + + StartParameterCategory(in_data, GetParamsStringPtr(StrID_Topic_Distortion_Start), Effect_Topic_Distortion_Start); + { + AddCheckBoxParameter(in_data, GetParamsStringPtr(StrID_Parameters_Distortion_Enable), Effect_Parameters_Distortion_Enable, true, PF_ParamFlag_SUPERVISE | PF_ParamFlag_CANNOT_TIME_VARY | PF_ParamFlag_CANNOT_INTERP); + } + EndParameterCategory(in_data, Effect_Topic_Distortion_End); + + + StartParameterCategory(in_data, GetParamsStringPtr(StrID_Topic_Bloom_Start), Effect_Topic_Bloom_Start); + { + AddCheckBoxParameter(in_data, GetParamsStringPtr(StrID_Parameters_Bloom_Enable), Effect_Parameters_Bloom_Enable, true, PF_ParamFlag_SUPERVISE | PF_ParamFlag_CANNOT_TIME_VARY | PF_ParamFlag_CANNOT_INTERP); + + AddFloatParameter(in_data, GetParamsStringPtr(StrID_Parameters_Bloom_BrightPassValue), Effect_Parameters_Bloom_BrightPassValue, 1.0f, 0.0f, 20.0f); + AddFloatParameter(in_data, GetParamsStringPtr(StrID_Parameters_Bloom_Intensity), Effect_Parameters_Bloom_Intensity, 0.75f, 0.0f, 20.0f); + AddFloatParameter(in_data, GetParamsStringPtr(StrID_Parameters_Bloom_Attenuation), Effect_Parameters_Bloom_Attenuation, 0.5f, 0.0f, 1.0f); + + AEFX_CLR_STRUCT(def); + def.flags = PF_ParamFlag_SUPERVISE | + PF_ParamFlag_CANNOT_TIME_VARY | + PF_ParamFlag_CANNOT_INTERP; + PF_ADD_POPUP(GetParamsStringPtr(StrID_Parameters_Bloom_GaussianBlur), + __GaussianBlurPixelRadius_Count, + GaussianBlurPixelRadius_5, + GetParamsStringPtr(StrID_Parameters_Bloom_GaussianBlur_Combobox), + Effect_Parameters_Bloom_GaussianBlur); + m_ParametersIndexes[Effect_Parameters_Bloom_GaussianBlur] = ++m_CurrentIndex; + + AddIntParameter(in_data, GetParamsStringPtr(StrID_Parameters_Bloom_RenderPassCount), Effect_Parameters_Bloom_RenderPassCount, 6, 0, 13, PF_ParamFlag_CANNOT_TIME_VARY | PF_ParamFlag_CANNOT_INTERP); + } + EndParameterCategory(in_data, Effect_Topic_Bloom_End); + + StartParameterCategory(in_data, GetParamsStringPtr(StrID_Topic_ToneMapping_Start), Effect_Topic_ToneMapping_Start); + { + AddCheckBoxParameter(in_data, GetParamsStringPtr(StrID_Parameters_ToneMapping_Enable), Effect_Parameters_ToneMapping_Enable, true, PF_ParamFlag_SUPERVISE | PF_ParamFlag_CANNOT_TIME_VARY | PF_ParamFlag_CANNOT_INTERP); + + AddFloatParameter(in_data, GetParamsStringPtr(StrID_Parameters_ToneMapping_Saturation), Effect_Parameters_ToneMapping_Saturation, 1.0f, 0.0f, 2.0f); + AddFloatParameter(in_data, GetParamsStringPtr(StrID_Parameters_ToneMapping_Exposure), Effect_Parameters_ToneMapping_Exposure, 0.0f, -5.0f, 5.0f); + } + EndParameterCategory(in_data, Effect_Topic_ToneMapping_End); + + StartParameterCategory(in_data, GetParamsStringPtr(StrID_Topic_FXAA_Start), Effect_Topic_FXAA_Start); + { + AddCheckBoxParameter(in_data, GetParamsStringPtr(StrID_Parameters_FXAA_Enable), Effect_Parameters_FXAA_Enable, true, PF_ParamFlag_SUPERVISE | PF_ParamFlag_CANNOT_TIME_VARY | PF_ParamFlag_CANNOT_INTERP); + } + EndParameterCategory(in_data, Effect_Topic_FXAA_End); + } + EndParameterCategory(in_data, Effect_Topic_PostFX_End); + } + EndParameterCategory(in_data, Effect_Topic_Rendering_End); + + StartParameterCategory(in_data, GetParamsStringPtr(StrID_Topic_BackdropMesh_Start), Effect_Topic_BackdropMesh_Start); + { + AddCheckBoxParameter(in_data, GetParamsStringPtr(StrID_Parameters_BackdropMesh_Enable_Rendering), Effect_Parameters_BackdropMesh_Enable_Rendering, true, PF_ParamFlag_SUPERVISE | PF_ParamFlag_CANNOT_TIME_VARY | PF_ParamFlag_CANNOT_INTERP); + AddCheckBoxParameter(in_data, GetParamsStringPtr(StrID_Parameters_BackdropMesh_Enable_Collisions), Effect_Parameters_BackdropMesh_Enable_Collisions, true, PF_ParamFlag_SUPERVISE | PF_ParamFlag_CANNOT_TIME_VARY | PF_ParamFlag_CANNOT_INTERP); + AddCheckBoxParameter(in_data, GetParamsStringPtr(StrID_Parameters_BackdropMesh_Enable_Animation), Effect_Parameters_BackdropMesh_Enable_Animation, true, PF_ParamFlag_SUPERVISE | PF_ParamFlag_CANNOT_TIME_VARY | PF_ParamFlag_CANNOT_INTERP); + + AEFX_CLR_STRUCT(def); + PF_ADD_BUTTON(GetParamsStringPtr(StrID_Parameters_BackdropMesh_Path), GetParamsStringPtr(StrID_Parameters_BackdropMesh_Path_Button), 0, PF_ParamFlag_SUPERVISE, Effect_Parameters_BackdropMesh_Path); + m_ParametersIndexes[Effect_Parameters_BackdropMesh_Path] = ++m_CurrentIndex; + + AEFX_CLR_STRUCT(def); + PF_ADD_BUTTON(GetParamsStringPtr(StrID_Parameters_BackdropMesh_Reset), GetParamsStringPtr(StrID_Parameters_BackdropMesh_Reset_Button), 0, PF_ParamFlag_SUPERVISE, Effect_Parameters_BackdropMesh_Reset); + m_ParametersIndexes[Effect_Parameters_BackdropMesh_Reset] = ++m_CurrentIndex; + + StartParameterCategory(in_data, GetParamsStringPtr(StrID_Topic_BackdropMesh_Transform_Start), Effect_Topic_BackdropMesh_Transform_Start); + { + AEFX_CLR_STRUCT(def); + PF_ADD_POINT_3D(GetParamsStringPtr(StrID_Parameters_BackdropMesh_Position), 0, 0, 0, Effect_Parameters_BackdropMesh_Position); + m_ParametersIndexes[Effect_Parameters_BackdropMesh_Position] = ++m_CurrentIndex; + + AddAngleParameter(in_data, GetParamsStringPtr(StrID_Parameters_BackdropMesh_Rotation_X), Effect_Parameters_BackdropMesh_Rotation_X, 0); + AddAngleParameter(in_data, GetParamsStringPtr(StrID_Parameters_BackdropMesh_Rotation_Y), Effect_Parameters_BackdropMesh_Rotation_Y, 0); + AddAngleParameter(in_data, GetParamsStringPtr(StrID_Parameters_BackdropMesh_Rotation_Z), Effect_Parameters_BackdropMesh_Rotation_Z, 0); + + AddFloatParameterUnbound(in_data, GetParamsStringPtr(StrID_Parameters_BackdropMesh_Scale_X), Effect_Parameters_BackdropMesh_Scale_X, 1.0f); + AddFloatParameterUnbound(in_data, GetParamsStringPtr(StrID_Parameters_BackdropMesh_Scale_Y), Effect_Parameters_BackdropMesh_Scale_Y, 1.0f); + AddFloatParameterUnbound(in_data, GetParamsStringPtr(StrID_Parameters_BackdropMesh_Scale_Z), Effect_Parameters_BackdropMesh_Scale_Z, 1.0f); + } + EndParameterCategory(in_data, Effect_Topic_BackdropMesh_Transform_End); + + AddFloatParameter(in_data, GetParamsStringPtr(StrID_Parameters_BackdropMesh_Roughness), Effect_Parameters_BackdropMesh_Roughness, 1.0f, 0.0f, 1.0f); + AddFloatParameter(in_data, GetParamsStringPtr(StrID_Parameters_BackdropMesh_Metalness), Effect_Parameters_BackdropMesh_Metalness, 0.0f, 0.0f, 1.0f); + } + EndParameterCategory(in_data, Effect_Topic_BackdropMesh_End); + + StartParameterCategory(in_data, GetParamsStringPtr(StrID_Topic_BackdropAudio_Start), Effect_Topic_BackdropAudio_Start); + { + AEFX_CLR_STRUCT(def); + def.flags = PF_ParamFlag_SUPERVISE; + PF_ADD_LAYER(GetParamsStringPtr(StrID_Parameters_Audio), PF_LayerDefault_NONE, Effect_Parameters_Audio); + m_ParametersIndexes[Effect_Parameters_Audio] = ++m_CurrentIndex; + } + EndParameterCategory(in_data, Effect_Topic_BackdropAudio_End); + + StartParameterCategory(in_data, GetParamsStringPtr(StrID_Topic_BackdropEnvMap_Start), Effect_Topic_BackdropEnvMap_Start); + { + AddCheckBoxParameter(in_data, GetParamsStringPtr(StrID_Parameters_BackdropEnvMap_Enable_Rendering), Effect_Parameters_BackdropEnvMap_Enable_Rendering); + + PF_ADD_BUTTON(GetParamsStringPtr(StrID_Parameters_BackdropEnvMap_Path), GetParamsStringPtr(StrID_Parameters_BackdropEnvMap_Path_Button), 0, PF_ParamFlag_SUPERVISE, Effect_Parameters_BackdropEnvMap_Path); + m_ParametersIndexes[Effect_Parameters_BackdropEnvMap_Path] = ++m_CurrentIndex; + + AEFX_CLR_STRUCT(def); + PF_ADD_BUTTON(GetParamsStringPtr(StrID_Parameters_BackdropEnvMap_Reset), GetParamsStringPtr(StrID_Parameters_BackdropEnvMap_Reset_Button), 0, PF_ParamFlag_SUPERVISE, Effect_Parameters_BackdropEnvMap_Reset); + m_ParametersIndexes[Effect_Parameters_BackdropEnvMap_Reset] = ++m_CurrentIndex; + + AddFloatParameter(in_data, GetParamsStringPtr(StrID_Parameters_BackdropEnvMap_Intensity), Effect_Parameters_BackdropEnvMap_Intensity, 1.0f, 0.0f, 10.0f); + + AEFX_CLR_STRUCT(def); + PF_ADD_COLOR(GetParamsStringPtr(StrID_Parameters_BackdropEnvMap_Color), 51, 51, 51, Effect_Parameters_BackdropEnvMap_Color); + m_ParametersIndexes[Effect_Parameters_BackdropEnvMap_Color] = ++m_CurrentIndex; + } + EndParameterCategory(in_data, Effect_Topic_BackdropEnvMap_End); + + StartParameterCategory(in_data, GetParamsStringPtr(StrID_Topic_Light_Start), Effect_Topic_Light_Start); + { + AEFX_CLR_STRUCT(def); + def.flags = PF_ParamFlag_SUPERVISE | + PF_ParamFlag_CANNOT_TIME_VARY | + PF_ParamFlag_CANNOT_INTERP; + PF_ADD_POPUP(GetParamsStringPtr(StrID_Parameters_Light_Category), + __ELightCategory_Count, + ELightCategory_Debug_Default, + GetParamsStringPtr(StrID_Parameters_Light_Combobox), + Effect_Parameters_Light_Category); + m_ParametersIndexes[Effect_Parameters_Light_Category] = ++m_CurrentIndex; + + AEFX_CLR_STRUCT(def); + //def.ui_flags = PF_PUI_INVISIBLE; + def.param_type = PF_Param_POINT_3D; + PF_STRCPY(def.name, (GetParamsStringPtr(StrID_Parameters_Light_Direction))); + def.u.point3d_d.x_value = def.u.point3d_d.x_dephault = 0; + def.u.point3d_d.y_value = def.u.point3d_d.y_dephault = 1; + def.u.point3d_d.z_value = def.u.point3d_d.z_dephault = 0; + def.uu.id = (Effect_Parameters_Light_Direction); + PF_ADD_PARAM(in_data, -1, &def); + m_ParametersIndexes[Effect_Parameters_Light_Direction] = ++m_CurrentIndex; + + AddFloatParameter(in_data, GetParamsStringPtr(StrID_Parameters_Light_Intensity), Effect_Parameters_Light_Intensity, 1.0f, -100.0f, 100.0f); + + AEFX_CLR_STRUCT(def); + PF_ADD_COLOR(GetParamsStringPtr(StrID_Parameters_Light_Color), 51, 51, 51, Effect_Parameters_Light_Color); + m_ParametersIndexes[Effect_Parameters_Light_Color] = ++m_CurrentIndex; + + AEFX_CLR_STRUCT(def); + PF_ADD_COLOR(GetParamsStringPtr(StrID_Parameters_Light_Ambient), 51, 51, 51, Effect_Parameters_Light_Ambient); + m_ParametersIndexes[Effect_Parameters_Light_Ambient] = ++m_CurrentIndex; + } + EndParameterCategory(in_data, Effect_Topic_Light_End); + + AddFloatParameter(in_data, GetParamsStringPtr(StrID_Parameters_Refresh_Render), Effect_Parameters_Refresh_Render, 0.0f, 0.0f, 10000.0f, 0, PF_PUI_INVISIBLE | PF_PUI_DISABLED); + + AAEData.m_OutData->num_params = __Effect_Parameters_Count; + + popcornFXSuite->SetParametersIndexes(m_ParametersIndexes, EPKChildPlugins::EMITTER); + return result; +} + +//---------------------------------------------------------------------------- + +PF_Err CPluginInterface::GlobalSetdown( SAAEIOData &AAEData, + PF_ParamDef *params[], + PF_LayerDef *output) +{ + (void)AAEData; + (void)output; + (void)params; + + if (m_ParametersIndexes != nullptr) + delete[] m_ParametersIndexes; + m_ParametersIndexes = nullptr; + for (auto it = m_QueuedEffectData.begin(); it != m_QueuedEffectData.end(); ++it) + { + if (*it != nullptr) + { + if ((*it)->m_Desc != nullptr) + { + delete ((*it)->m_Desc); + (*it)->m_Desc = nullptr; + } + delete (*it); + } + } + + for (auto it = m_EffectData.begin(); it != m_EffectData.end(); ++it) + { + if (it->second != nullptr) + { + if (it->second->m_Desc != nullptr) + { + delete (it->second->m_Desc); + it->second->m_Desc = nullptr; + } + delete (it->second); + it->second = nullptr; + } + } + m_EffectData.clear(); + + return PF_Err_NONE; +} + +//---------------------------------------------------------------------------- + +bool CPluginInterface::GetEffectSequenceUID(SAAEIOData &AAEData, std::string &out) +{ + AEGP_SuiteHandler suites(AAEData.m_InData->pica_basicP); + AEFX_SuiteScoper seqdata_suite = AEFX_SuiteScoper(AAEData.m_InData, kPFEffectSequenceDataSuite, kPFEffectSequenceDataSuiteVersion1, AAEData.m_OutData); + + PF_ConstHandle constSeq; + seqdata_suite->PF_GetConstSequenceData(AAEData.m_InData->effect_ref, &constSeq); + + const SEffectSequenceDataFlat *sequenceDataFlat = static_cast(suites.HandleSuite1()->host_lock_handle((PF_Handle)constSeq)); + + out.clear(); + if (sequenceDataFlat && sequenceDataFlat->m_IsFlat == true) + { + out.append(sequenceDataFlat->m_EffectUUID, strlen(sequenceDataFlat->m_EffectUUID)); + suites.HandleSuite1()->host_unlock_handle((PF_Handle)constSeq); + return true; + } + if (sequenceDataFlat) + suites.HandleSuite1()->host_unlock_handle((PF_Handle)constSeq); + return false; +} + +//---------------------------------------------------------------------------- + +//Called when creating an effect only. +PF_Err CPluginInterface::SequenceSetup( SAAEIOData &AAEData, + PF_ParamDef *params[], + PF_LayerDef *output) +{ + (void)output; + (void)params; + + A_Err result = A_Err_NONE; + SEffectSequenceDataFlat *sequenceData = nullptr; + AEGP_SuiteHandler suites(AAEData.m_InData->pica_basicP); + PF_Handle sequenceDataHandle = suites.HandleSuite1()->host_new_handle(sizeof(SEffectSequenceDataFlat)); + + if (!sequenceDataHandle) + return PF_Err_OUT_OF_MEMORY; + sequenceData = static_cast(suites.HandleSuite1()->host_lock_handle(sequenceDataHandle)); + if (sequenceData != nullptr) + { + AEFX_CLR_STRUCT(*sequenceData); + + sequenceData->m_IsFlat = true; + + sequenceData->SetEffectPathSource(""); + sequenceData->SetEffectBackdropMeshPath(""); + sequenceData->SetEffectName(""); + + AEGP_LayerH layerH; + A_long dstID = 0; + + result |= suites.PFInterfaceSuite1()->AEGP_GetEffectLayer(AAEData.m_InData->effect_ref, &layerH); + result |= suites.LayerSuite8()->AEGP_GetLayerID(layerH, &dstID); + + if (result == A_Err_NONE) + sequenceData->SetLayerID(dstID); + + sequenceData->SetUUID(std::to_string(dstID)); + + AAEData.m_OutData->sequence_data = sequenceDataHandle; + suites.HandleSuite1()->host_unlock_handle(sequenceDataHandle); + } + return PF_Err_NONE; +} + +//---------------------------------------------------------------------------- + +PF_Err CPluginInterface::SequenceReSetup(SAAEIOData &AAEData, PF_ParamDef *params[], PF_LayerDef *output) +{ + (void)output; + (void)params; + + AEGP_SuiteHandler suites(AAEData.m_InData->pica_basicP); + PF_Err result = PF_Err_NONE; + + if (AAEData.m_InData->sequence_data) + { + PF_Handle sequenceDataFlatHandle = AAEData.m_InData->sequence_data; + SEffectSequenceDataFlat *sequenceDataFlat = static_cast(suites.HandleSuite1()->host_lock_handle(sequenceDataFlatHandle)); + + if (sequenceDataFlat) + { + //Check Layer ID to determine if its a duplicate. if so, update LayerID and regenerate UUID + AEGP_LayerH layerH; + A_long dstID = 0; + + result |= suites.PFInterfaceSuite1()->AEGP_GetEffectLayer(AAEData.m_InData->effect_ref, &layerH); + result |= suites.LayerSuite8()->AEGP_GetLayerID(layerH, &dstID); + + if (result == A_Err_NONE) + { + if (sequenceDataFlat->m_LayerID != dstID) + { + sequenceDataFlat->m_LayerID = dstID; + sequenceDataFlat->SetUUID(std::to_string(dstID).c_str()); + } + } + _RegisterEffectInstancePlugin(AAEData, params, sequenceDataFlat); + + AAEData.m_OutData->sequence_data = sequenceDataFlatHandle; + suites.HandleSuite1()->host_unlock_handle(sequenceDataFlatHandle); + } + } + else + { + result = SequenceSetup(AAEData, params, output); + } + return result; +} + +//---------------------------------------------------------------------------- + +PF_Err CPluginInterface::SequenceFlatten(SAAEIOData &AAEData, PF_ParamDef *params[], PF_LayerDef *output) +{ + (void)output; + (void)params; + + AEGP_SuiteHandler suites(AAEData.m_InData->pica_basicP); + PF_Err result = PF_Err_NONE; + + if (!AAEData.m_InData->sequence_data) + return result; + + PF_Handle sequenceDataHandle = AAEData.m_InData->sequence_data; + SEffectSequenceDataFlat *sequenceData = static_cast(suites.HandleSuite1()->host_lock_handle(sequenceDataHandle)); + + if (sequenceData) + { + //First Update sequence Data to reflect RT information + std::string uuid; + + if (GetEffectSequenceUID(AAEData, uuid) == false) + return false; + if (m_EffectData.count(uuid) == 0) + return false; + SEffectData *data = m_EffectData[uuid]; + if (data->m_Desc != nullptr) + { + AEGP_LayerH layerH; + A_long dstID = 0; + + result |= suites.PFInterfaceSuite1()->AEGP_GetEffectLayer(AAEData.m_InData->effect_ref, &layerH); + result |= suites.LayerSuite8()->AEGP_GetLayerID(layerH, &dstID); + + size_t extensionIdx = data->m_Desc->m_Name.find_last_of('.'); + if (extensionIdx != std::string::npos) + data->m_Desc->m_Name = data->m_Desc->m_Name.substr(0, extensionIdx) + ".pkfx"; + + sequenceData->SetEffectName(data->m_Desc->m_Name.data()); + sequenceData->SetEffectPathSource(data->m_Desc->m_PathSource.data()); + sequenceData->SetEffectBackdropMeshPath(data->m_Desc->m_BackdropMesh.m_Path.data()); + sequenceData->SetEffectEnvironmentMapPath(data->m_Desc->m_BackdropEnvironmentMap.m_Path.data()); + sequenceData->SetLayerID(dstID); + sequenceData->SetUUID(std::to_string(dstID)); + } + AAEData.m_OutData->sequence_data = sequenceDataHandle; + suites.HandleSuite1()->host_unlock_handle(sequenceDataHandle); + } + else + result = PF_Err_INTERNAL_STRUCT_DAMAGED; + return result; +} + +//---------------------------------------------------------------------------- + +PF_Err CPluginInterface::SequenceShutdown(SAAEIOData &AAEData, PF_ParamDef *params[], PF_LayerDef *output) +{ + (void)output; + (void)params; + + AEGP_SuiteHandler suites(AAEData.m_InData->pica_basicP); + + if (AAEData.m_InData->sequence_data != nullptr) + { + PF_Handle sequenceDataHandle = AAEData.m_InData->sequence_data; + + _UnRegisterEffectInstancePlugin(AAEData, params, nullptr); + + suites.HandleSuite1()->host_dispose_handle(sequenceDataHandle); + } + AAEData.m_InData->sequence_data = nullptr; + AAEData.m_OutData->sequence_data = nullptr; + + return PF_Err_NONE; +} + +//---------------------------------------------------------------------------- + +PF_Err CPluginInterface::QueryDynamicFlags(SAAEIOData &AAEData, PF_ParamDef *params[]) +{ + (void)params; + (void)AAEData; + + PF_Err result = PF_Err_NONE; + + return result; +} + +//---------------------------------------------------------------------------- + +PF_Err CPluginInterface::PreRender(SAAEIOData &AAEData) +{ + PF_Err result = PF_Err_NONE; + PF_RenderRequest req = AAEData.m_ExtraData.m_PreRenderData->input->output_request; + PF_CheckoutResult in_result; + + req.preserve_rgb_of_zero_alpha = TRUE; + AAEData.m_ExtraData.m_PreRenderData->output->solid = false; + + result = AAEData.m_ExtraData.m_PreRenderData->cb->checkout_layer( AAEData.m_InData->effect_ref, + Effect_Parameters_InputReserved, + Effect_Parameters_InputReserved, + &req, + AAEData.m_InData->current_time, + AAEData.m_InData->local_time_step, + AAEData.m_InData->time_scale, + &in_result); + + UnionLRect(&in_result.result_rect, &AAEData.m_ExtraData.m_PreRenderData->output->result_rect); + UnionLRect(&in_result.max_result_rect, &AAEData.m_ExtraData.m_PreRenderData->output->max_result_rect); + return result; +} + +//---------------------------------------------------------------------------- + +PF_Err CPluginInterface::SmartRender(SAAEIOData &AAEData) +{ + PF_Err result = PF_Err_NONE; + std::string uuid; + + if (GetEffectSequenceUID(AAEData, uuid) == false) + return PF_Err_NONE; + if (m_EffectData.count(uuid) == 0) + return PF_Err_NONE; + + SEffectData *data = m_EffectData[uuid]; + SEmitterDesc *emitterDesc = data->m_Desc; + AEFX_SuiteScoper PopcornFXSuite = AEFX_SuiteScoper(AAEData.m_InData, kPopcornFXSuite1, kPopcornFXSuiteVersion1, AAEData.m_OutData, "PopcornFX suite was not found."); + + if (emitterDesc == nullptr || !PopcornFXSuite->CheckEmitterValidity(AAEData, data->m_Desc)) + { + return PF_Interrupt_CANCEL; + } + // With multi-frame rendering, multiple threads can execute this at the same time even with just one emitter per layer: + data->m_Lock.lock(); + { + SAAEScopedParams emitterTransformType { AAEData, Effect_Parameters_TransformType }; + + SAAEScopedParams emitterPosition { AAEData, Effect_Parameters_Position }; + + SAAEScopedParams emitterPosition2D { AAEData, Effect_Parameters_Position_2D }; + SAAEScopedParams emitterPosition2DDist { AAEData, Effect_Parameters_Position_2D_Distance }; + + SAAEScopedParams emitterRotationX { AAEData, Effect_Parameters_Rotation_X }; + SAAEScopedParams emitterRotationY { AAEData, Effect_Parameters_Rotation_Y }; + SAAEScopedParams emitterRotationZ { AAEData, Effect_Parameters_Rotation_Z }; + SAAEScopedParams emitterSeed { AAEData, Effect_Parameters_Seed }; + + SAAEScopedParams emitterSimulationState { AAEData, Effect_Parameters_Simulation_State }; + + emitterDesc->m_TransformType = (ETransformType)emitterTransformType.GetComboBoxValue(); + if (emitterDesc->m_TransformType == ETransformType_3D) + emitterDesc->m_Position = emitterPosition.GetPoint3D(); + else + { + A_FloatPoint xy = emitterPosition2D.GetPoint2D(); + emitterDesc->m_Position.x = xy.x; + emitterDesc->m_Position.y = xy.y; + emitterDesc->m_Position.z = emitterPosition2DDist.GetFloat(); + } + emitterDesc->m_Rotation.x = emitterRotationX.GetAngle(); + emitterDesc->m_Rotation.y = emitterRotationY.GetAngle(); + emitterDesc->m_Rotation.z = emitterRotationZ.GetAngle(); + emitterDesc->m_Seed = emitterSeed.GetInt(); + + {//Camera + SAAEScopedParams emitterCameraType{ AAEData, Effect_Parameters_Camera }; + emitterDesc->m_Camera.m_Internal = false; + + SAAEScopedParams cameraPosition{ AAEData, Effect_Parameters_Camera_Position }; + SAAEScopedParams cameraRotationX{ AAEData, Effect_Parameters_Camera_Rotation_X }; + SAAEScopedParams cameraRotationY{ AAEData, Effect_Parameters_Camera_Rotation_Y }; + SAAEScopedParams cameraRotationZ{ AAEData, Effect_Parameters_Camera_Rotation_Z }; + SAAEScopedParams cameraFOV{ AAEData, Effect_Parameters_Camera_FOV }; + + emitterDesc->m_Camera.m_Position = cameraPosition.GetPoint3D(); + emitterDesc->m_Camera.m_Rotation.x = cameraRotationX.GetAngle(); + emitterDesc->m_Camera.m_Rotation.y = cameraRotationY.GetAngle(); + emitterDesc->m_Camera.m_Rotation.z = cameraRotationZ.GetAngle(); + emitterDesc->m_Camera.m_FOV = cameraFOV.GetFloat(); + + SAAEScopedParams cameraNear { AAEData, Effect_Parameters_Camera_Near }; + SAAEScopedParams cameraFar { AAEData, Effect_Parameters_Camera_Far }; + + emitterDesc->m_Camera.m_Near = cameraNear.GetFloat(); + emitterDesc->m_Camera.m_Far = cameraFar.GetFloat(); + } + {//Rendering + SAAEScopedParams renderingType { AAEData, Effect_Parameters_Render_Type }; + SAAEScopedParams renderingReceiveLight { AAEData, Effect_Parameters_Receive_Light }; + SAAEScopedParams renderingDistortionEnable { AAEData, Effect_Parameters_Distortion_Enable }; + SAAEScopedParams renderingBloomEnable { AAEData, Effect_Parameters_Bloom_Enable }; + SAAEScopedParams renderingBloomBrightPass { AAEData, Effect_Parameters_Bloom_BrightPassValue }; + SAAEScopedParams renderingBloomIntensity { AAEData, Effect_Parameters_Bloom_Intensity }; + SAAEScopedParams renderingBloomAttenuation { AAEData, Effect_Parameters_Bloom_Attenuation }; + SAAEScopedParams renderingBloomGaussianBlur { AAEData, Effect_Parameters_Bloom_GaussianBlur }; + SAAEScopedParams renderingBloomRenderPassCount { AAEData, Effect_Parameters_Bloom_RenderPassCount }; + SAAEScopedParams renderingToneMappingEnable { AAEData, Effect_Parameters_ToneMapping_Enable }; + SAAEScopedParams renderingToneMappingSaturation { AAEData, Effect_Parameters_ToneMapping_Saturation }; + SAAEScopedParams renderingToneMappingExposure { AAEData, Effect_Parameters_ToneMapping_Exposure }; + SAAEScopedParams renderingFXAAEnable { AAEData, Effect_Parameters_FXAA_Enable }; + + SAAEScopedParams renderingAlphaOverride { AAEData, Effect_Parameters_Background_Toggle }; + SAAEScopedParams renderingAlphaOverrideValue { AAEData, Effect_Parameters_Background_Opacity }; + + + emitterDesc->m_Rendering.m_Type = (ERenderType)renderingType.GetComboBoxValue(); + emitterDesc->m_Rendering.m_ReceiveLight = renderingReceiveLight.GetCheckBoxValue(); + + emitterDesc->m_Rendering.m_Distortion.m_Enable = renderingDistortionEnable.GetCheckBoxValue(); + + emitterDesc->m_Rendering.m_Bloom.m_Enable = renderingBloomEnable.GetCheckBoxValue(); + emitterDesc->m_Rendering.m_Bloom.m_BrightPassValue = renderingBloomBrightPass.GetFloat(); + emitterDesc->m_Rendering.m_Bloom.m_Intensity = renderingBloomIntensity.GetFloat(); + emitterDesc->m_Rendering.m_Bloom.m_Attenuation = renderingBloomAttenuation.GetFloat(); + emitterDesc->m_Rendering.m_Bloom.m_GaussianBlur = (EGaussianBlurPixelRadius)renderingBloomGaussianBlur.GetComboBoxValue(); + emitterDesc->m_Rendering.m_Bloom.m_RenderPassCount = renderingBloomRenderPassCount.GetInt(); + + emitterDesc->m_Rendering.m_ToneMapping.m_Enable = renderingToneMappingEnable.GetCheckBoxValue(); + emitterDesc->m_Rendering.m_ToneMapping.m_Saturation = renderingToneMappingSaturation.GetFloat(); + emitterDesc->m_Rendering.m_ToneMapping.m_Exposure = renderingToneMappingExposure.GetFloat(); + + emitterDesc->m_Rendering.m_FXAA.m_Enable = renderingFXAAEnable.GetCheckBoxValue(); + + emitterDesc->m_IsAlphaBGOverride = renderingAlphaOverride.GetCheckBoxValue(); + emitterDesc->m_AlphaBGOverride = renderingAlphaOverrideValue.GetPercent(); + } + {//BackdropMesh + SAAEScopedParams backdropMeshEnableRendering { AAEData, Effect_Parameters_BackdropMesh_Enable_Rendering }; + SAAEScopedParams backdropMeshEnableCollisions { AAEData, Effect_Parameters_BackdropMesh_Enable_Collisions }; + SAAEScopedParams backdropMeshEnableAnimation { AAEData, Effect_Parameters_BackdropMesh_Enable_Animation }; + SAAEScopedParams backdropMeshPosition { AAEData, Effect_Parameters_BackdropMesh_Position }; + SAAEScopedParams backdropMeshRotationX { AAEData, Effect_Parameters_BackdropMesh_Rotation_X }; + SAAEScopedParams backdropMeshRotationY { AAEData, Effect_Parameters_BackdropMesh_Rotation_Y }; + SAAEScopedParams backdropMeshRotationZ { AAEData, Effect_Parameters_BackdropMesh_Rotation_Z }; + SAAEScopedParams backdropMeshScaleX { AAEData, Effect_Parameters_BackdropMesh_Scale_X }; + SAAEScopedParams backdropMeshScaleY { AAEData, Effect_Parameters_BackdropMesh_Scale_Y }; + SAAEScopedParams backdropMeshScaleZ { AAEData, Effect_Parameters_BackdropMesh_Scale_Z }; + SAAEScopedParams backdropMeshRoughness { AAEData, Effect_Parameters_BackdropMesh_Roughness }; + SAAEScopedParams backdropMeshMetalness { AAEData, Effect_Parameters_BackdropMesh_Metalness }; + + emitterDesc->m_BackdropMesh.m_EnableRendering = backdropMeshEnableRendering.GetCheckBoxValue(); + emitterDesc->m_BackdropMesh.m_EnableCollisions = backdropMeshEnableCollisions.GetCheckBoxValue(); + emitterDesc->m_BackdropMesh.m_EnableAnimations = backdropMeshEnableAnimation.GetCheckBoxValue(); + + emitterDesc->m_BackdropMesh.m_Position = backdropMeshPosition.GetPoint3D(); + emitterDesc->m_BackdropMesh.m_Rotation.x = DegToRad(backdropMeshRotationX.GetAngle()); + emitterDesc->m_BackdropMesh.m_Rotation.y = DegToRad(backdropMeshRotationY.GetAngle()); + emitterDesc->m_BackdropMesh.m_Rotation.z = DegToRad(backdropMeshRotationZ.GetAngle()); + emitterDesc->m_BackdropMesh.m_Scale = A_FloatPoint3{ backdropMeshScaleX.GetFloat(), backdropMeshScaleY.GetFloat(), backdropMeshScaleZ.GetFloat() }; + + emitterDesc->m_BackdropMesh.m_Roughness = backdropMeshRoughness.GetFloat(); + emitterDesc->m_BackdropMesh.m_Metalness = backdropMeshMetalness.GetFloat(); + + } + {//Backdrop Environment + SAAEScopedParams backdropEnvMapEnableRendering { AAEData, Effect_Parameters_BackdropEnvMap_Enable_Rendering }; + SAAEScopedParams backdropEnvMapIntensity { AAEData, Effect_Parameters_BackdropEnvMap_Intensity }; + SAAEScopedParams backdropEnvMapColor { AAEData, Effect_Parameters_BackdropEnvMap_Color }; + + emitterDesc->m_BackdropEnvironmentMap.m_EnableRendering = backdropEnvMapEnableRendering.GetCheckBoxValue(); + emitterDesc->m_BackdropEnvironmentMap.m_Intensity = backdropEnvMapIntensity.GetFloat(); + emitterDesc->m_BackdropEnvironmentMap.m_Color = backdropEnvMapColor.GetColor(); + } + + {//Light + SAAEScopedParams LightCategory{ AAEData, Effect_Parameters_Light_Category }; + SAAEScopedParams LightDirection{ AAEData, Effect_Parameters_Light_Direction }; + SAAEScopedParams LightIntensity{ AAEData, Effect_Parameters_Light_Intensity }; + SAAEScopedParams LightColor{ AAEData, Effect_Parameters_Light_Color }; + SAAEScopedParams LightAmbient{ AAEData, Effect_Parameters_Light_Ambient }; + + if (LightCategory.GetComboBoxValue() == ELightCategory_Debug_Default) + { + emitterDesc->m_Light.m_Internal = true; + } + else + { + emitterDesc->m_Light.m_Internal = false; + } + emitterDesc->m_Light.m_Category = (ELightCategory)LightCategory.GetComboBoxValue(); + emitterDesc->m_Light.m_Direction = LightDirection.GetPoint3D(); + emitterDesc->m_Light.m_Intensity = LightIntensity.GetFloat(); + emitterDesc->m_Light.m_Color = LightColor.GetColor(); + emitterDesc->m_Light.m_Ambient = LightAmbient.GetColor(); + } + { + SAAEScopedParams scaleFactor{ AAEData, Effect_Parameters_Scale_Factor }; + + emitterDesc->m_ScaleFactor = scaleFactor.GetFloat(); + } + } + +#if defined(PK_SCALE_DOWN) + emitterDesc->m_Position.x = emitterDesc->m_Position.x / emitterDesc->m_ScaleFactor; + emitterDesc->m_Position.y = emitterDesc->m_Position.y / emitterDesc->m_ScaleFactor; + emitterDesc->m_Position.z = emitterDesc->m_Position.z / emitterDesc->m_ScaleFactor; + + emitterDesc->m_BackdropMesh.m_Position.x = emitterDesc->m_BackdropMesh.m_Position.x / emitterDesc->m_ScaleFactor; + emitterDesc->m_BackdropMesh.m_Position.y = emitterDesc->m_BackdropMesh.m_Position.y / emitterDesc->m_ScaleFactor; + emitterDesc->m_BackdropMesh.m_Position.z = emitterDesc->m_BackdropMesh.m_Position.z / emitterDesc->m_ScaleFactor; + + emitterDesc->m_Camera.m_Position.x = emitterDesc->m_Camera.m_Position.x / emitterDesc->m_ScaleFactor; + emitterDesc->m_Camera.m_Position.y = emitterDesc->m_Camera.m_Position.y / emitterDesc->m_ScaleFactor; + emitterDesc->m_Camera.m_Position.z = emitterDesc->m_Camera.m_Position.z / emitterDesc->m_ScaleFactor; +#endif + + PF_EffectWorld *input_worldP = nullptr; + result |= AAEData.m_ExtraData.m_SmartRenderData->cb->checkout_layer_pixels(AAEData.m_InData->effect_ref, 0/*POPCORN_INPUT*/, &input_worldP); + if (input_worldP == nullptr) + { + data->m_Lock.unlock(); + return result; + } + + AEGP_SuiteHandler suites(AAEData.m_InData->pica_basicP); + AEGP_LayerH layerH; + A_long dstID = 0; + + result |= suites.PFInterfaceSuite1()->AEGP_GetEffectLayer(AAEData.m_InData->effect_ref, &layerH); + result |= suites.LayerSuite8()->AEGP_GetLayerID(layerH, &dstID); + + emitterDesc->m_UUID = std::to_string(dstID); + emitterDesc->m_LayerID = dstID; + + PopcornFXSuite->UpdateScene(AAEData, emitterDesc); + + result = PF_ABORT(AAEData.m_InData); + if (result) + { + AAEData.m_ExtraData.m_SmartRenderData->cb->checkin_layer_pixels(AAEData.m_InData->effect_ref, 0); + data->m_Lock.unlock(); + return result; + } + + AAEData.m_ExtraData.m_SmartRenderData->cb->checkin_layer_pixels(AAEData.m_InData->effect_ref, 0); + data->m_LastRenderTime = AAEData.m_InData->current_time; + + data->m_Lock.unlock(); + return result; +} + +//---------------------------------------------------------------------------- + +PF_Err CPluginInterface::ParamValueChanged(SAAEIOData &AAEData, PF_ParamDef *params[]) +{ + (void)params; + + std::string id; + PF_Err result = PF_Err_NONE; + + if (GetEffectSequenceUID(AAEData, id) == false) + return false; + if (m_EffectData.count(id) == 0) + return false; + + // this block must be in this function, if not, it will fail. + AEGP_SuiteHandler suites(AAEData.m_InData->pica_basicP); + A_Time AETime; + AEGP_LayerH cameraLayer = nullptr; + AETime.scale = AAEData.m_InData->time_scale; + AETime.value = AAEData.m_InData->current_time; + result |= suites.PFInterfaceSuite1()->AEGP_GetEffectCamera(AAEData.m_InData->effect_ref, &AETime, &cameraLayer); + if (cameraLayer == nullptr) + { + A_FloatPoint center; + AEGP_CompH effectComp = nullptr; + + center.x = AAEData.m_InData->width / 2.0f; + center.y = AAEData.m_InData->height / 2.0f; + + A_UTF16Char name[64]; + CopyCharToUTF16("PopcornFX Camera", name); + + AEGP_LayerH layerH = nullptr; + result |= suites.PFInterfaceSuite1()->AEGP_GetEffectLayer(AAEData.m_InData->effect_ref, &layerH); + result |= suites.LayerSuite5()->AEGP_GetLayerParentComp(layerH, &effectComp); + result |= suites.CompSuite11()->AEGP_CreateCameraInComp(name, center, effectComp, &cameraLayer); + if (result != A_Err_NONE) + return false; + + AEFX_SuiteScoper PopcornFXSuite = AEFX_SuiteScoper(AAEData.m_InData, kPopcornFXSuite1, kPopcornFXSuiteVersion1, AAEData.m_OutData, "PopcornFX suite was not found."); + PopcornFXSuite->SetDefaultLayerPosition(AAEData, cameraLayer); + + } + SEffectData *data = m_EffectData[id]; + AEFX_SuiteScoper PopcornFXSuite = AEFX_SuiteScoper(AAEData.m_InData, kPopcornFXSuite1, kPopcornFXSuiteVersion1, AAEData.m_OutData, "PopcornFX suite was not found."); + + if (data->m_Desc != nullptr) + { + if (data->m_Desc->m_IsDeleted) + { + m_EffectData.erase(id); + delete data->m_Desc; + delete data; + return PF_Err_NONE; + } + if (m_ParametersIndexes[Effect_Parameters_Path] == AAEData.m_ExtraData.m_ChangeParamData->param_index) + { + if (PopcornFXSuite->DisplayBrowseEffectPanel(AAEData, (data->m_Desc)) != A_Err_NONE) + { + strcpy(AAEData.m_OutData->return_msg, "PopcornFX Error: Unable to load effect"); + AAEData.m_OutData->out_flags |= PF_OutFlag_DISPLAY_ERROR_MESSAGE; + } + else + { + SetParameterStreamName(AAEData, data->m_Desc->m_Name, m_ParametersIndexes[Effect_Parameters_Path]); //_UpdateEmitterName(AAEData, desc); + AAEData.m_OutData->out_flags |= PF_OutFlag_FORCE_RERENDER | PF_OutFlag_REFRESH_UI; + } + } + else if (m_ParametersIndexes[Effect_Parameters_Path_Marketplace] == AAEData.m_ExtraData.m_ChangeParamData->param_index) + { + if (PopcornFXSuite->DisplayMarketplacePanel(AAEData, (data->m_Desc)) != A_Err_NONE) + { + strcpy(AAEData.m_OutData->return_msg, "PopcornFX Error: Unable to load effect"); + AAEData.m_OutData->out_flags |= PF_OutFlag_DISPLAY_ERROR_MESSAGE; + } + } + else if (m_ParametersIndexes[Effect_Parameters_Path_Reimport] == AAEData.m_ExtraData.m_ChangeParamData->param_index) + { + PopcornFXSuite->ReimportEffect(AAEData, (data->m_Desc)); + + AAEData.m_OutData->out_flags |= PF_OutFlag_FORCE_RERENDER | PF_OutFlag_REFRESH_UI; + } + else if (m_ParametersIndexes[Effect_Parameters_BackdropMesh_Path] == AAEData.m_ExtraData.m_ChangeParamData->param_index) + { + if (PopcornFXSuite->DisplayBrowseMeshDialog(AAEData, (data->m_Desc)) != A_Err_NONE) + { + strcpy(AAEData.m_OutData->return_msg, "PopcornFX Error: Unable to load mesh"); + AAEData.m_OutData->out_flags |= PF_OutFlag_DISPLAY_ERROR_MESSAGE; + } + else + AAEData.m_OutData->out_flags |= PF_OutFlag_FORCE_RERENDER | PF_OutFlag_REFRESH_UI; + } + else if (m_ParametersIndexes[Effect_Parameters_BackdropEnvMap_Path] == AAEData.m_ExtraData.m_ChangeParamData->param_index) + { + if (PopcornFXSuite->DisplayBrowseEnvironmentMapDialog(AAEData, (data->m_Desc)) != A_Err_NONE) + { + strcpy(AAEData.m_OutData->return_msg, "PopcornFX Error: Unable to load Env Map"); + AAEData.m_OutData->out_flags |= PF_OutFlag_DISPLAY_ERROR_MESSAGE; + } + else + AAEData.m_OutData->out_flags |= PF_OutFlag_FORCE_RERENDER | PF_OutFlag_REFRESH_UI; + } + else if (m_ParametersIndexes[Effect_Parameters_BackdropEnvMap_Reset] == AAEData.m_ExtraData.m_ChangeParamData->param_index) + { + data->m_Desc->m_BackdropEnvironmentMap.m_Path = ""; + data->m_Desc->m_Update = true; + AAEData.m_OutData->out_flags |= PF_OutFlag_FORCE_RERENDER | PF_OutFlag_REFRESH_UI; + } + else if (m_ParametersIndexes[Effect_Parameters_BackdropMesh_Reset] == AAEData.m_ExtraData.m_ChangeParamData->param_index) + { + data->m_Desc->m_BackdropMesh.m_Path = ""; + data->m_Desc->m_Update = true; + AAEData.m_OutData->out_flags |= PF_OutFlag_FORCE_RERENDER | PF_OutFlag_REFRESH_UI; + } + else if (m_ParametersIndexes[Effect_Parameters_Audio] == AAEData.m_ExtraData.m_ChangeParamData->param_index) + { + AAEData.m_OutData->out_flags |= PF_OutFlag_FORCE_RERENDER | PF_OutFlag_REFRESH_UI; + } + else if (m_ParametersIndexes[Effect_Parameters_BringEffectIntoView] == AAEData.m_ExtraData.m_ChangeParamData->param_index) + { + PopcornFXSuite->MoveEffectIntoCurrentView(AAEData, (data->m_Desc)); + + AAEData.m_OutData->out_flags |= PF_OutFlag_FORCE_RERENDER | PF_OutFlag_REFRESH_UI; + } + } + return result; +} + +//---------------------------------------------------------------------------- + +PF_Err CPluginInterface::UpdateParamsUI(SAAEIOData &AAEData, PF_ParamDef *params[]) +{ + (void)AAEData; + (void)params; + + PF_Err err = PF_Err_NONE; + AEGP_SuiteHandler suites(AAEData.m_InData->pica_basicP); + std::string id; + + if (GetEffectSequenceUID(AAEData, id) == false) + return false; + + // PK to AE + if (m_EffectData.count(id) != 0) + { + SEffectData *effectData = m_EffectData[id]; + SEmitterDesc *desc = effectData->m_Desc; + + if (desc) + { + if (desc->m_IsDeleted) + { + m_EffectData.erase(id); + delete desc; + delete effectData; + return PF_Err_NONE; + } + + if (desc->m_Update) + { + desc->m_Update = false; + err |= SetParameterStreamName(AAEData, desc->m_Name, m_ParametersIndexes[Effect_Parameters_Path]); //_UpdateEmitterName(AAEData, desc); + err |= SetParameterStreamName(AAEData, desc->m_BackdropMesh.m_Path, m_ParametersIndexes[Effect_Parameters_BackdropMesh_Path]); //_UpdateBackdropMeshPath(AAEData, desc); + } + } + } + PF_ParamDef paramCopy[__Effect_Parameters_Count]; + std::map indexChanged; + + MakeParamCopy(params, paramCopy, __Effect_Parameters_Count); + + if (params[m_ParametersIndexes[Effect_Parameters_TransformType]]->u.pd.value == ETransformType_3D) + { + indexChanged.insert({ { m_ParametersIndexes[Effect_Parameters_Position], paramCopy[m_ParametersIndexes[Effect_Parameters_Position]].ui_flags &= ~(PF_PUI_DISABLED | PF_PUI_INVISIBLE) }, + { m_ParametersIndexes[Effect_Parameters_Position_2D], paramCopy[m_ParametersIndexes[Effect_Parameters_Position_2D]].ui_flags |= PF_PUI_DISABLED | PF_PUI_INVISIBLE }, + { m_ParametersIndexes[Effect_Parameters_Position_2D_Distance], paramCopy[m_ParametersIndexes[Effect_Parameters_Position_2D_Distance]].ui_flags |= PF_PUI_DISABLED | PF_PUI_INVISIBLE }, + }); + + } + else if (params[m_ParametersIndexes[Effect_Parameters_TransformType]]->u.pd.value == ETransformType_2D) + { + indexChanged.insert({ { m_ParametersIndexes[Effect_Parameters_Position], paramCopy[m_ParametersIndexes[Effect_Parameters_Position]].ui_flags |= PF_PUI_DISABLED | PF_PUI_INVISIBLE }, + { m_ParametersIndexes[Effect_Parameters_Position_2D], paramCopy[m_ParametersIndexes[Effect_Parameters_Position_2D]].ui_flags &= ~(PF_PUI_DISABLED | PF_PUI_INVISIBLE) }, + { m_ParametersIndexes[Effect_Parameters_Position_2D_Distance], paramCopy[m_ParametersIndexes[Effect_Parameters_Position_2D_Distance]].ui_flags &= ~(PF_PUI_DISABLED | PF_PUI_INVISIBLE) }, + }); + } + //Apply Change on param + AEGP_EffectRefH effectHandle = nullptr; + err |= suites.PFInterfaceSuite1()->AEGP_GetNewEffectForEffect(m_AAEID, AAEData.m_InData->effect_ref, &effectHandle); + if (err != A_Err_NONE) + return err; + for (auto it = indexChanged.begin(); it != indexChanged.end(); ++it) + { + AEGP_StreamRefH streamHandle = nullptr; + // Toggle visibility of parameter + err |= suites.StreamSuite2()->AEGP_GetNewEffectStreamByIndex(m_AAEID, effectHandle, it->first, &streamHandle); + + bool visibility = false; + if ((it->second & PF_PUI_INVISIBLE) != 0) + visibility = true; + err |= suites.DynamicStreamSuite2()->AEGP_SetDynamicStreamFlag(streamHandle, AEGP_DynStreamFlag_HIDDEN, FALSE, visibility); + err |= suites.StreamSuite2()->AEGP_DisposeStream(streamHandle); + + paramCopy[it->first].ui_flags = it->second; + err |= suites.ParamUtilsSuite3()->PF_UpdateParamUI(AAEData.m_InData->effect_ref, it->first, ¶mCopy[it->first]); + } + + if (effectHandle) + err |= suites.EffectSuite2()->AEGP_DisposeEffect(effectHandle); + return err; +} + +//---------------------------------------------------------------------------- + +PF_Err CPluginInterface::HandleDataFromAEGP(SAAEIOData &AAEData, PF_ParamDef *params[]) +{ + (void)params; + + PF_Err result = PF_Err_NONE; + std::string id; + void *extraData = AAEData.m_ExtraData.m_UndefinedData; + + const EEmitterEffectGenericCall *extraDataType = (EEmitterEffectGenericCall*)(extraData); + + if (*extraDataType == EEmitterEffectGenericCall::EmitterDesc) + { + SEmitterDesc *desc = reinterpret_cast(extraData); + + if (desc) + { + if (desc->m_IsDeleted) + { + if (GetEffectSequenceUID(AAEData, id) == false) + return false; + if (m_EffectData.count(id) != 0) + { + SEffectData *effectData = m_EffectData[id]; + delete effectData; + m_EffectData.erase(id); + } + delete desc; + return PF_Err_NONE; + } + else + { + desc->m_Update = false; + + + size_t extensionIdx = desc->m_Name.find_last_of('.'); + if (extensionIdx != std::string::npos) + desc->m_Name = desc->m_Name.substr(0, extensionIdx) + ".pkfx"; + result |= SetParameterStreamName(AAEData, desc->m_Name, m_ParametersIndexes[Effect_Parameters_Path]); //_UpdateEmitterName(AAEData, desc); + result |= SetParameterStreamName(AAEData, desc->m_BackdropMesh.m_Path, m_ParametersIndexes[Effect_Parameters_BackdropMesh_Path]); //_UpdateBackdropMeshPath(AAEData, desc); + } + AAEData.m_OutData->out_flags |= PF_OutFlag_FORCE_RERENDER; + AAEData.m_OutData->out_flags |= PF_OutFlag_REFRESH_UI; + } + } + else if (*extraDataType == EEmitterEffectGenericCall::GetEmitterInfos) + { + SGetEmitterInfos *infoToFill = reinterpret_cast(extraData); + + if (GetEffectSequenceUID(AAEData, id) == false) + return false; + if (m_EffectData.count(id) != 0) + { + strncpy(infoToFill->m_Name, m_EffectData[id]->m_Desc->m_Name.c_str(), 1023); + infoToFill->m_Name[1023] = '\0'; + strncpy(infoToFill->m_PathSource, m_EffectData[id]->m_Desc->m_PathSource.c_str(), 1023); + infoToFill->m_PathSource[1023] = '\0'; + } + } + return result; +} + +//---------------------------------------------------------------------------- + +bool CPluginInterface::_RegisterEffectInstancePlugin(SAAEIOData &AAEData, PF_ParamDef *params[], SEffectSequenceDataFlat *sequenceData) +{ + (void)params; + + std::string id; + + if (sequenceData != nullptr) + id = sequenceData->m_EffectUUID; + else if (GetEffectSequenceUID(AAEData, id) == false) + return false; + + if (m_EffectData.count(id) == 0) + { + //Check if effect is valid + { + PF_Err result = PF_Err_NONE; + AEGP_SuiteHandler suites(AAEData.m_InData->pica_basicP); + AEGP_EffectRefH effectHandle = nullptr; + AEGP_LayerH layerH; + bool discard = false; + + result |= suites.PFInterfaceSuite1()->AEGP_GetNewEffectForEffect(m_AAEID, AAEData.m_InData->effect_ref, &effectHandle); + result |= suites.PFInterfaceSuite1()->AEGP_GetEffectLayer(AAEData.m_InData->effect_ref, &layerH); + + if (result != PF_Err_NONE || effectHandle == nullptr || layerH == nullptr) + discard = true; + if (effectHandle) + result |= suites.EffectSuite2()->AEGP_DisposeEffect(effectHandle); + if (discard == true) + return false; + } + SEffectData *effectData = new SEffectData{}; + effectData->m_Desc = new SEmitterDesc{}; + m_EffectData[id] = effectData; + + if (sequenceData != nullptr) + { + PF_Err result = PF_Err_NONE; + AEGP_SuiteHandler suites(AAEData.m_InData->pica_basicP); + AEGP_LayerH layerH; + A_long dstID = 0; + + result |= suites.PFInterfaceSuite1()->AEGP_GetEffectLayer(AAEData.m_InData->effect_ref, &layerH); + result |= suites.LayerSuite8()->AEGP_GetLayerID(layerH, &dstID); + + effectData->m_Desc->m_UUID = std::to_string(dstID); + effectData->m_Desc->m_LayerID = dstID; + if (sequenceData->m_EffectName) + effectData->m_Desc->m_Name = sequenceData->m_EffectName; + if (sequenceData->m_EffectPathSource) + effectData->m_Desc->m_PathSource = sequenceData->m_EffectPathSource; + if (sequenceData->m_EffectBackdropMeshPath) + effectData->m_Desc->m_BackdropMesh.m_Path = sequenceData->m_EffectBackdropMeshPath; + if (sequenceData->m_EffectEnvironmentMapPath) + effectData->m_Desc->m_BackdropEnvironmentMap.m_Path = sequenceData->m_EffectEnvironmentMapPath; + AEFX_SuiteScoper PopcornFXSuite = AEFX_SuiteScoper( AAEData.m_InData, kPopcornFXSuite1, kPopcornFXSuiteVersion1, AAEData.m_OutData, "PopcornFX suite was not found."); + PopcornFXSuite->HandleNewEmitterEvent(AAEData, effectData->m_Desc); + + AAEData.m_OutData->out_flags |= PF_OutFlag_REFRESH_UI; + } + } + return true; +} + +//---------------------------------------------------------------------------- + +bool CPluginInterface::_UnRegisterEffectInstancePlugin(SAAEIOData &AAEData, PF_ParamDef *params[], SEffectSequenceDataFlat *sequenceData) +{ + (void)params; + + std::string id; + + if (sequenceData != nullptr) + id = sequenceData->m_EffectUUID; + else if (GetEffectSequenceUID(AAEData, id) == false) + return false; + + if (m_EffectData.count(id) != 0) + { + SEffectData *effectData = m_EffectData[id]; + + AEFX_SuiteScoper PopcornFXSuite = AEFX_SuiteScoper(AAEData.m_InData, kPopcornFXSuite1, kPopcornFXSuiteVersion1, AAEData.m_OutData, "PopcornFX suite was not found."); + PopcornFXSuite->HandleDeleteEmitterEvent(AAEData, effectData->m_Desc); + + delete effectData->m_Desc; + delete effectData; + + m_EffectData.erase(id); + } + return true; +} + +//---------------------------------------------------------------------------- + +__AAEPK_END diff --git a/AE_Effect_Emitter/Sources/AEEffect_SequenceData.cpp b/AE_Effect_Emitter/Sources/AEEffect_SequenceData.cpp new file mode 100644 index 00000000..2f8c40e0 --- /dev/null +++ b/AE_Effect_Emitter/Sources/AEEffect_SequenceData.cpp @@ -0,0 +1,88 @@ +//---------------------------------------------------------------------------- +// Copyright Persistant Studios, SARL. All Rights Reserved. https://www.popcornfx.com/terms-and-conditions/ +//---------------------------------------------------------------------------- +#include "ae_precompiled.h" + +#include "AEEffect_SequenceData.h" + +#include +#include + +__AAEPK_BEGIN + +//---------------------------------------------------------------------------- + +bool SEffectSequenceDataFlat::SetEffectName(const char* name) +{ + strncpy(m_EffectName, name, SequenceCST::MAX_NAME_LEN); + + m_EffectNameLen = strlen(name) + 1; + return true; +} + +//---------------------------------------------------------------------------- + +bool SEffectSequenceDataFlat::SetEffectPathSource(const char *path) +{ + m_EffectPathSourceLen = strlen(path) + 1; + strncpy(m_EffectPathSource, path, SequenceCST::MAX_PATH_LEN); + return true; +} + +//---------------------------------------------------------------------------- + +bool SEffectSequenceDataFlat::SetEffectBackdropMeshPath(const char *path) +{ + m_EffectBackdropMeshPathLen = strlen(path) + 1; + strncpy(m_EffectBackdropMeshPath, path, SequenceCST::MAX_PATH_LEN); + return true; +} + +//---------------------------------------------------------------------------- + +bool SEffectSequenceDataFlat::SetEffectEnvironmentMapPath(const char *path) +{ + m_EffectEnvironmentMapPathLen = strlen(path) + 1; + strncpy(m_EffectEnvironmentMapPath, path, SequenceCST::MAX_PATH_LEN); + return true; +} + +//---------------------------------------------------------------------------- + +bool SEffectSequenceDataFlat::SetUUID(const char *uuid) +{ + strncpy(m_EffectUUID, uuid, SequenceCST::UUID_LEN); + return true; +} + +//---------------------------------------------------------------------------- + +bool SEffectSequenceDataFlat::SetUUID(const std::string &uuid) +{ + strncpy(m_EffectUUID, uuid.c_str(), SequenceCST::UUID_LEN); + return true; +} + +//---------------------------------------------------------------------------- + +void SEffectSequenceDataFlat::SetLayerID(A_long id) +{ + m_LayerID = id; +} + +//---------------------------------------------------------------------------- + +bool SEffectSequenceDataFlat::CopyFrom(SEffectSequenceDataFlat *src) +{ + SetEffectName(src->m_EffectName); + SetEffectPathSource(src->m_EffectPathSource); + SetEffectBackdropMeshPath(src->m_EffectBackdropMeshPath); + SetEffectEnvironmentMapPath(src->m_EffectEnvironmentMapPath); + SetUUID(src->m_EffectUUID); + SetLayerID(src->m_LayerID); + return true; +} + +//---------------------------------------------------------------------------- +__AAEPK_END + diff --git a/AE_Effect_Emitter/Sources/AE_Effect_Emitter.plugin-Info.plist b/AE_Effect_Emitter/Sources/AE_Effect_Emitter.plugin-Info.plist new file mode 100644 index 00000000..2f07e012 --- /dev/null +++ b/AE_Effect_Emitter/Sources/AE_Effect_Emitter.plugin-Info.plist @@ -0,0 +1,24 @@ + + + + + CFBundleExecutable + Emitter + CFBundleIdentifier + com.PersistantStudio.PopcornFX.Emitter + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + AE_Effect_Emitter + CFBundlePackageType + eFKT + CFBundleSignature + FXTC + LSRequiresCarbon + + NSAppleScriptEnabled + No + NSHumanReadableCopyright + © PersistantStudio PopcornFX + + diff --git a/AE_Effect_Emitter/Sources/AE_Effect_Emitter_PiPL.r b/AE_Effect_Emitter/Sources/AE_Effect_Emitter_PiPL.r new file mode 100644 index 00000000..7ef877b3 --- /dev/null +++ b/AE_Effect_Emitter/Sources/AE_Effect_Emitter_PiPL.r @@ -0,0 +1,73 @@ +#include "AEConfig.h" +#include "AE_EffectVers.h" + +#ifndef AE_OS_WIN + #include +#endif + +#ifdef AE_OS_WIN +#include "../../AE_Suites/PopcornFX_Define_Version.h" +#endif +#ifdef AE_OS_MAC +#include "PopcornFX_Define_Version.h" +#endif + +resource 'PiPL' (16000) { + { /* array properties: 12 elements */ + /* [1] */ + Kind { + AEEffect + }, + /* [2] */ + Name { + "Emitter" + }, + /* [3] */ + Category { + "PopcornFX" + }, +#ifdef AE_OS_WIN + #ifdef AE_PROC_INTELx64 + CodeWin64X86 {"EffectMain"}, + #endif +#else + #ifdef AE_OS_MAC + CodeMacIntel64 {"EffectMain"}, + #endif +#endif + /* [6] */ + AE_PiPL_Version { + 2, + 0 + }, + /* [7] */ + AE_Effect_Spec_Version { + PF_PLUG_IN_VERSION, + PF_PLUG_IN_SUBVERS + }, + /* [8] */ + AE_Effect_Version { + AEPOPCORNFX_PIPL_VERSION + }, + /* [9] */ + AE_Effect_Info_Flags { + 0 + }, + /* [10] */ + AE_Effect_Global_OutFlags { + 101187584 + }, + AE_Effect_Global_OutFlags_2 { + 134222855 + }, + /* [11] */ + AE_Effect_Match_Name { + "ADBE PopcornFX Emitter" + }, + /* [12] */ + AE_Reserved_Info { + 8 + } + } +}; + diff --git a/AE_GeneralPlugin/GeneralPlugin.manifest b/AE_GeneralPlugin/GeneralPlugin.manifest new file mode 100644 index 00000000..ad87fd43 --- /dev/null +++ b/AE_GeneralPlugin/GeneralPlugin.manifest @@ -0,0 +1,15 @@ + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/AE_GeneralPlugin/Include/AEGP_AEPKConversion.h b/AE_GeneralPlugin/Include/AEGP_AEPKConversion.h new file mode 100644 index 00000000..a965359d --- /dev/null +++ b/AE_GeneralPlugin/Include/AEGP_AEPKConversion.h @@ -0,0 +1,77 @@ +//---------------------------------------------------------------------------- +// Copyright Persistant Studios, SARL. All Rights Reserved. https://www.popcornfx.com/terms-and-conditions/ +//---------------------------------------------------------------------------- +#pragma once + +#ifndef __FX_AECONVERSION_H__ +#define __FX_AECONVERSION_H__ + +#include "AEGP_Define.h" + +#include + +#include +#include + +#include +#include +#include +#include +#include + +#include +#include + +#include + +__AEGP_PK_BEGIN + +//---------------------------------------------------------------------------- + +RHI::EPixelFormat AAEToPK(PF_PixelFormat format); +PF_PixelFormat PKToAAE(RHI::EPixelFormat format); +u32 GetPixelSizeFromPixelFormat(RHI::EPixelFormat format); + +void AAEToPK(A_Matrix4 &in, CFloat4x4 &out); +void AAEToPK(A_Matrix4 &in, CFloat4x4 *out); + +CFloat3 AAEToPK(A_FloatPoint3 &in); +A_FloatPoint3 PKToAAE(CFloat3 &in); + +CFloat3 AngleAAEToPK(A_FloatPoint3 &in); +A_FloatPoint3 AnglePKToAAE(CFloat3 &in); + +EAttributeSemantic AttributePKToAAE(EDataSemantic value); + +EAttributeType AttributePKToAAE(EBaseTypeID value); +EBaseTypeID AttributeAAEToPK(EAttributeType value); + +EAttributeSamplerType AttributeSamplerPKToAAE(SParticleDeclaration::SSampler::ESamplerType type); + +void AAEToPK(SPostFXBloomDesc &in, PKSample::SParticleSceneOptions::SBloom &out); +void AAEToPK(SPostFXDistortionDesc &in, PKSample::SParticleSceneOptions::SDistortion &out); +void AAEToPK(SPostFXToneMappingDesc &in, PKSample::SParticleSceneOptions::SToneMapping &out); +void AAEToPK(SRenderingDesc &in, PKSample::SParticleSceneOptions &out); + +CUbyte3 ConvertSRGBToLinear(CUbyte3 v); +CUbyte3 ConvertLinearToSRGB(CUbyte3 v); + +EApiValue RHIApiToAEApi(RHI::EGraphicalApi value); +RHI::EGraphicalApi AEApiToRHIApi(EApiValue value); + +PKSample::CRHIParticleSceneRenderHelper::ERenderTargetDebug AAEToPK(ERenderType format); +CParticleSamplerDescriptor_VectorField_Grid::EInterpolation AAEToPK(EInterpolationType &value); + +//---------------------------------------------------------------------------- + +inline void WCharToCString(aechar_t *input, CString *destination) +{ + CStringUnicode tmp = CStringUnicode::FromUTF16(input); + destination->Append(tmp.ToUTF8()); +} + +//---------------------------------------------------------------------------- + +__AEGP_PK_END + +#endif // !__FX_AECONVERSION_H__ diff --git a/AE_GeneralPlugin/Include/AEGP_AssetBaker.h b/AE_GeneralPlugin/Include/AEGP_AssetBaker.h new file mode 100644 index 00000000..c2b50a73 --- /dev/null +++ b/AE_GeneralPlugin/Include/AEGP_AssetBaker.h @@ -0,0 +1,222 @@ +//---------------------------------------------------------------------------- +// Copyright Persistant Studios, SARL. All Rights Reserved. https://www.popcornfx.com/terms-and-conditions/ +//---------------------------------------------------------------------------- +#pragma once + +#ifndef __AEGP_ASSET_BAKER_H__ +#define __AEGP_ASSET_BAKER_H__ + +#include "AEGP_Define.h" + +#include "pk_base_object/include/hbo_object.h" +#include "pk_kernel/include/kr_threads.h" +#include "pk_kernel/include/kr_timers.h" +#include "pk_kernel/include/kr_resources.h" +#include "pk_kernel/include/kr_file_directory_walker.h" +#include + +//---------------------------------------------------------------------------- + +__PK_API_BEGIN + +class CResourceHandlerMesh; +class CResourceHandlerImage; +class CResourceHandlerRectangleList; +class CResourceHandlerFontMetrics; +class CResourceHandlerVectorField; +class CResourceManager; +class CCookery; +namespace HBO { + class CContext; +} + +__PK_API_END + +__AEGP_PK_BEGIN + +//---------------------------------------------------------------------------- + +class CResourceHandlerDummy : public IResourceHandler +{ +public: + CResourceHandlerDummy() { } + virtual ~CResourceHandlerDummy() { } + virtual void *Load(const CResourceManager *resourceManager, u32 resourceTypeID, const CString &resourcePath, bool pathNotVirtual, const SResourceLoadCtl &loadCtl, CMessageStream &loadReport, SAsyncLoadStatus *asyncLoadStatus) override + { + (void)resourceManager; (void)resourceTypeID; (void)resourcePath; (void)pathNotVirtual; (void)loadCtl; (void)loadReport; (void)asyncLoadStatus; + return null; + } + virtual void *Load(const CResourceManager *resourceManager, u32 resourceTypeID, const CFilePackPath &resourcePath, const SResourceLoadCtl &loadCtl, CMessageStream &loadReport, SAsyncLoadStatus *asyncLoadStatus) override + { + (void)resourceManager; (void)resourceTypeID; (void)resourcePath; (void)loadCtl; (void)loadReport; (void)asyncLoadStatus; + return null; + } + + virtual void Unload(const CResourceManager *, u32, void *) override { } + virtual void AppendDependencies(const CResourceManager *, u32, void *, TArray &) const override { } + virtual void AppendDependencies(const CResourceManager *, u32, const CString &, bool, TArray &) const override { } + virtual void AppendDependencies(const CResourceManager *, u32, const CFilePackPath &, TArray &) const override { } + virtual void BroadcastResourceChanged(const CResourceManager *, const CFilePackPath &) override { } +}; + +class CProjectSettingsFinder : public CFileDirectoryWalker +{ +public: + CProjectSettingsFinder(const CString &rootDir, IFileSystem *controller = null); + + virtual void FileNotifier(const CFilePack *pack, const char *fullPath, u32 fileFirstCharPos) override; + virtual bool DirectoryNotifier(const CFilePack *pack, const char *fullPath, u32 directoryFirstCharPos) override; + const CString &ProjectSettingsPath() const; + +private: + static bool ProjectSettingsPathValidator(const char *filePath); + +private: + CString m_ProjectSettingsPath; +}; + +//---------------------------------------------------------------------------- + +class SBakeContext +{ +public: + SBakeContext(); + ~SBakeContext(); + + IResourceHandler *m_BakeResourceMeshHandler; + IResourceHandler *m_BakeResourceImageHandler; + IResourceHandler *m_BakeResourceRectangleListHandler; + IResourceHandler *m_BakeResourceFontMetricsHandler; + IResourceHandler *m_BakeResourceVectorFieldHandler; + + IFileSystem *m_BakeFSController; + CResourceManager *m_BakeResourceManager; + HBO::CContext *m_BakeContext; + + bool m_Initialized; + + bool Init(); + + static bool _RemapPath(CString &path); + static CString _RemapFX(const CString &path); +}; + +//---------------------------------------------------------------------------- + +enum EAssetChangesType : int +{ + Undefined = 0, + Add, + Remove, + Update, + Rename +}; + +//---------------------------------------------------------------------------- + +class HBO_CLASS(CEditorAssetEffect), public CBaseObject +{ +private: + // Camera + HBO_FIELD(CFloat3, StartCameraPosition); + HBO_FIELD(CFloat3, StartCameraOrientation); +public: + CEditorAssetEffect(); + virtual ~CEditorAssetEffect(); + + void CopyFrom(CEditorAssetEffect *other); + + HBO_CLASS_DECLARATION(); +}; +PK_DECLARE_REFPTRCLASS(EditorAssetEffect); + +//---------------------------------------------------------------------------- + +class CEffectBaker : public CRefCountedObject +{ +private: + struct SAssetChange + { + CString m_EffectPath; + CString m_EffectPathOld; + EAssetChangesType m_Type; + }; + + struct SDirectoryValidator + { + const CStringView m_LibraryDir; + const CStringView m_EditorCacheDir; + const CStringView m_TemplatesDir; + + bool cmp(const char *rawPath) + { + const CStringView path = CStringView::FromNullTerminatedString(rawPath); + return !path.Contains(m_LibraryDir) && !path.Contains(m_EditorCacheDir) && !path.Contains(m_TemplatesDir); + } + + SDirectoryValidator(const CString &library, const CString &editor, const CString &templat) + : m_LibraryDir(library) + , m_EditorCacheDir(editor) + , m_TemplatesDir(templat) + { + } + }; + +public: + CEffectBaker(); + ~CEffectBaker(); + + void FileAdded(const CString &path); + void FileRemoved(const CString &path); + void FileChanged(const CString &path); + void FileChangedRelativePath(const CString &path); + void FileRenamed(const CString &oldPath, const CString &newPath); + + void Initialize(const CString &srcPack, const CString &dstPack, const CString &pkprojPath); + void LoadProjectSettings(const CString &pkprojPath); + void Clear(); + + void Lock(); + void Unlock(); + + void CancelAllFileChanges(); + int PopFileChanges(); + bool IsChangeRegistered(const CString &path, EAssetChangesType type); + void ReimportAssets(TArray &paths, bool importPkri = true); + void ReimportAllAssets(bool refesh); + void GetAllAssetPath(); + const CString &GetSourcePackRootPath() const { return m_RootDir; } + bool BakeAssetOrAddToRetryStack(SAssetChange &path); + bool LoadAndBrowseEffect(const CString &path); + bool BakeAsset(const CString &path, bool bakeDependencies = true); + + SBakeContext &GetBakeContextData() { return m_BakeContext; } + + void ClearBakedPaths() { m_BakedPaths.Clear(); } +private: + + bool m_Initialized; + + TArray m_ToBake; + TArray m_BakedPaths; + CString m_DstPackPath; + CString m_SrcPackPath; + PFilePack m_SrcPack; + PFilePack m_DstPack; + + SBakeContext m_BakeContext; + CCookery m_Cookery; + Threads::CCriticalSection m_Lock; + + CString m_RootDir; + CString m_LibraryDir; + CString m_EditorCacheDir; + CString m_PresetsDir; +}; +PK_DECLARE_REFPTRCLASS(EffectBaker); + +//---------------------------------------------------------------------------- + +__AEGP_PK_END + +#endif diff --git a/AE_GeneralPlugin/Include/AEGP_Attribute.h b/AE_GeneralPlugin/Include/AEGP_Attribute.h new file mode 100644 index 00000000..760d8e8d --- /dev/null +++ b/AE_GeneralPlugin/Include/AEGP_Attribute.h @@ -0,0 +1,216 @@ +//---------------------------------------------------------------------------- +// Copyright Persistant Studios, SARL. All Rights Reserved. https://www.popcornfx.com/terms-and-conditions/ +//---------------------------------------------------------------------------- +#pragma once + +#ifndef __FX_AAEATTRIBUTE_H__ +#define __FX_AAEATTRIBUTE_H__ + +#include "AEGP_Define.h" + +#include + +#include +#include +#include +#include +#include + +#include +#include + +#include +#include +#include + +//---------------------------------------------------------------------------- + +namespace PopcornFX +{ + PK_FORWARD_DECLARE(ParticleSamplerDescriptor); + PK_FORWARD_DECLARE(ShapeDescriptor); + PK_FORWARD_DECLARE(ImageSampler); + PK_FORWARD_DECLARE(ResourceMeshBatch); + PK_FORWARD_DECLARE(ResourceMesh); + + class CMeshSurfaceSamplerStructuresRandom; + class CMeshSurfaceSamplerStructuresFromUV; + class CMeshKdTree; + class CMeshVolumeSamplerStructuresRandom; + class CMeshProjection; + + struct SDensitySamplerData; +} + +__AEGP_PK_BEGIN + +//---------------------------------------------------------------------------- + +struct SSamplerBase +{ + PParticleSamplerDescriptor m_SamplerDescriptor; + bool m_Dirty = true; + + SSamplerBase(); + virtual ~SSamplerBase(); +}; + +//---------------------------------------------------------------------------- + +struct SSamplerShape : public SSamplerBase +{ + ESamplerShapeType m_Type; + + PShapeDescriptor m_ShapeDesc; + + + PResourceMeshBatch m_MeshBatch; + + // Acceleration structures are now owned by the integration: +#if (PK_GEOMETRICS_BUILD_MESH_SAMPLER_SURFACE != 0) + CMeshSurfaceSamplerStructuresRandom *m_SurfaceSamplingStructs; + CMeshSurfaceSamplerStructuresFromUV *m_SurfaceUVSamplingStructs; + + bool CreateSurfaceSamplingStructs(const PResourceMeshBatch mesh); + bool CreateSurfaceUVSamplingStructs(const PResourceMeshBatch mesh); +#endif + +#if (PK_GEOMETRICS_BUILD_MESH_SAMPLER_VOLUME != 0) + CMeshVolumeSamplerStructuresRandom *m_VolumeSamplingStructs; + + bool CreateVolumeSamplingStructs(const PResourceMeshBatch mesh); +#endif + +#if (PK_GEOMETRICS_BUILD_MESH_PROJECTION != 0) && 0 + CMeshProjection *m_ProjectionStructs; + + bool CreateProjectionStructs(const PResourceMeshBatch mesh); +#endif + +#if (PK_GEOMETRICS_BUILD_KDTREE != 0) + CMeshKdTree *m_KdTree; + + bool CreateKdTree(const PResourceMeshBatch mesh); +#endif + + SSamplerShape(); + virtual ~SSamplerShape(); + bool UpdateShape(SShapeSamplerDescriptor *aeShapeDesc); +}; + +//---------------------------------------------------------------------------- + +struct SSamplerImage : public SSamplerBase +{ + PRefCountedMemoryBuffer m_TextureData; + u32 m_Width; + u32 m_Height; + u32 m_SizeInBytes; + CImage::EFormat m_PixelFormat; + + int m_WrapMode; + + CImageSampler *m_ImageDesc = null; + SDensitySamplerData *m_DensitySampler = null; + + SSamplerImage(); + virtual ~SSamplerImage(); + bool UpdateImage(SImageSamplerDescriptor *aeTextDesc); +}; + +//---------------------------------------------------------------------------- + +struct SSamplerText : public SSamplerBase +{ + CString m_Data; + + SSamplerText(); + virtual ~SSamplerText(); + bool UpdateText(STextSamplerDescriptor *aeTextDesc); +}; + +//---------------------------------------------------------------------------- + +struct SSamplerAudio : public SSamplerBase +{ + enum SamplingType + { + SamplingType_Unknown = 0, + SamplingType_WaveForm, + SamplingType_Spectrum, + }; + + float *m_Waveform; + u32 m_InputSampleCount; + u32 m_SampleCount; + + AEGP_SoundDataH m_SoundData; + + SamplingType m_SamplingType; + float *m_WaveformData; + TArray m_WaveformPyramid; + + CStringId m_Name; + + Threads::CCriticalSection m_Lock; + bool m_BuiltThisFrame; + + SSamplerAudio(); + virtual ~SSamplerAudio(); + bool UpdateSound(SAudioSamplerDescriptor *aeTextDesc); + + bool CleanAudioPyramid(); + bool BuildAudioPyramidIFN(); + + bool ReleaseAEResources(); +}; + +//---------------------------------------------------------------------------- + +struct SSamplerVectorField : public SSamplerBase +{ + SSamplerVectorField(); + virtual ~SSamplerVectorField(); + bool UpdateVectorField(SVectorFieldSamplerDescriptor *aeShapeDesc); +}; + +//---------------------------------------------------------------------------- + +struct SPendingAttribute +{ + PF_ProgPtr m_ParentEffectPtr; + + SAttributeBaseDesc *m_Desc; + + SSamplerBase *m_PKDesc; + + AEGP_EffectRefH m_AttributeEffectRef; + + bool m_Deleted = false; + + SPendingAttribute(PF_ProgPtr parent = null, SAttributeBaseDesc *desc = null, AEGP_EffectRefH effectRef = null) + : m_ParentEffectPtr(parent) + , m_Desc(desc) + , m_PKDesc(null) + , m_AttributeEffectRef(effectRef) + {}; + + SPendingAttribute(const SPendingAttribute &other) + : m_ParentEffectPtr(other.m_ParentEffectPtr) + , m_Desc(other.m_Desc) + , m_PKDesc(other.m_PKDesc) + , m_AttributeEffectRef(other.m_AttributeEffectRef) + {}; + + ~SPendingAttribute() + { + PK_ASSERT(!m_AttributeEffectRef); + }; + +}; + +//---------------------------------------------------------------------------- + +__AEGP_PK_END + +#endif diff --git a/AE_GeneralPlugin/Include/AEGP_Define.h b/AE_GeneralPlugin/Include/AEGP_Define.h new file mode 100644 index 00000000..68347847 --- /dev/null +++ b/AE_GeneralPlugin/Include/AEGP_Define.h @@ -0,0 +1,41 @@ +//---------------------------------------------------------------------------- +// Copyright Persistant Studios, SARL. All Rights Reserved. https://www.popcornfx.com/terms-and-conditions/ +//---------------------------------------------------------------------------- +#pragma once + +#ifndef __FX_AEGP_DEFINE_H__ +#define __FX_AEGP_DEFINE_H__ + +#include + +#include + +//---------------------------------------------------------------------------- + +#define __AEGP_PK_BEGIN namespace AEGPPk { +#define __AEGP_PK_END } + +#define ASSERT_AE_ERR(result, value) PK_ASSERT(value != A_Err_NONE); result |= value; + +__AEGP_PK_BEGIN + +//---------------------------------------------------------------------------- + +using namespace PK_NAMESPACE; +using namespace AAePk; + +//---------------------------------------------------------------------------- + +enum EApiValue //Do not reorder/change values +{ + D3D11 = 1, + D3D12, + Metal, + Size, +}; + +//---------------------------------------------------------------------------- + +__AEGP_PK_END + +#endif // !__FX_AEGP_DEFINE_H__ diff --git a/AE_GeneralPlugin/Include/AEGP_FileDialog.h b/AE_GeneralPlugin/Include/AEGP_FileDialog.h new file mode 100644 index 00000000..d57aa9c1 --- /dev/null +++ b/AE_GeneralPlugin/Include/AEGP_FileDialog.h @@ -0,0 +1,82 @@ +//---------------------------------------------------------------------------- +// Copyright Persistant Studios, SARL. All Rights Reserved. https://www.popcornfx.com/terms-and-conditions/ +//---------------------------------------------------------------------------- +#pragma once + +#ifndef __AEGP_FILEDIALOG_H__ +#define __AEGP_FILEDIALOG_H__ + +#include "AEGP_Define.h" +#if defined (PK_MACOSX) +#include "AEGP_FileDialogMac.h" +#endif +#if defined (PK_WINDOWS) +#include "AEGP_WinFileDialog.h" +#endif +#include + +#include + +__AEGP_PK_BEGIN + +//---------------------------------------------------------------------------- + +#if defined(PK_MACOSX) + +//---------------------------------------------------------------------------- + +struct SMacFileDialogFilterData +{ + CString m_Desc; + CString m_Type; + + SMacFileDialogFilterData(const CString desc, const CString type); +}; + +//---------------------------------------------------------------------------- + +struct SMacFileOpenData +{ + TArray m_Filters; + PopcornFX::FastDelegate m_Cb; + + SMacFileOpenData(); + + ~SMacFileOpenData(); + + bool AddFilter(const CString &desc, const CString &type); +}; + +//---------------------------------------------------------------------------- + +bool MacBasicFileOpen(SMacFileOpenData &data); + +//---------------------------------------------------------------------------- +#endif + +//---------------------------------------------------------------------------- + +struct SFileDialog +{ +#if defined(PK_WINDOWS) + SWinFileOpenData m_Data; +#elif defined (PK_MACOSX) + SMacFileOpenData m_Data; +#endif + bool m_Cancel; + + SFileDialog(); + + bool AddFilter(const CString &desc, const CString &type); + void SetCallback(FastDelegate cb) { m_Data.m_Cb = cb; }; + bool BasicFileOpen(); + + bool IsCancelled(); + +}; + +//---------------------------------------------------------------------------- + +__AEGP_PK_END + +#endif diff --git a/AE_GeneralPlugin/Include/AEGP_FileDialogMac.h b/AE_GeneralPlugin/Include/AEGP_FileDialogMac.h new file mode 100644 index 00000000..68a5dcab --- /dev/null +++ b/AE_GeneralPlugin/Include/AEGP_FileDialogMac.h @@ -0,0 +1,23 @@ +//---------------------------------------------------------------------------- +// Copyright Persistant Studios, SARL. All Rights Reserved. https://www.popcornfx.com/terms-and-conditions/ +//---------------------------------------------------------------------------- +#ifndef __AEGP_FILEDIALOGMAC_H__ +#define __AEGP_FILEDIALOGMAC_H__ + +#include "AEGP_Define.h" + +__AEGP_PK_BEGIN + +//---------------------------------------------------------------------------- + +#if defined(PK_MACOSX) + +CString OpenFileDialogMac(const TArray &filters, const CString &defaultPathAndFile = CString()); + +#endif + +//---------------------------------------------------------------------------- + +__AEGP_PK_END + +#endif diff --git a/AE_GeneralPlugin/Include/AEGP_FileWatcher.h b/AE_GeneralPlugin/Include/AEGP_FileWatcher.h new file mode 100644 index 00000000..c9989506 --- /dev/null +++ b/AE_GeneralPlugin/Include/AEGP_FileWatcher.h @@ -0,0 +1,43 @@ +//---------------------------------------------------------------------------- +// Copyright Persistant Studios, SARL. All Rights Reserved. https://www.popcornfx.com/terms-and-conditions/ +//---------------------------------------------------------------------------- +#pragma once + +#ifndef __AEGP_FILE_WATCHER_H__ +#define __AEGP_FILE_WATCHER_H__ + +#include "AEGP_Define.h" + +#include + +__AEGP_PK_BEGIN +//---------------------------------------------------------------------------- + +class CFileWatcher : public CRefCountedObject +{ +private: + PFileSystemWatcher m_FileWatcher; + CString m_PathToWatch; + + bool CreateWatcherIFN(); + void RemoveWatchIFN(); + +public: + CFileWatcher(); + ~CFileWatcher(); + + void PauseFileWatcher(); + void RestartFileWatcher(); + + bool SetWatchPack(const CString &pathToWatch); + void SetNotifierAdd(void(*callback)(const CString &filePath)); + void SetNotifierRemove(void(*callback)(const CString &filePath)); + void SetNotifierModify(void(*callback)(const CString &filePath)); + void SetNotifierRename(void(*callback)(const CString &oldFilePath, const CString &newFilePath)); +}; +PK_DECLARE_REFPTRCLASS(FileWatcher); + +//---------------------------------------------------------------------------- +__AEGP_PK_END + +#endif diff --git a/AE_GeneralPlugin/Include/AEGP_FrameCollector.h b/AE_GeneralPlugin/Include/AEGP_FrameCollector.h new file mode 100644 index 00000000..866c148d --- /dev/null +++ b/AE_GeneralPlugin/Include/AEGP_FrameCollector.h @@ -0,0 +1,46 @@ +//---------------------------------------------------------------------------- +// Copyright Persistant Studios, SARL. All Rights Reserved. https://www.popcornfx.com/terms-and-conditions/ +//---------------------------------------------------------------------------- +#pragma once + +#include "PK-SampleLib/PKSample.h" + +#include +#include + +#include + +#include "AEGP_Define.h" + +__AEGP_PK_BEGIN + +//---------------------------------------------------------------------------- +// +// Frame collector +// +//---------------------------------------------------------------------------- + +// CFrameCollector is specialized with our policy to work with RHI. +// Create your own policy to use it in your custom engine. +class CFrameCollector : public TFrameCollector +{ +public: + CFrameCollector(); + virtual ~CFrameCollector(); + + // Views to cull against (setup from update thread) + TMemoryView m_CullingFrustums; + +private: + // Early Cull: Culls an entire medium on the update thread (when collecting the frame) + virtual bool EarlyCull(const PopcornFX::CAABB &bbox) const override; + + // Late Cull: Cull draw requests or individual pages on the render thread (when collecting draw calls) + // You can use this method if you don't have render thread views available from the update thread + // Ideally, cull in EarlyCull, but you should implement both methods + // Late cull also allows for finer culling (per draw request / per page) + virtual bool LateCull(const PopcornFX::CAABB &bbox) const override { return EarlyCull(bbox); } +}; + +//---------------------------------------------------------------------------- +__AEGP_PK_END diff --git a/AE_GeneralPlugin/Include/AEGP_LayerHolder.h b/AE_GeneralPlugin/Include/AEGP_LayerHolder.h new file mode 100644 index 00000000..4d2556ae --- /dev/null +++ b/AE_GeneralPlugin/Include/AEGP_LayerHolder.h @@ -0,0 +1,152 @@ +//---------------------------------------------------------------------------- +// Copyright Persistant Studios, SARL. All Rights Reserved. https://www.popcornfx.com/terms-and-conditions/ +//---------------------------------------------------------------------------- +#pragma once +#include "AEGP_Define.h" + +#include "AEGP_Attribute.h" + +#include + +#include +#include +#include +#include +#include + +#include + +#include +#include + +#include +#include +#include + +namespace AAePk +{ + struct SAAEIOData; + struct SAttributeDesc; + struct SAttributeSamplerDesc; + struct SEmitterDesc; +}; + +__AEGP_PK_BEGIN + +PK_FORWARD_DECLARE(AAEScene); +PK_FORWARD_DECLARE(RendererProperties); + +//---------------------------------------------------------------------------- + +class HBO_CLASS(CGraphicOverride), public CBaseObject +{ +public: + HBO_FIELD(u32, RendererID); + HBO_FIELD(u32, PropertyID); + + HBO_FIELD(CString, Value); +public: + CGraphicOverride(); + ~CGraphicOverride(); + + bool operator==(const CGraphicOverride &other); + + HBO_CLASS_DECLARATION(); +}; +PK_DECLARE_REFPTRCLASS(GraphicOverride); + +//---------------------------------------------------------------------------- + +class HBO_CLASS(CLayerProperty), public CBaseObject +{ +public: + HBO_FIELD(CString, CompName); + HBO_FIELD(u32, ID); + HBO_FIELD(TArray, RendererProperties); + +public: + CLayerProperty(); + ~CLayerProperty(); + + HBO_CLASS_DECLARATION(); +}; +PK_DECLARE_REFPTRCLASS(LayerProperty); + +//---------------------------------------------------------------------------- + +struct SPendingEmitter +{ + PF_ProgPtr m_EffectHandle; + + //Data Owned by AEEffect. Do not free in AEGP + SEmitterDesc *m_Desc; + + SPendingEmitter(PF_ProgPtr ptr = null, SEmitterDesc *desc = null) + : m_EffectHandle(ptr) + , m_Desc(desc) + { + + } + + SPendingEmitter(const SPendingEmitter& other) + { + m_EffectHandle = other.m_EffectHandle; + m_Desc = other.m_Desc; + } + + ~SPendingEmitter() + { + m_EffectHandle = null; + m_Desc = null; + } +}; + +//---------------------------------------------------------------------------- + +struct SLayerHolder +{ + u32 ID = 0; + + u32 m_TimeScale = 0; + u32 m_TimeStep = 0; + u32 m_CurrentTime = 0; + CFloat4x4 m_ViewMatrix = CFloat4x4::IDENTITY; + CFloat4 m_CameraPos = CFloat4::ZERO; + + AEGP_LayerH m_EffectLayer = null; + AEGP_LayerH m_CameraLayer = null; + PAAEScene m_Scene = null; + + TArray m_SPendingEmitters; + SPendingEmitter m_SpawnedEmitter; + + TArray m_SPendingAttributes; + THashMap m_DeletedAttributes; + THashMap m_SpawnedAttributes; + + THashMap m_DeletedAttributesSampler; + THashMap m_SpawnedAttributesSampler; + + SSamplerAudio *m_BackdropAudioWaveform = null; + SSamplerAudio *m_BackdropAudioSpectrum = null; + + float m_ScaleFactor = 1; + bool m_ForceRender = false; + bool m_Deleted = false; + + Threads::CCriticalSection m_LayerLock; + + CString m_SourcePackPath; + PFilePack m_BakedPack = null; + + CString m_LayerName; + CString m_CompositionName; + PLayerProperty m_LayerProperty = null; + + SLayerHolder(); + ~SLayerHolder(); + + bool Clear(SPBasicSuite* suite); +}; + +__AEGP_PK_END diff --git a/AE_GeneralPlugin/Include/AEGP_Log.h b/AE_GeneralPlugin/Include/AEGP_Log.h new file mode 100644 index 00000000..2778c891 --- /dev/null +++ b/AE_GeneralPlugin/Include/AEGP_Log.h @@ -0,0 +1,51 @@ +//---------------------------------------------------------------------------- +// Copyright Persistant Studios, SARL. All Rights Reserved. https://www.popcornfx.com/terms-and-conditions/ +//---------------------------------------------------------------------------- +#pragma once + +#ifndef __FX_AEGP_LOG_H__ +#define __FX_AEGP_LOG_H__ + +#include + +#include +#include +#include +#include +#include +#include + +#include "AEGP_Define.h" + +//---------------------------------------------------------------------------- +namespace AAePk +{ + struct SAAEIOData; +} + +//---------------------------------------------------------------------------- + +__AEGP_PK_BEGIN + +class CAELog +{ + static bool s_PKState; + static SAAEIOData *s_IOData; +public: + static bool LogErrorWindows(SAAEIOData *AAEData, const CString errorStr); + + static bool SetIOData(SAAEIOData *AAEData); + static void ClearIOData(); + static bool TryLogErrorWindows(const CString errorStr); + static void SetPKLogState(bool state); + + + static bool TryLogInfoWindows(const CString infoStr); +}; + +//---------------------------------------------------------------------------- + +__AEGP_PK_END + +#endif + diff --git a/AE_GeneralPlugin/Include/AEGP_Main.h b/AE_GeneralPlugin/Include/AEGP_Main.h new file mode 100644 index 00000000..8f3086d9 --- /dev/null +++ b/AE_GeneralPlugin/Include/AEGP_Main.h @@ -0,0 +1,30 @@ +//---------------------------------------------------------------------------- +// Copyright Persistant Studios, SARL. All Rights Reserved. https://www.popcornfx.com/terms-and-conditions/ +//---------------------------------------------------------------------------- +#pragma once + +#ifndef __FX_AEGP_MAIN_H__ +#define __FX_AEGP_MAIN_H__ + +#include + +#include +#include +#include +#include +#include +#include + +#ifdef AE_OS_WIN + typedef unsigned short PixelType; + #include +#endif + +//---------------------------------------------------------------------------- +// This entry point is exported through the PiPL (.r file) +extern "C" DllExport AEGP_PluginInitFuncPrototype EntryPointFunc; + +//---------------------------------------------------------------------------- + +#endif + diff --git a/AE_GeneralPlugin/Include/AEGP_PackExplorer.h b/AE_GeneralPlugin/Include/AEGP_PackExplorer.h new file mode 100644 index 00000000..5e777cd4 --- /dev/null +++ b/AE_GeneralPlugin/Include/AEGP_PackExplorer.h @@ -0,0 +1,61 @@ +//---------------------------------------------------------------------------- +// Copyright Persistant Studios, SARL. All Rights Reserved. https://www.popcornfx.com/terms-and-conditions/ +//---------------------------------------------------------------------------- +#pragma once + +#ifndef __FX_PACK_EXPLORER_H__ +#define __FX_PACK_EXPLORER_H__ + +#include "AEGP_Define.h" + +#include + +__AEGP_PK_BEGIN + +//---------------------------------------------------------------------------- + +class CPackExplorer : public CFileDirectoryWalker, public CRefCountedObject +{ +protected: + CString m_Pack; + TArray m_EffectPaths; + + virtual bool DirectoryNotifier(const CFilePack *pack, const char *fullPath, u32 directoryFirstCharPos) override; + virtual void FileNotifier(const CFilePack *pack, const char *fullPath, u32 fileFirstCharPos) override; + +public: + CPackExplorer(const CString &pack, IFileSystem *fileSystem = null); + virtual ~CPackExplorer(); + + void Explore(); // will start scanning + + const CString &Pack() const { return m_Pack; } + TMemoryView EffectPaths() const { return m_EffectPaths; } +}; + +//---------------------------------------------------------------------------- + +class CBakedPackExplorer : public CFileDirectoryWalker, public CRefCountedObject +{ +protected: + CString m_Pack; + TArray m_EffectPaths; + + virtual bool DirectoryNotifier(const CFilePack *pack, const char *fullPath, u32 directoryFirstCharPos) override; + virtual void FileNotifier(const CFilePack *pack, const char *fullPath, u32 fileFirstCharPos) override; + +public: + CBakedPackExplorer(const CString &pack, IFileSystem *fileSystem = null); + virtual ~CBakedPackExplorer(); + + void Explore(); // will start scanning + + const CString &Pack() const { return m_Pack; } + TMemoryView EffectPaths() const { return m_EffectPaths; } +}; + +//---------------------------------------------------------------------------- + +__AEGP_PK_END + +#endif // __FX_PACK_EXPLORER_H__ diff --git a/AE_GeneralPlugin/Include/AEGP_ParticleScene.h b/AE_GeneralPlugin/Include/AEGP_ParticleScene.h new file mode 100644 index 00000000..52206183 --- /dev/null +++ b/AE_GeneralPlugin/Include/AEGP_ParticleScene.h @@ -0,0 +1,54 @@ +//---------------------------------------------------------------------------- +// Copyright Persistant Studios, SARL. All Rights Reserved. https://www.popcornfx.com/terms-and-conditions/ +//---------------------------------------------------------------------------- +#pragma once + +#ifndef __FX_AAEPARTICLESCENE_H__ +#define __FX_AAEPARTICLESCENE_H__ + +#include "AEGP_Define.h" + +#include + +#include +#include +#include + +#include + +__AEGP_PK_BEGIN + +class CAAEScene; + +//---------------------------------------------------------------------------- + +class CAAEParticleScene : public IParticleScene +{ +public: + CAAEParticleScene() {} + virtual ~CAAEParticleScene() {} + + virtual void RayTracePacket( const Colliders::STraceFilter &traceFilter, + const Colliders::SRayPacket &packet, + const Colliders::STracePacket &results) override; + + void ClearBackdropMesh(); + void SetBackdropMeshTransform(const CFloat4x4 &transforms); + void SetBackdropMesh(const TResourcePtr &resourceMesh, const CFloat4x4 &transforms); + const CFloat4x4 &BackdropMeshTransforms() const { return m_BackdropMeshTransforms; } + + virtual TMemoryView GetAudioSpectrum(CStringId channelGroup, u32 &outBaseCount) const override; + virtual TMemoryView GetAudioWaveform(CStringId channelGroup, u32 &outBaseCount) const override; + + CAAEScene *m_Parent = null; +private: + // Mesh backdrop + TArray m_BackdropMeshes; + CFloat4x4 m_BackdropMeshTransforms = CFloat4x4::IDENTITY; +}; + +//---------------------------------------------------------------------------- + +__AEGP_PK_END + +#endif diff --git a/AE_GeneralPlugin/Include/AEGP_PopcornFXPlugins.h b/AE_GeneralPlugin/Include/AEGP_PopcornFXPlugins.h new file mode 100644 index 00000000..eeda0a43 --- /dev/null +++ b/AE_GeneralPlugin/Include/AEGP_PopcornFXPlugins.h @@ -0,0 +1,55 @@ +//---------------------------------------------------------------------------- +// Copyright Persistant Studios, SARL. All Rights Reserved. https://www.popcornfx.com/terms-and-conditions/ +//---------------------------------------------------------------------------- +#pragma once + +#ifndef __FX_POPCORNPLUGINS_H__ +#define __FX_POPCORNPLUGINS_H__ + +#include "AEGP_Define.h" + +__AEGP_PK_BEGIN +//---------------------------------------------------------------------------- + +enum ERuntimePlugin +{ + EPlugin_ImageCodecDDS = 1 << 0, + EPlugin_ImageCodecPNG = 1 << 1, + EPlugin_ImageCodecJPG = 1 << 2, + EPlugin_ImageCodecTGA = 1 << 3, + EPlugin_ImageCodecTIFF = 1 << 4, + EPlugin_ImageCodecPKM = 1 << 5, + EPlugin_ImageCodecPVR = 1 << 6, + EPlugin_ImageCodecHDR = 1 << 7, + EPlugin_ImageCodecEXR = 1 << 8, + + EPlugin_MeshCodecFBX = 1 << 16, + EPlugin_MeshCodecGranny = 1 << 17, + + EPlugin_CompilerBackendVM = 1 << 20, + EPlugin_CompilerBackendISPC = 1 << 21, + EPlugin_CompilerBackendD3D = 1 << 22, + EPlugin_CompilerBackendPSSLC = 1 << 23, + + // All "base" plugins + EPlugin_Default = EPlugin_CompilerBackendVM | + EPlugin_CompilerBackendD3D | + EPlugin_ImageCodecDDS | + EPlugin_ImageCodecPNG | + EPlugin_ImageCodecJPG | + EPlugin_ImageCodecTGA | + EPlugin_ImageCodecHDR, +}; + +//---------------------------------------------------------------------------- + +// loads selected plugins. set 'selected' to a bitwise combinations of the above plugin flags. must be matched by a call to 'UnregisterPlugins' +bool PopcornRegisterPlugins(u32 selected = 0); + +// unloads all previously loaded plugins +void PopcornUnregisterPlugins(); + +//---------------------------------------------------------------------------- +__AEGP_PK_END + +#endif diff --git a/AE_GeneralPlugin/Include/AEGP_RenderContext.h b/AE_GeneralPlugin/Include/AEGP_RenderContext.h new file mode 100644 index 00000000..9fb4ebc5 --- /dev/null +++ b/AE_GeneralPlugin/Include/AEGP_RenderContext.h @@ -0,0 +1,120 @@ +//---------------------------------------------------------------------------- +// Copyright Persistant Studios, SARL. All Rights Reserved. https://www.popcornfx.com/terms-and-conditions/ +//---------------------------------------------------------------------------- +#pragma once + +#ifndef __FX_RENDERCONTEXT_H__ +#define __FX_RENDERCONTEXT_H__ + +#include "AEGP_Define.h" + +#include +#include +#include + +#include + +#include +#include + +//---------------------------------------------------------------------------- + +namespace AAePk +{ + struct SAAEIOData; +} + +__AEGP_PK_BEGIN + +class CAAEBaseContext; +PK_FORWARD_DECLARE(AAERenderContext); + +//---------------------------------------------------------------------------- + +class CAAERenderContext : public CRefCountedObject +{ +public: + CAAERenderContext(); + ~CAAERenderContext(); + + bool InitializeIFN(RHI::EGraphicalApi api, const CString &className); + bool InitGraphicContext(RHI::EPixelFormat rhiformat, u32 width, u32 height); + bool Destroy(); + + CAAEBaseContext *GetAEGraphicContext(); + + PKSample::CRHIParticleSceneRenderHelper *GetCurrentSceneRenderer(); + CUint2 GetViewportSize() const; + void *GetWindowHandle() { return m_WindowHandle; } + + void LogGraphicsErrors(); + + void SetShaderLoader(PKSample::CShaderLoader *sl); + PKSample::CShaderLoader *GetShaderLoader(); + void SetPostFXOptions(PKSample::SParticleSceneOptions &so); + + bool SetAsCurrentContext(); + + void SetBackgroundOptions(bool isOverride, float alphaValue) { m_IsOverride = isOverride; m_AlphaValue = alphaValue; } + void SetGamma(float gamma) { m_Gamma = gamma; } + + bool RenderFrameBegin(u32 width, u32 height); + bool RenderFrameEnd(); + + bool AERenderFrameBegin (SAAEIOData &AAEData, bool getBackground = true); + bool AERenderFrameEnd (SAAEIOData &AAEData); + bool RenderToSAAEWorld (SAAEIOData &AAEData, AEGP_SuiteHandler &suiteHandler, PF_EffectWorld *inputWorld, PF_EffectWorld *effectWorld, PF_PixelFormat format); + bool GetCompositingBuffer(SAAEIOData &AAEData, AEGP_SuiteHandler &suiteHandler, PF_EffectWorld *inputWorld, PF_EffectWorld *effectWorld, PF_PixelFormat format); + + CUint2 GetContextSize(); + +private: + bool CreateInternalWindowIFN(const CString& className); + + void *m_WindowHandle; + void *m_DeviceContext; + + u32 m_Width; + u32 m_Height; + + RHI::EGraphicalApi m_API; + + static Threads::CCriticalSection m_AEGraphicContextLock; + static CAAEBaseContext *m_AEGraphicContext; + + RHI::EPixelFormat m_Format; + PF_PixelFormat m_AAEFormat; + + bool m_Initialized; + + float m_Gamma = 1.0f; + bool m_IsOverride = false; + float m_AlphaValue = 1.0f; + + PKSample::CRHIParticleSceneRenderHelper *m_RHIRendering; + + //Shared between rendercontexts + PKSample::CShaderLoader *m_ShaderLoader; + + PKSample::SParticleSceneOptions m_SceneOptions; + + PRefCountedMemoryBuffer m_UploadBuffer = null; + u32 m_UploadBufferSize = 0; + + PRefCountedMemoryBuffer m_DownloadBuffer = null; + u32 m_DownloadBufferSize = 0; + +private: + void ResetCheckedOutWorlds(SAAEIOData &AAEData); + + PF_EffectWorld *m_InputWorld = null; + PF_EffectWorld *m_OutputWorld = null; + +}; +PK_DECLARE_REFPTRCLASS(AAERenderContext); + +//---------------------------------------------------------------------------- + +__AEGP_PK_END + +#endif diff --git a/AE_GeneralPlugin/Include/AEGP_Scene.h b/AE_GeneralPlugin/Include/AEGP_Scene.h new file mode 100644 index 00000000..d43adcb7 --- /dev/null +++ b/AE_GeneralPlugin/Include/AEGP_Scene.h @@ -0,0 +1,316 @@ +//---------------------------------------------------------------------------- +// Copyright Persistant Studios, SARL. All Rights Reserved. https://www.popcornfx.com/terms-and-conditions/ +//---------------------------------------------------------------------------- +#pragma once + +#ifndef __FX_AAESCENE_H__ +#define __FX_AAESCENE_H__ + +#include "AEGP_Define.h" + +#include "AEGP_RenderContext.h" +#include "AEGP_FrameCollector.h" + +#include + +#include + +#include + +#include +#include +#include + +#include "AEGP_Attribute.h" +#include "AEGP_ParticleScene.h" + +#include + +//---------------------------------------------------------------------------- + +__PK_API_BEGIN +PK_FORWARD_DECLARE(SkeletonState); +__PK_API_END + +__AAEPK_BEGIN + +struct SEmitterDesc; + +__AAEPK_END + + +__AEGP_PK_BEGIN + +PK_FORWARD_DECLARE(AAERenderContext); +PK_FORWARD_DECLARE(SkinnedMeshInstance); + +// Forward declare our simple scene definition +struct SSimpleSceneDef; +struct SLayerHolder; + +struct SSamplerAudio; +struct SPendingAttribute; + +//---------------------------------------------------------------------------- + +struct SAAEWorld +{ + CFloat3 m_WorldOrigin; + float m_WorldWidth = -1.0f; + float m_WorldHeight = -1.0f; +}; + +//---------------------------------------------------------------------------- + +struct SRendererProperties +{ + CString m_Name; + CString m_Value; + + CString m_EffectLayerName; + u32 m_EffectLayerUID; + + CStringId m_LayerID; + + u32 m_RendererUID; + u32 m_PropertyUID; + + + SRendererProperties(const CString &name, const CString &value, const CString &effectLayerName, u32 effectLayerUID, CStringId layerID, u32 rdrUID, u32 propUID) + : m_Name(name) + , m_Value(value) + , m_EffectLayerName(effectLayerName) + , m_EffectLayerUID(effectLayerUID) + , m_LayerID(layerID) + , m_RendererUID(rdrUID) + , m_PropertyUID(propUID) + { + + } +}; + +PK_FORWARD_DECLARE(AAEScene); + +//---------------------------------------------------------------------------- + +class CAAEScene : public CRefCountedObject +{ +public: + + struct SSkinnedDataSimple + { + struct SSkinnedDataSubMesh + { + u32 m_SubMeshID; + TStridedMemoryView m_Positions; + TStridedMemoryView m_Normals; + SSkinnedDataSubMesh() : m_SubMeshID(0) {} + }; + + bool m_Valid; + TSemiDynamicArray m_SubMeshes; + + SSkinnedDataSimple() : m_Valid(false) {} + }; +public: + static u32 s_SceneID; + u32 m_ID; +public: + CAAEScene(); + virtual ~CAAEScene(); + + bool Init(SAAEIOData &AAEData); + bool Quit(); + static void ShutdownPopcornFX(); + + bool Update(SAAEIOData &AAEData); + bool UpdateLight(SLayerHolder *layer); + bool UpdateAttributes(SLayerHolder *layer); + + void UpdateBackdropTransform(SEmitterDesc *desc); + bool UpdateBackdrop(SLayerHolder *layer, SEmitterDesc *desc); + bool Render(SAAEIOData &AAEData); + + bool ResetEffect(bool unload); + + TArray &GetRenderers() { return m_OverridableProperties; } + HBO::CContext *GetContext() { return m_HBOContext; } + bool GetEmitterBounds(CAABB &bounds); + + void SetLayerHolder(SLayerHolder *parent); + void SetCameraViewMatrix(const CFloat4x4 &viewMatrix, const CFloat4 &pos, const float cameraZoom); + + void SetWorldSize(SAAEIOData &AAEData); + void SetEmitterPosition(const CFloat3 &position, ETransformType type); + void SetEmitterRotation(const CFloat3 &rotation); + void SetEmitterTeleport(bool teleport = true); + + bool SetupScene(bool seeking, bool refresh); + + //Pack&Effect Management + bool SetPack(PFilePack pack, bool unload); + bool SetSelectedEffect(CString name, bool refresh); + + void SetEffectDescriptor(SEmitterDesc* desc); + + bool RefreshAssetList(); + + SSamplerAudio *GetAudioSamplerDescriptor(CStringId name, SSamplerAudio::SamplingType type); + + void SetSeeking(bool seekingEnabled) { m_SeekingEnabled = seekingEnabled; } + void SetSkinnedBackdropParams(bool enabled, bool weightedSampling, u32 colorStreamID, u32 weightStreamID); + +protected: + bool _LateInitializeIFN(); + bool _SetupMediumCollection(); + void _FastForwardSimulation(SAAEIOData &AAEData, float timeTarget); + bool _UpdateShapeSampler(SPendingAttribute &samplerData, SAttributeSamplerDesc* descriptor); + bool _UpdateTextSampler(SPendingAttribute &samplerData, SAttributeSamplerDesc* descriptor); + bool _UpdateImageSampler(SPendingAttribute &samplerData, SAttributeSamplerDesc* descriptor); + bool _UpdateAudioSampler(SPendingAttribute &samplerData, SAttributeSamplerDesc* descriptor); + bool _UpdateVectorFieldSampler(SPendingAttribute &samplerData, SAttributeSamplerDesc* descriptor); + bool _SeekingUpdateEffect(float dt, float elapsedTime, float timeTarget, u32 curUpdateIdx, u32 totalUpdatesCount); + void _SeekingLoadAndRunEffect(CParticleMediumCollection *mediumCollection, + const CParticleEffect *effect, + const CFloat4x4 &transform, + float timeFromStartOfFrame, + float timeToEndOfFrame, + float elapsedTime); + bool _SeekingWaitForUpdateFence(CTimer *waitTimer, float customMaxUpdateTime = -1.0f); + u32 _PickNewEffectSeed(); + + // Scene + bool _LoadScene(const SSimpleSceneDef &fxPath); + void _CollectCurrentFrame(); + void _RenderLastCollectedFrame(); + + void _UpdateEmitter(float dt); + void _UpdateCamera(); + void _UpdateMediumCollectionView(); + + void _OnUpdateComplete(CParticleMediumCollection *collection); + + // Effects + bool _LoadEffectIFN(const SSimpleSceneDef &sceneDef); + PParticleEffectInstance _InstantiateEffect(); + PParticleEffectInstance _InstantiateEffect(float timeFromStartOfFrame, float timeToEndOfFrame); + void _OnInstanceDeath(const PParticleEffectInstance &instance); + + bool _RebuildAttributes(const SSimpleSceneDef &sceneDef); + + void _ExtractAEFrameInfo(SAAEIOData &AAEData); + bool _CheckRenderAbort(SAAEIOData *AAEData); + // Camera + void _SetProj(float fovxDegrees, const CFloat2 &winDimPixel, float zNear, float zFar); + + void _FillAdditionnalDataForRender(); +public: + // GPU Sim +#if (PK_PARTICLES_UPDATER_USE_D3D12 != 0 || PK_PARTICLES_UPDATER_USE_D3D11 != 0) + static bool SimDispatchMask(const PopcornFX::CParticleDescriptor *descriptor, PopcornFX::SSimDispatchHint &outHint); + void D3D12_EnqueueTask(const PopcornFX::PParticleUpdaterTaskD3D12 &task); +#endif + +protected: + //World + SAAEWorld m_SAAEWorldData; + PF_ProgPtr m_EffectRef; + SEmitterDesc *m_EffectDesc; + + SLayerHolder *m_LayerHolder; + + CFloat3 m_EmitterDefaultPosition; + CFloat3 m_EmitterDefaultOrientation; + + ETransformType m_EmitterTransformType; + CFloat4x4 m_EmitterTransformsCurrent; + CFloat4x4 m_EmitterTransformsPrevious; + CFloat3 m_EmitterVelCurrent; + CFloat3 m_EmitterVelPrevious; + + CUint2 m_OriginViewport; + + bool m_Paused; + + //AE Interface + CFloat3 m_AEEmitterPosition; + CFloat3 m_AEEmitterRotation; + u32 m_AEEmitterSeed; + + CFloat4x4 m_AEViewMatrix; + CFloat4 m_AECameraPos; + float m_AECameraZoom; + bool m_TeleportEmitter; + + u32 m_FrameNumber; + float m_DT; + float m_PreviousTimeSec; + float m_CurrentTimeSec; + + bool m_Initialized; + bool m_SeekingEnabled; + + A_Err m_FrameAbortedDuringSeeking; + + PKSample::SCamera m_Camera; + + PParticleEffect m_Effect; + + PBaseObjectFile m_EffectFile; + CString m_EffectPath; + PParticleEffectInstance m_EffectLastInstance; + + PParticleAttributeList m_AttributesList; + + TArray m_ActiveAudioSamplers; + + CFloat4 m_EmitterPositionNormalized_Debug; + CFloat4x4 m_LastInstanceXForms; + float m_ElapsedTimeSinceLastSpawn; + + PKSample::CRHIParticleRenderDataFactory m_ParticleRenderDataFactory; + CFrameCollector m_FrameCollector; + PKSample::SRHIDrawOutputs m_DrawOutputs; + EDrawCallSortMethod m_DCSortMethod; + + PKSample::SSceneInfoData m_SceneInfoData; + RHI::PConstantSet m_SceneInfoConstantSet; + RHI::PGpuBuffer m_SceneInfoConstantBuffer; + + CString m_SelectedEffect; + + PFilePack m_LoadedPack; + + HBO::CContext *m_HBOContext; + CAAEParticleScene *m_ParticleScene; + CParticleMediumCollection *m_ParticleMediumCollection; + float m_Stats_SimulationTime; + + CGuid m_ViewSlotInMediumCollection; + PKSample::SBackdropsData m_BackdropData; + + TResourcePtr m_ResourceMesh; + PSkinnedMeshInstance m_SkinnedMeshInstance; + PSkeletonState m_SkeletonState; + TArray m_FXInstancesSkinnedData; + + CResourceManager *m_ResourceManager; + + //Skinned Mesh Sampling + bool m_HasBoundBackdrop; + bool m_IsWeightedSampling; + u32 m_ColorStreamID; + u32 m_WeightStreamID; + SAAEIOData *m_AAEDataForSeeking; + +private: + TArray m_OverridableProperties; + bool m_ForceRestartSeeking; +}; +PK_DECLARE_REFPTRCLASS(AAEScene); + +//---------------------------------------------------------------------------- + +__AEGP_PK_END + +#endif diff --git a/AE_GeneralPlugin/Include/AEGP_SkinnedMesh.h b/AE_GeneralPlugin/Include/AEGP_SkinnedMesh.h new file mode 100644 index 00000000..529b6509 --- /dev/null +++ b/AE_GeneralPlugin/Include/AEGP_SkinnedMesh.h @@ -0,0 +1,122 @@ +//---------------------------------------------------------------------------- +// Copyright Persistant Studios, SARL. All Rights Reserved. https://www.popcornfx.com/terms-and-conditions/ +//---------------------------------------------------------------------------- +#pragma once + +#ifndef __AEGP_SKINNEDMESH_H__ +#define __AEGP_SKINNEDMESH_H__ + +#include "AEGP_Define.h" + +#include +#include + +// For skinned mesh backdrops +#include +#include +#include + +//---------------------------------------------------------------------------- + +namespace PopcornFX +{ + PK_FORWARD_DECLARE(SkeletonState); + PK_FORWARD_DECLARE(ResourceMeshBatch); +} + +__AEGP_PK_BEGIN + +//---------------------------------------------------------------------------- + +enum EMeshChannels +{ + Channel_Position = 0x1, + Channel_Normal = 0x2, + Channel_Tangent = 0x4, + Channel_Velocity = 0x8, +}; + +//---------------------------------------------------------------------------- + +class CSkinnedMesh : public CRefCountedObject +{ +protected: + PSkeletonState m_SkeletonState; + CTimeline m_Timeline; + + struct SSubMesh + { + PCResourceMeshBatch m_SkeletalMesh; + PSkeletonState m_SkeletonState; + CSkinAsyncContext m_SkinUpdateContext; + SSamplerSourceOverride m_SampleSourceOverride; + void *m_RawSkinnedData = null; + u32 m_RawSkinnedDataElementCount = 0; + TStridedMemoryView m_Positions; // view inside 'm_RawSkinnedData' + TStridedMemoryView m_Normals; // view inside 'm_RawSkinnedData' + TStridedMemoryView m_Tangents; // view inside 'm_RawSkinnedData' + TStridedMemoryView m_OldPositions; // view inside 'm_RawSkinnedData' + TStridedMemoryView m_Velocities; // view inside 'm_RawSkinnedData' + float m_SkinDt; // accessed by skinning jobs + bool m_FirstFrame; + + ~SSubMesh() + { + PK_FREE(m_RawSkinnedData); + } + + bool Empty() const { return m_SkeletalMesh == null; } + + void Skin_PreProcess(u32 vertexStart, u32 vertexCount, const SSkinContext &ctx); + void Skin_PostProcess(u32 vertexStart, u32 vertexCount, const SSkinContext &ctx); + }; + + TArray m_SubMeshes; + + float m_SkinDt; // accessed by skinning jobs + bool m_FirstFrame; + u32 m_SamplingChannels; + + bool _Init_Impl(const TResourcePtr &meshResource, u32 samplingChannels, const PSkeletonState &srcSkeletonState); + +public: + CSkinnedMesh(); + ~CSkinnedMesh(); + + void Reset(); + bool Init(const TResourcePtr &meshResource, u32 samplingChannels, const PSkeletonState &srcSkeletonState); + bool Play(const PSkeletonAnimationInstance &animInstance); + void Stop(); + void Update(float dt); + bool Valid() const { return m_SkeletonState != null; } + // void Render(); + void StartAsyncUpdateSkin(float dt); + bool WaitAsyncUpdateSkin(); + void ClearVelocities(); + + u32 SubMeshCount() const { return m_SubMeshes.Count(); } + TStridedMemoryView Positions(u32 batchId) const { return m_SubMeshes[batchId].m_Positions; } + TStridedMemoryView Normals(u32 batchId) const { return m_SubMeshes[batchId].m_Normals; } + + u32 SamplingChannels() const { return m_SamplingChannels; } + + // CMeshAnimRenderer &Renderer() { return m_Renderer; } + PSkeletonState SkeletonState() { return m_SkeletonState; } + bool HasGeometry() const + { + for (const auto &mesh : m_SubMeshes) + { + if (mesh.m_SkeletalMesh != null && mesh.m_SkeletalMesh->RawMesh() != null && !mesh.m_SkeletalMesh->RawMesh()->TriangleBatch().Empty()) + return true;; + } + return false; + } + SSamplerSourceOverride *SamplerSourceOverride(u32 batchId) { return &m_SubMeshes[batchId].m_SampleSourceOverride; } +}; +PK_DECLARE_REFPTRCLASS(SkinnedMesh); + +//---------------------------------------------------------------------------- + +__AEGP_PK_END + +#endif diff --git a/AE_GeneralPlugin/Include/AEGP_SkinnedMeshInstance.h b/AE_GeneralPlugin/Include/AEGP_SkinnedMeshInstance.h new file mode 100644 index 00000000..1df464a7 --- /dev/null +++ b/AE_GeneralPlugin/Include/AEGP_SkinnedMeshInstance.h @@ -0,0 +1,82 @@ +//---------------------------------------------------------------------------- +// Copyright Persistant Studios, SARL. All Rights Reserved. https://www.popcornfx.com/terms-and-conditions/ +//---------------------------------------------------------------------------- +#pragma once + +#ifndef __AEGP_SKINNEDMESHINSTANCE_H__ +#define __AEGP_SKINNEDMESHINSTANCE_H__ + +#include "AEGP_Define.h" + +#include + +#include +#include +#include +#include + +//---------------------------------------------------------------------------- + +__PK_API_BEGIN + +PK_FORWARD_DECLARE(SkeletonAnimationInstance); +PK_FORWARD_DECLARE(ParticleSamplerDescriptor_Shape); +PK_FORWARD_DECLARE(MeshSurfaceSamplerStructuresRandom); +PK_FORWARD_DECLARE(MeshVolumeSamplerStructuresRandom); +PK_FORWARD_DECLARE(ResourceMesh); + +namespace HBO { + class CContext; +} +__PK_API_END + +__AEGP_PK_BEGIN + +PK_FORWARD_DECLARE(SkinnedMesh); + +//---------------------------------------------------------------------------- + +class CSkinnedMeshInstance : public CRefCountedObject +{ +public: + PSkeletonAnimationInstance m_SkeletonAnimationInstance; + CString m_CurrentAnimationPath; + PSkinnedMesh m_SkinnedMesh; + PParticleSamplerDescriptor_Shape m_ShapeDescOverride; + + CMeshSurfaceSamplerStructuresRandom *m_SurfaceSamplingStruct = null; + CMeshVolumeSamplerStructuresRandom *m_VolumeSamplingStruct = null; + + CFloat4x4 m_CurMeshTransformScaled; + CFloat4x4 m_CurMeshTransform; + CFloat4x4 m_PrevMeshTransform; + +public: + CSkinnedMeshInstance(); + ~CSkinnedMeshInstance(); + + CSkinnedMeshInstance &operator = (const CSkinnedMeshInstance &other); + + + void ResetXForms(const CFloat4x4 &backdropXForm); + void SetBackdropXForms(const CFloat4x4 &backdropXForm); + + CFloat3 PredictVelocity(float dt); + + void ResetAnimationCursor(); + + void Update(float dt); + void StartAsyncUpdateSkin(float dt); + bool WaitAsyncUpdateSkin(); + + void ClearSkinnedMesh(); + bool LoadSkinnedMeshIFN(const TResourcePtr &meshResource, u32 samplingChannels, const PSkeletonState &scrSkeletonState); + bool LoadAnimationIFN(HBO::CContext *context, const CString &pksaPath, bool forceReload); + bool SetupAttributeSampler(CMeshNew *srcMesh, bool weightedSampling, u32 weightedSamplingColorStreamId, u32 weightedSamplingChannelId); +}; + +//---------------------------------------------------------------------------- + +__AEGP_PK_END + +#endif diff --git a/AE_GeneralPlugin/Include/AEGP_System.h b/AE_GeneralPlugin/Include/AEGP_System.h new file mode 100644 index 00000000..63a3c71d --- /dev/null +++ b/AE_GeneralPlugin/Include/AEGP_System.h @@ -0,0 +1,60 @@ +//---------------------------------------------------------------------------- +// Copyright Persistant Studios, SARL. All Rights Reserved. https://www.popcornfx.com/terms-and-conditions/ +//---------------------------------------------------------------------------- +#pragma once +#include "AEGP_Define.h" + +#include +#include + +__AEGP_PK_BEGIN + +//---------------------------------------------------------------------------- + +struct SEditorExecutable +{ + CString m_BinaryPathUninstall; + CString m_BinaryPath; + SEngineVersion m_Version; + + SEditorExecutable() {} + SEditorExecutable(const CString &path, const CString &uninstallerPath, const SEngineVersion &version) + : m_BinaryPathUninstall(uninstallerPath) + , m_BinaryPath(path) + , m_Version(version) + { + + } + + bool operator < (const SEditorExecutable &other) const { return m_Version < other.m_Version; } +}; + +//---------------------------------------------------------------------------- + +class CSystemHelper +{ +public: // Get Hardware ID + static const CString GetUniqueHardwareID(); + static const CString GetUniqueHardwareIDForHuman(); + + static bool LaunchEditorAsPopup(); + +private: + static u16 *_ComputeSystemUniqueId(); + + static void _Smear(u16 *id); + static void _Unsmear(u16 *id); + + static u16 _GetMacHash(); + + static u16 _GetCPUHash(); + static const char *_GetMachineName(); + +private: + CSystemHelper() = delete; + ~CSystemHelper() = delete; +}; + +//---------------------------------------------------------------------------- + +__AEGP_PK_END diff --git a/AE_GeneralPlugin/Include/AEGP_UpdateAEState.h b/AE_GeneralPlugin/Include/AEGP_UpdateAEState.h new file mode 100644 index 00000000..8e2d7dcc --- /dev/null +++ b/AE_GeneralPlugin/Include/AEGP_UpdateAEState.h @@ -0,0 +1,90 @@ +//---------------------------------------------------------------------------- +// Copyright Persistant Studios, SARL. All Rights Reserved. https://www.popcornfx.com/terms-and-conditions/ +//---------------------------------------------------------------------------- +#pragma once + +#ifndef __AEGP_UPDATEAESTATE_H__ +#define __AEGP_UPDATEAESTATE_H__ + +#include "AEGP_Define.h" +#include "PopcornFX_Suite.h" + +#include "AEGP_World.h" + +#include +#include +#include +#include +#include + +__AEGP_PK_BEGIN + +//---------------------------------------------------------------------------- + +struct SLayerHolder; +struct SPendingAttribute; + +//---------------------------------------------------------------------------- + +class CAEUpdater +{ +public: + static A_Err UpdateLayerAtTime(SLayerHolder *targetLayer, float time, bool isSeeking); + + static bool GetLightsAtTime(SLayerHolder *layer, A_Time &AETime, TArray &lights); + static bool GetCameraViewMatrixAtTime(SLayerHolder *layer, CFloat4x4 &view, CFloat4 &pos, A_Time &AETime, float &cameraZoom); + + static int s_AttributeIndexes[__Attribute_Parameters_Count]; + static int s_EmitterIndexes[__Effect_Parameters_Count]; + static int s_SamplerIndexes[__AttributeSamplerType_Parameters_Count]; +private: + CAEUpdater(); + ~CAEUpdater(); + + static A_Err _UpdateLayerAtTime(SLayerHolder *targetLayer, A_Time &AETime, bool isSeeking); + + static A_Err _UpdateSamplerAtTime(SLayerHolder *targetLayer, SPendingAttribute *sampler, AEGP_EffectRefH effect, A_Time &AETime, bool isSeeking); + static A_Err _UpdateAttributeAtTime(SLayerHolder *targetLayer, SPendingAttribute *attribute, AEGP_EffectRefH effect, A_Time &AETime, bool isSeeking); + static A_Err _UpdateEmitterAtTime(SLayerHolder *layer, AEGP_EffectRefH effectRef, A_Time &AETime, bool isSeeking); + static bool _SetupAudioSampler(SLayerHolder *targetLayer, AEGP_LayerIDVal layerID, A_Time &AETime, SSamplerAudio *samplerAudio, bool isSeeking); + + template + static A_Err _GetParamsStreamValueAtTime(s32 idx, AEGP_EffectRefH effectRef, A_Time &AETime, T &out) + { + A_Err result = A_Err_NONE; + CPopcornFXWorld &PKFXWorld = CPopcornFXWorld::Instance(); + AEGP_SuiteHandler suites(PKFXWorld.GetAESuites()); + AEGP_StreamRefH streamHandler; + AEGP_StreamValue2 value; + AEGP_StreamType stream_type; + + result |= suites.StreamSuite5()->AEGP_GetNewEffectStreamByIndex(PKFXWorld.GetPluginID(), effectRef, idx, &streamHandler); + + AEFX_CLR_STRUCT(value); + if (!PK_VERIFY(streamHandler != null)) + return result; + + result |= suites.StreamSuite5()->AEGP_GetStreamType(streamHandler, &stream_type); + if (AEGP_StreamType_NO_DATA == stream_type) + { + PK_ASSERT_NOT_REACHED(); + result |= suites.StreamSuite5()->AEGP_DisposeStream(streamHandler); + return result; + } + result |= suites.StreamSuite5()->AEGP_GetNewStreamValue(PKFXWorld.GetPluginID(), streamHandler, AEGP_LTimeMode_CompTime, &AETime, false, &value); + + out = *reinterpret_cast(&value.val.one_d); + + result |= suites.StreamSuite5()->AEGP_DisposeStreamValue(&value); + result |= suites.StreamSuite5()->AEGP_DisposeStream(streamHandler); + + return result; + } +}; + +//---------------------------------------------------------------------------- + + +__AEGP_PK_END + +#endif diff --git a/AE_GeneralPlugin/Include/AEGP_VaultHandler.h b/AE_GeneralPlugin/Include/AEGP_VaultHandler.h new file mode 100644 index 00000000..78103e2d --- /dev/null +++ b/AE_GeneralPlugin/Include/AEGP_VaultHandler.h @@ -0,0 +1,99 @@ +//---------------------------------------------------------------------------- +// Copyright Persistant Studios, SARL. All Rights Reserved. https://www.popcornfx.com/terms-and-conditions/ +//---------------------------------------------------------------------------- +#pragma once + +#ifndef __AEGP_VAULHANDLER_H__ +#define __AEGP_VAULHANDLER_H__ + +#include + +#include "AEGP_Define.h" +#include "AEGP_FileWatcher.h" + +#include +#include + +//---------------------------------------------------------------------------- + +namespace AAePk +{ + struct SAttributeSamplerDesc; +} + +__AEGP_PK_BEGIN + +PK_DECLARE_REFPTRCLASS(LogListenerFile); + +//---------------------------------------------------------------------------- + +struct SResourceBakeConfig +{ + bool m_StraightCopy = false; + bool m_IsAnimTrack = false; + bool m_IsSkeletalAnim = false; +}; + +//---------------------------------------------------------------------------- + +class CVaultHandler +{ +public: + CVaultHandler(); + ~CVaultHandler(); + + bool InitializeIFN(); + bool ShutdownIFN(); + //func ptr callback for the file watcher + static void FileAdded(const CString &path); + static void FileRemoved(const CString &path); + static void FileChanged(const CString &path); + static void FileChangedRelativePath(const CString &path); + static void FileRenamed(const CString &oldPath, const CString &newPath); + + bool IsBakedAssetLatestVersion(const CString &srcPath, const CString &dstPath); + bool LoadEffectIntoVault(const CString &packPath, CString &effectPath, const CString &pkprojPath, bool &refresh); + CString ImportResource(const CString resourcePath); + + CString CopyResource(const CString resourcePath); + + CString BakeVectorField(const CString resourcePath, const CString targetPath, const SResourceBakeConfig &config); + CString BakeMesh(const CString resourcePath, const CString targetPath, const SResourceBakeConfig &config); + CString BakeResource(const CString resourcePath, const SResourceBakeConfig &config); + + PFilePack GetVaultPackFromPath(CString path); + + const CString VaultPathRoot() const { return m_VaultPathRoot; }; + const CString VaultPathAssets() const { return m_VaultPathAssets; }; + const CString VaultPathCache() const { return m_VaultPathCache; }; + const CString VaultPathLog() const { return m_VaultPathLogs; }; + PFilePack InternalPack() const { return m_InternalPack; }; +private: + + bool _SetupVault(); +private: + + bool m_Initialized = false; + + PFileWatcher m_FileWatcher = null; + + PLogListenerFile m_AELogFileListener = null; + + PFilePack m_InternalPack = null; + + CString m_VaultPathRoot = ""; + CString m_VaultPathAssets = ""; + CString m_VaultPathCache = ""; + CString m_VaultPathLogs = ""; + + static const char *k_VaultFolderMainName; + static const char *k_VaultFolderAssetsName; + static const char *k_VaultFolderCacheName; + static const char *k_VaultFolderLogsName; +}; + +//---------------------------------------------------------------------------- + +__AEGP_PK_END + +#endif diff --git a/AE_GeneralPlugin/Include/AEGP_WinFileDialog.h b/AE_GeneralPlugin/Include/AEGP_WinFileDialog.h new file mode 100644 index 00000000..46c22aa2 --- /dev/null +++ b/AE_GeneralPlugin/Include/AEGP_WinFileDialog.h @@ -0,0 +1,111 @@ +//---------------------------------------------------------------------------- +// Copyright Persistant Studios, SARL. All Rights Reserved. https://www.popcornfx.com/terms-and-conditions/ +//---------------------------------------------------------------------------- +#pragma once + +#if defined(PK_WINDOWS) + +#include +#include + +using namespace PopcornFX; + +//---------------------------------------------------------------------------- + +struct SWinFileDialogFilterData +{ + wchar_t *m_Desc; + wchar_t *m_Type; + + COMDLG_FILTERSPEC m_Spec; + + SWinFileDialogFilterData(const CString desc, const CString type) + : m_Desc(null) + , m_Type(null) + { + convert(&m_Desc, desc); + convert(&m_Type, type); + + m_Spec.pszName = m_Desc; + m_Spec.pszSpec = m_Type; + } + + // Simple move assignment operator + SWinFileDialogFilterData(SWinFileDialogFilterData&& other) + { + m_Desc = other.m_Desc; + m_Type = other.m_Type; + + m_Spec.pszName = m_Desc; + m_Spec.pszSpec = m_Type; + + other.m_Desc = null; + other.m_Type = null; + } + + SWinFileDialogFilterData& operator=(SWinFileDialogFilterData&& other) + { + m_Desc = other.m_Desc; + m_Type = other.m_Type; + + m_Spec.pszName = m_Desc; + m_Spec.pszSpec = m_Type; + + other.m_Desc = null; + other.m_Type = null; + return *this; + } + + ~SWinFileDialogFilterData() + { + if (m_Desc != null) + PK_FREE(m_Desc); + if (m_Type != null) + PK_FREE(m_Type); + } + + void convert(wchar_t **dst, const CString& desc) + { + const int wideStringLength = ::MultiByteToWideChar(CP_UTF8, 0, desc.Data(), -1, NULL, 0); + if (!PK_VERIFY(wideStringLength >= 0)) + return; + *dst = PK_TALLOC(wideStringLength); + if (!PK_VERIFY(*dst != null)) + return; + + ::MultiByteToWideChar(CP_UTF8, 0, desc.Data(), -1, *dst, wideStringLength); + } +}; + +//---------------------------------------------------------------------------- + +struct SWinFileOpenData +{ + TArray m_Filters; + PopcornFX::FastDelegate m_Cb; + + SWinFileOpenData() + { + } + + + ~SWinFileOpenData() + { + } + + bool AddFilter(const CString &desc, const CString &type) + { + //SWinFileDialogFilterData filterData(desc, type); + if (!PK_VERIFY(m_Filters.PushBack(SWinFileDialogFilterData(desc, type)).Valid())) + return false; + return true; + } +}; + +//---------------------------------------------------------------------------- + +HRESULT WinBasicFileOpen(SWinFileOpenData& data); + +//---------------------------------------------------------------------------- + +#endif diff --git a/AE_GeneralPlugin/Include/AEGP_WinSystem.h b/AE_GeneralPlugin/Include/AEGP_WinSystem.h new file mode 100644 index 00000000..61616ccc --- /dev/null +++ b/AE_GeneralPlugin/Include/AEGP_WinSystem.h @@ -0,0 +1,34 @@ +//---------------------------------------------------------------------------- +// Copyright Persistant Studios, SARL. All Rights Reserved. https://www.popcornfx.com/terms-and-conditions/ +//---------------------------------------------------------------------------- +#pragma once +#include "AEGP_Define.h" +#include "AEGP_System.h" + +#include + +__AEGP_PK_BEGIN + +//---------------------------------------------------------------------------- + +#if defined(PK_WINDOWS) + +class CWinSystemHelper +{ +private: + CWinSystemHelper() = delete; + ~CWinSystemHelper() = delete; +public: + static CString GetLastErrorAsString(); + static CString GetLastErrorAsString(TArray &ignore); + static CString _GetWindowsInstallDir(); + static TArray _FindInstalledVersions(const CString &baseSearchPath); + + static SEditorExecutable GetMatchingEditor(const SEngineVersion &version); +}; + +#endif + +//---------------------------------------------------------------------------- + +__AEGP_PK_END diff --git a/AE_GeneralPlugin/Include/AEGP_World.h b/AE_GeneralPlugin/Include/AEGP_World.h new file mode 100644 index 00000000..5ac41b71 --- /dev/null +++ b/AE_GeneralPlugin/Include/AEGP_World.h @@ -0,0 +1,322 @@ +//---------------------------------------------------------------------------- +// Copyright Persistant Studios, SARL. All Rights Reserved. https://www.popcornfx.com/terms-and-conditions/ +//---------------------------------------------------------------------------- +#pragma once + +#ifndef __FX_WORLD_H__ +#define __FX_WORLD_H__ + +#include + +#include +#if defined(PK_MACOSX) +# include +#endif +#include +#include +#include +#include +#include + +#include + +#include + +#include +#include + + +#include "AEGP_Define.h" +#include "AEGP_Attribute.h" +#include "AEGP_Scene.h" +#include "AEGP_LayerHolder.h" +#include "AEGP_VaultHandler.h" + +#include + +#include + +//---------------------------------------------------------------------------- + +namespace AAePk +{ + struct SAAEIOData; + struct SAttributeDesc; + struct SAttributeSamplerDesc; + struct SEmitterDesc; +} + +namespace PopcornFX +{ + PK_FORWARD_DECLARE(LogListenerFile); +} + + +__AEGP_PK_BEGIN +//---------------------------------------------------------------------------- + +PK_FORWARD_DECLARE(EffectBaker); +PK_FORWARD_DECLARE(AAERenderContext); + +class CPanelBaseGUI; + +//---------------------------------------------------------------------------- + +struct SUIEvent +{ + virtual ~SUIEvent() {}; + virtual bool Exec() = 0; +}; + +//---------------------------------------------------------------------------- + +struct SUIEventString : public SUIEvent +{ + SLayerHolder *m_TargetLayer; + CString m_Data; + PopcornFX::FastDelegate m_Cb; + + virtual bool Exec() override + { + return m_Cb(m_TargetLayer, m_Data); + } +}; + +//---------------------------------------------------------------------------- + +struct SAEPreferenciesKeys +{ + static constexpr const char *kSection = "AEPocornFX"; + static constexpr const char *kApi = "Api"; + + static constexpr const EApiValue kSupportedAPIs[] = + { +#if PK_BUILD_WITH_D3D12_SUPPORT != 0 + EApiValue::D3D11, +#endif +#if PK_BUILD_WITH_D3D11_SUPPORT != 0 + EApiValue::D3D12, +#endif +#if PK_BUILD_WITH_METAL_SUPPORT != 0 + EApiValue::Metal, +#endif + }; + static constexpr const char *kApiNames[EApiValue::Size] = { "Unknown", "DirectX 11", "DirectX 12", "Metal" }; + + static const char *GetGraphicsApiAsCharPtr(EApiValue value); + static const char *GetGraphicsApiAsCharPtr(RHI::EGraphicalApi value); +}; + +//---------------------------------------------------------------------------- + +class HBO_CLASS(CAEPProjectProperties), public CBaseObject +{ +public: + HBO_FIELD(CString, ProjectName); + HBO_FIELD(TArray, LayerProperties); + +public: + CAEPProjectProperties(); + ~CAEPProjectProperties(); + + HBO_CLASS_DECLARATION(); +}; +PK_DECLARE_REFPTRCLASS(AEPProjectProperties); + +//---------------------------------------------------------------------------- + +class CPopcornFXWorld +{ +public: + ~CPopcornFXWorld(); + static CPopcornFXWorld &Instance(); + + bool Setup(SPBasicSuite *pica_basicP, AEGP_PluginID id); + bool SetCommandHandle(AEGP_Command &command, const char *name); + + AEGP_PluginID GetPluginID(); + SPBasicSuite *GetAESuites(); + + bool FetchAEProject(); + + RHI::EGraphicalApi GetRenderApi(); + void SetRenderApi(EApiValue AEGraphicsApi); + + bool IdleUpdate(); + bool HandleNewAttributeEvent(PF_ProgPtr &effectRef, SAttributeDesc *desc, bool asyncMerge = true, SLayerHolder *layer = null); + bool HandleNewAttributeSamplerEvent(PF_ProgPtr &effectRef, SAttributeSamplerDesc *desc, bool asyncMerge = true, SLayerHolder *layer = null); + bool HandleNewAttributes(TArray &attributes, PF_ProgPtr &effectRef, SLayerHolder *layer, bool asyncMerge = true); + + void CreatePanel(AEGP_PlatformViewRef container, AEGP_PanelH panelH, AEGP_PanelFunctions1 *outFunctionTable, AEGP_PanelRefcon *outRefcon); + void Command(AEGP_Command command, AEGP_HookPriority hookPriority, A_Boolean alreadyHandled, A_Boolean *handledPB); + void UpdateMenu(AEGP_WindowType activeWindow); + + void ClearAttributesAndSamplers(SLayerHolder *layer); + + CStringId GetAEEffectID(AEGP_EffectRefH &effect, s32 paramIdx); + + CStringId GetAttributeID(AEGP_EffectRefH &effect); + CStringId GetAttributeID(SAttributeBaseDesc *desc); + + CStringId GetAttributeSamplerID(AEGP_EffectRefH &effect); + + s32 _ExecSPendingEmitters(SLayerHolder *layer); + + s32 _ExecSPendingAttributes(SLayerHolder *layer); + s32 _ExecClearAttributes(SLayerHolder *layer); + + bool _ExecDeleteAttribute(SPendingAttribute *attribute, AEGP_EffectRefH &effectRef); + bool _ExecDeleteAttributeSampler(SPendingAttribute *attribute, AEGP_EffectRefH &effectRef); + + bool _SetupAutoRender(AEGP_EffectRefH &effect); + + bool _GetAEPath(AEGP_GetPathTypes type, CString &dst); + + //Pack Management + bool SetDestinationPackFromPath(SLayerHolder &layer, const CString &packPath); + + CString GetPluginInstallationPath(); + CString GetInternalPackPath(); + CString GetResourcesPath(); + + CString GetPluginVersion() const; + AEGP_InstalledEffectKey GetPluginEffectKey(EPKChildPlugins type) const; + + void SetWorkerCount(u32 count) { m_WorkerCount = count; } + u32 GetWorkerCount() const { return m_WorkerCount; } + + CVaultHandler &GetVaultHandler() { return m_VaultHandler; } + + void RefreshAssetList(); + + TArray &GetLayers() { return m_Layers; } + SLayerHolder *GetLayerForSEmitterDesc(SEmitterDesc *desc); + SLayerHolder *GetLayerForSEmitterDescID(CStringId id); + + bool SetSelectedEffectAsync(SLayerHolder *targetLayer, CString &name); + bool SetSelectedEffectFromPath(SEmitterDesc *desc, CString path, bool forceReload = false); + bool SetSelectedEffect(SLayerHolder *layer, CString &name); + bool SetEffectDefaultTransform(SLayerHolder *layer, const CFloat3 &pos, const CFloat3 &rot); + bool SetBackdropMeshDefaultTransform(SLayerHolder *layer); + + bool SetPanelInstance(CPanelBaseGUI *panel); + + //Suite + bool InitializeIFN(SAAEIOData &AAEData); + bool HandleNewEmitterEvent(AAePk::SAAEIOData &AAEData, SEmitterDesc *desc); + bool HandleDeleteEmitterEvent(AAePk::SAAEIOData &AAEData, SEmitterDesc *desc); + + bool CheckEmitterValidity(AAePk::SAAEIOData &AAEData, AAePk::SEmitterDesc *descriptor); + bool UpdateScene(SAAEIOData &AAEData, SEmitterDesc *desc); + bool UpdateEmitter(SAAEIOData &AAEData, SEmitterDesc *desc); + + bool InvalidateEmitterRender(SLayerHolder *layer, AEGP_EffectRefH effectRef); + bool InvalidateEmitterRender(SAAEIOData &AAEData, SEmitterDesc *desc); + + bool LaunchEditorAsPopup(AAePk::SAAEIOData &AAEData, SEmitterDesc *desc); + + bool ShutdownIFN(); + + void SetProfilingState(bool state); + + void SetParametersIndexes(const int *indexes, EPKChildPlugins plugin); + bool SetDefaultLayerPosition(SAAEIOData& AAEData, AEGP_LayerH layer); + bool MoveEffectIntoCurrentView(SAAEIOData &AAEData, SEmitterDesc *descriptor); + + PAAERenderContext GetCurrentRenderContext(); + + void OnEndSetupScene(); + + bool GetMostRecentCompName(CString &compName); + bool SetLayerName(SLayerHolder *layer); + bool SetLayerCompName(SLayerHolder *layer); + + const PBaseObjectFile &GetProjectConfFile(); + bool CreateLayerPropertyIFP(SLayerHolder *layer); + + bool SetResourceOverride(CStringId layerID, u32 rdrID, u32 propID, const CString &value); + bool WriteProjectFileModification(); + + //HOOK + static A_Err DeathHook(AEGP_GlobalRefcon pluginRefCon, AEGP_DeathRefcon refCon); + static A_Err IdleHook(AEGP_GlobalRefcon pluginRefCon, AEGP_IdleRefcon refCon, A_long *maxSleep); + + static A_Err CreatePanelHook(AEGP_GlobalRefcon pluginRefconP, + AEGP_CreatePanelRefcon refconP, + AEGP_PlatformViewRef container, + AEGP_PanelH panelH, + AEGP_PanelFunctions1 *outFunctionTable, + AEGP_PanelRefcon *outRefcon); + + static A_Err CommandHook( AEGP_GlobalRefcon plugin_refconP, + AEGP_CommandRefcon refconP, + AEGP_Command command, + AEGP_HookPriority hook_priority, + A_Boolean already_handledB, + A_Boolean *handledPB); + + static A_Err UpdateMenuHook( AEGP_GlobalRefcon plugin_refconP, + AEGP_UpdateMenuRefcon refconP, + AEGP_WindowType active_window); + + Threads::CCriticalSection &GetRenderLock() { return m_RenderLock; } + +private: + CPopcornFXWorld(); + + + static CPopcornFXWorld *m_Instance; + + bool m_Initialized; + + CString m_ClassName; + + TArray m_AAETreadID; + u32 m_WorkerCount; + + TArray m_Layers; + + Threads::CCriticalSection m_Lock; + + CPanelBaseGUI *m_Panel = null; + + SPBasicSuite *m_Suites; + AEGP_PluginID m_AEGPID; + AEGP_InstalledEffectKey m_PKInstalledPluginKeys[_PLUGIN_COUNT]; + + AEGP_Command m_Command = 42; + CString m_CommandName; + + RHI::EGraphicalApi m_GraphicsApi; + + CVaultHandler m_VaultHandler; + + //Developpement + float m_CameraZoom = 2000.0; + + PFilePack m_ProjectPack = null; + PBaseObjectFile m_ProjectConfFile = null; + PAEPProjectProperties m_ProjectProperty = null; + CString m_AEProjectFilename; + CString m_AEProjectPath; + PLogListenerFile m_AELogFileListener; + + CString m_PluginPath; + CString m_UserPluginPath; + CString m_AllUserPluginPath; + CString m_AEPath; + CString m_MostRecentCompName; + + + Threads::CCriticalSection m_UIEventLock; + TArray m_UIEvents; + + Threads::CCriticalSection m_RenderLock; +}; + +//---------------------------------------------------------------------------- + +__AEGP_PK_END + +#endif //!__FX_WORLD_H__ + diff --git a/AE_GeneralPlugin/Include/Panels/AEGP_GraphicalResourcesTreeModel.h b/AE_GeneralPlugin/Include/Panels/AEGP_GraphicalResourcesTreeModel.h new file mode 100644 index 00000000..e064ad6a --- /dev/null +++ b/AE_GeneralPlugin/Include/Panels/AEGP_GraphicalResourcesTreeModel.h @@ -0,0 +1,163 @@ +//---------------------------------------------------------------------------- +// Copyright Persistant Studios, SARL. All Rights Reserved. https://www.popcornfx.com/terms-and-conditions/ +//---------------------------------------------------------------------------- +#pragma once + +#ifndef __AEGP_GRAPHICALRESOURCESTREEMODEL_H__ +#define __AEGP_GRAPHICALRESOURCESTREEMODEL_H__ + +#include "AEGP_Define.h" + +#include "pk_kernel/include/kr_string_id.h" + +#include +#include +#include +#include +#include +#include + +//---------------------------------------------------------------------------- + +__AEGP_PK_BEGIN + +struct SRendererProperties; + +//---------------------------------------------------------------------------- + +class CGraphicResetButtonView +{ +public: + explicit CGraphicResetButtonView(); + + void paint(QPainter *painter, const QRect &rect, const QPalette &palette, bool hover) const; + QSize sizeHint() const; + + QPixmap m_Pixmap; +}; + +//---------------------------------------------------------------------------- + +class CGraphicResourceView +{ +public: + enum class ViewType { ViewType_Effect, ViewType_PathResource, ViewType_Layer }; + + explicit CGraphicResourceView(); + explicit CGraphicResourceView(ViewType type); + explicit CGraphicResourceView(ViewType type, const QPixmap &pixmap); + + void paint(QPainter *painter, const QRect &rect, const QPalette &palette, bool hover) const; + QSize sizeHint() const; + + ViewType Type() const { return m_Type; } +private: + ViewType m_Type; + QPixmap m_Pixmap; +}; + +//---------------------------------------------------------------------------- + +class CGraphicResourceDelegate : public QStyledItemDelegate +{ + Q_OBJECT +public: + using QStyledItemDelegate::QStyledItemDelegate; + + void paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const override; + QSize sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const override; +}; + +//---------------------------------------------------------------------------- + +class CGraphicalResourcesTreeItem +{ +public: + explicit CGraphicalResourcesTreeItem(); + explicit CGraphicalResourcesTreeItem(const QVector &data, CGraphicalResourcesTreeItem *parentItem = nullptr); + ~CGraphicalResourcesTreeItem(); + + void AppendChild(CGraphicalResourcesTreeItem *child); + void InsertChild(CGraphicalResourcesTreeItem *child, int index); + CGraphicalResourcesTreeItem *Child(int row); + int ChildCount() const; + int ColumnCount() const; + QVariant Data(int column) const; + int Row() const; + CGraphicalResourcesTreeItem *ParentItem(); + void ClearChildren(); + void RemoveChild(int index); + void RemoveChildren(int from, int count); + + void SetData(int column, const QVariant &data); + + u32 GetID() const { return m_UID; } + bool GetUpdated() { return m_Updated; } + void SetID(u32 id) { m_UID = id; } + void SetUpdated(bool updated) { m_Updated = updated; } + + CStringId GetLayerID() const { return m_LayerUID; } + u32 GetRendererID() const { return m_RendererUID; } + void SetLayerID(CStringId id) { m_LayerUID = id; } + void SetRendererID(u32 id) { m_RendererUID = id; } +private: + QVector m_ChildItems; + QVector m_ItemData; + CGraphicalResourcesTreeItem *m_ParentItem = null; + + u32 m_UID; + bool m_Updated; + + CStringId m_LayerUID; + u32 m_RendererUID; +}; + +//---------------------------------------------------------------------------- + +class CGraphicalResourcesTreeModel : public QAbstractItemModel +{ + Q_OBJECT + +public: + explicit CGraphicalResourcesTreeModel(QObject *parent = nullptr); + ~CGraphicalResourcesTreeModel(); + + QVariant data(const QModelIndex &index, int role) const override; + Qt::ItemFlags flags(const QModelIndex &index) const override; + QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const override; + QModelIndex index(int row, int column, const QModelIndex &parent = QModelIndex()) const override; + QModelIndex parent(const QModelIndex &index) const override; + int rowCount(const QModelIndex &parent = QModelIndex()) const override; + int columnCount(const QModelIndex &parent = QModelIndex()) const override; + + CGraphicalResourcesTreeItem *Item(const QModelIndex &index) const; + QModelIndex Index(CGraphicalResourcesTreeItem *item) const; + + void UpdateModel(); +private: + void _UpdateModel(); + void _ResetModel(); + + CGraphicalResourcesTreeItem *_CreateEffect(const QString &layerName, const QString &emitterName, u32 uid); + CGraphicalResourcesTreeItem *_CreateEffectLayer(const QString &layerName, u32 uid, CGraphicalResourcesTreeItem *effect); + CGraphicalResourcesTreeItem *_CreateRenderer(SRendererProperties *renderer, CGraphicalResourcesTreeItem *layer); + + CGraphicalResourcesTreeItem *_FindChild(CGraphicalResourcesTreeItem *parent, u32 childId); + void _UnflagUpdated(CGraphicalResourcesTreeItem *parent); + void _RemoveOldItems(CGraphicalResourcesTreeItem *parent); + + bool _LoadImageThumbnail(const CString &path, QPixmap *outThumbnail); + + CGraphicalResourcesTreeItem *m_RootItem = null; + CString m_CompositionName; +}; + +//---------------------------------------------------------------------------- + +__AEGP_PK_END + +Q_DECLARE_METATYPE(AEGPPk::CGraphicResetButtonView) +Q_DECLARE_METATYPE(AEGPPk::CGraphicResourceView) +Q_DECLARE_METATYPE(AEGPPk::CGraphicalResourcesTreeItem) + +#endif //!__AEGP_GRAPHICALRESOURCESTREEMODEL_H__ diff --git a/AE_GeneralPlugin/Include/Panels/AEGP_PanelQT.h b/AE_GeneralPlugin/Include/Panels/AEGP_PanelQT.h new file mode 100644 index 00000000..0a100011 --- /dev/null +++ b/AE_GeneralPlugin/Include/Panels/AEGP_PanelQT.h @@ -0,0 +1,201 @@ +//---------------------------------------------------------------------------- +// Copyright Persistant Studios, SARL. All Rights Reserved. https://www.popcornfx.com/terms-and-conditions/ +//---------------------------------------------------------------------------- +#pragma once + +#ifndef __FX_PANELQT_H__ +#define __FX_PANELQT_H__ + +#include "AEGP_Define.h" + +#include +#include + +#include +#include + +#include +#include + +//---------------------------------------------------------------------------- + +struct SPBasicSuite; + +__AEGP_PK_BEGIN + +class CGraphicalResourcesTreeModel; + +//---------------------------------------------------------------------------- + +class QPanelAppSignalSink : public QObject +{ + Q_OBJECT +public: + QPanelAppSignalSink(QApplication *app, QObject *parent = null); + + Q_SIGNAL void OnWindowHandlerChanged(WId wid); + Q_SIGNAL void OnWindowSizeChanged(const QRect &rect); + Q_SIGNAL void OnRenderersChanged(); + Q_SIGNAL void OnExit(); + + void DoExit(); + +private: + QApplication *m_App = null; +}; + +//---------------------------------------------------------------------------- + +class QPanel : public QObject +{ + Q_OBJECT +public: + QPanel(QPanelAppSignalSink* appSignal, QApplication *application, QObject *parent = null); + ~QPanel(); + +private: + void _CreateWindowContent(); + + void _SetWindow(WId wid); + void _SetGeometry(const QRect &windowRect); + void _UpdateModel(); + + + CGraphicalResourcesTreeModel *m_TreeModel = null; + + QPanelAppSignalSink *m_AppSignal = null; + QApplication *m_App = null; + + QWindow *m_Window = null; + QWidget *m_Widget = null; + + WId m_PendingWindowHandle = 0; +}; + +//---------------------------------------------------------------------------- + +class CPanelApp +{ +public: + CPanelApp(); + ~CPanelApp(); + + bool Startup(); + void LaunchApp(); + void Shutdown(); + + void OnWindowHandlerChanged(WId wid); + void OnWindowSizeChanged(const QRect &rect); + void OnRenderersChanged(); + void OnExit(); + +private: + QApplication *m_QApp = null; +#if defined(PK_MACOSX) + QEventLoop *m_EventLoop = null; +#endif + QPanelAppSignalSink *m_AppSignalSink = null; + + QPanel *m_Panel = null; +}; + +//---------------------------------------------------------------------------- + +#if !defined(PK_MACOSX) +class CAsynchronousJob_QtThread : public CAsynchronousJob +{ +public: + CAsynchronousJob_QtThread(); + ~CAsynchronousJob_QtThread(); + virtual void _OnRefptrDestruct() override {} + + +protected: + virtual void _VirtualLaunch(Threads::SThreadContext &) override { ImmediateExecute(); } + +public: + void ImmediateExecute(); + + CPanelApp &App() { return m_App; } + + // Waited for by the main thread: + Threads::CEvent m_Initialized; + Threads::CEvent m_Exited; + +private: + CPanelApp m_App; +}; +PK_DECLARE_REFPTRCLASS(AsynchronousJob_QtThread); +#endif + +//---------------------------------------------------------------------------- + +class CPanelBaseGUI +{ + static CPanelBaseGUI *m_Instance; + + CPanelBaseGUI(); + virtual ~CPanelBaseGUI(); + +public: + static CPanelBaseGUI *GetInstance(); + static bool DestroyInstance(); + + + bool InitializeIFN(); +#if defined(PK_MACOSX) + void IdleUpdate(); +#endif + bool CreatePanel(SPBasicSuite *spbP, AEGP_PanelH panelH, AEGP_PlatformViewRef platformWindowRef, AEGP_PanelFunctions1 *outFunctionTable); + void SetGeometry(const QRect &rect); + void UpdateScenesModel(); + +protected: + //Base AE Commands + void operator=(const CPanelBaseGUI&) = delete; + CPanelBaseGUI(const CPanelBaseGUI&) = delete; + + AEGP_PanelH m_PanelHandle; + + virtual void GetSnapSizes(A_LPoint *snapSizes, A_long *numSizesP); + virtual void PopulateFlyout(AEGP_FlyoutMenuItem *itemsP, A_long *in_out_numItemsP); + virtual void DoFlyoutCommand(AEGP_FlyoutMenuCmdID commandID); + +private: + + static A_Err _GetSnapSizes(AEGP_PanelRefcon refcon, A_LPoint *snapSizes, A_long *numSizesP); + static A_Err _PopulateFlyout(AEGP_PanelRefcon refcon, AEGP_FlyoutMenuItem *itemsP, A_long *in_out_numItemsP); + static A_Err _DoFlyoutCommand(AEGP_PanelRefcon refcon, AEGP_FlyoutMenuCmdID commandID); + + SPBasicSuite *m_BasicSuite = null; + +#if !defined(PK_MACOSX) + PAsynchronousJob_QtThread m_Task; +#else + CPanelApp m_App; +#endif + + bool m_Initialized = false; + +#if defined(PK_WINDOWS) +public: + + static LRESULT CALLBACK StaticOSWindowWndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam); + LRESULT OSWindowWndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam); + +private: + typedef LRESULT(CALLBACK* WindowProc)(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam); + + Threads::CCriticalSection m_HandleLock; + HWND m_WindowHandle; + WindowProc m_WindowProc; + + void _SetWindowHandle(HWND hwnd); +#endif +}; + +//---------------------------------------------------------------------------- + +__AEGP_PK_END + +#endif //!__FX_PANELQT_H__ diff --git a/AE_GeneralPlugin/Include/RenderApi/AEGP_BaseContext.h b/AE_GeneralPlugin/Include/RenderApi/AEGP_BaseContext.h new file mode 100644 index 00000000..491062eb --- /dev/null +++ b/AE_GeneralPlugin/Include/RenderApi/AEGP_BaseContext.h @@ -0,0 +1,68 @@ +//---------------------------------------------------------------------------- +// Copyright Persistant Studios, SARL. All Rights Reserved. https://www.popcornfx.com/terms-and-conditions/ +//---------------------------------------------------------------------------- +#pragma once + +#ifndef __FX_BASECONTEXT_H__ +#define __FX_BASECONTEXT_H__ + +#include "AEGP_Define.h" +#include +#include "AEGP_RenderContext.h" + +namespace AAePk { + struct SAAEIOData; +} + +//---------------------------------------------------------------------------- + +__AEGP_PK_BEGIN + +PK_FORWARD_DECLARE(Texture); + +//---------------------------------------------------------------------------- + +class CAAEBaseContext +{ +public: + static CAAEBaseContext *GetInstance() { return null; } + + CAAEBaseContext(); + virtual ~CAAEBaseContext(); + + virtual bool BeginFrame() { return false; }; + virtual bool EndFrame() { return m_ApiManager->EndFrame(); }; + + virtual void LogApiError() { return; }; + + virtual bool InitIFN() { return true; }; + + virtual bool CreatePlatformContext(void *winHandle, void *deviceContext) { (void)winHandle; (void)deviceContext; return false; }; + virtual bool CreateRenderTarget(RHI::EPixelFormat format, CUint3 size) { (void)format; (void)size; return false; }; + + virtual TMemoryView GetCurrentSwapChain() { return TMemoryView(); }; + + virtual bool SetAsCurrent(void *deviceContext) { (void)deviceContext; return false; }; + + virtual bool FillRenderBuffer(PRefCountedMemoryBuffer dstBuffer, RHI::PFrameBuffer srcBuffer, RHI::EPixelFormat format, u32 width, u32 height, u32 rowLength) { (void)dstBuffer; (void)srcBuffer; (void)format; (void)width; (void)height; (void)rowLength; return false; }; + + virtual bool FillCompositingTexture(void* srcBuffer, RHI::EPixelFormat format, u32 width, u32 height, u32 rowLength) { (void)srcBuffer; (void)format; (void)width; (void)height; (void)rowLength; return false; }; + + RHI::PApiManager GetApiManager(); + RHI::SApiContext *GetApiContext(); + RHI::PTexture GetCompositingTexture(); + +protected: + bool m_Initialized = false; + RHI::PApiManager m_ApiManager; + RHI::SApiContext *m_ApiContext; + + RHI::PTexture m_CompositingTexture; +}; + +//---------------------------------------------------------------------------- + +__AEGP_PK_END + + +#endif // ! diff --git a/AE_GeneralPlugin/Include/RenderApi/AEGP_CopyPixels.h b/AE_GeneralPlugin/Include/RenderApi/AEGP_CopyPixels.h new file mode 100644 index 00000000..f9bf91b9 --- /dev/null +++ b/AE_GeneralPlugin/Include/RenderApi/AEGP_CopyPixels.h @@ -0,0 +1,45 @@ +//---------------------------------------------------------------------------- +// Copyright Persistant Studios, SARL. All Rights Reserved. https://www.popcornfx.com/terms-and-conditions/ +//---------------------------------------------------------------------------- +#pragma once + +#ifndef __FX_COPYPIXELS_H__ +#define __FX_COPYPIXELS_H__ + +#include "AEGP_Define.h" + +#include + +namespace PopcornFX +{ + PK_FORWARD_DECLARE(RefCountedMemoryBuffer); +} + +//---------------------------------------------------------------------------- + +__AEGP_PK_BEGIN + +struct SCopyPixel { + PRefCountedMemoryBuffer m_BufferPtr; + PF_EffectWorld *m_InputWorld; + double m_Gamma; + + bool m_IsAlphaOverride; + double m_AlphaOverrideValue; +}; + +//---------------------------------------------------------------------------- + +PF_Err CopyPixelIn32(void *refcon, A_long x, A_long y, PF_Pixel32 *inP, PF_Pixel32 *); +PF_Err CopyPixelIn16(void *refcon, A_long x, A_long y, PF_Pixel16 *inP, PF_Pixel16 *); +PF_Err CopyPixelIn8(void *refcon, A_long x, A_long y, PF_Pixel8 *inP, PF_Pixel8 *); + +PF_Err CopyPixelOut32(void *refcon, A_long x, A_long y, PF_Pixel32 *, PF_Pixel32 *outP); +PF_Err CopyPixelOut16(void *refcon, A_long x, A_long y, PF_Pixel16 *, PF_Pixel16 *outP); +PF_Err CopyPixelOut8(void *refcon, A_long x, A_long y, PF_Pixel8 *, PF_Pixel8 *outP); + +//---------------------------------------------------------------------------- + +__AEGP_PK_END + +#endif diff --git a/AE_GeneralPlugin/Include/RenderApi/AEGP_CopyTask.h b/AE_GeneralPlugin/Include/RenderApi/AEGP_CopyTask.h new file mode 100644 index 00000000..f9d9ba7b --- /dev/null +++ b/AE_GeneralPlugin/Include/RenderApi/AEGP_CopyTask.h @@ -0,0 +1,70 @@ +//---------------------------------------------------------------------------- +// Copyright Persistant Studios, SARL. All Rights Reserved. https://www.popcornfx.com/terms-and-conditions/ +//---------------------------------------------------------------------------- +#pragma once + +#ifndef __FX_AEGP_COPYTASK_H__ +#define __FX_AEGP_COPYTASK_H__ + +#include "AEGP_Define.h" + +#include "RenderApi/AEGP_BaseContext.h" + +#include "pk_render_helpers/include/draw_requests/rh_tasks.h" // Task::CBase +#include "pk_render_helpers/include/draw_requests/rh_job_pools.h" + +__AEGP_PK_BEGIN + +//---------------------------------------------------------------------------- + +class CAsynchronousJob_CopyTextureTask : public CAsynchronousJob +{ +public: + TAtomic *m_Counter; + Threads::CEvent *m_EndCB; + + u32 m_TargetCount; + + // data + u32 m_Height; + u32 m_StartOffset; + + BYTE *m_DestinationPtr; + BYTE *m_SourcePtr; + + u32 m_WidthSize; + u32 m_RowPitch; + +public: + CAsynchronousJob_CopyTextureTask() { } + ~CAsynchronousJob_CopyTextureTask() { } + +protected: + virtual void _VirtualLaunch(Threads::SThreadContext &) override { ImmediateExecute(); } + +public: + bool Setup() { return true; } + void ImmediateExecute() + { + PK_NAMEDSCOPEDPROFILE("Copy Task"); + + //Loop + for (u32 i = 0; i < m_Height; ++i) + { + memcpy(m_DestinationPtr + (m_StartOffset + i) * m_WidthSize, m_SourcePtr + (m_StartOffset + i) * m_RowPitch, m_WidthSize); + } + + u32 value = m_Counter->Inc(); + + if (value == m_TargetCount) + m_EndCB->Trigger(); + } +}; +PK_DECLARE_REFPTRCLASS(AsynchronousJob_CopyTextureTask); + +//---------------------------------------------------------------------------- + +__AEGP_PK_END + + +#endif __FX_AEGP_COPYTASK_H__ diff --git a/AE_GeneralPlugin/Include/RenderApi/AEGP_D3D11Context.h b/AE_GeneralPlugin/Include/RenderApi/AEGP_D3D11Context.h new file mode 100644 index 00000000..083debe2 --- /dev/null +++ b/AE_GeneralPlugin/Include/RenderApi/AEGP_D3D11Context.h @@ -0,0 +1,77 @@ +#pragma once + +#ifndef __FX_D3D11CONTEXT_H__ +#define __FX_D3D11CONTEXT_H__ + +#if (PK_BUILD_WITH_D3D11_SUPPORT != 0) + +#include "AEGP_Define.h" + +#include "RenderApi/AEGP_BaseContext.h" + +#include + +namespace AAePk { + struct SAAEIOData; +} + +PK_FORWARD_DECLARE(CD3D11ApiManager); + +__AEGP_PK_BEGIN + +PK_FORWARD_DECLARE(AsynchronousJob_CopyTextureTask); + +struct SD3D11PlatformContext; + +class CAAED3D11Context : public CAAEBaseContext +{ +public: + static CAAEBaseContext *GetInstance() + { + return PK_NEW(CAAED3D11Context); + } + + CAAED3D11Context(); + virtual ~CAAED3D11Context(); + + virtual bool BeginFrame() override; + virtual bool EndFrame() override; + virtual void LogApiError() override; + + + virtual bool InitIFN() override; + virtual bool CreatePlatformContext(void *winHandle, void *deviceContext) override; + virtual bool CreateRenderTarget(RHI::EPixelFormat format, CUint3 size) override; + + virtual bool SetAsCurrent(void *deviceContext) override; + + virtual bool FillRenderBuffer(PRefCountedMemoryBuffer dstBuffer, RHI::PFrameBuffer srcBuffer, RHI::EPixelFormat format, u32 width, u32 height, u32 rowLength) override; + + virtual bool FillCompositingTexture(void* srcBuffer, RHI::EPixelFormat format, u32 width, u32 height, u32 rowLength) override; + + virtual TMemoryView GetCurrentSwapChain() override; + + RHI::SD3D11BasicContext *m_D3D11Context = null; +private: + bool _LoadDynamicLibrary(); + bool _CreateDevice(); + bool _PickHardwareAdapter(); + + RHI::CD3D11ApiManager *m_D3D11Manager = null; + SD3D11PlatformContext *m_Context = null; + + ID3D11Texture2D *m_Texture = null; + ID3D11Texture2D *m_StagingTexture = null; + RHI::PD3D11RenderTarget m_SwapChainRenderTarget; + + + TArray m_Tasks; + u32 m_WorkerCount; + +}; + +__AEGP_PK_END + +#endif + +#endif // __FX_D3D11CONTEXT_H__! diff --git a/AE_GeneralPlugin/Include/RenderApi/AEGP_D3D12Context.h b/AE_GeneralPlugin/Include/RenderApi/AEGP_D3D12Context.h new file mode 100644 index 00000000..15566f4a --- /dev/null +++ b/AE_GeneralPlugin/Include/RenderApi/AEGP_D3D12Context.h @@ -0,0 +1,105 @@ +//---------------------------------------------------------------------------- +// Copyright Persistant Studios, SARL. All Rights Reserved. https://www.popcornfx.com/terms-and-conditions/ +//---------------------------------------------------------------------------- +#pragma once + +#ifndef __FX_D3D12CONTEXT_H__ +#define __FX_D3D12CONTEXT_H__ + +#if (PK_BUILD_WITH_D3D12_SUPPORT != 0) + +#include "AEGP_Define.h" + +#include "RenderApi/AEGP_BaseContext.h" + +#include + +//---------------------------------------------------------------------------- + +namespace AAePk { + struct SAAEIOData; +} + +PK_FORWARD_DECLARE(CD3D12ApiManager); + +__AEGP_PK_BEGIN + +PK_FORWARD_DECLARE(AsynchronousJob_CopyTextureTask); +struct SD3D12PlatformContext; + +//---------------------------------------------------------------------------- + +class CAAED3D12Context : public CAAEBaseContext +{ + + static bool m_Once; + static CAAED3D12Context *m_Instance; +public: + static CAAEBaseContext *GetInstance() + { + if (m_Instance == null) + m_Instance = PK_NEW(CAAED3D12Context); + return m_Instance; + } + + CAAED3D12Context(); + virtual ~CAAED3D12Context(); + + CAAED3D12Context(CAAED3D12Context &) = delete; + CAAED3D12Context &operator=(CAAED3D12Context &) = delete; + + virtual bool BeginFrame() override; + virtual bool EndFrame() override; + virtual void LogApiError() override; + + + virtual bool InitIFN() override; + virtual bool CreatePlatformContext(void *winHandle, void *deviceContext) override; + virtual bool CreateRenderTarget(RHI::EPixelFormat format, CUint3 size) override; + + + virtual bool SetAsCurrent(void *deviceContext) override; + + virtual bool FillRenderBuffer(PRefCountedMemoryBuffer dstBuffer, RHI::PFrameBuffer srcBuffer, RHI::EPixelFormat format, u32 width, u32 height, u32 rowLength) override; + + virtual bool FillCompositingTexture(void* srcBuffer, RHI::EPixelFormat format, u32 width, u32 height, u32 rowLength) override; + + bool CreateCommandQueue(); + + + virtual TMemoryView GetCurrentSwapChain() override; + + RHI::SD3D12BasicContext *m_D3D12Context; + + //Don't iterate over the different RT yet; + static const u32 kFrameCount = 1; +private: + bool LoadDynamicLibrary(); + bool CreateDevice(); + bool PickHardwareAdapter(); + bool CreateDescriptorAllocator(); + PRefCountedMemoryBuffer CreateBufferFromReadBackTexture(RHI::PCReadBackTexture readBackTexture) const; + void ClearContextSwapchainsRT(); + + RHI::CD3D12ApiManager *m_D3D12Manager; + SD3D12PlatformContext *m_Context; + RHI::PD3D12Fence m_Fence; + u64 m_FrameCount = 0; + + + ID3D12Resource *m_Resources[CAAED3D12Context::kFrameCount]; + RHI::PD3D12RenderTarget m_SwapChainRenderTarget; + + + TArray m_Tasks; + u32 m_WorkerCount = 0; + +}; + +//---------------------------------------------------------------------------- + +__AEGP_PK_END + +#endif + +#endif // __FX_D3D12CONTEXT_H__! diff --git a/AE_GeneralPlugin/Include/RenderApi/AEGP_MetalContext.h b/AE_GeneralPlugin/Include/RenderApi/AEGP_MetalContext.h new file mode 100644 index 00000000..c2fd2208 --- /dev/null +++ b/AE_GeneralPlugin/Include/RenderApi/AEGP_MetalContext.h @@ -0,0 +1,90 @@ +//---------------------------------------------------------------------------- +// Copyright Persistant Studios, SARL. All Rights Reserved. https://www.popcornfx.com/terms-and-conditions/ +//---------------------------------------------------------------------------- +#pragma once + +#ifndef __AEGP_METALCONTEXT_H__ +#define __AEGP_METALCONTEXT_H__ + +#if defined (PK_MACOSX) + + +#include "AEGP_Define.h" +#include "RenderApi/AEGP_BaseContext.h" + +#include "pk_render_helpers/include/draw_requests/rh_tasks.h" // Task::CBase +#include "pk_render_helpers/include/draw_requests/rh_job_pools.h" + +//---------------------------------------------------------------------------- + +#if (PK_BUILD_WITH_METAL_SUPPORT != 0) + +namespace AAePk { + struct SAAEIOData; +} + +__PK_RHI_API_BEGIN + struct SMetalBasicContext; + struct SWaitAllSwapChains; + class CMetalApiManager; +__PK_RHI_API_END + +PK_FORWARD_DECLARE(CMetalApiManager); + +__AEGP_PK_BEGIN + struct SMetalPlatformContext; +__AEGP_PK_END + + +__AEGP_PK_BEGIN + +//---------------------------------------------------------------------------- + +class CAAEMetalContext : public CAAEBaseContext +{ +public: + static CAAEMetalContext *GetInstance() + { + if (m_Instance == null) + m_Instance = PK_NEW(CAAEMetalContext); + return m_Instance; + } + + CAAEMetalContext(); + virtual ~CAAEMetalContext(); + + virtual bool BeginFrame() override; + virtual bool EndFrame() override; + virtual void LogApiError() override; + + + virtual bool InitIFN() override; + + virtual bool SetAsCurrent(void *deviceContext) { (void)deviceContext; return true; }; + + virtual bool CreateRenderTarget(RHI::EPixelFormat format, CUint3 size) override; + + virtual bool FillRenderBuffer(PRefCountedMemoryBuffer dstBuffer, RHI::PFrameBuffer srcBuffer, RHI::EPixelFormat format, u32 width, u32 height, u32 rowLength) override; + + virtual bool FillCompositingTexture(void *srcBuffer, RHI::EPixelFormat format, u32 width, u32 height, u32 rowLength) override; + + virtual TMemoryView GetCurrentSwapChain() override; + + virtual bool CreatePlatformContext(void *winHandle, void *deviceContext) override; + +private: + SMetalPlatformContext *m_Data; + bool m_Parented; + static CAAEMetalContext *m_Instance; + RHI::SWaitAllSwapChains *m_LastFrameSyncInfo = null; +}; + +__AEGP_PK_END + +//---------------------------------------------------------------------------- + +#endif //PK_BUILD_WITH_METAL_SUPPORT != 0 + +#endif //PK_MACOSX + +#endif //__AEGP_METALCONTEXT_H__ diff --git a/AE_GeneralPlugin/PkgInfo b/AE_GeneralPlugin/PkgInfo new file mode 100644 index 00000000..62f1eddb --- /dev/null +++ b/AE_GeneralPlugin/PkgInfo @@ -0,0 +1 @@ +AEgxFXTC \ No newline at end of file diff --git a/AE_GeneralPlugin/Precompiled/ae_precompiled.cpp b/AE_GeneralPlugin/Precompiled/ae_precompiled.cpp new file mode 100644 index 00000000..84e52276 --- /dev/null +++ b/AE_GeneralPlugin/Precompiled/ae_precompiled.cpp @@ -0,0 +1 @@ +#include "ae_precompiled.h" diff --git a/AE_GeneralPlugin/Precompiled/ae_precompiled.h b/AE_GeneralPlugin/Precompiled/ae_precompiled.h new file mode 100644 index 00000000..b6bb494c --- /dev/null +++ b/AE_GeneralPlugin/Precompiled/ae_precompiled.h @@ -0,0 +1,28 @@ +#pragma once + +#ifndef __AE_PRECOMPILED_H__ +#define __AE_PRECOMPILED_H__ + +#undef PV_MODULE_NAME +#undef PV_MODULE_SYM +#define PV_MODULE_NAME "AEPlugin" +#define PV_MODULE_SYM AEPlugin + +#include + +PK_LOG_MODULE_DEFINE(); + +#include + + + +#ifdef PK_NULL_AS_VARIABLE +using PopcornFX::null; +#endif + +#if defined(PK_WINDOWS) +#define WIN32_LEAN_AND_MEAN +#include +#endif + +#endif //__AE_PRECOMPILED_H__ diff --git a/AE_GeneralPlugin/Sources/AEGP_AEPKConversion.cpp b/AE_GeneralPlugin/Sources/AEGP_AEPKConversion.cpp new file mode 100644 index 00000000..a2f51712 --- /dev/null +++ b/AE_GeneralPlugin/Sources/AEGP_AEPKConversion.cpp @@ -0,0 +1,492 @@ +//---------------------------------------------------------------------------- +// Copyright Persistant Studios, SARL. All Rights Reserved. https://www.popcornfx.com/terms-and-conditions/ +//---------------------------------------------------------------------------- +#include "ae_precompiled.h" + +#include "AEGP_AEPKConversion.h" +#include "AEGP_World.h" + +#include +#include + + +__AEGP_PK_BEGIN + +//---------------------------------------------------------------------------- + +RHI::EPixelFormat AAEToPK(PF_PixelFormat format) +{ + RHI::EPixelFormat result = RHI::EPixelFormat::FormatUnknown; + switch (format) + { + case PF_PixelFormat_ARGB32: + result = RHI::EPixelFormat::FormatUnorm8RGBA; + break; + case PF_PixelFormat_ARGB64: + result = RHI::EPixelFormat::FormatUnorm16RGBA; + break; + case PF_PixelFormat_ARGB128: + result = RHI::EPixelFormat::FormatFloat32RGBA; + break; + default: + //PF_PixelFormat_INVALID 1717854562 + PK_ASSERT_MESSAGE(false, "Unknown conversion of pixel format between PopcornFX and AfterEffects."); + break; + } + return result; +} + +//---------------------------------------------------------------------------- + +PF_PixelFormat PKToAAE(RHI::EPixelFormat format) +{ + PF_PixelFormat result = PF_PixelFormat_INVALID; + switch (format) + { + case RHI::EPixelFormat::FormatUnorm8RGBA: + result = PF_PixelFormat_ARGB32; + break; + case RHI::EPixelFormat::FormatUnorm16RGBA: + result = PF_PixelFormat_ARGB64; + break; + case RHI::EPixelFormat::FormatFloat32RGBA: + result = PF_PixelFormat_ARGB128; + break; + default: + PK_ASSERT_MESSAGE(false, "Unknown conversion of pixel format between PopcornFX and AfterEffects."); + break; + } + return result; +} + +//---------------------------------------------------------------------------- + +u32 GetPixelSizeFromPixelFormat(RHI::EPixelFormat format) +{ + u32 result = 0; + + switch (format) + { + case RHI::EPixelFormat::FormatUnorm8RGBA: + return sizeof(PF_Pixel8); + break; + case RHI::EPixelFormat::FormatUnorm16RGBA: + return sizeof(PF_Pixel16); + break; + case RHI::EPixelFormat::FormatFloat32RGBA: + return sizeof(PF_PixelFloat); + break; + default: + PK_ASSERT_MESSAGE(false, "Unknown conversion of pixel format between PopcornFX and AfterEffects."); + break; + } + return result; +} + +//---------------------------------------------------------------------------- + +void AAEToPK(A_Matrix4 &in, CFloat4x4 &out) +{ + out.XAxis() = CFloat4((float)in.mat[0][0], (float)in.mat[0][1], (float)in.mat[0][2], (float)in.mat[0][3]); + out.YAxis() = CFloat4((float)in.mat[1][0], (float)in.mat[1][1], (float)in.mat[1][2], (float)in.mat[1][3]); + out.ZAxis() = CFloat4((float)in.mat[2][0], (float)in.mat[2][1], (float)in.mat[2][2], (float)in.mat[2][3]); + out.WAxis() = CFloat4((float)in.mat[3][0], (float)in.mat[3][1], (float)in.mat[3][2], (float)in.mat[3][3]); +} + +//---------------------------------------------------------------------------- + +void AAEToPK(A_Matrix4 &in, CFloat4x4 *out) +{ + AAEToPK(in, *out); +} + +//---------------------------------------------------------------------------- + +CFloat3 AAEToPK(A_FloatPoint3 &in) +{ + CFloat3 res((float)in.x, (float)in.y, (float)in.z); + return res; +} + +//---------------------------------------------------------------------------- + +A_FloatPoint3 PKToAAE(CFloat3 &in) +{ + A_FloatPoint3 res; + res.x = in.x(); + res.y = in.y(); + res.z = in.z(); + return res; +} + +//---------------------------------------------------------------------------- + +CFloat3 AngleAAEToPK(A_FloatPoint3 &in) +{ + return CFloat3(DegToRad((float)in.x), DegToRad((float)in.y), DegToRad((float)in.z)); +} + +//---------------------------------------------------------------------------- + +A_FloatPoint3 AnglePKToAAE(CFloat3 &in) +{ + CFloat3 degree(RadToDeg(in.x()), RadToDeg(in.y()), RadToDeg(in.z())); + return PKToAAE(degree); +} + +//---------------------------------------------------------------------------- + +EAttributeSemantic AttributePKToAAE(EDataSemantic value) +{ + PK_STATIC_ASSERT((int)EDataSemantic::DataSemantic_None == (int)EAttributeSemantic::AttributeSemantic_None); + PK_STATIC_ASSERT((int)EDataSemantic::DataSemantic_3DCoordinate == (int)EAttributeSemantic::AttributeSemantic_Coordinate); + PK_STATIC_ASSERT((int)EDataSemantic::DataSemantic_3DScale == (int)EAttributeSemantic::AttributeSemantic_Scale); + PK_STATIC_ASSERT((int)EDataSemantic::DataSemantic_Color == (int)EAttributeSemantic::AttributeSemantic_Color); + + return (EAttributeSemantic)value; +} + +//---------------------------------------------------------------------------- + +EAttributeType AttributePKToAAE(EBaseTypeID value) +{ + EAttributeType res = AttributeType_None; + switch(value) + { + case (BaseType_Bool): + res = AttributeType_Bool1; + break; + case (BaseType_Bool2): + res = AttributeType_Bool2; + break; + case (BaseType_Bool3): + res = AttributeType_Bool3; + break; + case (BaseType_Bool4): + res = AttributeType_Bool4; + break; + case (BaseType_I32): + res = AttributeType_Int1; + break; + case (BaseType_Int2): + res = AttributeType_Int2; + break; + case (BaseType_Int3): + res = AttributeType_Int3; + break; + case (BaseType_Int4): + res = AttributeType_Int4; + break; + case (BaseType_Float): + res = AttributeType_Float1; + break; + case (BaseType_Float2): + res = AttributeType_Float2; + break; + case (BaseType_Float3): + res = AttributeType_Float3; + break; + case (BaseType_Float4): + res = AttributeType_Float4; + break; + default: + PK_ASSERT_NOT_REACHED_MESSAGE("Attribute Type missmatch !"); + } + return res; +} + +//---------------------------------------------------------------------------- + +EAttributeSamplerType AttributeSamplerPKToAAE(SParticleDeclaration::SSampler::ESamplerType type) +{ + EAttributeSamplerType res = AttributeSamplerType_None; + switch (type) + { + case (SParticleDeclaration::SSampler::ESamplerType::Sampler_Animtrack): + res = AttributeSamplerType_Animtrack; + break; + case (SParticleDeclaration::SSampler::ESamplerType::Sampler_Audio): + res = AttributeSamplerType_Audio; + break; + case (SParticleDeclaration::SSampler::ESamplerType::Sampler_Curve): + res = AttributeSamplerType_Curve; + break; + case (SParticleDeclaration::SSampler::ESamplerType::Sampler_EventStream): + res = AttributeSamplerType_EventStream; + break; + case (SParticleDeclaration::SSampler::ESamplerType::Sampler_Geometry): + res = AttributeSamplerType_Geometry; + break; + case (SParticleDeclaration::SSampler::ESamplerType::Sampler_Image): + res = AttributeSamplerType_Image; + break; + case (SParticleDeclaration::SSampler::ESamplerType::Sampler_Grid): + res = AttributeSamplerType_Grid; + break; + case (SParticleDeclaration::SSampler::ESamplerType::Sampler_ImageAtlas): + res = AttributeSamplerType_ImageAtlas; + break; + case (SParticleDeclaration::SSampler::ESamplerType::Sampler_Text): + res = AttributeSamplerType_Text; + break; + case (SParticleDeclaration::SSampler::ESamplerType::Sampler_VectorField): + res = AttributeSamplerType_VectorField; + break; + default: + PK_ASSERT_NOT_REACHED_MESSAGE("Attribute Sampler Type missmatch !"); + break; + } + return res; +} + +//---------------------------------------------------------------------------- + +EBaseTypeID AttributeAAEToPK(EAttributeType value) +{ + EBaseTypeID res = BaseType_Evolved; + switch (value) + { + case (AttributeType_Bool1): + res = BaseType_Bool; + break; + case (AttributeType_Bool2): + res = BaseType_Bool2; + break; + case (AttributeType_Bool3): + res = BaseType_Bool3; + break; + case (AttributeType_Bool4): + res = BaseType_Bool4; + break; + case (AttributeType_Int1): + res = BaseType_I32; + break; + case (AttributeType_Int2): + res = BaseType_Int2; + break; + case (AttributeType_Int3): + res = BaseType_Int3; + break; + case (AttributeType_Int4): + res = BaseType_Int4; + break; + case (AttributeType_Float1): + res = BaseType_Float; + break; + case (AttributeType_Float2): + res = BaseType_Float2; + break; + case (AttributeType_Float3): + res = BaseType_Float3; + break; + case (AttributeType_Float4): + res = BaseType_Float4; + break; + default: + PK_ASSERT_NOT_REACHED_MESSAGE("Attribute Type missmatch !"); + } + return res; +} + +//---------------------------------------------------------------------------- + +PKSample::CRHIParticleSceneRenderHelper::ERenderTargetDebug AAEToPK(ERenderType value) +{ + PKSample::CRHIParticleSceneRenderHelper::ERenderTargetDebug res = PKSample::CRHIParticleSceneRenderHelper::RenderTargetDebug_NoDebug; + switch (value) + { + case (RenderType_FinalCompositing): + res = PKSample::CRHIParticleSceneRenderHelper::RenderTargetDebug_NoDebug; + break; + case (RenderType_Emissive): + res = PKSample::CRHIParticleSceneRenderHelper::RenderTargetDebug_NoDebug; + break; + case (RenderType_Albedo): + res = PKSample::CRHIParticleSceneRenderHelper::RenderTargetDebug_Diffuse; + break; + case (RenderType_Normal): + res = PKSample::CRHIParticleSceneRenderHelper::RenderTargetDebug_NormalUnpacked; + break; + case (RenderType_Depth): + res = PKSample::CRHIParticleSceneRenderHelper::RenderTargetDebug_Depth; + break; + default: + PK_ASSERT_NOT_REACHED_MESSAGE("Render Type missmatch !"); + + } + return res; +} + +//---------------------------------------------------------------------------- + +void AAEToPK(SPostFXBloomDesc &in, PKSample::SParticleSceneOptions::SBloom &out) +{ + out.m_Enable = in.m_Enable; + out.m_BrightPassValue = in.m_BrightPassValue; + out.m_Intensity = in.m_Intensity; + out.m_Attenuation = in.m_Attenuation; + + switch (in.m_GaussianBlur) + { + case (GaussianBlurPixelRadius_5): + out.m_BlurTap = PKSample::GaussianBlurCombination_5_Tap; + break; + case (GaussianBlurPixelRadius_9): + out.m_BlurTap = PKSample::GaussianBlurCombination_9_Tap; + break; + case (GaussianBlurPixelRadius_13): + out.m_BlurTap = PKSample::GaussianBlurCombination_13_Tap; + break; + } + out.m_RenderPassCount = in.m_RenderPassCount; +} + +//---------------------------------------------------------------------------- + +void AAEToPK(SPostFXDistortionDesc &in, PKSample::SParticleSceneOptions::SDistortion &out) +{ + out.m_Enable = in.m_Enable; +} + +//---------------------------------------------------------------------------- + +void AAEToPK(SPostFXToneMappingDesc &in, PKSample::SParticleSceneOptions::SToneMapping &out) +{ + out.m_Saturation = in.m_Saturation; + out.m_Enable = in.m_Enable; + out.m_Exposure = in.m_Exposure; +} + +//---------------------------------------------------------------------------- + +void AAEToPK(SPostFXAADesc &in, PKSample::SParticleSceneOptions::SFXAA &out) +{ + out.m_Enable = in.m_Enable; +} + +//---------------------------------------------------------------------------- + +void AAEToPK(SRenderingDesc &in, PKSample::SParticleSceneOptions &out) +{ + AAEToPK(in.m_Bloom, out.m_Bloom); + AAEToPK(in.m_Distortion, out.m_Distortion); + AAEToPK(in.m_ToneMapping, out.m_ToneMapping); + AAEToPK(in.m_FXAA, out.m_FXAA); +} + +//---------------------------------------------------------------------------- + +CParticleSamplerDescriptor_VectorField_Grid::EInterpolation AAEToPK(EInterpolationType &value) +{ + CParticleSamplerDescriptor_VectorField_Grid::EInterpolation res = CParticleSamplerDescriptor_VectorField_Grid::EInterpolation::__MaxInterpolations; + switch (value) + { + case EInterpolationType::EInterpolationType_Point: + res = CParticleSamplerDescriptor_VectorField_Grid::EInterpolation::Interpolation_Point; + break; + case EInterpolationType::EInterpolationType_Trilinear: + res = CParticleSamplerDescriptor_VectorField_Grid::EInterpolation::Interpolation_Trilinear; + break; + case EInterpolationType::EInterpolationType_Quadrilinear: + res = CParticleSamplerDescriptor_VectorField_Grid::EInterpolation::Interpolation_Quadrilinear; + break; + default: + PK_ASSERT_NOT_REACHED_MESSAGE("Render Type missmatch !"); + break; + } + return res; +} + +//---------------------------------------------------------------------------- + +CUbyte3 ConvertSRGBToLinear(CUbyte3 v) +{ + CFloat3 vf(v.x() / 255.0f, v.y() / 255.0f, v.z() / 255.0f); + + CFloat3 vfl = PKSample::ConvertSRGBToLinear(vf); + return CUbyte3(static_cast(vfl.x() * 255.0f), static_cast(vfl.y() * 255.0f), static_cast(vfl.z() * 255.0f)); +} + +//---------------------------------------------------------------------------- + +CUbyte3 ConvertLinearToSRGB(CUbyte3 v) +{ + CFloat3 vf(v.x() / 255.0f, v.y() / 255.0f, v.z() / 255.0f); + + CFloat3 vfl = PKSample::ConvertLinearToSRGB(vf); + return CUbyte3(static_cast(vfl.x() * 255.0f), static_cast(vfl.y() * 255.0f), static_cast(vfl.z() * 255.0f)); +} + +//---------------------------------------------------------------------------- + +EApiValue RHIApiToAEApi(RHI::EGraphicalApi value) +{ + EApiValue ret; + switch (value) + { +#if PK_BUILD_WITH_D3D12_SUPPORT != 0 + case RHI::EGraphicalApi::GApi_D3D12: + ret = EApiValue::D3D12; + break; +#endif +#if PK_BUILD_WITH_D3D11_SUPPORT != 0 + case RHI::EGraphicalApi::GApi_D3D11: + ret = EApiValue::D3D11; + break; +#endif +#if PK_BUILD_WITH_METAL_SUPPORT != 0 + case RHI::EGraphicalApi::GApi_Metal: + ret = EApiValue::Metal; + break; +#endif + default: +#if defined(PK_WINDOWS) && PK_BUILD_WITH_D3D11_SUPPORT != 0 + ret = EApiValue::D3D11; +#elif defined(PK_MACOSX) && PK_BUILD_WITH_METAL_SUPPORT != 0 + ret = EApiValue::Metal; +#else + PK_ASSERT_NOT_REACHED_MESSAGE("Cannot choose a compatible default API for the current platform"); +#endif + break; + } + return ret; +} + +//---------------------------------------------------------------------------- + +RHI::EGraphicalApi AEApiToRHIApi(EApiValue value) +{ + RHI::EGraphicalApi ret; + switch (value) + { +#if PK_BUILD_WITH_D3D12_SUPPORT != 0 + case EApiValue::D3D12: + ret = RHI::EGraphicalApi::GApi_D3D12; + break; +#endif +#if PK_BUILD_WITH_D3D11_SUPPORT != 0 + case EApiValue::D3D11: + ret = RHI::EGraphicalApi::GApi_D3D11; + break; +#endif +#if PK_BUILD_WITH_METAL_SUPPORT != 0 + case EApiValue::Metal: + ret = RHI::EGraphicalApi::GApi_Metal; + break; +#endif + default: +#if defined(PK_WINDOWS) && PK_BUILD_WITH_D3D11_SUPPORT != 0 + ret = RHI::EGraphicalApi::GApi_D3D11; +#elif defined(PK_MACOSX) && PK_BUILD_WITH_METAL_SUPPORT != 0 + ret = RHI::EGraphicalApi::GApi_Metal; +#else + PK_ASSERT_NOT_REACHED_MESSAGE("Cannot choose a compatible default API for the current platform"); +#endif + break; + } + return ret; + +} + +//---------------------------------------------------------------------------- +__AEGP_PK_END diff --git a/AE_GeneralPlugin/Sources/AEGP_AssetBaker.cpp b/AE_GeneralPlugin/Sources/AEGP_AssetBaker.cpp new file mode 100644 index 00000000..4880ba38 --- /dev/null +++ b/AE_GeneralPlugin/Sources/AEGP_AssetBaker.cpp @@ -0,0 +1,799 @@ +//---------------------------------------------------------------------------- +// Copyright Persistant Studios, SARL. All Rights Reserved. https://www.popcornfx.com/terms-and-conditions/ +//---------------------------------------------------------------------------- +#include "ae_precompiled.h" +#include "AEGP_AssetBaker.h" + +#include "AEGP_World.h" + +#include "AEGP_PopcornFXPlugins.h" + +#include "AEGP_PackExplorer.h" +#include "AEGP_FileWatcher.h" +#include "pk_kernel/include/kr_log_listeners_file.h" + +//Baking +#include "pk_imaging/include/im_resource.h" +#include "pk_geometrics/include/ge_mesh_resource_handler.h" +#include "pk_geometrics/include/ge_rectangle_list.h" +#include "pk_particles/include/ps_font_metrics_resource.h" +#include "pk_particles/include/ps_vectorfield_resource.h" +#include "pk_base_object/include/hbo_context.h" + +#include "PK-AssetBakerLib/AssetBaker_Oven.h" +#include "PK-AssetBakerLib/AssetBaker_Oven_HBO.h" +#include "PK-AssetBakerLib/AssetBaker_Oven_Mesh.h" +#include "PK-AssetBakerLib/AssetBaker_Oven_VectorField.h" +#include "PK-AssetBakerLib/AssetBaker_Oven_Texture.h" +#include "PK-AssetBakerLib/AssetBaker_Oven_StraightCopy.h" + +#include "AEGP_Log.h" + +__AEGP_PK_BEGIN + +//---------------------------------------------------------------------------- + +static const CStringView kPopcornProjectExtension = "pkproj"; + +//---------------------------------------------------------------------------- + +HBO_CLASS_DEFINITION_BEGIN(CEditorAssetEffect) +.HBO_FIELD_DEFINITION(StartCameraPosition) +[ + HBO::Properties::DefaultValue(CFloat3(0.0f, 0.0f, 5.0f)), + HBO::Properties::AlwaysSerialize(), + HBO::Properties::Caracs(HBO::FieldCaracs::Caracs_3DCoordinateDistance), + HBO::Properties::Description("Initial position of the camera when opening the effect") +] +.HBO_FIELD_DEFINITION(StartCameraOrientation) +[ + HBO::Properties::DefaultValue(CFloat3::ZERO), + HBO::Properties::AlwaysSerialize(), + HBO::Properties::Caracs(HBO::Caracs_3DCoordinate), + HBO::Properties::Description("Initial euler orientation of the camera when opening the effect") +] +HBO_CLASS_DEFINITION_END + +//---------------------------------------------------------------------------- + +CEditorAssetEffect::CEditorAssetEffect() + :HBO_CONSTRUCT(CEditorAssetEffect) +{ + +} + +//---------------------------------------------------------------------------- + +CEditorAssetEffect::~CEditorAssetEffect() +{ + +} + +//---------------------------------------------------------------------------- + +void CEditorAssetEffect::CopyFrom(CEditorAssetEffect *other) +{ + SetStartCameraPosition(other->StartCameraPosition()); + SetStartCameraOrientation(other->StartCameraOrientation()); +} + +//---------------------------------------------------------------------------- + +CProjectSettingsFinder::CProjectSettingsFinder(const CString &rootDir, IFileSystem *controller) + : CFileDirectoryWalker(rootDir, IgnoreVirtualFS, controller) +{ + SetFilePathValidator(ProjectSettingsPathValidator); +} + +//---------------------------------------------------------------------------- + +void CProjectSettingsFinder::FileNotifier(const CFilePack *pack, const char *fullPath, u32 fileFirstCharPos) +{ + (void)pack; + (void)fileFirstCharPos; + + PK_ASSERT(CFilePath::IsPure(fullPath)); + PK_ASSERT(kPopcornProjectExtension == CFilePath::ExtractExtension(fullPath)); + + if (!PK_VERIFY(m_ProjectSettingsPath == null)) + { + CLog::Log(PK_ERROR, "Multiple pkproj found in RootDir (\"%s\").", fullPath); + } + else + { + m_ProjectSettingsPath = fullPath; + } +} + +//---------------------------------------------------------------------------- + +bool CProjectSettingsFinder::DirectoryNotifier(const CFilePack *pack, const char *fullPath, u32 directoryFirstCharPos) +{ + (void)pack; + (void)fullPath; + (void)directoryFirstCharPos; + return true; // Recursive search +} + +//---------------------------------------------------------------------------- + +const CString &CProjectSettingsFinder::ProjectSettingsPath() const +{ + return m_ProjectSettingsPath; +} + +//---------------------------------------------------------------------------- + +bool CProjectSettingsFinder::ProjectSettingsPathValidator(const char *filePath) +{ + return kPopcornProjectExtension == CFilePath::ExtractExtension(filePath); +} + +//---------------------------------------------------------------------------- +// SBakeContext +//---------------------------------------------------------------------------- + +SBakeContext::SBakeContext() + : m_BakeResourceMeshHandler(null) + , m_BakeResourceImageHandler(null) + , m_BakeResourceRectangleListHandler(null) + , m_BakeResourceFontMetricsHandler(null) + , m_BakeResourceVectorFieldHandler(null) + , m_BakeFSController(null) + , m_BakeResourceManager(null) + , m_Initialized(false) +{ +} + +//---------------------------------------------------------------------------- + +SBakeContext::~SBakeContext() +{ + if (!m_Initialized) + return; + + CCookeryLogger::Shutdown(); + + if (m_BakeResourceManager != null) + { + PK_ASSERT(m_BakeResourceMeshHandler != null); + PK_ASSERT(m_BakeResourceImageHandler != null); + PK_ASSERT(m_BakeResourceVectorFieldHandler != null); + PK_ASSERT(m_BakeResourceFontMetricsHandler != null); + PK_ASSERT(m_BakeResourceRectangleListHandler != null); + + m_BakeResourceManager->UnregisterHandler(m_BakeResourceMeshHandler); + m_BakeResourceManager->UnregisterHandler(m_BakeResourceImageHandler); + m_BakeResourceManager->UnregisterHandler(m_BakeResourceRectangleListHandler); + m_BakeResourceManager->UnregisterHandler(m_BakeResourceFontMetricsHandler); + m_BakeResourceManager->UnregisterHandler(m_BakeResourceVectorFieldHandler); + } + PK_SAFE_DELETE(m_BakeResourceMeshHandler); + PK_SAFE_DELETE(m_BakeResourceImageHandler); + PK_SAFE_DELETE(m_BakeResourceVectorFieldHandler); + PK_SAFE_DELETE(m_BakeResourceFontMetricsHandler); + PK_SAFE_DELETE(m_BakeResourceRectangleListHandler); + PK_SAFE_DELETE(m_BakeContext); + PK_SAFE_DELETE(m_BakeFSController); + PK_SAFE_DELETE(m_BakeResourceManager); + + // unregister the oven's HBO bake-config classes: + COvenBakeConfig_Audio::UnregisterHandler(); + COvenBakeConfig_StraightCopy::UnregisterHandler(); + COvenBakeConfig_Particle::UnregisterHandler(); + COvenBakeConfig_ParticleCompiler::UnregisterHandler(); + COvenBakeConfig_VectorField::UnregisterHandler(); + COvenBakeConfig_TextureAtlas::UnregisterHandler(); + COvenBakeConfig_Texture::UnregisterHandler(); + COvenBakeConfig_Mesh::UnregisterHandler(); + COvenBakeConfig_HBO::UnregisterHandler(); + COvenBakeConfig_Base::UnregisterHandler(); +} + +//---------------------------------------------------------------------------- + +bool SBakeContext::Init() +{ + PK_ASSERT(m_BakeResourceMeshHandler == null); + PK_ASSERT(m_BakeResourceImageHandler == null); + PK_ASSERT(m_BakeResourceVectorFieldHandler == null); + PK_ASSERT(m_BakeResourceFontMetricsHandler == null); + PK_ASSERT(m_BakeResourceRectangleListHandler == null); + PK_ASSERT(m_BakeFSController == null); + PK_ASSERT(m_BakeResourceManager == null); + + // We do not constant fold the images because we do not want to link with all the image codecs: + m_BakeResourceImageHandler = PK_NEW(CResourceHandlerDummy); + m_BakeResourceVectorFieldHandler = PK_NEW(CResourceHandlerDummy); + // Keep this updated with all PopcornFX resource types + m_BakeResourceMeshHandler = PK_NEW(PopcornFX::CResourceHandlerMesh); + m_BakeResourceRectangleListHandler = PK_NEW(PopcornFX::CResourceHandlerRectangleList); + m_BakeResourceFontMetricsHandler = PK_NEW(PopcornFX::CResourceHandlerFontMetrics); + + if (!PK_VERIFY(m_BakeResourceMeshHandler != null) || + !PK_VERIFY(m_BakeResourceImageHandler != null) || + !PK_VERIFY(m_BakeResourceRectangleListHandler != null) || + !PK_VERIFY(m_BakeResourceFontMetricsHandler != null) || + !PK_VERIFY(m_BakeResourceVectorFieldHandler != null)) + return false; + + m_BakeFSController = File::NewInternalFileSystem(); + if (!PK_VERIFY(m_BakeFSController != null)) + return false; + + m_BakeResourceManager = PK_NEW(PopcornFX::CResourceManager(m_BakeFSController)); + if (!PK_VERIFY(m_BakeResourceManager != null)) + return false; + m_BakeResourceManager->RegisterHandler(m_BakeResourceMeshHandler); + m_BakeResourceManager->RegisterHandler(m_BakeResourceImageHandler); + m_BakeResourceManager->RegisterHandler(m_BakeResourceRectangleListHandler); + m_BakeResourceManager->RegisterHandler(m_BakeResourceFontMetricsHandler); + m_BakeResourceManager->RegisterHandler(m_BakeResourceVectorFieldHandler); + + m_BakeContext = PK_NEW(PopcornFX::HBO::CContext(m_BakeResourceManager)); + if (!PK_VERIFY(m_BakeContext != null)) + return false; + + // register the oven's HBO bake-config classes: + COvenBakeConfig_Base::RegisterHandler(); + COvenBakeConfig_HBO::RegisterHandler(); + COvenBakeConfig_Mesh::RegisterHandler(); + COvenBakeConfig_Texture::RegisterHandler(); + COvenBakeConfig_TextureAtlas::RegisterHandler(); + COvenBakeConfig_VectorField::RegisterHandler(); + COvenBakeConfig_ParticleCompiler::RegisterHandler(); + COvenBakeConfig_Particle::RegisterHandler(); + COvenBakeConfig_StraightCopy::RegisterHandler(); + COvenBakeConfig_Audio::RegisterHandler(); + + const CVaultHandler &vault = CPopcornFXWorld::Instance().GetVaultHandler(); + + const CString vaultlogs = vault.VaultPathLog(); + + if (!PK_VERIFY(CCookeryLogger::Startup(vaultlogs / "AssetBakerLogs", true))) + return false; + + m_Initialized = true; + return true; +} + +//---------------------------------------------------------------------------- + +bool SBakeContext::_RemapPath(CString &path) +{ + CString extension = CFilePath::ExtractExtension(path.Data()); + + if (extension.Compare("fbx", CaseInsensitive)) + path = CFilePath::StripExtension(path) + ".pkmm"; + if (extension.Compare("fga", CaseInsensitive)) + path = CFilePath::StripExtension(path) + ".pkvf"; + if (extension.Compare("pkfx", CaseInsensitive)) + path = CFilePath::StripExtension(path) + ".pkb"; + + return true; +} + +CString SBakeContext::_RemapFX(const CString &path) +{ + CString extension = CFilePath::ExtractExtension(path.Data()); + + if (extension.Compare("pkfx", CaseInsensitive)) + return CFilePath::StripExtension(path) + ".pkb"; + return null; +} + +//---------------------------------------------------------------------------- + +CEffectBaker::CEffectBaker() + : m_Initialized(false) + , m_SrcPack(null) + , m_DstPack(null) +{ + m_BakeContext.Init(); +} + +//---------------------------------------------------------------------------- + +CEffectBaker::~CEffectBaker() +{ + Clear(); + m_Initialized = false; +} + +//---------------------------------------------------------------------------- + +void CEffectBaker::FileAdded(const CString &path) +{ + if (path.EndsWith(".pkfx") == true || path.EndsWith(".pkri")) + { + SAssetChange effect; + + if (IsChangeRegistered(path, EAssetChangesType::Add) == true) + return; + CString cleanPath = path.Extract(m_SrcPackPath.SlashAppended().Length(), path.Length()); + CFilePath::Purify(cleanPath); + effect.m_EffectPath = cleanPath; + effect.m_Type = EAssetChangesType::Add; + + PK_SCOPEDLOCK(m_Lock); + m_ToBake.PushBack(effect); + } +} + +//---------------------------------------------------------------------------- + +void CEffectBaker::FileRemoved(const CString &path) +{ + (void)path; +#if 0 //User isn't supposed to remove content of the vault during play ? + if (path.EndsWith(".pkfx") == true || path.EndsWith(".pkri")) + { + SAssetChange effect; + + if (IsChangeRegistered(path, EAssetChangesType::Remove) == true) + return; + CString cleanPath = path.Extract(m_SrcPackPath.SlashAppended().Length(), path.Length()); + CFilePath::Purify(cleanPath); + effect.m_EffectPath = cleanPath; + effect.m_Type = EAssetChangesType::Remove; + + PK_SCOPEDLOCK(m_Lock); + } +#endif +} + +//---------------------------------------------------------------------------- + +void CEffectBaker::FileChanged(const CString &path) +{ + if (path.EndsWith(".pkfx") == true || path.EndsWith(".pkri")) + { + SAssetChange effect; + + if (IsChangeRegistered(path, EAssetChangesType::Update) == true) + return; + CString cleanPath = path.Extract(m_SrcPackPath.SlashAppended().Length(), path.Length()); + CFilePath::Purify(cleanPath); + + CEffectBaker::FileChangedRelativePath(cleanPath); + } +} + +//---------------------------------------------------------------------------- + +void CEffectBaker::FileChangedRelativePath(const CString &path) +{ + SAssetChange effect; + + effect.m_EffectPath = path; + effect.m_Type = EAssetChangesType::Update; + + PK_SCOPEDLOCK(m_Lock); + m_ToBake.PushBack(effect); +} + +//---------------------------------------------------------------------------- + +void CEffectBaker::FileRenamed(const CString &oldPath, const CString &newPath) +{ + if (newPath.EndsWith(".pkfx") == true) + { + SAssetChange effect; + + if (IsChangeRegistered(newPath, EAssetChangesType::Rename) == true) + return; + + CString cleanPath = newPath.Extract(m_SrcPackPath.SlashAppended().Length(), newPath.Length()); + CString cleanOldPath = oldPath.Extract(m_SrcPackPath.SlashAppended().Length(), oldPath.Length()); + + CFilePath::Purify(cleanPath); + CFilePath::Purify(cleanOldPath); + + effect.m_EffectPath = cleanPath; + effect.m_EffectPathOld = cleanOldPath; + effect.m_Type = EAssetChangesType::Rename; + + PK_SCOPEDLOCK(m_Lock); + m_ToBake.PushBack(effect); + } +} + +//---------------------------------------------------------------------------- + +void CEffectBaker::Initialize(const CString &srcPack, const CString &dstPack, const CString &pkprojPath) +{ + m_RootDir = ""; + if (!pkprojPath.Empty()) + LoadProjectSettings(pkprojPath); + + m_SrcPackPath = srcPack / m_RootDir; + m_DstPackPath = dstPack; + + if (m_SrcPackPath == m_DstPackPath) + { + CAELog::TryLogErrorWindows("Bake Error: Trying to bake into the source pack, aborting"); + return; + } + CLog::Log(PK_INFO, "Setting up cookery with source pack: \"%s\" and destination path: \"%s\"", m_SrcPackPath.Data(), m_DstPackPath.Data()); + m_BakeContext.m_BakeFSController->UnmountAllPacks(); + + m_SrcPack = m_BakeContext.m_BakeFSController->MountPack(m_SrcPackPath); + + // Initialize the cookery: + if (!m_Initialized) + { + Mem::Reinit(m_Cookery); + + m_Cookery.SetHBOContext(m_BakeContext.m_BakeContext); + if (!m_Cookery.TurnOn()) + { + CLog::Log(PK_WARN, "Couldn't initialize the cookery, TurnOn Failed."); + return; + } + + const CGuid ovenIdHBO = m_Cookery.RegisterOven(PK_NEW(COven_HBO)); + const CGuid ovenIdMesh = m_Cookery.RegisterOven(PK_NEW(COven_Mesh)); + const CGuid ovenIdTexture = m_Cookery.RegisterOven(PK_NEW(COven_Texture)); + const CGuid ovenIdTextureAtlas = m_Cookery.RegisterOven(PK_NEW(COven_TextureAtlas)); + const CGuid ovenIdVectorField = m_Cookery.RegisterOven(PK_NEW(COven_VectorField)); + + COven_Particle *ovenParticle = PK_NEW(COven_Particle); + ovenParticle->SetExternalPathRemapper(FastDelegate(SBakeContext::_RemapPath)); + const CGuid ovenIdParticle = m_Cookery.RegisterOven(ovenParticle); + + const CGuid ovenIdStraightCopy = m_Cookery.RegisterOven(PK_NEW(COven_StraightCopy)); + const CGuid ovenIdAudio = m_Cookery.RegisterOven(PK_NEW(COven_Audio)); + + if (!ovenIdHBO.Valid() || !ovenIdMesh.Valid() || !ovenIdTexture.Valid() || !ovenIdTextureAtlas.Valid() || + !ovenIdVectorField.Valid() || !ovenIdParticle.Valid() || !ovenIdStraightCopy.Valid() || + !ovenIdAudio.Valid()) + { + CLog::Log(PK_WARN, "Couldn't initialize the cookery, RegisterOven Failed."); + return; + } + + m_Cookery.MapOven("pkri", ovenIdStraightCopy); // Editor Material + m_Cookery.MapOven("pkma", ovenIdStraightCopy); // Editor Material + // map all known extensions to the appropriate oven: + m_Cookery.MapOven("fbx", ovenIdMesh); // FBX mesh + m_Cookery.MapOven("pkmm", ovenIdMesh); // PopcornFX multi-mesh + m_Cookery.MapOven("dds", ovenIdTexture); // dds image + m_Cookery.MapOven("png", ovenIdTexture); // png image + m_Cookery.MapOven("jpg", ovenIdTexture); // jpg image + m_Cookery.MapOven("jpeg", ovenIdTexture); // jpg image + m_Cookery.MapOven("tga", ovenIdTexture); // tga image + m_Cookery.MapOven("tif", ovenIdTexture); // tiff image + m_Cookery.MapOven("tiff", ovenIdTexture); // tiff image + m_Cookery.MapOven("pkm", ovenIdTexture); // pkm image + m_Cookery.MapOven("pvr", ovenIdTexture); // pvrtc image + //m_Cookery.MapOven("exr", ovenIdTexture); // exr image ------------- Collide with FBX + m_Cookery.MapOven("hdr", ovenIdTexture); // hdr image + m_Cookery.MapOven("txt", ovenIdStraightCopy); // misc + m_Cookery.MapOven("fga", ovenIdVectorField); // FGA vector-field + m_Cookery.MapOven("pkfm", ovenIdStraightCopy); // PopcornFX font + m_Cookery.MapOven("pkvf", ovenIdStraightCopy); // PopcornFX vector-field + m_Cookery.MapOven("pkat", ovenIdTextureAtlas); // PopcornFX atlas definition + m_Cookery.MapOven("pksc", ovenIdStraightCopy); // PopcornFX simulation cache + m_Cookery.MapOven("pkbo", ovenIdHBO); // PopcornFX base object + m_Cookery.MapOven("pkan", ovenIdHBO); // PopcornFX Animation + m_Cookery.MapOven("pksa", ovenIdHBO); // PopcornFX Skeletal Animation + m_Cookery.MapOven("mp3", ovenIdAudio); // mp3 sound + m_Cookery.MapOven("wav", ovenIdAudio); // wav sound + m_Cookery.MapOven("ogg", ovenIdAudio); // ogg sound + m_Cookery.MapOven("pkfx", ovenIdParticle, FastDelegate(SBakeContext::_RemapFX)); // PopcornFX Effect + + m_Cookery.AddOvenFlags(PopcornFX::COven::Flags_BakeMemoryVersion); + AEGPPk::CPopcornFXWorld &world = AEGPPk::CPopcornFXWorld::Instance(); + CString installPath = world.GetPluginInstallationPath(); + CString SrcPackPath = srcPack.Replace('/', '\\'); + + PopcornFX::PBaseObjectFile configFile = m_Cookery.m_BaseConfigFile; + PK_FOREACH(it, configFile->ObjectList()) + { + PopcornFX::COvenBakeConfig_Particle *config = PopcornFX::HBO::Cast(*it); + if (config != null) + { + config->SetCompile(true); + config->SetSourceConfig(Bake_NoSource); + config->SetRemoveEditorNodes(true); + config->SetBakeMode(PopcornFX::COvenBakeConfig_HBO::Bake_SaveAsBinary); + + COvenBakeConfig_Particle::_TypeOfBackendCompilers backendCompilers; + +#if (PK_COMPILER_BUILD_COMPILER_D3D12 != 0) + if (world.GetRenderApi() == RHI::GApi_D3D12) + { + //BakeBytecodeCommandLine_Windows = "\"{DXC}\" -T cs_6_0 -E main -WX -Ges -O3 -nologo -all_resources_bound -Fo \"$(TargetPath)\" \"$(InputPath)\""; + const CString cmdLine_D3D12 = "\"" + installPath + "fxc.exe\"" + " -T cs_5_1 -E main -WX -Ges -O3 -all_resources_bound -Fo \"$(TargetPath)\" \"$(InputPath)\""; + POvenBakeConfig_ParticleCompiler backendCompiler = m_Cookery.HBOContext()->NewObject(configFile.Get()); + if (!PK_VERIFY(backendCompiler != null) || + !PK_VERIFY(backendCompilers.PushBack(backendCompiler).Valid())) + return; + backendCompiler->SetTarget(BackendTarget_D3D12); + backendCompiler->SetBakeBytecodeCommandLine_Windows(cmdLine_D3D12); + } +#endif +#if (PK_COMPILER_BUILD_COMPILER_D3D11 != 0) + if (world.GetRenderApi() == RHI::GApi_D3D11) + { + const CString cmdLine_D3D11 = "\"" + installPath + "fxc.exe\"" + " -T cs_5_0 -E main -WX -Ges -O3 -Fo \"$(TargetPath)\" \"$(InputPath)\""; + POvenBakeConfig_ParticleCompiler backendCompiler = m_Cookery.HBOContext()->NewObject(configFile.Get()); + if (!PK_VERIFY(backendCompiler != null) || + !PK_VERIFY(backendCompilers.PushBack(backendCompiler).Valid())) + return; + backendCompiler->SetTarget(BackendTarget_D3D11); + backendCompiler->SetBakeBytecodeCommandLine_Windows(cmdLine_D3D11); + } +#endif + config->SetBackendCompilers(backendCompilers); + + config->SetCompilerSwitches("--determinism"); + config->SetCommandLine_Windows( "\"" + installPath + "PK-ShaderTool_r.exe\" -v -k false -O \"$(TargetPath)\"" + " -P \"" + SrcPackPath + "\" " + + "-api d3d " + "-c \"\\\"" + installPath + "fxc.exe\\\" -T ##ShortStage##_5_0 ##InputPath## -Fo ##OutputPath## -nologo -O3\" \"$(InputPath)\""); + config->SetCommandLine_MacOsX( "\"" + installPath + "AE_GeneralPlugin.plugin/Contents/MacOs/PK-ShaderTool_r\" -v -k false -O \"$(TargetPath)\"" + " -P \"" + SrcPackPath + "\" " + + "-api metal -c \"xcrun -sdk macosx metal -mmacosx-version-min=10.14 -std=macos-metal2.1 ##InputPath## -o ##OutputPath##\" \"$(InputPath)\""); + continue; + } + PopcornFX::COvenBakeConfig_Base *configBase = PopcornFX::HBO::Cast(*it); + if (configBase != null) + continue; + } + m_Initialized = true; + } + const PopcornFX::SBakeTarget defaultTarget("AfterEffect_Generic", m_DstPackPath); + + m_Cookery.m_DstPackPaths.PushBack(defaultTarget); + +} + +//---------------------------------------------------------------------------- + +void CEffectBaker::Clear() +{ + PK_SCOPEDLOCK(m_Lock); + + m_BakeContext.m_BakeFSController->UnmountAllPacks(); +} + +//---------------------------------------------------------------------------- + +void CEffectBaker::Lock() +{ + m_Lock.Lock(); +} + +//---------------------------------------------------------------------------- + +void CEffectBaker::Unlock() +{ + m_Lock.Unlock(); +} + +//---------------------------------------------------------------------------- + +void CEffectBaker::CancelAllFileChanges() +{ + m_ToBake.Clear(); +} + +//---------------------------------------------------------------------------- + +int CEffectBaker::PopFileChanges() +{ + if (m_ToBake.Count() != 0) + { + SAssetChange effect = m_ToBake.Pop(); + + BakeAssetOrAddToRetryStack(effect); + } + return m_ToBake.Count(); +} + +//---------------------------------------------------------------------------- + +bool CEffectBaker::IsChangeRegistered(const CString &path, EAssetChangesType type) +{ + for (u32 i = 0; i < m_ToBake.Count(); ++i) + { + if (m_ToBake[i].m_Type == type && path.Compare(m_ToBake[i].m_EffectPath)) + return true; + } + return false; +} + +//---------------------------------------------------------------------------- + +void CEffectBaker::ReimportAssets(TArray &paths, bool importPkri /*=true*/) +{ + for (u32 i = 0; i < paths.Count(); ++i) + { + FileChangedRelativePath(paths[i]); + } + if (importPkri) + FileChangedRelativePath(m_LibraryDir + "/PopcornFXCore/Materials/Interface/Editor.pkri"); +} + +//---------------------------------------------------------------------------- + +void CEffectBaker::ReimportAllAssets(bool refresh) +{ + (void)refresh; + + CPackExplorer packExplorer(m_SrcPack->Path(), m_BakeContext.m_BakeFSController); + packExplorer.Explore(); + + TMemoryView path = packExplorer.EffectPaths(); + + for (u32 i = 0; i < path.Count(); ++i) + { + FileChangedRelativePath(path[i]); + } +} + +//---------------------------------------------------------------------------- + +void CEffectBaker::LoadProjectSettings(const CString &pkprojPath) +{ + CString projectSettingsFilePath; + HBO::CContext context; + if (pkprojPath.Empty()) + { + CProjectSettingsFinder finder(m_SrcPack->Path(), m_BakeContext.m_BakeFSController); + + finder.Walk(); + + projectSettingsFilePath = finder.ProjectSettingsPath(); + } + else + projectSettingsFilePath = pkprojPath; + + if (projectSettingsFilePath.Empty() || + !m_BakeContext.m_BakeFSController->Exists(projectSettingsFilePath, true)) + { + CLog::Log(PK_ERROR, "Could not find Project Settings in pack \"%s\"", m_SrcPack->Path().Data()); + return; + } + + const CString fileBuffer = m_BakeContext.m_BakeFSController->BufferizeToString(projectSettingsFilePath, true); + if (fileBuffer == null) + { + CLog::Log(PK_ERROR, "Failed to read project settings file at \"%s\"", projectSettingsFilePath.Data()); + return; + } + + CConstMemoryStream stream(fileBuffer.Data(), fileBuffer.Length()); + PProjectSettings projectSettings = CProjectSettings::LoadFromStream(stream, &context); + if (projectSettings == null) + { + CLog::Log(PK_ERROR, "Failed to load project settings file at \"%s\"", projectSettingsFilePath.Data()); + return; + } + + PProjectSettingsGeneral general = projectSettings->General(); + m_RootDir = general->RootDir(); + m_LibraryDir = general->LibraryDir(); + m_EditorCacheDir = general->EditorCacheDir(); + m_PresetsDir = general->PresetsDir(); +} + +//---------------------------------------------------------------------------- + +void CEffectBaker::GetAllAssetPath() +{ + CPackExplorer packExplorer(m_SrcPack->Path(), m_BakeContext.m_BakeFSController); + SDirectoryValidator directoryValidator(m_LibraryDir, m_EditorCacheDir, m_PresetsDir); + CPackExplorer::PathValidator directoryPathValidator = CPackExplorer::PathValidator(&(directoryValidator), &SDirectoryValidator::cmp); + + packExplorer.SetDirectoryPathValidator(directoryPathValidator); + packExplorer.Explore(); + + TMemoryView paths = packExplorer.EffectPaths(); + TArray pathChar(paths.Count()); + for (u32 i = 0; i < paths.Count(); ++i) + { + pathChar[i] = paths[i].Data(); + } +} + +//---------------------------------------------------------------------------- + +bool CEffectBaker::BakeAssetOrAddToRetryStack(SAssetChange &assetInfo) +{ + CLog::Log(PK_INFO, "Baking asset '%s' and its dependencies...", assetInfo.m_EffectPath.Data()); + if (!BakeAsset(assetInfo.m_EffectPath)) + { + CString errorLog = "Bake Error: " + assetInfo.m_EffectPath + " failed to bake"; + CAELog::TryLogErrorWindows(errorLog); + return false; + } + return true; +} + +//---------------------------------------------------------------------------- + +bool CEffectBaker::LoadAndBrowseEffect(const CString &path) +{ + PBaseObjectFile file = m_BakeContext.m_BakeContext->LoadFile(path); + + if (!PK_VERIFY(file != null)) + { + CLog::Log(PK_ERROR, "Could not load the effect file for '%s'", path.Data()); + return false; + } + + PEditorAssetEffect editorAssetEffect = file->FindFirstOf(); + if (!PK_VERIFY(editorAssetEffect != null)) + { + CLog::Log(PK_ERROR, "Could not find the CEditorAssetEffect object in file for '%s'", path.Data()); + return false; + } + CString pkboPath = CFilePath::StripExtension(path) + ".pkbo"; + IFileSystem *fileSystem = File::DefaultFileSystem(); + PFilePack dstPack = fileSystem->MountPack(m_DstPackPath); + + fileSystem->SetForcedFileCreationPack(dstPack); + PBaseObjectFile pkboFile = HBO::g_Context->LoadFile_AndCreateIFN_Pure(pkboPath.View(), false); + + + PEditorAssetEffect editorProp = pkboFile->FindFirstOf(); + if (editorProp == null) + { + editorProp = HBO::g_Context->NewObject(pkboFile.Get()); + } + editorProp->CopyFrom(editorAssetEffect.Get()); + + if (!PK_VERIFY(HBO::g_Context->WriteFile(pkboFile.Get(), pkboFile->Path()))) + { + return false; + } + fileSystem->SetForcedFileCreationPack(null); + editorAssetEffect = null; + file->Unload(); + return true; +} + +//---------------------------------------------------------------------------- + +bool CEffectBaker::BakeAsset(const CString &path, bool bakeDependencies) +{ + if (m_BakedPaths.Contains(path)) + return true; + + m_BakedPaths.PushBack(path); + + if (bakeDependencies) + { + TArray dependencies; + + m_Cookery.GetAssetDependencies(path, dependencies); + for (u32 i = 0; i < dependencies.Count(); i++) + { + const CString &dependency = (dependencies[i]); + if (dependency == null || + dependency.EndsWith(".pkfx") || + dependency.EndsWith(".pkbo")) + continue; + if (BakeAsset(dependency, true) == false) + { + CLog::Log(PK_ERROR, "Asset Dependency of '%s' failed baking: '%s'", path.Data(), dependency.Data()); + return false; + } + } + } + PopcornFX::CMessageStream bakerErrors; + if (!m_Cookery.BakeAsset(path, m_Cookery.m_BaseConfigFile, bakerErrors)) + { + CLog::Log(PK_ERROR, "Couldn't bake effect '%s':", path.Data()); + bakerErrors.Log(); + return false; + } + if (path.EndsWith(".pkfx")) + { + LoadAndBrowseEffect(path); + } + return true; +} + +//---------------------------------------------------------------------------- + +__AEGP_PK_END diff --git a/AE_GeneralPlugin/Sources/AEGP_Attribute.cpp b/AE_GeneralPlugin/Sources/AEGP_Attribute.cpp new file mode 100644 index 00000000..22f0060e --- /dev/null +++ b/AE_GeneralPlugin/Sources/AEGP_Attribute.cpp @@ -0,0 +1,758 @@ +//---------------------------------------------------------------------------- +// Copyright Persistant Studios, SARL. All Rights Reserved. https://www.popcornfx.com/terms-and-conditions/ +//---------------------------------------------------------------------------- +#include "ae_precompiled.h" + +#include "AEGP_Attribute.h" +#include "AEGP_AEPKConversion.h" + +#include +#include + +#include "AEGP_FileWatcher.h" +#include "pk_kernel/include/kr_log_listeners_file.h" + +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include + +#include +#include +#include +#include +#include +#include + +#include + +#include "AEGP_World.h" + +#include + +__AEGP_PK_BEGIN + +//---------------------------------------------------------------------------- + +SSamplerBase::SSamplerBase() + : m_SamplerDescriptor(null) +{ + +} + +//---------------------------------------------------------------------------- + +SSamplerBase::~SSamplerBase() +{ + m_SamplerDescriptor = null; +} + +//---------------------------------------------------------------------------- + +SSamplerShape::SSamplerShape() + : m_Type(SamplerShapeType_None) + , m_ShapeDesc(null) + , m_MeshBatch(null) +{ + +} + +//---------------------------------------------------------------------------- + +SSamplerShape::~SSamplerShape() +{ + m_ShapeDesc = null; + +} + +//---------------------------------------------------------------------------- + +#if (PK_GEOMETRICS_BUILD_MESH_SAMPLER_SURFACE != 0) + +bool SSamplerShape::CreateSurfaceSamplingStructs(const PResourceMeshBatch mesh) +{ + m_SurfaceSamplingStructs = PK_NEW(CMeshSurfaceSamplerStructuresRandom); + if (!PK_VERIFY(m_SurfaceSamplingStructs != null)) + return false; + return m_SurfaceSamplingStructs->Build(mesh->RawMesh()->TriangleBatch().m_IStream, mesh->RawMesh()->TriangleBatch().m_VStream.Positions()); +} + +//---------------------------------------------------------------------------- + +bool SSamplerShape::CreateSurfaceUVSamplingStructs(const PResourceMeshBatch mesh) +{ + m_SurfaceUVSamplingStructs = PK_NEW(CMeshSurfaceSamplerStructuresFromUV); + if (!PK_VERIFY(m_SurfaceUVSamplingStructs != null)) + return false; + return m_SurfaceUVSamplingStructs->Build(SMeshUV2PCBuildConfig(), mesh->RawMesh()->TriangleBatch().m_VStream, mesh->RawMesh()->TriangleBatch().m_IStream); +} + +#endif + +//---------------------------------------------------------------------------- + +#if (PK_GEOMETRICS_BUILD_MESH_SAMPLER_VOLUME != 0) +bool SSamplerShape::CreateVolumeSamplingStructs(const PResourceMeshBatch mesh) +{ + m_VolumeSamplingStructs = PK_NEW(CMeshVolumeSamplerStructuresRandom); + if (!PK_VERIFY(m_VolumeSamplingStructs != null)) + return false; + + if (!mesh->RawMesh()->HasTetrahedralMeshing()) + return false; + + return m_VolumeSamplingStructs->Build(mesh->RawMesh()->TriangleBatch().m_VStream.Positions(), mesh->RawMesh()->TetrahedralOtherPositions(), mesh->RawMesh()->TetrahedralIndices(), mesh->RawMesh()->TetrahedralIndicesCount()); +} +#endif + +//---------------------------------------------------------------------------- + +#if (PK_GEOMETRICS_BUILD_MESH_PROJECTION) && 0 +bool SSamplerShape::CreateProjectionStructs(const PResourceMeshBatch mesh) +{ + m_ProjectionStructs = PK_NEW(CMeshProjection); + if (!PK_VERIFY(m_ProjectionStructs != null)) + return false; + return m_ProjectionStructs->Build(mesh->RawMesh()->TriangleBatch()); +} +#endif + +//---------------------------------------------------------------------------- + +#if (PK_GEOMETRICS_BUILD_KDTREE != 0) +bool SSamplerShape::CreateKdTree(const PResourceMeshBatch mesh) +{ + m_KdTree = PK_NEW(CMeshKdTree); + if (!PK_VERIFY(m_KdTree != null)) + return false; + SMeshKdTreeBuildConfig buildConfig; + buildConfig.m_Flags |= SMeshKdTreeBuildConfig::LowQualityButFasterBuild; + return m_KdTree->Build(mesh->RawMesh()->TriangleBatch(), buildConfig); +} +#endif + +//---------------------------------------------------------------------------- + +bool SSamplerShape::UpdateShape(SShapeSamplerDescriptor *aeShapeDesc) +{ + CParticleSamplerDescriptor_Shape_Default *desc = static_cast(m_SamplerDescriptor.Get()); + + if (m_ShapeDesc == null || + m_Type != aeShapeDesc->m_Type) + { + m_Type = aeShapeDesc->m_Type; + // Create new shape descriptor: + switch (m_Type) + { + case SamplerShapeType_Box: + m_ShapeDesc = PK_NEW(CShapeDescriptor_Box(CFloat3(aeShapeDesc->m_Dimension[0], aeShapeDesc->m_Dimension[1], aeShapeDesc->m_Dimension[2]))); + break; + case SamplerShapeType_Sphere: + m_ShapeDesc = PK_NEW(CShapeDescriptor_Sphere(aeShapeDesc->m_Dimension[0], aeShapeDesc->m_Dimension[1])); + break; + case SamplerShapeType_Ellipsoid: + m_ShapeDesc = PK_NEW(CShapeDescriptor_Ellipsoid(aeShapeDesc->m_Dimension[0], aeShapeDesc->m_Dimension[1])); + break; + case SamplerShapeType_Cylinder: + m_ShapeDesc = PK_NEW(CShapeDescriptor_Cylinder(aeShapeDesc->m_Dimension[0], aeShapeDesc->m_Dimension[1], aeShapeDesc->m_Dimension[2])); + break; + case SamplerShapeType_Capsule: + m_ShapeDesc = PK_NEW(CShapeDescriptor_Capsule(aeShapeDesc->m_Dimension[0], aeShapeDesc->m_Dimension[1], aeShapeDesc->m_Dimension[2])); + break; + case SamplerShapeType_Cone: + m_ShapeDesc = PK_NEW(CShapeDescriptor_Cone(aeShapeDesc->m_Dimension[0], aeShapeDesc->m_Dimension[1])); + break; + case SamplerShapeType_Mesh: + m_ShapeDesc = PK_NEW(CShapeDescriptor_Mesh()); + break; + default: + break; + } + } + if (aeShapeDesc->m_Type == m_Type) + { + // Update shape descriptor: + if (m_Type == SamplerShapeType_Box) + { + static_cast(m_ShapeDesc.Get())->SetDimensions(CFloat3(aeShapeDesc->m_Dimension[0], aeShapeDesc->m_Dimension[1], aeShapeDesc->m_Dimension[2])); + } + else if (m_Type == SamplerShapeType_Sphere) + { + CShapeDescriptor_Sphere *sphereDesc = static_cast(m_ShapeDesc.Get()); + sphereDesc->SetRadius(aeShapeDesc->m_Dimension[0]); + sphereDesc->SetInnerRadius(aeShapeDesc->m_Dimension[1]); + } + else if (m_Type == SamplerShapeType_Ellipsoid) + { + CShapeDescriptor_Ellipsoid *ellipsoidDesc = static_cast(m_ShapeDesc.Get()); + ellipsoidDesc->SetRadius(aeShapeDesc->m_Dimension[0]); + ellipsoidDesc->SetInnerRadius(aeShapeDesc->m_Dimension[1]); + } + else if (m_Type == SamplerShapeType_Cylinder) + { + CShapeDescriptor_Cylinder *cylinderDesc = static_cast(m_ShapeDesc.Get()); + cylinderDesc->SetRadius(aeShapeDesc->m_Dimension[0]); + cylinderDesc->SetHeight(aeShapeDesc->m_Dimension[1]); + cylinderDesc->SetInnerRadius(aeShapeDesc->m_Dimension[2]); + } + else if (m_Type == SamplerShapeType_Capsule) + { + CShapeDescriptor_Capsule *capsuleDesc = static_cast(m_ShapeDesc.Get()); + capsuleDesc->SetRadius(aeShapeDesc->m_Dimension[0]); + capsuleDesc->SetHeight(aeShapeDesc->m_Dimension[1]); + capsuleDesc->SetInnerRadius(aeShapeDesc->m_Dimension[2]); + } + else if (m_Type == SamplerShapeType_Cone) + { + CShapeDescriptor_Cone *coneDesc = static_cast(m_ShapeDesc.Get()); + coneDesc->SetRadius(aeShapeDesc->m_Dimension[0]); + coneDesc->SetHeight(aeShapeDesc->m_Dimension[1]); + } + else if (m_Type == SamplerShapeType_Mesh) + { + CShapeDescriptor_Mesh *meshDesc = static_cast(m_ShapeDesc.Get()); + + if (aeShapeDesc->m_Path.length() == 0) + return true; + + //Todo do it with the resource manager + CFilePackPath filePackPath = CFilePackPath::FromPhysicalPath(aeShapeDesc->m_Path.data(), File::DefaultFileSystem()); + + if (!filePackPath.Empty()) + { + CMessageStream loadReport; + PResourceMesh mesh = CResourceMesh::Load(File::DefaultFileSystem(), filePackPath, loadReport); + loadReport.Log(); + if (!PK_VERIFY(mesh != null)) + { + CLog::Log(PK_ERROR, "Fail loading the CMeshResource from the pkmm content"); + return false; + } + const u32 uSubMeshId = static_cast(0); + const u32 batchCount = mesh->BatchList().Count(); + if (!PK_VERIFY(uSubMeshId < batchCount)) + { + CLog::Log(PK_ERROR, "Cannot use the submesh ID %d: the mesh only has %d submeshes", uSubMeshId, batchCount); + return false; + } + m_MeshBatch = mesh->BatchList()[uSubMeshId]; + + // ------------------------------------------ + // Build KD Tree IFN + if ((aeShapeDesc->m_UsageFlags & SParticleDeclaration::SSampler::UsageFlags_Mesh_Intersect) != 0 || + (aeShapeDesc->m_UsageFlags & SParticleDeclaration::SSampler::UsageFlags_Mesh_Project) != 0 || + (aeShapeDesc->m_UsageFlags & SParticleDeclaration::SSampler::UsageFlags_Mesh_Contains) != 0 || + (aeShapeDesc->m_UsageFlags & SParticleDeclaration::SSampler::UsageFlags_Mesh_DistanceField) != 0) + { +#if (PK_GEOMETRICS_BUILD_KDTREE != 0) + if (!CreateKdTree(m_MeshBatch)) + CLog::Log(PK_WARN, "Failed building mesh kdTree acceleration structure"); + else + meshDesc->SetKdTree(m_KdTree); +#endif + } + +#if (PK_GEOMETRICS_BUILD_MESH_SAMPLER_SURFACE != 0) + // Build sampling info IFN + if ((aeShapeDesc->m_UsageFlags & SParticleDeclaration::SSampler::UsageFlags_Mesh_Sample) != 0) + { + if (!CreateSurfaceSamplingStructs(m_MeshBatch)) + CLog::Log(PK_WARN, "Failed building mesh surface-sampling acceleration structure"); + else + meshDesc->SetSamplingStructs(m_SurfaceSamplingStructs, null); + } + + // Build UV 2 PCoords info IFN + if ((aeShapeDesc->m_UsageFlags & SParticleDeclaration::SSampler::UsageFlags_Mesh_SampleFromUV) != 0) + { + if (!CreateSurfaceUVSamplingStructs(m_MeshBatch)) + CLog::Log(PK_WARN, "Failed building mesh uv-to-pcoords acceleration structure"); + else + meshDesc->SetUVSamplingStructs(m_SurfaceUVSamplingStructs, 0); + } +#endif +#if (PK_GEOMETRICS_BUILD_MESH_SAMPLER_VOLUME) + if ((aeShapeDesc->m_UsageFlags & SParticleDeclaration::SSampler::UsageFlags_Mesh_Sample) != 0) + { + if (!CreateVolumeSamplingStructs(m_MeshBatch)) + CLog::Log(PK_WARN, "Failed building mesh surface-sampling acceleration structure"); + } +#endif + meshDesc->SetMesh(m_MeshBatch->RawMesh()); + meshDesc->SetScale(CFloat3(aeShapeDesc->m_Dimension[0], aeShapeDesc->m_Dimension[0], aeShapeDesc->m_Dimension[0])); + } + } + } + + if (desc == null && m_ShapeDesc != null) + { + desc = PK_NEW(CParticleSamplerDescriptor_Shape_Default(m_ShapeDesc.Get())); + m_SamplerDescriptor = desc; + } + else if (m_ShapeDesc != null) + { + desc->m_Shape = m_ShapeDesc.Get(); + } + + return true; +} + +//---------------------------------------------------------------------------- + +SSamplerImage::SSamplerImage() + : m_ImageDesc(null) + , m_TextureData(null) + , m_Width(0) + , m_Height(0) + , m_SizeInBytes(0) + , m_PixelFormat(CImage::EFormat::Format_Invalid) + , m_DensitySampler(null) + +{ +} + +//---------------------------------------------------------------------------- + +SSamplerImage::~SSamplerImage() +{ + PK_SAFE_DELETE(m_DensitySampler); + PK_SAFE_DELETE(m_ImageDesc); +} + +//---------------------------------------------------------------------------- + +bool SSamplerImage::UpdateImage(SImageSamplerDescriptor *aeImageDesc) +{ + const u32 width = m_Width; + const u32 height = m_Height; + const u32 sizeInBytes = m_SizeInBytes; + const CImage::EFormat format = m_PixelFormat; + + CParticleSamplerDescriptor_Image_Default *desc = static_cast(m_SamplerDescriptor.Get()); + + if (width == 0 || height == 0) + return false; + + CImageMap map; + + map.m_RawBuffer = m_TextureData; + map.m_Dimensions = CUint3(width, height, 1); + + CImageSampler *imageDesc = m_ImageDesc; + CImageSurface surface(map, format); + + if (imageDesc == null) + { + imageDesc = PK_NEW(CImageSamplerBilinear); + m_ImageDesc = imageDesc; + } + + if (!PK_VERIFY(m_ImageDesc != null)) + { + CLog::Log(PK_ERROR, "Could not create the image sampler"); + return false; + } + + if (!imageDesc->SetupFromSurface(surface)) + { + surface.Convert(CImage::Format_BGRA8); + if (!PK_VERIFY(imageDesc->SetupFromSurface(surface))) + { + CLog::Log(PK_ERROR, "Could not setup the image sampler"); + return false; + } + } + + if (desc == null) + { + desc = PK_NEW(CParticleSamplerDescriptor_Image_Default(m_ImageDesc)); + m_SamplerDescriptor = desc; + } + else + { + desc->m_Sampler = m_ImageDesc; + desc->m_ImageDimensions = m_ImageDesc->Dimensions(); + } + + if (aeImageDesc->m_UsageFlags & SParticleDeclaration::SSampler::UsageFlags_Image_Density) + { + if (m_DensitySampler == null) + { + m_DensitySampler = PK_NEW(SDensitySamplerData); + + PK_ASSERT(m_DensitySampler != null); + } + SDensitySamplerBuildSettings densityBuildSettings; + + if (!m_DensitySampler->Build(surface, densityBuildSettings)) + { + CLog::Log(PK_ERROR, "Could not build the density sampler"); + return false; + } + if (!desc->SetupDensity(m_DensitySampler)) + { + CLog::Log(PK_ERROR, "Could not setup the density image sampler"); + return false; + } + } + return true; +} + +//---------------------------------------------------------------------------- + +SSamplerText::SSamplerText() +{ +} + +//---------------------------------------------------------------------------- + +SSamplerText::~SSamplerText() +{ +} + +//---------------------------------------------------------------------------- + +bool SSamplerText::UpdateText(STextSamplerDescriptor *aeTextDesc) +{ + m_Data = aeTextDesc->m_Data.c_str(); + + CParticleSamplerDescriptor_Text_Default *desc = static_cast(m_SamplerDescriptor.Get()); + + const CFontMetrics *fontKerning = null; + bool useKerning = false; + + if (desc == null) + { + desc = PK_NEW(CParticleSamplerDescriptor_Text_Default()); + m_SamplerDescriptor = desc; + } + if (desc != null) + { + if (!desc->_Setup(m_Data, fontKerning, useKerning)) + { + CLog::Log(PK_ERROR, "Could not setup the text descriptor"); + return false; + } + } + return true; +} + +//---------------------------------------------------------------------------- + +SSamplerAudio::SSamplerAudio() + : m_Waveform(null) + , m_InputSampleCount(0) + , m_SampleCount(0) + , m_Name(null) + , m_SoundData(null) + , m_SamplingType(SamplingType_Unknown) + , m_WaveformData(null) + , m_BuiltThisFrame(false) +{ +} + +//---------------------------------------------------------------------------- + +SSamplerAudio::~SSamplerAudio() +{ + CleanAudioPyramid(); +} + +//---------------------------------------------------------------------------- + +bool SSamplerAudio::UpdateSound(SAudioSamplerDescriptor *aeSoundDesc) +{ + (void)aeSoundDesc; + CParticleSamplerDescriptor_Audio_Default *desc = static_cast(m_SamplerDescriptor.Get()); + + if (desc == null) + { + desc = PK_NEW(CParticleSamplerDescriptor_Audio_Default()); + m_SamplerDescriptor = desc; + } + m_Name = desc->m_ChannelGroupNameID; + return true; +} + +//---------------------------------------------------------------------------- + +bool SSamplerAudio::CleanAudioPyramid() +{ + for (u32 i = 0; i < m_WaveformPyramid.Count(); i++) + { + PK_FREE(m_WaveformPyramid[i]); + } + m_WaveformPyramid.Clean(); + return true; +} + +//---------------------------------------------------------------------------- + +unsigned int BitReverse(u32 x, int log2n) +{ + return IntegerTools::ReverseBits(x) >> (32 - log2n); +} + +void BasicFFT(std::complex *inputs, std::complex *outputs, int log2n) +{ + const float kPI = 3.1415926536f; + const std::complex kImag(0, 1); + u32 n = 1 << log2n; + for (u32 i = 0; i < n; ++i) + { + outputs[BitReverse(i, log2n)] = inputs[i]; + } + for (s32 s = 1; s <= log2n; ++s) + { + u32 m = 1 << s; + u32 m2 = m >> 1; + std::complex w(1, 0); + std::complex wm = exp(-kImag * (kPI / m2)); + for (u32 j = 0; j < m2; ++j) + { + for (u32 k = j; k < n; k += m) + { + std::complex t = w * outputs[k + m2]; + std::complex u = outputs[k]; + outputs[k] = u + t; + outputs[k + m2] = u - t; + } + w *= wm; + } + } +} + +//---------------------------------------------------------------------------- + +bool SSamplerAudio::BuildAudioPyramidIFN() +{ + PK_SCOPEDLOCK(m_Lock); + + if (m_InputSampleCount == 0 || + m_Waveform == null) + return false; + + m_SampleCount = 1024; + PK_ASSERT(m_InputSampleCount >= m_SampleCount); + if (m_SamplingType == SamplingType_Spectrum) + { + const u32 frequencyCount = m_SampleCount * 2; + PK_ASSERT(m_InputSampleCount >= frequencyCount); + TArray > inData; + TArray > outData; + + if (!PK_VERIFY(inData.Resize(m_InputSampleCount) && outData.Resize(frequencyCount))) + return false; + + for (u32 i = 0; i < m_InputSampleCount; ++i) + { + inData[i].real(m_Waveform[i]); + inData[i].imag(0); + } + BasicFFT(inData.RawDataPointer(), outData.RawDataPointer(), IntegerTools::Log2(frequencyCount)); + for (u32 j = 0; j < m_SampleCount; ++j) + { + m_Waveform[j] = std::sqrt(PKSquared(outData[j].real()) + PKSquared(outData[j].imag())) / static_cast(m_SampleCount); + } + } + + // lazy-allocation + if (m_WaveformData == null) + { + CleanAudioPyramid(); + + const u32 baseAllocSize = m_SampleCount; + // allocate two double borders to avoid checking for overflow during sampling w/ Cubic or Linear filters + const u32 baseByteCount = (2 + baseAllocSize + 2) * sizeof(*m_WaveformData); + m_WaveformData = (float*)PK_MALLOC_ALIGNED(baseByteCount, 0x80); + if (m_WaveformData == null) + return false; + Mem::Clear(m_WaveformData, baseByteCount); + + bool success = true; + const u32 pyramidSize = IntegerTools::Log2(m_SampleCount) + 1; + if (m_WaveformPyramid.Resize(pyramidSize)) + { + u32 currentCount = m_SampleCount; + for (u32 i = 1; i < pyramidSize; i++) + { + currentCount >>= 1; + PK_ASSERT(currentCount != 0); + const u32 mipByteCount = (2 + currentCount + 2) * sizeof(float); + m_WaveformPyramid[i] = (float*)PK_MALLOC_ALIGNED(mipByteCount, 0x10); + if (m_WaveformPyramid[i] != null) + Mem::Clear(m_WaveformPyramid[i], mipByteCount); + success &= (m_WaveformPyramid[i] != null); + } + } + m_WaveformPyramid[0] = m_WaveformData; + + if (!success) + { + m_WaveformData = null; + CleanAudioPyramid(); + return false; + } + } + + PK_ASSERT(m_WaveformData != null); + float *realDataPtr = m_WaveformData + 2; // ptr to the first real element, skipping the two-element border + memcpy(realDataPtr, m_Waveform, m_SampleCount * sizeof(*m_WaveformData)); + + { + const float firstEntry = realDataPtr[0]; + const float lastEntry = realDataPtr[m_SampleCount - 1]; + realDataPtr[-1] = firstEntry; // duplicate the first entry in the two start borders + realDataPtr[-2] = firstEntry; + realDataPtr[m_SampleCount + 0] = lastEntry; // duplicate the last entry in the two end borders + realDataPtr[m_SampleCount + 1] = lastEntry; + } + + // right, rebuild the spectrum pyramid: + if (!m_WaveformPyramid.Empty()) + { + u32 currentCount = m_SampleCount; + for (u32 i = 1; i < m_WaveformPyramid.Count(); i++) + { + const float * __restrict src = 2 + m_WaveformPyramid[i - 1]; + float * __restrict dst = 2 + m_WaveformPyramid[i]; + + currentCount >>= 1; + + // downsample + for (u32 j = 0; j < currentCount; j++) + { + dst[j] = 0.5f * (src[j * 2 + 0] + src[j * 2 + 1]); + } + + const float firstEntry = dst[0]; + const float lastEntry = dst[currentCount - 1]; + dst[-1] = firstEntry; // duplicate the first entry in the two start borders + dst[-2] = firstEntry; + dst[currentCount + 0] = lastEntry; // duplicate the last entry in the two end borders + dst[currentCount + 1] = lastEntry; + } + } + m_BuiltThisFrame = true; + return true; +} + +//---------------------------------------------------------------------------- + +bool SSamplerAudio::ReleaseAEResources() +{ + m_Waveform = null; + if (m_SoundData != null) + { + CPopcornFXWorld &instance = AEGPPk::CPopcornFXWorld::Instance(); + A_Err result = A_Err_NONE; + AEGP_SuiteHandler suites(instance.GetAESuites()); + + result |= suites.SoundDataSuite1()->AEGP_UnlockSoundDataSamples(m_SoundData); + result |= suites.SoundDataSuite1()->AEGP_DisposeSoundData(m_SoundData); + + m_SoundData = null; + if (result != A_Err_NONE) + return false; + } + return true; +} + +//---------------------------------------------------------------------------- + +SSamplerVectorField::SSamplerVectorField() +{ +} + +//---------------------------------------------------------------------------- + +SSamplerVectorField::~SSamplerVectorField() +{ +} + +//---------------------------------------------------------------------------- + +bool SSamplerVectorField::UpdateVectorField(SVectorFieldSamplerDescriptor * aeTurbulenceDesc) +{ + CParticleSamplerDescriptor_VectorField_Grid *desc = static_cast(m_SamplerDescriptor.Get()); + + if (m_Dirty == false) + return true; + + m_Dirty = false; + + if (desc == null) + { + desc = PK_NEW(CParticleSamplerDescriptor_VectorField_Grid()); + m_SamplerDescriptor = desc; + } + + + if (aeTurbulenceDesc->m_ResourceUpdate) + { + if (aeTurbulenceDesc->m_Path.length() == 0) + return true; + + CFilePackPath filePackPath = CFilePackPath::FromPhysicalPath(aeTurbulenceDesc->m_Path.data(), File::DefaultFileSystem()); + TResourcePtr rscVf = Resource::DefaultManager()->Load(filePackPath); + + CParticleSamplerDescriptor_VectorField_Grid::EDataType dataType = CParticleSamplerDescriptor_VectorField_Grid::DataType_Void; + switch (rscVf->m_DataType) + { + case VFDataType_Fp32: + dataType = CParticleSamplerDescriptor_VectorField_Grid::DataType_Fp32; + break; + case VFDataType_Fp16: + dataType = CParticleSamplerDescriptor_VectorField_Grid::DataType_Fp16; + break; + case VFDataType_U8SN: + dataType = CParticleSamplerDescriptor_VectorField_Grid::DataType_U8SN; + break; + default: + break; + } + CFloat4x4 transform = CFloat4x4::IDENTITY; + + transform.StrippedTranslations() = AAEToPK(aeTurbulenceDesc->m_Position); + + if (!(desc->Setup( rscVf->m_Dimensions, + rscVf->m_IntensityMultiplier, + rscVf->m_BoundsMin, + rscVf->m_BoundsMax, + rscVf->m_Data, + dataType, + aeTurbulenceDesc->m_Strength, //Strength + transform, //Xforms + 0, //Flags + AAEToPK(aeTurbulenceDesc->m_Interpolation)))) + return false; + } + else + { + CFloat4x4 transform = CFloat4x4::IDENTITY; + + transform.StrippedTranslations() = AAEToPK(aeTurbulenceDesc->m_Position); + + desc->SetTransforms(transform); + desc->SetStrength(aeTurbulenceDesc->m_Strength); + } + return true; +} + +//---------------------------------------------------------------------------- + +__AEGP_PK_END + diff --git a/AE_GeneralPlugin/Sources/AEGP_FileDialog.cpp b/AE_GeneralPlugin/Sources/AEGP_FileDialog.cpp new file mode 100644 index 00000000..0b0e4856 --- /dev/null +++ b/AE_GeneralPlugin/Sources/AEGP_FileDialog.cpp @@ -0,0 +1,107 @@ +//---------------------------------------------------------------------------- +// Copyright Persistant Studios, SARL. All Rights Reserved. https://www.popcornfx.com/terms-and-conditions/ +//---------------------------------------------------------------------------- +#include + +#include "AEGP_FileDialog.h" + +#include "AEGP_World.h" + +#include +#include + +__AEGP_PK_BEGIN + +#if defined(PK_MACOSX) + +//---------------------------------------------------------------------------- + +SMacFileDialogFilterData::SMacFileDialogFilterData(const CString desc, const CString type) + : m_Desc(desc) + , m_Type(type) +{ +} + +//---------------------------------------------------------------------------- + +SMacFileOpenData::SMacFileOpenData() +{ +} + +//---------------------------------------------------------------------------- + +SMacFileOpenData::~SMacFileOpenData() +{ +} + +//---------------------------------------------------------------------------- + +bool SMacFileOpenData::AddFilter(const CString &desc, const CString &type) +{ + if (!PK_VERIFY(m_Filters.PushBack(SMacFileDialogFilterData(desc, type)).Valid())) + return false; + return true; +} + +//---------------------------------------------------------------------------- + +bool MacBasicFileOpen(SMacFileOpenData &data) +{ + TArray filters; + + for (u32 i = 0; i < data.m_Filters.Count(); ++i) + filters.PushBack(CFilePath::ExtractExtension(data.m_Filters[i].m_Type)); + + CString stringResult = OpenFileDialogMac(filters); + + if (!stringResult.Empty()) + { + data.m_Cb(stringResult); + return true; + } + return false; +} + +//---------------------------------------------------------------------------- + +#endif + +SFileDialog::SFileDialog() +{ + +} + +//---------------------------------------------------------------------------- + +bool SFileDialog::AddFilter(const CString &desc, const CString &type) +{ + if (!PK_VERIFY(m_Data.AddFilter(desc, type))) + return false; + return true; +} + +//---------------------------------------------------------------------------- + +bool SFileDialog::IsCancelled() +{ + return m_Cancel; +} + +//---------------------------------------------------------------------------- + +bool SFileDialog::BasicFileOpen() +{ + m_Cancel = false; +#if defined(PK_WINDOWS) + HRESULT hr = WinBasicFileOpen(m_Data); + if (HRESULT_CODE(hr) == ERROR_CANCELLED) + m_Cancel = true; + return SUCCEEDED(hr); +#elif defined(PK_MACOSX) + return MacBasicFileOpen(m_Data); +#endif +} + +//---------------------------------------------------------------------------- + +__AEGP_PK_END diff --git a/AE_GeneralPlugin/Sources/AEGP_FileDialogMac.mm b/AE_GeneralPlugin/Sources/AEGP_FileDialogMac.mm new file mode 100644 index 00000000..f6c45179 --- /dev/null +++ b/AE_GeneralPlugin/Sources/AEGP_FileDialogMac.mm @@ -0,0 +1,66 @@ +#include "ae_precompiled.h" +#include "AEGP_FileDialogMac.h" + +#if defined(PK_OS_MACOSX) +#import + +#import +#import + +#include +#endif + +#include +#include + +__AEGP_PK_BEGIN + +#if defined(PK_OS_MACOSX) + +CString OpenFileDialogMac(const TArray &filters, const CString &defaultPathAndFile) +{ + TArray fileList; + + // Create a File Open Dialog class. + NSOpenPanel* openDlg = [NSOpenPanel openPanel]; + [openDlg setLevel:CGShieldingWindowLevel()]; + + // Set array of file types + NSMutableArray * fileTypesArray = [NSMutableArray array]; + for (unsigned int i = 0; i < filters.Count(); i++) + { + NSString * filt =[NSString stringWithUTF8String:filters[i].Data()]; + [fileTypesArray addObject:filt]; + } + + // Enable options in the dialog. + [openDlg setCanChooseFiles:YES]; + [openDlg setAllowedFileTypes:fileTypesArray]; + [openDlg setAllowsMultipleSelection:TRUE]; + + if (!defaultPathAndFile.Empty()) + { + [openDlg setDirectoryURL:[NSURL URLWithString:[NSString stringWithUTF8String:defaultPathAndFile.Data() ] ] ]; + } + + // Display the dialog box. If the OK pressed, + // process the files. + if ( [openDlg runModal] == NSModalResponseOK ) + { + // Gets list of all files selected + NSArray *files = [openDlg URLs]; + // Loop through the files and process them. + for (unsigned int i = 0; i < [files count]; i++ ) + { + // Do something with the filename. + fileList.PushBack(CString([[[files objectAtIndex:i] path] UTF8String])); + } + } + if (fileList.Empty()) + return CString(); + return fileList[0]; +} +#endif + + +__AEGP_PK_END diff --git a/AE_GeneralPlugin/Sources/AEGP_FileWatcher.cpp b/AE_GeneralPlugin/Sources/AEGP_FileWatcher.cpp new file mode 100644 index 00000000..f41c98f4 --- /dev/null +++ b/AE_GeneralPlugin/Sources/AEGP_FileWatcher.cpp @@ -0,0 +1,113 @@ +//---------------------------------------------------------------------------- +// Copyright Persistant Studios, SARL. All Rights Reserved. https://www.popcornfx.com/terms-and-conditions/ +//---------------------------------------------------------------------------- +#include "ae_precompiled.h" +#include "AEGP_FileWatcher.h" + +__AEGP_PK_BEGIN +//---------------------------------------------------------------------------- + +bool CFileWatcher::CreateWatcherIFN() +{ + if (m_FileWatcher == null) + { + m_FileWatcher = CFileSystemWatcher::NewWatcher(); + if (!PK_VERIFY(m_FileWatcher != null)) + { + CLog::Log(PK_ERROR, "Could not create the file watcher"); + return false; + } + } + return true; +} + +//---------------------------------------------------------------------------- + +void CFileWatcher::RemoveWatchIFN() +{ + if (m_FileWatcher != null) + m_FileWatcher->RemoveWatch(m_PathToWatch); +} + +//---------------------------------------------------------------------------- + +CFileWatcher::CFileWatcher() +{ +} + +//---------------------------------------------------------------------------- + +CFileWatcher::~CFileWatcher() +{ + RemoveWatchIFN(); + m_FileWatcher = null; +} + +//---------------------------------------------------------------------------- + +void CFileWatcher::PauseFileWatcher() +{ + RemoveWatchIFN(); +} + +//---------------------------------------------------------------------------- + +void CFileWatcher::RestartFileWatcher() +{ + SetWatchPack(m_PathToWatch); +} + +//---------------------------------------------------------------------------- + +bool CFileWatcher::SetWatchPack(const CString &pathToWatch) +{ + CString purifiedPath = pathToWatch; + CFilePath::Purify(purifiedPath); + purifiedPath.AppendSlash(); + + RemoveWatchIFN(); + CreateWatcherIFN(); + + m_PathToWatch = pathToWatch; + m_FileWatcher->AddWatch(m_PathToWatch); + return true; +} + +//---------------------------------------------------------------------------- + +void CFileWatcher::SetNotifierAdd(void(*callback)(const CString &filePath)) +{ + CreateWatcherIFN(); + m_FileWatcher->m_NotifierAdd.Clear(); + m_FileWatcher->m_NotifierAdd += callback; +} + +//---------------------------------------------------------------------------- + +void CFileWatcher::SetNotifierRemove(void(*callback)(const CString &filePath)) +{ + CreateWatcherIFN(); + m_FileWatcher->m_NotifierRemove.Clear(); + m_FileWatcher->m_NotifierRemove += callback; +} + +//---------------------------------------------------------------------------- + +void CFileWatcher::SetNotifierModify(void(*callback)(const CString &filePath)) +{ + CreateWatcherIFN(); + m_FileWatcher->m_NotifierModify.Clear(); + m_FileWatcher->m_NotifierModify += callback; +} + +//---------------------------------------------------------------------------- + +void CFileWatcher::SetNotifierRename(void(*callback)(const CString &oldFilePath, const CString &newFilePath)) +{ + CreateWatcherIFN(); + m_FileWatcher->m_NotifierRename.Clear(); + m_FileWatcher->m_NotifierRename += callback; +} + +//---------------------------------------------------------------------------- +__AEGP_PK_END diff --git a/AE_GeneralPlugin/Sources/AEGP_FrameCollector.cpp b/AE_GeneralPlugin/Sources/AEGP_FrameCollector.cpp new file mode 100644 index 00000000..b977c768 --- /dev/null +++ b/AE_GeneralPlugin/Sources/AEGP_FrameCollector.cpp @@ -0,0 +1,45 @@ +//---------------------------------------------------------------------------- +// Copyright Persistant Studios, SARL. All Rights Reserved. https://www.popcornfx.com/terms-and-conditions/ +//---------------------------------------------------------------------------- +#include "ae_precompiled.h" + +#include "AEGP_FrameCollector.h" + +__AEGP_PK_BEGIN + +//---------------------------------------------------------------------------- + +CFrameCollector::CFrameCollector() +{ +} + +//---------------------------------------------------------------------------- + +CFrameCollector::~CFrameCollector() +{ +} + +//---------------------------------------------------------------------------- + +bool CFrameCollector::EarlyCull(const CAABB &bbox) const +{ + // Can happen if bounds are not active + if (!bbox.IsFinite() || + !bbox.Valid()) + return false; + + if (m_CullingFrustums.Empty()) + return false; + + const u32 viewCount = m_CullingFrustums.Count(); + for (u32 iView = 0; iView < viewCount; ++iView) + { + if (m_CullingFrustums[iView].Touches(bbox)) + return false; + } + return true; +} + +//---------------------------------------------------------------------------- + +__AEGP_PK_END diff --git a/AE_GeneralPlugin/Sources/AEGP_LayerHolder.cpp b/AE_GeneralPlugin/Sources/AEGP_LayerHolder.cpp new file mode 100644 index 00000000..77cfd4ac --- /dev/null +++ b/AE_GeneralPlugin/Sources/AEGP_LayerHolder.cpp @@ -0,0 +1,155 @@ +//---------------------------------------------------------------------------- +// Copyright Persistant Studios, SARL. All Rights Reserved. https://www.popcornfx.com/terms-and-conditions/ +//---------------------------------------------------------------------------- +#include +#include "AEGP_LayerHolder.h" + +#include "AEGP_Scene.h" + +__AEGP_PK_BEGIN + +//---------------------------------------------------------------------------- +// +//---------------------------------------------------------------------------- + +HBO_CLASS_DEFINITION_BEGIN(CGraphicOverride) + .HBO_FIELD_DEFINITION(RendererID) + .HBO_FIELD_DEFINITION(PropertyID) + .HBO_FIELD_DEFINITION(Value) +HBO_CLASS_DEFINITION_END + +CGraphicOverride::CGraphicOverride() + : HBO_CONSTRUCT(CGraphicOverride) + +{ +} + +//---------------------------------------------------------------------------- + +CGraphicOverride::~CGraphicOverride() +{ +} + +//---------------------------------------------------------------------------- + +bool CGraphicOverride::operator==(const CGraphicOverride &other) +{ + if (other.m_RendererID == m_RendererID && + other.m_PropertyID == m_PropertyID) + return true; + return false; +} + +//---------------------------------------------------------------------------- +// +//---------------------------------------------------------------------------- + +HBO_CLASS_DEFINITION_BEGIN(CLayerProperty) + .HBO_FIELD_DEFINITION(CompName) + .HBO_FIELD_DEFINITION(ID) + .HBO_FIELD_DEFINITION(RendererProperties) +HBO_CLASS_DEFINITION_END + +CLayerProperty::CLayerProperty() + : HBO_CONSTRUCT(CLayerProperty) +{ +} + +//---------------------------------------------------------------------------- + +CLayerProperty::~CLayerProperty() +{ +} + +//---------------------------------------------------------------------------- +// +//---------------------------------------------------------------------------- + +SLayerHolder::SLayerHolder() +{ + +} + +//---------------------------------------------------------------------------- + +SLayerHolder::~SLayerHolder() +{ + + +} +//---------------------------------------------------------------------------- + +bool SLayerHolder::Clear(SPBasicSuite* suite) +{ + AEGP_SuiteHandler suites(suite); + + bool result = true; + if (m_Scene->Quit() == false) + result = false; + m_Scene = null; + + for (s32 i = m_SPendingAttributes.Count() - 1; i >= 0; --i) + { + if (m_SPendingAttributes[i].m_AttributeEffectRef != null) + suites.EffectSuite4()->AEGP_DisposeEffect(m_SPendingAttributes[i].m_AttributeEffectRef); + m_SPendingAttributes[i].m_AttributeEffectRef = null; + m_SPendingAttributes[i].m_Desc->m_IsDeleted = true; + m_SPendingAttributes[i].m_Desc = null; + } + m_SPendingAttributes.Clear(); + + for (auto &it : m_DeletedAttributes) + { + if (it.m_AttributeEffectRef != null) + suites.EffectSuite4()->AEGP_DisposeEffect(it.m_AttributeEffectRef); + it.m_AttributeEffectRef = null; + it.m_Desc->m_IsDeleted = true; + it.m_Desc = null; + } + m_DeletedAttributes.Clear(); + + for (auto &it : m_SpawnedAttributes) + { + if (it.m_AttributeEffectRef != null) + suites.EffectSuite4()->AEGP_DisposeEffect(it.m_AttributeEffectRef); + it.m_AttributeEffectRef = null; + it.m_Desc->m_IsDeleted = true; + it.m_Desc = null; + } + m_SpawnedAttributes.Clear(); + + for (auto &it : m_SpawnedAttributesSampler) + { + if (it.m_AttributeEffectRef != null) + suites.EffectSuite4()->AEGP_DisposeEffect(it.m_AttributeEffectRef); + it.m_AttributeEffectRef = null; + it.m_Desc->m_IsDeleted = true; + it.m_Desc = null; + } + m_SpawnedAttributes.Clear(); + + for (auto &it : m_SPendingEmitters) + { + if (it.m_EffectHandle) + it.m_EffectHandle = null; + it.m_Desc->m_IsDeleted = true; + it.m_Desc = null; + } + m_SPendingEmitters.Clear(); + + if (m_SpawnedEmitter.m_EffectHandle) + m_SpawnedEmitter.m_EffectHandle = null; + m_SpawnedEmitter.m_Desc->m_IsDeleted = true; + m_SpawnedEmitter.m_Desc = null; + + m_EffectLayer = null; + m_CameraLayer = null; + + PK_SAFE_DELETE(m_BackdropAudioWaveform); + PK_SAFE_DELETE(m_BackdropAudioSpectrum); + return result; +} + +//---------------------------------------------------------------------------- + +__AEGP_PK_END diff --git a/AE_GeneralPlugin/Sources/AEGP_Log.cpp b/AE_GeneralPlugin/Sources/AEGP_Log.cpp new file mode 100644 index 00000000..f09a78db --- /dev/null +++ b/AE_GeneralPlugin/Sources/AEGP_Log.cpp @@ -0,0 +1,108 @@ +//---------------------------------------------------------------------------- +// Copyright Persistant Studios, SARL. All Rights Reserved. https://www.popcornfx.com/terms-and-conditions/ +//---------------------------------------------------------------------------- +#include "ae_precompiled.h" + +#include "AEGP_Log.h" +#include "AEGP_World.h" + +//Suite +#include +#include + +//AE +#include +#include +#include + +__AEGP_PK_BEGIN +//---------------------------------------------------------------------------- + +bool CAELog::s_PKState = false; +SAAEIOData *CAELog::s_IOData = null; + +//---------------------------------------------------------------------------- + +bool CAELog::LogErrorWindows(SAAEIOData *AAEData, const CString errorStr) +{ + PK_ASSERT(errorStr.Length() < 256); + + if (s_PKState) + CLog::Log(PK_ERROR, errorStr); + if (AAEData == null || AAEData->m_OutData == null) + return false; + AAEData->m_OutData->out_flags |= PF_OutFlag_DISPLAY_ERROR_MESSAGE; + sprintf(AAEData->m_OutData->return_msg, "%s", errorStr.Data()); + + CPopcornFXWorld &instance = AEGPPk::CPopcornFXWorld::Instance(); + SPBasicSuite *basicSuite = instance.GetAESuites(); + + if (basicSuite) + { + AEGP_SuiteHandler suites(basicSuite); + + suites.UtilitySuite6()->AEGP_WriteToDebugLog("PopcornFX Plugin", "Error", errorStr.Data()); + suites.AdvAppSuite2()->PF_InfoDrawText("PopcornFX Plugin [ERROR]", errorStr.Data()); + } + return false; +} + +//---------------------------------------------------------------------------- + +bool CAELog::SetIOData(SAAEIOData *AAEData) +{ + s_IOData = AAEData; + return true; +} + +//---------------------------------------------------------------------------- + +void CAELog::ClearIOData() +{ + s_IOData = null; +} + +//---------------------------------------------------------------------------- + +bool CAELog::TryLogErrorWindows(const CString errorStr) +{ + if (s_IOData == null) + return false; + LogErrorWindows(s_IOData, errorStr); + return false; +} + +//---------------------------------------------------------------------------- + +void CAELog::SetPKLogState(bool state) +{ + s_PKState = state; +} + +//---------------------------------------------------------------------------- + +bool CAELog::TryLogInfoWindows(const CString infoStr) +{ + CPopcornFXWorld &instance = AEGPPk::CPopcornFXWorld::Instance(); + + if (s_PKState) + CLog::Log(PK_INFO, infoStr); + + SPBasicSuite *basicSuite = instance.GetAESuites(); + + if (basicSuite) + { + AEGP_SuiteHandler suites(basicSuite); + + suites.UtilitySuite6()->AEGP_ReportInfo(instance.GetPluginID(), infoStr.Data()); + + suites.UtilitySuite6()->AEGP_WriteToDebugLog("PopcornFX Plugin", "Info", infoStr.Data()); + + suites.AdvAppSuite2()->PF_InfoDrawText("PopcornFX Plugin [INFO]", infoStr.Data()); + } + return true; +} + +//---------------------------------------------------------------------------- + +__AEGP_PK_END diff --git a/AE_GeneralPlugin/Sources/AEGP_Main.cpp b/AE_GeneralPlugin/Sources/AEGP_Main.cpp new file mode 100644 index 00000000..1dcb2410 --- /dev/null +++ b/AE_GeneralPlugin/Sources/AEGP_Main.cpp @@ -0,0 +1,475 @@ +//---------------------------------------------------------------------------- +// Copyright Persistant Studios, SARL. All Rights Reserved. https://www.popcornfx.com/terms-and-conditions/ +//---------------------------------------------------------------------------- +#include "ae_precompiled.h" + +#include "AEGP_Main.h" +#include "AEGP_World.h" +#include "AEGP_FileDialog.h" +#include "AEGP_PopcornFXPlugins.h" +#include "AEGP_Scene.h" +#include "AEGP_AEPKConversion.h" +#include "AEGP_Log.h" +#include "AEGP_VaultHandler.h" +#include + +//AE +#include +#include + +#include + +#include + +using namespace PopcornFX; +//---------------------------------------------------------------------------- + +static SPAPI A_Err InitializePopcornFXIFN(AAePk::SAAEIOData& AAEData) +{ + AEGPPk::CAELog::SetIOData(&AAEData); + if (AEGPPk::CPopcornFXWorld::Instance().InitializeIFN(AAEData) == false) + { + AEGPPk::CAELog::ClearIOData(); + return A_Err_GENERIC; + } + return A_Err_NONE; +} + +//---------------------------------------------------------------------------- + +static SPAPI A_Err HandleNewEmitterEvent(AAePk::SAAEIOData& AAEData, AAePk::SEmitterDesc *descriptor) +{ + AEGPPk::CAELog::SetIOData(&AAEData); + if (AEGPPk::CPopcornFXWorld::Instance().HandleNewEmitterEvent(AAEData, descriptor) == false) + { + AEGPPk::CAELog::ClearIOData(); + return A_Err_GENERIC; + } + return A_Err_NONE; +} + +//---------------------------------------------------------------------------- + +static SPAPI A_Err HandleDeleteEmitterEvent(AAePk::SAAEIOData& AAEData, AAePk::SEmitterDesc *descriptor) +{ + AEGPPk::CAELog::SetIOData(&AAEData); + if (AEGPPk::CPopcornFXWorld::Instance().HandleDeleteEmitterEvent(AAEData, descriptor) == false) + { + AEGPPk::CAELog::ClearIOData(); + return A_Err_GENERIC; + } + return A_Err_NONE; +} + +//---------------------------------------------------------------------------- + +static SPAPI bool CheckEmitterValidity(AAePk::SAAEIOData &AAEData, AAePk::SEmitterDesc *descriptor) +{ + AEGPPk::CAELog::SetIOData(&AAEData); + bool ret = AEGPPk::CPopcornFXWorld::Instance().CheckEmitterValidity(AAEData, descriptor); + AEGPPk::CAELog::ClearIOData(); + return ret; +} + +//---------------------------------------------------------------------------- + +static SPAPI A_Err UpdateScene(AAePk::SAAEIOData &AAEData, AAePk::SEmitterDesc *descriptor) +{ + AEGPPk::CAELog::SetIOData(&AAEData); + if (AEGPPk::CPopcornFXWorld::Instance().UpdateScene(AAEData, descriptor) == false) + { + AEGPPk::CAELog::ClearIOData(); + return A_Err_GENERIC; + } + return A_Err_NONE; +} + +//---------------------------------------------------------------------------- + +static SPAPI A_Err UpdateEmitter(AAePk::SAAEIOData &AAEData, AAePk::SEmitterDesc *descriptor) +{ + AEGPPk::CAELog::SetIOData(&AAEData); + if (AEGPPk::CPopcornFXWorld::Instance().UpdateEmitter(AAEData, descriptor) == false) + { + AEGPPk::CAELog::ClearIOData(); + return A_Err_GENERIC; + } + return A_Err_NONE; +} + +//---------------------------------------------------------------------------- + +static SPAPI A_Err DisplayMarketplacePanel(AAePk::SAAEIOData &AAEData, AAePk::SEmitterDesc *descriptor) +{ + AEGPPk::CAELog::SetIOData(&AAEData); + + AEGPPk::CPopcornFXWorld::Instance().LaunchEditorAsPopup(AAEData, descriptor); + + AAEData.m_OutData->out_flags |= PF_OutFlag_FORCE_RERENDER | PF_OutFlag_REFRESH_UI; + return A_Err_NONE; +} + +//---------------------------------------------------------------------------- + +static SPAPI A_Err DisplayBrowseEffectPanel(AAePk::SAAEIOData &AAEData, AAePk::SEmitterDesc *descriptor) +{ + AEGPPk::CAELog::SetIOData(&AAEData); + + AEGPPk::SFileDialog cbData; + + cbData.AddFilter("PopcornFX effect file (*.pkfx)", "*.pkfx"); + + struct SFunctor + { + void Function(const PopcornFX::CString path) + { + AEGPPk::CPopcornFXWorld::Instance().SetSelectedEffectFromPath(m_Descriptor, path); + } + + AAePk::SEmitterDesc *m_Descriptor = null; + }; + + static SFunctor functor; + + functor.m_Descriptor = descriptor; + cbData.SetCallback(PopcornFX::FastDelegate(&functor, &SFunctor::Function)); + + if (!cbData.BasicFileOpen()) + { + AEGPPk::CAELog::ClearIOData(); + if (cbData.IsCancelled()) + return A_Err_NONE; + return A_Err_GENERIC; + } + AEGPPk::CAELog::ClearIOData(); + AAEData.m_OutData->out_flags |= PF_OutFlag_FORCE_RERENDER | PF_OutFlag_REFRESH_UI; + return A_Err_NONE; +} + +//---------------------------------------------------------------------------- + +static SPAPI A_Err DisplayBrowseMeshDialog(AAePk::SAAEIOData &AAEData, AAePk::SEmitterDesc *descriptor) +{ + AEGPPk::CAELog::SetIOData(&AAEData); + + AEGPPk::SFileDialog cbData; + + cbData.AddFilter("Baked Mesh file (*.fbx)", "*.fbx"); + + struct SFunctor + { + void Function(const CString path) + { + if (m_Descriptor != null) + { + AEGPPk::CPopcornFXWorld &world = AEGPPk::CPopcornFXWorld::Instance(); + AEGPPk::SResourceBakeConfig bakeConfig; + + m_Descriptor->m_BackdropMesh.m_Path = world.GetVaultHandler().BakeResource(path, bakeConfig).Data(); + bakeConfig.m_IsSkeletalAnim = true; + world.GetVaultHandler().BakeResource(path, bakeConfig).Data(); + m_Descriptor->m_LoadBackdrop = true; + m_Descriptor->m_UpdateBackdrop = true; + } + } + + AAePk::SEmitterDesc* m_Descriptor = null; + }; + + static SFunctor functor; + + functor.m_Descriptor = descriptor; + cbData.SetCallback(PopcornFX::FastDelegate(&functor, &SFunctor::Function)); + + + AEGPPk::CPopcornFXWorld &world = AEGPPk::CPopcornFXWorld::Instance(); + AEGPPk::SLayerHolder *layer = world.GetLayerForSEmitterDesc(descriptor); + + if (layer) + { + AEGP_LayerH layerH = null; + AEGP_SuiteHandler suites(world.GetAESuites()); + PF_Err result = A_Err_NONE; + + result |= suites.PFInterfaceSuite1()->AEGP_GetEffectLayer(AAEData.m_InData->effect_ref, &layerH); + if (!PK_VERIFY(result == A_Err_NONE)) + return A_Err_GENERIC; + if (layerH != null) + layer->m_EffectLayer = layerH; + if (!cbData.BasicFileOpen()) + { + AEGPPk::CAELog::ClearIOData(); + if (cbData.IsCancelled()) + return A_Err_NONE; + return A_Err_GENERIC; + } + } + return A_Err_NONE; +} + +//---------------------------------------------------------------------------- + +static SPAPI A_Err DisplayBrowseEnvironmentMapDialog(AAePk::SAAEIOData &AAEData, AAePk::SEmitterDesc *descriptor) +{ + AEGPPk::CAELog::SetIOData(&AAEData); + AEGPPk::SFileDialog cbData; + cbData.AddFilter("Image file", "*.*"); + + struct SFunctor + { + void Function(const CString path) + { + if (m_Descriptor != null) + { + AEGPPk::CPopcornFXWorld &world = AEGPPk::CPopcornFXWorld::Instance(); + AEGPPk::SResourceBakeConfig bakeConfig; + + bakeConfig.m_StraightCopy = true; + m_Descriptor->m_BackdropEnvironmentMap.m_Path = world.GetVaultHandler().BakeResource(path, bakeConfig).Data(); + m_Descriptor->m_Update = true; + } + } + AAePk::SEmitterDesc* m_Descriptor = null; + }; + + static SFunctor functor; + + functor.m_Descriptor = descriptor; + cbData.SetCallback(PopcornFX::FastDelegate(&functor, &SFunctor::Function)); + + if (!cbData.BasicFileOpen()) + { + AEGPPk::CAELog::ClearIOData(); + if (cbData.IsCancelled()) + return A_Err_NONE; + return A_Err_GENERIC; + } + return A_Err_NONE; +} + +//---------------------------------------------------------------------------- + +static SPAPI A_Err ReimportEffect(AAePk::SAAEIOData &AAEData, AAePk::SEmitterDesc *descriptor) +{ + if (descriptor == null || descriptor->m_PathSource.empty()) + return A_Err_NONE; + + AEGPPk::CAELog::SetIOData(&AAEData); + + PopcornFX::CString path = PopcornFX::CString(descriptor->m_PathSource.c_str()) / PopcornFX::CString(descriptor->m_Name.c_str()); + + path = CFilePath::StripExtension(path) + ".pkfx"; + + AEGPPk::CPopcornFXWorld::Instance().SetSelectedEffectFromPath(descriptor, path, true); + + AEGPPk::CPopcornFXWorld::Instance().InvalidateEmitterRender(AAEData, descriptor); + + AAEData.m_OutData->out_flags |= PF_OutFlag_FORCE_RERENDER | PF_OutFlag_REFRESH_UI; + return A_Err_NONE; +} + +//---------------------------------------------------------------------------- + +static SPAPI A_Err Display_AttributeSampler_BrowseMeshDialog(AAePk::SAAEIOData &AAEData, AAePk::SAttributeSamplerDesc *descriptor) +{ + AEGPPk::CAELog::SetIOData(&AAEData); + AEGPPk::SFileDialog cbData; + + if (descriptor->m_Type == AAePk::AttributeSamplerType_Geometry) + { + cbData.AddFilter("Mesh file (*.fbx)", "*.fbx"); + } + else if (descriptor->m_Type == AAePk::AttributeSamplerType_VectorField) + { + cbData.AddFilter("Baked Mesh file (*.fga)", "*.fga"); + } + else + return A_Err_NONE; + + struct SFunctor + { + AAePk::SAttributeSamplerDesc* m_Descriptor = null; + + void Function(const CString path) + { + if (m_Descriptor != null) + { + AEGPPk::SResourceBakeConfig bakeConfig; + + if (m_Descriptor->m_Type == AEGPPk::AttributeSamplerType_Animtrack) + { + bakeConfig.m_IsAnimTrack = true; + } + + AEGPPk::CPopcornFXWorld &world = AEGPPk::CPopcornFXWorld::Instance(); + m_Descriptor->m_ResourcePath = world.GetVaultHandler().BakeResource(path, bakeConfig).Data(); + + } + } + }; + + static SFunctor functor; + + functor.m_Descriptor = descriptor; + cbData.SetCallback(PopcornFX::FastDelegate(&functor, &SFunctor::Function)); + + if (!cbData.BasicFileOpen()) + { + AEGPPk::CAELog::ClearIOData(); + if (cbData.IsCancelled()) + return A_Err_NONE; + return A_Err_GENERIC; + } + return A_Err_NONE; +} + +//---------------------------------------------------------------------------- + +static SPAPI A_Err SetParametersIndexes(const int *indexes, AAePk::EPKChildPlugins plugin) +{ + AEGPPk::CPopcornFXWorld::Instance().SetParametersIndexes(indexes, plugin); + return A_Err_NONE; +} + +//---------------------------------------------------------------------------- + +static SPAPI A_Err ShutdownPopcornFXIFN(AAePk::SAAEIOData &AAEData) +{ + AEGPPk::CAELog::SetIOData(&AAEData); + if (AEGPPk::CPopcornFXWorld::Instance().ShutdownIFN() == false) + { + AEGPPk::CAELog::ClearIOData(); + return A_Err_GENERIC; + } + return A_Err_NONE; +} + +//---------------------------------------------------------------------------- + +static SPAPI A_Err SetDefaultLayerPosition(AAePk::SAAEIOData& AAEData, AEGP_LayerH layer) +{ + AEGPPk::CAELog::SetIOData(&AAEData); + if (AEGPPk::CPopcornFXWorld::Instance().SetDefaultLayerPosition(AAEData, layer) == false) + { + AEGPPk::CAELog::ClearIOData(); + return A_Err_GENERIC; + } + return A_Err_NONE; +} + +//---------------------------------------------------------------------------- + +static SPAPI A_Err MoveEffectIntoCurrentView(AAePk::SAAEIOData &AAEData, AAePk::SEmitterDesc *descriptor) +{ + AEGPPk::CAELog::SetIOData(&AAEData); + if (AEGPPk::CPopcornFXWorld::Instance().MoveEffectIntoCurrentView(AAEData, descriptor) == false) + { + AEGPPk::CAELog::ClearIOData(); + return A_Err_GENERIC; + } + AEGPPk::CPopcornFXWorld::Instance().InvalidateEmitterRender(AAEData, descriptor); + AAEData.m_OutData->out_flags |= PF_OutFlag_FORCE_RERENDER | PF_OutFlag_REFRESH_UI; + + return A_Err_NONE; +} + +//---------------------------------------------------------------------------- + +static PopcornFXSuite1 g_PopcornFXSuite = +{ + InitializePopcornFXIFN, + HandleNewEmitterEvent, + HandleDeleteEmitterEvent, + CheckEmitterValidity, + UpdateScene, + UpdateEmitter, + DisplayMarketplacePanel, + DisplayBrowseEffectPanel, + DisplayBrowseMeshDialog, + DisplayBrowseEnvironmentMapDialog, + ReimportEffect, + Display_AttributeSampler_BrowseMeshDialog, + ShutdownPopcornFXIFN, + SetParametersIndexes, + SetDefaultLayerPosition, + MoveEffectIntoCurrentView, +}; + +//---------------------------------------------------------------------------- + +A_Err EntryPointFunc( struct SPBasicSuite *pica_basicP, /* >> */ + A_long major_versionL, /* >> */ + A_long minor_versionL, /* >> */ + AEGP_PluginID aegp_plugin_id, /* >> */ + AEGP_GlobalRefcon *global_refconP) /* << */ +{ + (void)global_refconP; + (void)minor_versionL; + (void)major_versionL; + + A_Err err = A_Err_NONE; + SPSuiteRef my_ref = 0; + AEGP_SuiteHandler suites(pica_basicP); + SuiteHelper panelSuite(pica_basicP); + SPSuitesSuite *suitesOfSuite = nullptr; + AEGP_Command command; + const A_u_char *commandName = (const A_u_char*)"PopcornFX"; + AEGPPk::CPopcornFXWorld &PKWorld = AEGPPk::CPopcornFXWorld::Instance(); + + *global_refconP = (AEGP_GlobalRefcon)&PKWorld; + + if (!PKWorld.Setup(pica_basicP, aegp_plugin_id)) + return A_Err_GENERIC; + + AEGP_RegisterSuite5 *registerSuite = suites.RegisterSuite5(); + if (registerSuite != NULL) + { + err |= registerSuite->AEGP_RegisterDeathHook(aegp_plugin_id, AEGPPk::CPopcornFXWorld::DeathHook, 0); + err |= registerSuite->AEGP_RegisterIdleHook(aegp_plugin_id, AEGPPk::CPopcornFXWorld::IdleHook, 0); + } + else + return A_Err_MISSING_SUITE; + + AEGP_CommandSuite1 *commandSuite = suites.CommandSuite1(); + if (commandSuite != NULL) + { + err |= commandSuite->AEGP_GetUniqueCommand(&command); + if (command != 0) + { + PKWorld.SetCommandHandle(command, (const char*)commandName); + err |= commandSuite->AEGP_InsertMenuCommand(command, (const A_char*)commandName, AEGP_Menu_WINDOW, AEGP_MENU_INSERT_SORTED); + } + } + else + return A_Err_MISSING_SUITE; + + err |= registerSuite->AEGP_RegisterCommandHook( aegp_plugin_id, + AEGP_HP_BeforeAE, + command, + &AEGPPk::CPopcornFXWorld::CommandHook, + (AEGP_CommandRefcon)(&PKWorld)); + err |= registerSuite->AEGP_RegisterUpdateMenuHook( aegp_plugin_id, + &AEGPPk::CPopcornFXWorld::UpdateMenuHook, + null); + err |= panelSuite->AEGP_RegisterCreatePanelHook( aegp_plugin_id, + commandName, + &AEGPPk::CPopcornFXWorld::CreatePanelHook, + (AEGP_CreatePanelRefcon)&PKWorld, + true); + + err |= pica_basicP->AcquireSuite(kSPSuitesSuite, kSPSuitesSuiteVersion, (const void **)&suitesOfSuite); + if (err == A_Err_NONE && suitesOfSuite) + { + err |= suitesOfSuite->AddSuite( kSPRuntimeSuiteList, + 0, + kPopcornFXSuite1, + kPopcornFXSuiteVersion1, + 1, + &g_PopcornFXSuite, + &my_ref); + err |= pica_basicP->ReleaseSuite(kSPSuitesSuite, kSPSuitesSuiteVersion); + } + return err; +} + +//---------------------------------------------------------------------------- diff --git a/AE_GeneralPlugin/Sources/AEGP_PackExplorer.cpp b/AE_GeneralPlugin/Sources/AEGP_PackExplorer.cpp new file mode 100644 index 00000000..5e7a3b0c --- /dev/null +++ b/AE_GeneralPlugin/Sources/AEGP_PackExplorer.cpp @@ -0,0 +1,124 @@ +//---------------------------------------------------------------------------- +// Copyright Persistant Studios, SARL. All Rights Reserved. https://www.popcornfx.com/terms-and-conditions/ +//---------------------------------------------------------------------------- +#include "ae_precompiled.h" + +#include "AEGP_PackExplorer.h" + +__AEGP_PK_BEGIN + +//---------------------------------------------------------------------------- + +CPackExplorer::CPackExplorer(const CString &pack, IFileSystem *fileSystem) + : CFileDirectoryWalker(pack, IgnoreVirtualFS, fileSystem) + , m_Pack(pack) +{ +} + +//---------------------------------------------------------------------------- + +CPackExplorer::~CPackExplorer() +{ + m_Pack = null; +} + +//---------------------------------------------------------------------------- + +void CPackExplorer::Explore() +{ + if (!m_Pack.Empty()) + { + Walk(); + } +} + +//---------------------------------------------------------------------------- + +bool CPackExplorer::DirectoryNotifier(const CFilePack *pack, const char *fullPath, u32 directoryFirstCharPos) +{ + (void)directoryFirstCharPos; + (void)pack; + + const CString filename = CFilePath::ExtractFilename(fullPath); + + // go full recursive unless a hidden directory somehow ended up in the pack + return filename[0] != '.'; +} + +//---------------------------------------------------------------------------- + +void CPackExplorer::FileNotifier(const CFilePack *pack, const char *fullPath, u32 fileFirstCharPos) +{ + (void)fileFirstCharPos; + (void)pack; + + const char *extension = CFilePath::ExtractExtension(fullPath); + + // add the effect to the list + if (extension != null && !strcasecmp(extension, "pkfx")) + { + const CString effectPath = CFilePath::Relativize(m_Pack.Data(), fullPath); + + m_EffectPaths.PushBack(effectPath); + } +} + +//---------------------------------------------------------------------------- + +CBakedPackExplorer::CBakedPackExplorer(const CString &pack, IFileSystem *fileSystem) + : CFileDirectoryWalker(pack, IgnoreVirtualFS, fileSystem) + , m_Pack(pack) +{ +} + +//---------------------------------------------------------------------------- + +CBakedPackExplorer::~CBakedPackExplorer() +{ + m_Pack = null; +} + +//---------------------------------------------------------------------------- + +void CBakedPackExplorer::Explore() +{ + if (!m_Pack.Empty()) + { + Walk(); + } +} + +//---------------------------------------------------------------------------- + +bool CBakedPackExplorer::DirectoryNotifier(const CFilePack *pack, const char *fullPath, u32 directoryFirstCharPos) +{ + (void)directoryFirstCharPos; + (void)pack; + + const CString filename = CFilePath::ExtractFilename(fullPath); + + // go full recursive unless a hidden directory somehow ended up in the pack + return filename[0] != '.'; +} + +//---------------------------------------------------------------------------- + +void CBakedPackExplorer::FileNotifier(const CFilePack *pack, const char *fullPath, u32 fileFirstCharPos) +{ + (void)fileFirstCharPos; + (void)pack; + + const char *extension = CFilePath::ExtractExtension(fullPath); + + // add the effect to the list + if (extension != null && !strcasecmp(extension, "pkb")) + { + const CString effectPath = CFilePath::Relativize(m_Pack.Data(), fullPath); + + m_EffectPaths.PushBack(effectPath); + } +} + +//---------------------------------------------------------------------------- + +__AEGP_PK_END diff --git a/AE_GeneralPlugin/Sources/AEGP_ParticleScene.cpp b/AE_GeneralPlugin/Sources/AEGP_ParticleScene.cpp new file mode 100644 index 00000000..ea69af9c --- /dev/null +++ b/AE_GeneralPlugin/Sources/AEGP_ParticleScene.cpp @@ -0,0 +1,134 @@ +//---------------------------------------------------------------------------- +// Copyright Persistant Studios, SARL. All Rights Reserved. https://www.popcornfx.com/terms-and-conditions/ +//---------------------------------------------------------------------------- +#include "ae_precompiled.h" + +#include "AEGP_ParticleScene.h" + +#include + +#include "AEGP_Scene.h" +#include + +__AEGP_PK_BEGIN + +//---------------------------------------------------------------------------- + +void CAAEParticleScene::RayTracePacket( const Colliders::STraceFilter &traceFilter, + const Colliders::SRayPacket &packet, + const Colliders::STracePacket &results) +{ + (void)traceFilter; + PK_NAMEDSCOPEDPROFILE_C("CParticleSceneInterface: RayTracePacket", CFloat3(0.0f, 0.6f, 1.0f)); + // pre-conditions + PK_ASSERT(packet.m_RayOrigins_Aligned16.Count() == packet.m_RayDirectionsAndLengths_Aligned16.Count()); + PK_ASSERT(results.Count() == packet.m_RayOrigins_Aligned16.Count()); + + const s32 kMaskTrue = -1; + TStridedMemoryView enableMasks = packet.m_RayMasks_Aligned16; + if (enableMasks.Empty()) + enableMasks = TStridedMemoryView(&kMaskTrue, results.Count(), 0); + + if (!m_BackdropMeshes.Empty()) + { + // we've got a mesh to collide against. Store the previous ray lengths so we may + // detect which rays intersect the mesh: + PK_STACKALIGNEDMEMORYVIEW(float, prevHitTimes, results.Count(), 0x10); + Mem::Copy(prevHitTimes.Data(), results.m_HitTimes_Aligned16, results.Count() * sizeof(float)); + + const CFloat4x4 &meshXForms = m_BackdropMeshTransforms; + const CFloat4x4 meshXFormsInv = meshXForms.Inverse(); + + for (u32 i = 0; i < m_BackdropMeshes.Count(); ++i) + { + // trace the mesh: + m_BackdropMeshes[i]->TracePacket(CMeshNew::STraceFlags(), packet, results, &meshXForms, &meshXFormsInv); + + if (results.m_ContactObjects_Aligned16 != null) // the caller wants us to report contact objects + { + for (u32 j = 0; j < results.Count(); j++) + { + PK_ASSERT(results.m_HitTimes_Aligned16[j] <= prevHitTimes[j]); + + // if the hit time is different from the original hit-time, + // this ray has hit the mesh, set the contact object: + if (results.m_HitTimes_Aligned16[j] != prevHitTimes[j]) + results.m_ContactObjects_Aligned16[j] = CollidableObject::DEFAULT; + } + } + } + } +} + +//---------------------------------------------------------------------------- + +void CAAEParticleScene::ClearBackdropMesh() +{ + m_BackdropMeshes.Clear(); +} + +//---------------------------------------------------------------------------- + +void CAAEParticleScene::SetBackdropMeshTransform(const CFloat4x4 &transforms) +{ + m_BackdropMeshTransforms = transforms; +} + +//---------------------------------------------------------------------------- + +void CAAEParticleScene::SetBackdropMesh(const TResourcePtr &resourceMesh, const CFloat4x4 &transforms) +{ + m_BackdropMeshes.Clear(); + if (resourceMesh == null || resourceMesh->Empty()) + return; + for (const auto &staticBatch : resourceMesh->BatchList()) + { + m_BackdropMeshes.PushBack(staticBatch->RawMesh()); + } + m_BackdropMeshTransforms = transforms; +} + +//---------------------------------------------------------------------------- + +TMemoryView CAAEParticleScene::GetAudioSpectrum(CStringId channelGroup, u32 &outBaseCount) const +{ + PK_ASSERT(m_Parent != null); + SSamplerAudio *samplerAudio = m_Parent->GetAudioSamplerDescriptor(channelGroup, SSamplerAudio::SamplingType_Spectrum); + + if (samplerAudio == null) + return TMemoryView(); + + samplerAudio->m_SamplingType = SSamplerAudio::SamplingType_Spectrum; + + samplerAudio->BuildAudioPyramidIFN(); + + outBaseCount = samplerAudio->m_SampleCount; + if (samplerAudio->m_SampleCount == 0) + return TMemoryView(); + return TMemoryView(samplerAudio->m_WaveformPyramid.RawDataPointer(), samplerAudio->m_WaveformPyramid.Count()); +} + +//---------------------------------------------------------------------------- + +TMemoryView CAAEParticleScene::GetAudioWaveform(CStringId channelGroup, u32 &outBaseCount) const +{ + PK_ASSERT(m_Parent != null); + SSamplerAudio *samplerAudio = m_Parent->GetAudioSamplerDescriptor(channelGroup, SSamplerAudio::SamplingType_WaveForm); + + if (samplerAudio == null) + return TMemoryView(); + + samplerAudio->m_SamplingType = SSamplerAudio::SamplingType_WaveForm; + + samplerAudio->BuildAudioPyramidIFN(); + + outBaseCount = samplerAudio->m_SampleCount; + if (samplerAudio->m_SampleCount == 0) + return TMemoryView(); + return TMemoryView(samplerAudio->m_WaveformPyramid.RawDataPointer(), samplerAudio->m_WaveformPyramid.Count()); + +} + +//---------------------------------------------------------------------------- + +__AEGP_PK_END diff --git a/AE_GeneralPlugin/Sources/AEGP_PopcornFXPlugins.cpp b/AE_GeneralPlugin/Sources/AEGP_PopcornFXPlugins.cpp new file mode 100644 index 00000000..c3efb2d3 --- /dev/null +++ b/AE_GeneralPlugin/Sources/AEGP_PopcornFXPlugins.cpp @@ -0,0 +1,282 @@ +//---------------------------------------------------------------------------- +// Copyright Persistant Studios, SARL. All Rights Reserved. https://www.popcornfx.com/terms-and-conditions/ +//---------------------------------------------------------------------------- +#include "ae_precompiled.h" + +#include "AEGP_PopcornFXPlugins.h" + +#include +#include + +#define USE_COMPILER_BACKEND +#define USE_IMAGE_PLUGINS +#define USE_IMAGE_PLUGIN_TIFF +#define USE_IMAGE_PLUGIN_PKM +#define USE_IMAGE_PLUGIN_PVR +#define USE_FBXIMPORTER + +//------------------------------------------------------------------------------ +// +// toolkit to load/unload PKFX runtime plugins +// +//------------------------------------------------------------------------------ + +#ifdef PK_PLUGINS_STATIC +# if defined(USE_COMPILER_BACKEND) +PK_PLUGIN_DECLARE(CCompilerBackendCPU_VM); +# if defined(PK_PARTICLES_UPDATER_USE_D3D12) || defined(PK_PARTICLES_UPDATER_USE_D3D11) +PK_PLUGIN_DECLARE(CCompilerBackendGPU_D3D); +# endif +# endif + + +# if defined(USE_IMAGE_PLUGINS) +PK_PLUGIN_DECLARE(CImageDDSCodec); +PK_PLUGIN_DECLARE(CImagePNGCodec); +PK_PLUGIN_DECLARE(CImageTGACodec); +PK_PLUGIN_DECLARE(CImageJPEGCodec); +PK_PLUGIN_DECLARE(CImageHDRCodec); +# if defined(USE_IMAGE_PLUGIN_TIFF) +PK_PLUGIN_DECLARE(CImageTIFFCodec); +# endif +# if defined(USE_IMAGE_PLUGIN_PKM) +PK_PLUGIN_DECLARE(CImagePKMCodec); +# endif +# if defined(USE_IMAGE_PLUGIN_PVR) +PK_PLUGIN_DECLARE(CImagePVRCodec); +# endif +# endif + +# if defined(USE_FBXIMPORTER) +PK_PLUGIN_DECLARE(CMeshCodecFBX); +# endif + +# if defined(PK_DEBUG) +# define PK_PLUGIN_POSTFIX_BUILD "_D" +# else +# define PK_PLUGIN_POSTFIX_BUILD "" +# endif +# if defined(PK_WINDOWS) +# define PK_PLUGIN_POSTFIX_EXT ".dll" +# else +# define PK_PLUGIN_POSTFIX_EXT "" +# endif +#endif + +__AEGP_PK_BEGIN +//------------------------------------------------------------------------------ + +static u32 g_LoadedPlugins = 0; + +//----------------------------------------------------------------------------- +// +// Loads selected plugins +// +//----------------------------------------------------------------------------- + +bool PopcornRegisterPlugins(u32 selected /*= 0*/) +{ + PK_ASSERT(g_LoadedPlugins == 0); + + bool success = true; +#ifndef PK_PLUGINS_STATIC + // plugins are .dll + PopcornFX::CPluginManager::RegisterDirectory("Plugins", false); + +#else + // plugins are linked statically + if (selected & EPlugin_CompilerBackendVM) + { + const char *backendPath = "Plugins/CBCPU_VM" PK_PLUGIN_POSTFIX_BUILD PK_PLUGIN_POSTFIX_EXT; + IPluginModule *backend = StartupPlugin_CCompilerBackendCPU_VM(); + success &= (backend != null && PopcornFX::CPluginManager::PluginRegister(backend, true, backendPath)); + } +# if (PK_PARTICLES_UPDATER_USE_D3D12 != 0 || PK_PARTICLES_UPDATER_USE_D3D11 != 0) + if (selected & EPlugin_CompilerBackendD3D) + { + const char *backendPath = "Plugins/CBGPU_D3D" PK_PLUGIN_POSTFIX_BUILD PK_PLUGIN_POSTFIX_EXT; + IPluginModule *backend = StartupPlugin_CCompilerBackendGPU_D3D(); + success &= (backend != null && CPluginManager::PluginRegister(backend, true, backendPath)); + } +# endif +# ifdef USE_IMAGE_PLUGINS + if (selected & EPlugin_ImageCodecDDS) + { + const char *codecPathDDS = "Plugins/image_codec_dds" PK_PLUGIN_POSTFIX_BUILD PK_PLUGIN_POSTFIX_EXT; + IPluginModule *codecDDS = StartupPlugin_CImageDDSCodec(); + success &= (codecDDS != null && PopcornFX::CPluginManager::PluginRegister(codecDDS, true, codecPathDDS)); + } + + if (selected & EPlugin_ImageCodecPNG) + { + const char *codecPathPNG = "Plugins/image_codec_png" PK_PLUGIN_POSTFIX_BUILD PK_PLUGIN_POSTFIX_EXT; + IPluginModule *codecPNG = StartupPlugin_CImagePNGCodec(); + success &= (codecPNG != null && PopcornFX::CPluginManager::PluginRegister(codecPNG, true, codecPathPNG)); + } + + if (selected & EPlugin_ImageCodecJPG) + { + const char *codecPathJPG = "Plugins/image_codec_jpeg" PK_PLUGIN_POSTFIX_BUILD PK_PLUGIN_POSTFIX_EXT; + IPluginModule *codecJPG = StartupPlugin_CImageJPEGCodec(); + success &= (codecJPG != null && PopcornFX::CPluginManager::PluginRegister(codecJPG, true, codecPathJPG)); + } + + if (selected & EPlugin_ImageCodecTGA) + { + const char *codecPathTGA = "Plugins/image_codec_tga" PK_PLUGIN_POSTFIX_BUILD PK_PLUGIN_POSTFIX_EXT; + IPluginModule *codecTGA = StartupPlugin_CImageTGACodec(); + success &= (codecTGA != null && PopcornFX::CPluginManager::PluginRegister(codecTGA, true, codecPathTGA)); + } + + if (selected & EPlugin_ImageCodecHDR) + { + const char *codecPathHDR = "Plugins/image_codec_hdr" PK_PLUGIN_POSTFIX_BUILD PK_PLUGIN_POSTFIX_EXT; + IPluginModule *codecHDR = StartupPlugin_CImageHDRCodec(); + success &= (codecHDR != null && PopcornFX::CPluginManager::PluginRegister(codecHDR, true, codecPathHDR)); + } +# endif + +# if defined(USE_IMAGE_PLUGIN_TIFF) + if (selected & EPlugin_ImageCodecTIFF) + { + const char *codecPathTIFF = "Plugins/image_codec_tiff" PK_PLUGIN_POSTFIX_BUILD PK_PLUGIN_POSTFIX_EXT; + IPluginModule *codecTIFF = StartupPlugin_CImageTIFFCodec(); + success &= (codecTIFF != null && PopcornFX::CPluginManager::PluginRegister(codecTIFF, true, codecPathTIFF)); + } +# endif + +# if defined(USE_IMAGE_PLUGIN_PKM) + if (selected & EPlugin_ImageCodecPKM) + { + const char *codecPathPKM = "Plugins/image_codec_pkm" PK_PLUGIN_POSTFIX_BUILD PK_PLUGIN_POSTFIX_EXT; + IPluginModule *codecPKM = StartupPlugin_CImagePKMCodec(); + success &= (codecPKM != null && PopcornFX::CPluginManager::PluginRegister(codecPKM, true, codecPathPKM)); + } +# endif + +# if defined(USE_IMAGE_PLUGIN_PVR) + if (selected & EPlugin_ImageCodecPVR) + { + const char *codecPathPVR = "Plugins/image_codec_pvr" PK_PLUGIN_POSTFIX_BUILD PK_PLUGIN_POSTFIX_EXT; + IPluginModule *codecPVR = StartupPlugin_CImagePVRCodec(); + success &= (codecPVR != null && PopcornFX::CPluginManager::PluginRegister(codecPVR, true, codecPathPVR)); + } +# endif + +# if defined(USE_FBXIMPORTER) + if (selected & EPlugin_MeshCodecFBX) + { + const char *codecPath = "Plugins/MeshCodecFBX" PK_PLUGIN_POSTFIX_BUILD PK_PLUGIN_POSTFIX_EXT; + IPluginModule *codec = StartupPlugin_CMeshCodecFBX(); + success &= (codec != null && PopcornFX::CPluginManager::PluginRegister(codec, true, codecPath)); + } +# endif +#endif + + g_LoadedPlugins = selected; + return success; +} + +//----------------------------------------------------------------------------- +// +// Unloads all plugins +// +//----------------------------------------------------------------------------- + +void PopcornUnregisterPlugins() +{ + // unregister plugins: +#ifdef PK_PLUGINS_STATIC + if (g_LoadedPlugins & EPlugin_CompilerBackendVM) + { + IPluginModule *backend = GetPlugin_CCompilerBackendCPU_VM(); + (backend != null && PopcornFX::CPluginManager::PluginRelease(backend)); + ShutdownPlugin_CCompilerBackendCPU_VM(); + } + +# if (PK_PARTICLES_UPDATER_USE_D3D12 != 0 || PK_PARTICLES_UPDATER_USE_D3D11 != 0) + if (g_LoadedPlugins & EPlugin_CompilerBackendD3D) + { + IPluginModule *backend = GetPlugin_CCompilerBackendGPU_D3D(); + (backend != null && PopcornFX::CPluginManager::PluginRelease(backend)); + ShutdownPlugin_CCompilerBackendGPU_D3D(); + } +# endif +# ifdef USE_IMAGE_PLUGINS + if (g_LoadedPlugins & EPlugin_ImageCodecDDS) + { + IPluginModule *codecDDS = GetPlugin_CImageDDSCodec(); + (codecDDS != null && PopcornFX::CPluginManager::PluginRelease(codecDDS)); + ShutdownPlugin_CImageDDSCodec(); + } + + if (g_LoadedPlugins & EPlugin_ImageCodecPNG) + { + IPluginModule *codecPNG = GetPlugin_CImagePNGCodec(); + (codecPNG != null && PopcornFX::CPluginManager::PluginRelease(codecPNG)); + ShutdownPlugin_CImagePNGCodec(); + } + + if (g_LoadedPlugins & EPlugin_ImageCodecJPG) + { + IPluginModule *codecJPG = GetPlugin_CImageJPEGCodec(); + (codecJPG != null && PopcornFX::CPluginManager::PluginRelease(codecJPG)); + ShutdownPlugin_CImageJPEGCodec(); + } + + if (g_LoadedPlugins & EPlugin_ImageCodecTGA) + { + IPluginModule *codecTGA = GetPlugin_CImageTGACodec(); + (codecTGA != null && PopcornFX::CPluginManager::PluginRelease(codecTGA)); + ShutdownPlugin_CImageTGACodec(); + } + + if (g_LoadedPlugins & EPlugin_ImageCodecHDR) + { + IPluginModule *codecHDR = GetPlugin_CImageHDRCodec(); + (codecHDR != null && PopcornFX::CPluginManager::PluginRelease(codecHDR)); + ShutdownPlugin_CImageHDRCodec(); + } +# endif + +# if defined(USE_IMAGE_PLUGIN_TIFF) + if (g_LoadedPlugins & EPlugin_ImageCodecTIFF) + { + IPluginModule *codecTIFF = GetPlugin_CImageTIFFCodec(); + (codecTIFF != null && PopcornFX::CPluginManager::PluginRelease(codecTIFF)); + ShutdownPlugin_CImageTIFFCodec(); + } +# endif + +# if defined(USE_IMAGE_PLUGIN_PKM) + if (g_LoadedPlugins & EPlugin_ImageCodecPKM) + { + IPluginModule *codecPKM = GetPlugin_CImagePKMCodec(); + (codecPKM != null && PopcornFX::CPluginManager::PluginRelease(codecPKM)); + ShutdownPlugin_CImagePKMCodec(); + } +# endif + +# if defined(USE_IMAGE_PLUGIN_PVR) + if (g_LoadedPlugins & EPlugin_ImageCodecPVR) + { + IPluginModule *codecPVR = GetPlugin_CImagePVRCodec(); + (codecPVR != null && PopcornFX::CPluginManager::PluginRelease(codecPVR)); + ShutdownPlugin_CImagePVRCodec(); + } +# endif + +# if defined(USE_FBXIMPORTER) + if (g_LoadedPlugins & EPlugin_MeshCodecFBX) + { + IPluginModule *codec = GetPlugin_CMeshCodecFBX(); + (codec != null && PopcornFX::CPluginManager::PluginRelease(codec)); + ShutdownPlugin_CMeshCodecFBX(); + } +# endif +#endif + g_LoadedPlugins = 0; +} + +//------------------------------------------------------------------------------ +__AEGP_PK_END diff --git a/AE_GeneralPlugin/Sources/AEGP_RenderContext.cpp b/AE_GeneralPlugin/Sources/AEGP_RenderContext.cpp new file mode 100644 index 00000000..e5558e55 --- /dev/null +++ b/AE_GeneralPlugin/Sources/AEGP_RenderContext.cpp @@ -0,0 +1,703 @@ +//---------------------------------------------------------------------------- +// Copyright Persistant Studios, SARL. All Rights Reserved. https://www.popcornfx.com/terms-and-conditions/ +//---------------------------------------------------------------------------- +#include "ae_precompiled.h" + +#include "AEGP_RenderContext.h" +#include "AEGP_AEPKConversion.h" + +#include "PopcornFX_Suite.h" + +//AAE +#include +#include +#include +#include +#include +#include +#include +#include +#include + +//CreateInternalWindow +#if defined(PK_MACOSX) +# include +# include +# include +#else +# include +# include +#endif + +#include +#include +//RHI +#include +#include + +//D3D11 +#if (PK_BUILD_WITH_D3D11_SUPPORT != 0) +#include "RenderApi/AEGP_D3D11Context.h" +#endif +//D3D12 +#if (PK_BUILD_WITH_D3D12_SUPPORT != 0) +#include "RenderApi/AEGP_D3D12Context.h" +#endif +#if (PK_BUILD_WITH_METAL_SUPPORT != 0) +#include "RenderApi/AEGP_MetalContext.h" +#endif + +#include "RenderApi/AEGP_CopyPixels.h" + +//Samples +#include + +__AEGP_PK_BEGIN + +//---------------------------------------------------------------------------- + +CAAEBaseContext *CAAERenderContext::m_AEGraphicContext = null; +Threads::CCriticalSection CAAERenderContext::m_AEGraphicContextLock; + +//---------------------------------------------------------------------------- + +CAAERenderContext::CAAERenderContext() +: m_WindowHandle(null) +, m_DeviceContext(null) +, m_Width(0) +, m_Height(0) +, m_Initialized(false) +, m_RHIRendering(null) +, m_ShaderLoader(null) +{ +} + +//---------------------------------------------------------------------------- + +CAAERenderContext::~CAAERenderContext() +{ + PKSample::SPassDescription::s_PassDescriptions.Clean(); +} + +//---------------------------------------------------------------------------- + +bool CAAERenderContext::InitializeIFN(RHI::EGraphicalApi api, const CString &className) +{ + if (m_Initialized == true) + { + return true; + } + m_API = api; + + if (!CreateInternalWindowIFN(className)) + return false; + + PK_SCOPEDLOCK(m_AEGraphicContextLock); + if (m_AEGraphicContext == null) + { + switch (m_API) + { + #if (PK_BUILD_WITH_METAL_SUPPORT != 0) + case (RHI::GApi_Metal): + m_AEGraphicContext = PK_NEW(CAAEMetalContext); + break; + #endif + #if (PK_BUILD_WITH_D3D11_SUPPORT != 0) + case (RHI::GApi_D3D11): + m_AEGraphicContext = PK_NEW(CAAED3D11Context); + break; + #endif + #if (PK_BUILD_WITH_D3D12_SUPPORT != 0) + case (RHI::GApi_D3D12): + m_AEGraphicContext = PK_NEW(CAAED3D12Context); + break; + #endif + default: + CLog::Log(PK_ERROR, "No compatible API context could be created"); + PK_ASSERT_NOT_REACHED(); + return false; + break; + } + if (!PK_VERIFY(m_AEGraphicContext != null)) + return false; + if (!PK_VERIFY(m_AEGraphicContext->CreatePlatformContext(m_WindowHandle, m_DeviceContext))) + { + CLog::Log(PK_ERROR, "CreatePlatformContext failed"); + return false; + } + if (!PK_VERIFY(m_AEGraphicContext->InitIFN())) + { + CLog::Log(PK_ERROR, "Graphic context initialization failed"); + return false; + } + } + m_Initialized = true; + return true; +} + +//---------------------------------------------------------------------------- + +bool CAAERenderContext::Destroy() +{ + PK_SAFE_DELETE(m_RHIRendering); + PK_SAFE_DELETE(m_AEGraphicContext); + m_Initialized = false; + return true; +} + +//---------------------------------------------------------------------------- +// GETTER +//---------------------------------------------------------------------------- + +PKSample::CRHIParticleSceneRenderHelper *CAAERenderContext::GetCurrentSceneRenderer() +{ + PK_ASSERT(m_RHIRendering != null); + return m_RHIRendering; +} + +//---------------------------------------------------------------------------- + +CUint2 CAAERenderContext::GetViewportSize() const +{ + return CUint2{ m_Width, m_Height }; +} + +//---------------------------------------------------------------------------- + +void CAAERenderContext::LogGraphicsErrors() +{ + m_AEGraphicContext->LogApiError(); +} + +//---------------------------------------------------------------------------- + +CAAEBaseContext *CAAERenderContext::GetAEGraphicContext() +{ + return m_AEGraphicContext; +} + +//---------------------------------------------------------------------------- +// Setter +//---------------------------------------------------------------------------- + +void CAAERenderContext::SetShaderLoader(PKSample::CShaderLoader *shaderLoader) +{ + m_ShaderLoader = shaderLoader; +} + +//---------------------------------------------------------------------------- + +PKSample::CShaderLoader *CAAERenderContext::GetShaderLoader() +{ + return m_ShaderLoader; +} + +//---------------------------------------------------------------------------- + +void CAAERenderContext::SetPostFXOptions(PKSample::SParticleSceneOptions &postFXOptions) +{ + m_SceneOptions = postFXOptions; +} + +//---------------------------------------------------------------------------- + +bool CAAERenderContext::SetAsCurrentContext() +{ + PK_ASSERT(m_DeviceContext != null); + + return m_AEGraphicContext->SetAsCurrent(m_DeviceContext); +} + +//---------------------------------------------------------------------------- + +//Used for IMGUI Context +bool CAAERenderContext::RenderFrameBegin(u32 width, u32 height) +{ + if (!PK_VERIFY(SetAsCurrentContext())) + return false; + if (m_Width != width || m_Height != height) + { + if (InitGraphicContext(m_Format, width, height) == false) + return false; + } + //Frame + return m_AEGraphicContext->BeginFrame(); +} + +//---------------------------------------------------------------------------- + +bool CAAERenderContext::RenderFrameEnd() +{ + return m_AEGraphicContext->EndFrame(); +} + +//---------------------------------------------------------------------------- +// AEE Interface +//---------------------------------------------------------------------------- + +bool CAAERenderContext::InitGraphicContext(RHI::EPixelFormat rhiformat, u32 width, u32 height) +{ + PK_SCOPEDPROFILE(); + + // Force the format to 32bpc for precision issues: + rhiformat = RHI::EPixelFormat::FormatFloat32RGBA; + + bool updateRHISize = false; + if (m_Format != rhiformat || m_Width != width || m_Height != height) + updateRHISize = true; + m_Format = rhiformat; + m_Width = width; + m_Height = height; + + RHI::PApiManager apiManager = m_AEGraphicContext->GetApiManager(); + + if (!m_AEGraphicContext->CreateRenderTarget(m_Format, CUint3{ m_Width, m_Height, 1 })) + { + CLog::Log(PK_ERROR, "Graphic context CreateRenderTarget failed"); + return false; + } + + bool newRHIRendering = false; + if (m_RHIRendering == null) + { + m_RHIRendering = PK_NEW(PKSample::CRHIParticleSceneRenderHelper); + if (!PK_VERIFY(m_RHIRendering != null)) + return false; + if (!PK_VERIFY(m_ShaderLoader != null)) + { + CLog::Log(PK_ERROR, "Shader loader was not properly set on the render context"); + return false; + } + + if (!m_RHIRendering->Init( apiManager, m_ShaderLoader, Resource::DefaultManager(), + PKSample::CRHIParticleSceneRenderHelper::InitRP_All)) + { + CLog::Log(PK_ERROR, "RHIRendering Initialisation failed"); + return false; + } + newRHIRendering = true; + } + if (updateRHISize || newRHIRendering) + { + if (!m_RHIRendering->Resize(m_AEGraphicContext->GetCurrentSwapChain())) + { + CLog::Log(PK_ERROR, "Particle render scene Resize failed"); + return false; + } + if (!m_RHIRendering->SetupPostFX_Distortion(m_SceneOptions.m_Distortion, newRHIRendering)) + { + CLog::Log(PK_ERROR, "Particle render scene SetupPostFX_Distortion failed"); + return false; + } + if (!m_RHIRendering->SetupPostFX_ToneMapping(m_SceneOptions.m_ToneMapping, m_SceneOptions.m_Vignetting, true /*dithering*/, newRHIRendering, false)) + { + CLog::Log(PK_ERROR, "Particle render scene SetupPostFX_ToneMapping failed"); + return false; + } + if (!m_RHIRendering->SetupPostFX_Bloom(m_SceneOptions.m_Bloom, newRHIRendering, true)) + { + CLog::Log(PK_ERROR, "Particle render scene SetupPostFX_Bloom failed"); + return false; + } + if (!m_RHIRendering->SetupPostFX_FXAA(m_SceneOptions.m_FXAA, newRHIRendering, false)) + { + CLog::Log(PK_ERROR, "Particle render scene SetupPostFX_FXAA failed"); + return false; + } + if (!m_RHIRendering->SetupShadows()) + { + CLog::Log(PK_ERROR, "Particle render scene SetupShadows failed"); + return false; + } + } + return true; +} + +//---------------------------------------------------------------------------- + +bool CAAERenderContext::AERenderFrameBegin(SAAEIOData &AAEData, bool getBackground /*=true*/) +{ + PK_SCOPEDPROFILE(); + PF_PixelFormat format = PF_PixelFormat_INVALID; + RHI::EPixelFormat rhiFormat = RHI::EPixelFormat::FormatUnknown; + AEGP_SuiteHandler suites(AAEData.m_InData->pica_basicP); + + PK_ASSERT(m_AEGraphicContext != null); + m_AEGraphicContext->SetAsCurrent(m_DeviceContext); + { + PK_NAMEDSCOPEDPROFILE("checkout_layer_pixels"); + AAEData.m_ExtraData.m_SmartRenderData->cb->checkout_layer_pixels(AAEData.m_InData->effect_ref, 0, &m_InputWorld); + if (!PK_VERIFY(m_InputWorld != null)) + { + CLog::Log(PK_ERROR, "Checkout AE input world failed"); + return false; + } + AAEData.m_ExtraData.m_SmartRenderData->cb->checkout_output(AAEData.m_InData->effect_ref, &m_OutputWorld); + if (!PK_VERIFY(m_OutputWorld != null)) + { + CLog::Log(PK_ERROR, "Checkout AE output world failed"); + ResetCheckedOutWorlds(AAEData); + return false; + } + } + + AAEData.m_WorldSuite->PF_GetPixelFormat(m_InputWorld, &format); + + rhiFormat = AAEToPK(format); + + u32 width = (u32)m_InputWorld->width; + u32 height = (u32)m_InputWorld->height; + + m_AAEFormat = format; + + if (m_Width != width || m_Height != height) + { + if (InitGraphicContext(rhiFormat, width, height) == false) + { + CLog::Log(PK_ERROR, "InitGraphicContext failed"); + ResetCheckedOutWorlds(AAEData); + return false; + } + } + + //Frame + if (!PK_VERIFY(m_AEGraphicContext->BeginFrame())) + { + CLog::Log(PK_ERROR, "Graphic context BeginFrame failed"); + ResetCheckedOutWorlds(AAEData); + return false; + } + + if (getBackground) + { + if (!GetCompositingBuffer(AAEData, suites, m_InputWorld, m_OutputWorld, format)) + { + CLog::Log(PK_ERROR, "GetCompositingBuffer failed"); + ResetCheckedOutWorlds(AAEData); + m_AEGraphicContext->EndFrame(); + return false; + } + } + else + m_RHIRendering->SetBackGroundTexture(null); + return true; +} + +//---------------------------------------------------------------------------- + +bool CAAERenderContext::AERenderFrameEnd(SAAEIOData &AAEData) +{ + PK_SCOPEDPROFILE(); + AEGP_SuiteHandler suites(AAEData.m_InData->pica_basicP); + + m_AEGraphicContext->EndFrame(); + + if (m_InputWorld == null || m_OutputWorld == null) + { + ResetCheckedOutWorlds(AAEData); + return false; + } + RenderToSAAEWorld(AAEData, suites, m_InputWorld, m_OutputWorld, m_AAEFormat); + ResetCheckedOutWorlds(AAEData); + return true; +} + +//---------------------------------------------------------------------------- + +bool CAAERenderContext::RenderToSAAEWorld(SAAEIOData &AAEData, AEGP_SuiteHandler &suiteHandler, PF_EffectWorld *inputWorld, PF_EffectWorld *effectWorld, PF_PixelFormat format) +{ + PK_SCOPEDPROFILE(); + + u32 requiredBufferSize = GetPixelSizeFromPixelFormat(m_Format) * inputWorld->width * inputWorld->height; + if (m_DownloadBuffer == null || m_DownloadBufferSize < requiredBufferSize) + { + m_DownloadBufferSize = requiredBufferSize; + if (m_DownloadBuffer != null) + m_DownloadBuffer = null; + m_DownloadBuffer = CRefCountedMemoryBuffer::Alloc(requiredBufferSize); + PK_ASSERT(m_DownloadBuffer != null); + } + + if (!m_AEGraphicContext->FillRenderBuffer(m_DownloadBuffer, m_RHIRendering->GetFinalFrameBuffers(0), m_Format, m_Width, m_Height, m_Width)) + { + CLog::Log(PK_ERROR, "FillRenderBuffer failed"); + return false; + } + + + PF_Err res = PF_Err_NONE; + + switch (format) + { + case PF_PixelFormat_ARGB128: + { + PK_NAMEDSCOPEDPROFILE("CopyPixelOut32"); + SCopyPixel refcon = { m_DownloadBuffer, inputWorld, m_Gamma, m_IsOverride, m_AlphaValue }; + + res = suiteHandler.IterateFloatSuite1()->iterate( AAEData.m_InData, + 0, + inputWorld->height, + inputWorld, + null, + reinterpret_cast(&refcon), + CopyPixelOut32, + effectWorld); + break; + } + case PF_PixelFormat_ARGB64: + { + PK_NAMEDSCOPEDPROFILE("CopyPixelOut16"); + SCopyPixel refcon = { m_DownloadBuffer, inputWorld, m_Gamma, m_IsOverride, m_AlphaValue }; + + res = suiteHandler.Iterate16Suite1()->iterate( AAEData.m_InData, + 0, + inputWorld->height, + inputWorld, + null, + reinterpret_cast(&refcon), + CopyPixelOut16, + effectWorld); + break; + } + + case PF_PixelFormat_ARGB32: + { + PK_NAMEDSCOPEDPROFILE("CopyPixelOut8"); + SCopyPixel refcon = { m_DownloadBuffer, inputWorld, m_Gamma, m_IsOverride, m_AlphaValue }; + + res = suiteHandler.Iterate8Suite1()->iterate( AAEData.m_InData, + 0, + inputWorld->height, + inputWorld, + null, + reinterpret_cast(&refcon), + CopyPixelOut8, + effectWorld); + break; + } + default: + PK_ASSERT(true); + break; + } + + if (res != PF_Err_NONE) + { + AAEData.m_ReturnCode = res; + return false; + } + return true; +} + +//---------------------------------------------------------------------------- + +bool CAAERenderContext::GetCompositingBuffer(SAAEIOData &AAEData, AEGP_SuiteHandler &suiteHandler, PF_EffectWorld *inputWorld, PF_EffectWorld *effectWorld, PF_PixelFormat format) +{ + PK_SCOPEDPROFILE(); + PF_Err res = PF_Err_NONE; + RHI::EPixelFormat rhiFormat = RHI::FormatFloat32RGBA; + + PF_Rect rect = inputWorld->extent_hint; + PF_Point origin; + + origin.h = (A_short)(AAEData.m_InData->output_origin_x); + origin.v = (A_short)(AAEData.m_InData->output_origin_y); + + // We always copy the pixels in 32 bpc + u32 requiredBufferSize = sizeof(CFloat4) * inputWorld->width * inputWorld->height; + if (m_UploadBuffer == null || m_UploadBufferSize < requiredBufferSize) + { + m_UploadBufferSize = requiredBufferSize; + m_UploadBuffer = CRefCountedMemoryBuffer::Alloc(requiredBufferSize); + PK_ASSERT(m_UploadBuffer != null); + } + void *srcBuffer = m_UploadBuffer->Data(); + + switch (format) + { + case PF_PixelFormat_ARGB128: + { + PK_NAMEDSCOPEDPROFILE("CopyPixelIn32_TryCatch"); + SCopyPixel refcon = { m_UploadBuffer, inputWorld, m_Gamma, m_IsOverride, m_AlphaValue }; + + try + { + PK_NAMEDSCOPEDPROFILE("CopyPixelIn32"); + res = suiteHandler.IterateFloatSuite1()->iterate_origin_non_clip_src(AAEData.m_InData, 0, inputWorld->height, inputWorld, &rect, &origin, + reinterpret_cast(&refcon), CopyPixelIn32, effectWorld); + } + catch (PF_Err& thrownErr) + { + res = thrownErr; + } + catch (...) + { + res = PF_Err_OUT_OF_MEMORY; + } + if (res == A_Err_NONE) + { + if (!m_AEGraphicContext->FillCompositingTexture(srcBuffer, rhiFormat, inputWorld->width, inputWorld->height, inputWorld->rowbytes / sizeof(PF_Pixel32))) + res = A_Err_GENERIC; + } + break; + } + case PF_PixelFormat_ARGB64: + { + PK_NAMEDSCOPEDPROFILE("CopyPixelIn16_TryCatch"); + SCopyPixel refcon = { m_UploadBuffer, inputWorld, m_Gamma, m_IsOverride, m_AlphaValue }; + + try + { + PK_NAMEDSCOPEDPROFILE("CopyPixelIn16"); + res = suiteHandler.Iterate16Suite1()->iterate_origin_non_clip_src(AAEData.m_InData, 0, inputWorld->height, inputWorld, &rect, &origin, + reinterpret_cast(&refcon), CopyPixelIn16, effectWorld); + } + catch (PF_Err& thrownErr) + { + res = thrownErr; + } + catch (...) + { + res = PF_Err_OUT_OF_MEMORY; + } + if (res == A_Err_NONE) + { + if (!m_AEGraphicContext->FillCompositingTexture(srcBuffer, rhiFormat, inputWorld->width, inputWorld->height, inputWorld->rowbytes / sizeof(PF_Pixel32))) + res = A_Err_GENERIC; + } + break; + } + + case PF_PixelFormat_ARGB32: + { + PK_NAMEDSCOPEDPROFILE("CopyPixelIn8_TryCatch"); + SCopyPixel refcon = { m_UploadBuffer, inputWorld, m_Gamma, m_IsOverride, m_AlphaValue }; + + try + { + PK_NAMEDSCOPEDPROFILE("CopyPixelIn8"); + res = suiteHandler.Iterate8Suite1()->iterate_origin_non_clip_src(AAEData.m_InData, 0, inputWorld->height, inputWorld, &rect, &origin, + reinterpret_cast(&refcon), CopyPixelIn8, effectWorld); + } + catch (PF_Err& thrownErr) + { + res = thrownErr; + } + catch (...) + { + res = PF_Err_OUT_OF_MEMORY; + } + if (res == A_Err_NONE) + { + if (!m_AEGraphicContext->FillCompositingTexture(srcBuffer, rhiFormat, inputWorld->width, inputWorld->height, inputWorld->rowbytes / sizeof(PF_Pixel32))) + res = A_Err_GENERIC; + } + break; + } + default: + break; + } + if (res) + { + AAEData.m_ReturnCode = res; + if (res == PF_Interrupt_CANCEL) + return false; + CLog::Log(PK_WARN, "Unknown error"); + return false; + } + + if (res == A_Err_NONE) + m_RHIRendering->SetBackGroundTexture(m_AEGraphicContext->GetCompositingTexture()); + + if (res != PF_Err_NONE) + { + AAEData.m_ReturnCode = res; + return false; + } + return true; +} + +//---------------------------------------------------------------------------- + +CUint2 CAAERenderContext::GetContextSize() +{ + return CUint2(m_Width, m_Height); +} + +//---------------------------------------------------------------------------- + +void CAAERenderContext::ResetCheckedOutWorlds(SAAEIOData &AAEData) +{ + AAEData.m_ExtraData.m_SmartRenderData->cb->checkin_layer_pixels(AAEData.m_InData->effect_ref, 0); + m_InputWorld = null; + m_OutputWorld = null; +} + +//---------------------------------------------------------------------------- + +bool CAAERenderContext::CreateInternalWindowIFN(const CString& className) +{ + if (m_WindowHandle != null) + return true; +#if defined(PK_MACOSX) + (void)className; + NSRect frameRect = NSMakeRect(100, 100 , 256, 256); + NSView *view = [[NSView alloc] initWithFrame:frameRect]; + [view setHidden:NO]; + [view setNeedsDisplay:YES]; + + NSWindow *myWindow = [[NSWindow alloc] initWithContentRect:NSMakeRect(100,100,256,256) styleMask:NSTitledWindowMask backing:NSBackingStoreBuffered defer:NO]; + [myWindow setContentView:view]; + //[myWindow makeKeyAndOrderFront:self]; + + m_WindowHandle = (void*)myWindow; + m_DeviceContext = null; + return m_WindowHandle != null; +#else + MSG uMsg; + + ::memset(&uMsg, 0, sizeof(uMsg)); + + // tricky, windows needs a unique class name for each window instance + // to derive a unique name, a pointer to "this" is used + static std::atomic_int S_cnt; + std::stringstream ss; + + ss << " PK_Win_Class" << S_cnt.load(); + S_cnt++; + CString name = className + CString(ss.str().c_str()); + + WNDCLASSEX winClass; + ::memset(&winClass, 0, sizeof(winClass)); + winClass.lpszClassName = name.Data(); + winClass.cbSize = sizeof(WNDCLASSEX); + winClass.style = CS_HREDRAW | CS_VREDRAW; + winClass.lpfnWndProc = ::DefWindowProc; + winClass.hInstance = GetModuleHandle(null); + winClass.hCursor = ::LoadCursor(null, IDC_ARROW); + winClass.hbrBackground = (HBRUSH)::GetStockObject(BLACK_BRUSH); + + if (!(::RegisterClassEx(&winClass))) + { + return false; + } + + HWND hwnd = ::CreateWindowEx(WS_EX_APPWINDOW | WS_EX_WINDOWEDGE, + name.Data(), + "PopcornFX context", + 0, 0, + 0, 8, 8, + null, + null, + null, + null); + + PK_ASSERT(hwnd != null); + m_WindowHandle = (void*)hwnd; + m_DeviceContext = (void*)::GetDC(hwnd); + return m_WindowHandle != null && m_DeviceContext != null; +#endif +} + +//---------------------------------------------------------------------------- + +__AEGP_PK_END diff --git a/AE_GeneralPlugin/Sources/AEGP_Scene.cpp b/AE_GeneralPlugin/Sources/AEGP_Scene.cpp new file mode 100644 index 00000000..76c71799 --- /dev/null +++ b/AE_GeneralPlugin/Sources/AEGP_Scene.cpp @@ -0,0 +1,2057 @@ +//---------------------------------------------------------------------------- +// Copyright Persistant Studios, SARL. All Rights Reserved. https://www.popcornfx.com/terms-and-conditions/ +//---------------------------------------------------------------------------- +#include "ae_precompiled.h" + +#include "AEGP_Scene.h" + +#include "AEGP_World.h" +#include "AEGP_AEPKConversion.h" + +#include "AEGP_RenderContext.h" +#include "RenderApi/AEGP_BaseContext.h" +#include "RenderApi/AEGP_D3D12Context.h" +#include "RenderApi/AEGP_D3D11Context.h" + +#include "AEGP_Attribute.h" +#include "AEGP_Log.h" +#include "AEGP_PackExplorer.h" + +#include "AEGP_Main.h" +#include "AEGP_Attribute.h" + +#include "AEGP_AssetBaker.h" +#include "AEGP_SkinnedMeshInstance.h" +#include "AEGP_SkinnedMesh.h" + +#include + + +#include + +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include + +#include // for Random::DefaultGenerator() +#include // for PRNG +#include // for CPlane in CParticleSceneBasic + +#include +#include + +#include + +#include +#include + +#include +#include + +#include + +__AEGP_PK_BEGIN + +//---------------------------------------------------------------------------- + +struct SSimpleSceneDef +{ + CString m_EffectPath; + CString m_BackdropMeshPath; + + CUint3 m_SpawnGridResolution; // defined in side-up-forward coordinates + float m_SpawnGridRange; + + float m_RespawnDelay; + + bool m_Seeking = false; + bool m_Refresh = false; + struct + { + float m_Distance; + CFloat3 m_Angles; // { pitch, yaw, roll } + float m_Height; + } m_CameraStartParameters; +}; + +//---------------------------------------------------------------------------- + + +u32 CAAEScene::s_SceneID = 0; + +//---------------------------------------------------------------------------- + +CAAEScene::CAAEScene() +: m_EffectRef(null) +, m_EffectDesc(null) +, m_LayerHolder(null) +, m_EmitterDefaultPosition(CFloat3::ZERO) +, m_EmitterDefaultOrientation(CFloat3::ZERO) +, m_EmitterTransformType(ETransformType::ETransformType_3D) +, m_EmitterTransformsCurrent(CFloat4x4::IDENTITY) +, m_EmitterTransformsPrevious(CFloat4x4::IDENTITY) +, m_EmitterVelCurrent(CFloat3::ZERO) +, m_EmitterVelPrevious(CFloat3::ZERO) +, m_OriginViewport(CUint2::ZERO) +, m_Paused(false) +, m_AEEmitterPosition(CFloat3::ZERO) +, m_AEEmitterRotation(CFloat3::ZERO) +, m_AEEmitterSeed(0) +, m_AEViewMatrix(CFloat4x4::IDENTITY) +, m_AECameraPos(CFloat4::ZERO) +, m_AECameraZoom(1.0f) +, m_TeleportEmitter(false) +, m_FrameNumber(0) +, m_DT(0.0f) +, m_PreviousTimeSec(0.0f) +, m_CurrentTimeSec(0.0f) +, m_Initialized(false) +, m_FrameAbortedDuringSeeking(A_Err_NONE) +, m_Effect(null) +, m_EffectFile(null) +, m_EffectLastInstance(null) +, m_AttributesList(null) +, m_EmitterPositionNormalized_Debug(CFloat4::ZERO) +, m_LastInstanceXForms(CFloat4x4::IDENTITY) +, m_DCSortMethod(EDrawCallSortMethod::Sort_DrawCalls) +, m_SceneInfoConstantSet(null) +, m_SceneInfoConstantBuffer(null) +, m_LoadedPack(null) +, m_HBOContext(null) +, m_ParticleScene(null) +, m_ParticleMediumCollection(null) +, m_Stats_SimulationTime(0.0f) +, m_ViewSlotInMediumCollection(CGuid::INVALID) +, m_SkinnedMeshInstance(null) +, m_SkeletonState(null) +, m_ResourceManager(null) +, m_HasBoundBackdrop(false) +, m_IsWeightedSampling(false) +, m_ColorStreamID(0) +, m_WeightStreamID(0) +, m_ForceRestartSeeking(true) +{ + m_ID = s_SceneID++; +} + +//---------------------------------------------------------------------------- + +CAAEScene::~CAAEScene() +{ + Quit(); +} + +//---------------------------------------------------------------------------- + +bool CAAEScene::Init(SAAEIOData &AAEData) +{ + if (AAEData.m_InData) + m_EffectRef = AAEData.m_InData->effect_ref; + else + m_EffectRef = null; + + m_ResourceManager = Resource::DefaultManager(); + if (!PK_VERIFY(m_ResourceManager != null)) + return CAELog::LogErrorWindows(&AAEData, "Could not allocate PopcornFX ResourceManager"); + if (m_HBOContext != null) + PK_SAFE_DELETE(m_HBOContext); + m_HBOContext = PK_NEW(HBO::CContext); + if (m_ParticleScene != null) + PK_SAFE_DELETE(m_ParticleScene); + m_ParticleScene = PK_NEW(CAAEParticleScene); + if (!PK_VERIFY(m_ParticleScene != null)) + return false; + m_ParticleScene->m_Parent = this; + //AAE INFO + SetWorldSize(AAEData); + // Medium collection + if (m_ParticleMediumCollection == null) + { + if (_SetupMediumCollection() == false) + return false; + } + + return true; +} + +//---------------------------------------------------------------------------- + +void CAAEScene::SetWorldSize(SAAEIOData &AAEData) +{ + if (AAEData.m_InData) + { + m_SAAEWorldData.m_WorldWidth = (float)AAEData.m_InData->width; + m_SAAEWorldData.m_WorldHeight = (float)AAEData.m_InData->height; + m_SAAEWorldData.m_WorldOrigin = CFloat3{ m_SAAEWorldData.m_WorldWidth / 2, m_SAAEWorldData.m_WorldHeight / 2, 0 }; + } +} + +//---------------------------------------------------------------------------- + +void CAAEScene::SetEmitterPosition(const CFloat3 &position, ETransformType type) +{ + m_EmitterTransformType = type; + m_AEEmitterPosition = position; +} + +//---------------------------------------------------------------------------- + +void CAAEScene::SetEmitterRotation(const CFloat3 &rotation) +{ + m_AEEmitterRotation = rotation; +} + +//---------------------------------------------------------------------------- + +void CAAEScene::SetEmitterTeleport(bool teleport) +{ + m_TeleportEmitter = teleport; +} + +//---------------------------------------------------------------------------- + +void CAAEScene::SetLayerHolder(SLayerHolder *parent) +{ + m_LayerHolder = parent; +} + +//---------------------------------------------------------------------------- + +void CAAEScene::SetCameraViewMatrix(const CFloat4x4 &viewMatrix, const CFloat4 &pos, const float cameraZoom) +{ + m_AECameraZoom = cameraZoom; + m_AECameraPos = pos; + m_AEViewMatrix = viewMatrix; +} + +//---------------------------------------------------------------------------- + +bool CAAEScene::RefreshAssetList() +{ + m_LoadedPack = null; + PK_ASSERT(m_LayerHolder != null); + + if (m_LayerHolder->m_BakedPack == null) + return false; + + m_LoadedPack = m_LayerHolder->m_BakedPack; + return true; +} + +//---------------------------------------------------------------------------- + +SSamplerAudio *CAAEScene::GetAudioSamplerDescriptor(CStringId name, SSamplerAudio::SamplingType type) +{ + if (!name.Valid() || name.Empty()) + return null; + + for (u32 i = 0; i < m_ActiveAudioSamplers.Count(); ++i) + { + if (name == m_ActiveAudioSamplers[i]->m_Name && type == m_ActiveAudioSamplers[i]->m_SamplingType) + { + return m_ActiveAudioSamplers[i]; + } + } + for (u32 i = 0; i < m_ActiveAudioSamplers.Count(); ++i) + { + if (name == m_ActiveAudioSamplers[i]->m_Name && m_ActiveAudioSamplers[i]->m_SamplingType == SSamplerAudio::SamplingType::SamplingType_Unknown) + { + return m_ActiveAudioSamplers[i]; + } + } + for (u32 i = 0; i < m_ActiveAudioSamplers.Count(); ++i) + { + if (!m_ActiveAudioSamplers[i]->m_Name.Valid() || m_ActiveAudioSamplers[i]->m_Name.Empty()) + { + m_ActiveAudioSamplers[i]->m_Name = name; + return m_ActiveAudioSamplers[i]; + } + } + return null; +} +//---------------------------------------------------------------------------- + +bool CAAEScene::GetEmitterBounds(CAABB &bounds) +{ + if (m_EffectLastInstance == null) + return false; + const CParticleMediumCollection::SEffectMediums *mediums = m_ParticleMediumCollection->MapEffectMediumLookup(m_Effect.Get()); + + for (auto medium : mediums->m_Mediums) + { + bounds.Add(medium->ExactBounds()); + } + return true; +} + +//---------------------------------------------------------------------------- + +bool CAAEScene::SetPack(PFilePack pack, bool unload) +{ + if (pack == null) + return false; + + ResetEffect(unload); + + m_LoadedPack = pack; + return true; +} + +//---------------------------------------------------------------------------- + +bool CAAEScene::SetSelectedEffect(CString name, bool refresh) +{ + if (name == null || name.Empty()) + return false; + CBakedPackExplorer packExplorer(m_LoadedPack->Path(), File::DefaultFileSystem()); + CString bakedName = CFilePath::StripExtension(name); + + bakedName += ".pkb"; + + packExplorer.Explore(); + TMemoryView effectPaths = packExplorer.EffectPaths(); + + if (effectPaths.IndexOf(bakedName).Valid()) + { + m_SelectedEffect = bakedName; + return SetupScene(false, refresh); + } + else + { + CAELog::TryLogInfoWindows("Trying to load " + bakedName + " Missing file in " + m_LoadedPack->Path() + " Reimport effect"); + } + return false; +} + +//---------------------------------------------------------------------------- + +void CAAEScene::SetEffectDescriptor(SEmitterDesc *desc) +{ + m_EffectDesc = desc; +} + +//---------------------------------------------------------------------------- + +bool CAAEScene::SetupScene(bool seeking, bool refresh) +{ + m_PreviousTimeSec = 0.0f; + m_CurrentTimeSec = 0.0f; + m_DT = 0.0f; + + PK_ASSERT(m_ParticleMediumCollection != null); + m_ParticleMediumCollection->Clear(); + + SetEmitterTeleport(); + + SSimpleSceneDef def; + def.m_Seeking = seeking; + def.m_Refresh = refresh; + if (m_SelectedEffect == null) + { + if (!m_LayerHolder->m_SpawnedEmitter.m_Desc->m_PathSource.empty()) + CPopcornFXWorld::Instance().SetDestinationPackFromPath(*m_LayerHolder, CString(m_LayerHolder->m_SpawnedEmitter.m_Desc->m_PathSource.c_str())); + SetPack(m_LayerHolder->m_BakedPack, true); + SetEffectDescriptor(m_LayerHolder->m_SpawnedEmitter.m_Desc); + SetSelectedEffect(CString(m_LayerHolder->m_SpawnedEmitter.m_Desc->m_Name.c_str()), false); + } + def.m_EffectPath = m_SelectedEffect; + + if (!_LoadScene(def)) + return false; + CPopcornFXWorld::Instance().OnEndSetupScene(); + return true; +} + +//---------------------------------------------------------------------------- + +bool CAAEScene::Quit() +{ + m_EffectRef = null; + m_EffectDesc = null; + + m_LayerHolder = null; + if (m_EffectLastInstance != null) + { + // Not strictly necessary to -= the callback, the instance is getting destroyed anyway. + m_EffectLastInstance->m_DeathNotifier -= FastDelegate(this, &CAAEScene::_OnInstanceDeath); + //m_EffectLastInstance->KillImmediate(); + m_EffectLastInstance = null; + } + m_AttributesList = null; + + m_EffectPath = null; + if (m_Effect != null) + m_Effect = null; + if (m_EffectFile != null) + { + m_EffectFile->Unload(); + m_EffectFile = null; + } + + m_ActiveAudioSamplers.Clear(); + + m_ParticleRenderDataFactory.UpdateThread_Release(); + + if (m_SkinnedMeshInstance != null) + { + m_SkinnedMeshInstance->WaitAsyncUpdateSkin(); + m_SkinnedMeshInstance->ClearSkinnedMesh(); + } + m_SkinnedMeshInstance = null; + + m_DrawOutputs.Clear(); + m_SceneInfoConstantSet = null; + m_SceneInfoConstantBuffer = null; + + m_LoadedPack = null; + + PK_SAFE_DELETE(m_ParticleScene); + + if (m_Initialized) + { + m_FrameCollector.UpdateThread_UninstallFromMediumCollection(m_ParticleMediumCollection); + if (m_ParticleMediumCollection) + { + m_ParticleMediumCollection->Clear(); + PK_SAFE_DELETE(m_ParticleMediumCollection); + } + m_FrameCollector.DestroyBillboardingBatches(); + m_FrameCollector.UpdateThread_Destroy(); + } + + m_ResourceManager = null; + + for (u32 i = 0; i < m_OverridableProperties.Count(); ++i) + PK_SAFE_DELETE(m_OverridableProperties[i]); + m_OverridableProperties.Clean(); + + PK_SAFE_DELETE(m_HBOContext); + + m_Initialized = false; + return true; +} + +//---------------------------------------------------------------------------- + +void CAAEScene::ShutdownPopcornFX() +{ + +} + +//---------------------------------------------------------------------------- + +bool CAAEScene::Update(SAAEIOData &AAEData) +{ + PK_SCOPEDPROFILE(); + + if (m_LayerHolder == null || m_EffectDesc == null) //Waiting for AE to process new effects + return true; + + SetWorldSize(AAEData); + if (!PK_VERIFY(_LateInitializeIFN())) + return false; + + m_EffectRef = AAEData.m_InData->effect_ref; + + if (!m_Paused) + { + if (m_EffectLastInstance == null) + { + if (!SetupScene(false, false)) + return false; + } + } + /// Update ------------------------------------------------------------------------------------------ + if (!m_Paused) + { + PK_NAMEDSCOPEDPROFILE("Scene Update"); + _ExtractAEFrameInfo(AAEData); + m_FrameCollector.ReleaseRenderedFrame(); + m_FrameAbortedDuringSeeking = A_Err_NONE; + _FastForwardSimulation(AAEData, m_CurrentTimeSec + m_DT); + if (m_FrameAbortedDuringSeeking != A_Err_NONE) + { + AAEData.m_ReturnCode = m_FrameAbortedDuringSeeking; + m_ParticleMediumCollection->Clear(); + return true; + } + if (_CheckRenderAbort(&AAEData)) + { + m_ParticleMediumCollection->Clear(); + return true; + } + _CollectCurrentFrame(); + } + + _FillAdditionnalDataForRender(); + +#if _DEBUG + auto v = m_ParticleMediumCollection->Stats(); +#endif + return true; +} + +//---------------------------------------------------------------------------- + +bool CAAEScene::UpdateAttributes(SLayerHolder *layer) +{ + PK_SCOPEDPROFILE(); + if (m_EffectLastInstance == null || layer == null) + return true; + + for (auto it = layer->m_SpawnedAttributes.Begin(); it != layer->m_SpawnedAttributes.End(); ++it) + { + SAttributeDesc *descriptor = static_cast(it->m_Desc); + if (descriptor == null) // Corrupt attribute on AE Side + it->m_Deleted = true; + else if (descriptor->m_IsDirty) + { + //Update Attributes Values +#if defined(PK_SCALE_DOWN) + if (descriptor->m_IsAffectedByScale) + { + void *attributeValue = descriptor->GetRawValue(); + CInt4 *intData = null; + CFloat4 *floatData = null; + + switch (descriptor->m_Type) + { + case (AttributeType_Int1): + case (AttributeType_Int2): + case (AttributeType_Int3): + case (AttributeType_Int4): + intData = static_cast(attributeValue); + *((CFloat4*)intData) /= layer->m_ScaleFactor; + break; + case (AttributeType_Float1): + case (AttributeType_Float2): + case (AttributeType_Float3): + case (AttributeType_Float4): + floatData = static_cast(attributeValue); + *floatData /= layer->m_ScaleFactor; + break; + default: + break; + } + if (!PK_VERIFY(m_EffectLastInstance->SetRawAttribute(descriptor->m_Name.data(), AttributeAAEToPK(descriptor->m_Type), attributeValue))) + return false; + } + else + { + if (!PK_VERIFY(m_EffectLastInstance->SetRawAttribute(descriptor->m_Name.data(), AttributeAAEToPK(descriptor->m_Type), descriptor->GetRawValue()))) + return false; + } +#else + if (!PK_VERIFY(m_EffectLastInstance->SetRawAttribute(descriptor->m_Name.data(), AttributeAAEToPK(descriptor->m_Type), descriptor->GetRawValue()))) + return false; +#endif + descriptor->m_IsDirty = false; + } + } + for (auto it = layer->m_SpawnedAttributesSampler.Begin(); it != layer->m_SpawnedAttributesSampler.End(); ++it) + { + SAttributeSamplerDesc *descriptor = static_cast(it->m_Desc); + if (descriptor == null) // Corrupt attribute on AE Side + it->m_Deleted = true; + + switch (descriptor->m_Type) + { + case AttributeSamplerType_Geometry: + _UpdateShapeSampler(*it, descriptor); + break; + case AttributeSamplerType_Text: + _UpdateTextSampler(*it, descriptor); + break; + case AttributeSamplerType_Image: + _UpdateImageSampler(*it, descriptor); + break; + case AttributeSamplerType_Audio: + _UpdateAudioSampler(*it, descriptor); + break; + case AttributeSamplerType_VectorField: + _UpdateVectorFieldSampler(*it, descriptor); + break; + default: + break; + } + if ((*it).m_PKDesc != null) + (*it).m_PKDesc->m_Dirty = false; + } + if (layer->m_BackdropAudioWaveform != null) + { + layer->m_BackdropAudioWaveform->m_BuiltThisFrame = false; + if (!PK_VERIFY(m_ActiveAudioSamplers.PushBack(layer->m_BackdropAudioWaveform).Valid())) + return false; + layer->m_BackdropAudioWaveform->m_Dirty = false; + } + if (layer->m_BackdropAudioSpectrum != null) + { + layer->m_BackdropAudioSpectrum->m_BuiltThisFrame = false; + if (!PK_VERIFY(m_ActiveAudioSamplers.PushBack(layer->m_BackdropAudioSpectrum).Valid())) + return false; + layer->m_BackdropAudioSpectrum->m_Dirty = false; + } + return true; +} + +//---------------------------------------------------------------------------- + +static CString _GetAnimPathFromMesh(const CResourceManager *resourceManager, const CString &meshPath) +{ + PK_ASSERT(resourceManager != null); + if (meshPath.Empty()) + return null; + + CString remappedPath = meshPath; + bool remappedPathNotVirtual = false; + resourceManager->RemapAndPurifyPathIFN(remappedPath, remappedPathNotVirtual); + PK_ASSERT(!remappedPathNotVirtual); + return CFilePath::StripExtension(remappedPath) + ".pksa"; +} + +//---------------------------------------------------------------------------- + +static bool _PreloadMeshResource(CResourceManager *resourceManager, const CString &path, TResourcePtr &dstMeshResource, PSkeletonState &dstBindPose) +{ + dstMeshResource = resourceManager->Load(path, false, SResourceLoadCtl(false, true)); + if (dstMeshResource == null) + { + CLog::Log(PK_ERROR, "Failed loading mesh resource \"%s\"", path.Data()); + return false; + } + + for (const auto &batch : dstMeshResource->BatchList()) + { + batch->RawMesh()->BuildTangentsIFN(); + } + + PSkeleton skeleton = dstMeshResource->Skeleton(); + if (skeleton != null) + { + dstBindPose = PK_NEW(CSkeletonState(skeleton)); + if (dstBindPose == null) + return false; + } + return true; +} + +//---------------------------------------------------------------------------- + +void CAAEScene::UpdateBackdropTransform(SEmitterDesc *desc) +{ + const CQuaternion quat = Transforms::Quaternion::FromEuler(CFloat3((float)desc->m_BackdropMesh.m_Rotation.x, (float)desc->m_BackdropMesh.m_Rotation.y, (float)desc->m_BackdropMesh.m_Rotation.z)); + const CFloat3 pos((float)desc->m_BackdropMesh.m_Position.x, (float)desc->m_BackdropMesh.m_Position.y, (float)desc->m_BackdropMesh.m_Position.z); + const CFloat4 scale((float)desc->m_BackdropMesh.m_Scale.x, (float)desc->m_BackdropMesh.m_Scale.y, (float)desc->m_BackdropMesh.m_Scale.z, 1.0f); + + m_BackdropData.m_MeshBackdropTransforms = Transforms::Matrix::FromQuaternion(quat, CFloat4(pos, 1.0f)); + m_BackdropData.m_MeshBackdropTransforms.Scale(scale); + if (desc->m_BackdropMesh.m_EnableCollisions) + m_ParticleScene->SetBackdropMeshTransform(m_BackdropData.m_MeshBackdropTransforms); +} + +//---------------------------------------------------------------------------- + +bool CAAEScene::UpdateBackdrop(SLayerHolder *layer,SEmitterDesc *desc) +{ + if (!desc->m_BackdropMesh.m_Path.empty()) + { + const CQuaternion quat = Transforms::Quaternion::FromEuler(CFloat3((float)desc->m_BackdropMesh.m_Rotation.x, (float)desc->m_BackdropMesh.m_Rotation.y, (float)desc->m_BackdropMesh.m_Rotation.z)); + const CFloat3 pos((float)desc->m_BackdropMesh.m_Position.x, (float)desc->m_BackdropMesh.m_Position.y, (float)desc->m_BackdropMesh.m_Position.z); + const CFloat4 scale((float)desc->m_BackdropMesh.m_Scale.x, (float)desc->m_BackdropMesh.m_Scale.y, (float)desc->m_BackdropMesh.m_Scale.z, 1.0f); + + m_BackdropData.m_MeshBackdropTransforms = Transforms::Matrix::FromQuaternion(quat, CFloat4(pos, 1.0f)); + m_BackdropData.m_MeshBackdropTransforms.Scale(scale); + if (m_BackdropData.m_MeshBackdropTransforms == CFloat4x4::IDENTITY && desc->m_LoadBackdrop) + { + CPopcornFXWorld &pkfxWorld = CPopcornFXWorld::Instance(); + m_BackdropData.m_MeshBackdropTransforms = m_EmitterTransformsCurrent; + pkfxWorld.SetBackdropMeshDefaultTransform(layer); + } + + m_BackdropData.m_MeshMetalness = desc->m_BackdropMesh.m_Metalness; + m_BackdropData.m_MeshRoughness = desc->m_BackdropMesh.m_Roughness; + + m_BackdropData.m_ShowMesh = desc->m_BackdropMesh.m_EnableRendering; + } + if (!desc->m_BackdropEnvironmentMap.m_Path.empty()) + { + CFilePackPath filePackPath = CFilePackPath::FromPhysicalPath(desc->m_BackdropEnvironmentMap.m_Path.data(), File::DefaultFileSystem()); + + m_BackdropData.m_EnvironmentMapPath = filePackPath.Path(); + m_BackdropData.m_EnvironmentMapColor = CFloat3((float)desc->m_BackdropEnvironmentMap.m_Color.x, (float)desc->m_BackdropEnvironmentMap.m_Color.y, (float)desc->m_BackdropEnvironmentMap.m_Color.z); + m_BackdropData.m_EnvironmentMapIntensity = desc->m_BackdropEnvironmentMap.m_Intensity; + m_BackdropData.m_BackgroundUsesEnvironmentMap = desc->m_BackdropEnvironmentMap.m_EnableRendering; + m_BackdropData.m_EnvironmentMapAffectsAmbient = true; + } + else + { + m_BackdropData.m_EnvironmentMapPath = null; + } + + if (!desc->m_UpdateBackdrop && !desc->m_LoadBackdrop) + return true; + + desc->m_LoadBackdrop = false; + desc->m_UpdateBackdrop = false; + if (!desc->m_BackdropMesh.m_Path.empty()) + { + CFilePackPath filePackPath = CFilePackPath::FromPhysicalPath(desc->m_BackdropMesh.m_Path.data(), File::DefaultFileSystem()); + + m_BackdropData.m_MeshPath = filePackPath.Path(); + + _PreloadMeshResource(m_ResourceManager, m_BackdropData.m_MeshPath, m_ResourceMesh, m_SkeletonState); + + if (desc->m_BackdropMesh.m_EnableCollisions) + m_ParticleScene->SetBackdropMesh(m_ResourceMesh, m_BackdropData.m_MeshBackdropTransforms); + else + m_ParticleScene->ClearBackdropMesh(); + if (desc->m_BackdropMesh.m_EnableAnimations) + { + const CString animPath = (!m_BackdropData.m_MeshPath.Empty()) ? _GetAnimPathFromMesh(m_ResourceManager, m_BackdropData.m_MeshPath) : CString::EmptyString; + m_SkinnedMeshInstance = PK_NEW(CSkinnedMeshInstance); + if (!m_SkinnedMeshInstance->LoadSkinnedMeshIFN(m_ResourceMesh, EMeshChannels::Channel_Tangent | EMeshChannels::Channel_Velocity | EMeshChannels::Channel_Normal | EMeshChannels::Channel_Position, m_SkeletonState) || + !m_SkinnedMeshInstance->LoadAnimationIFN(m_HBOContext, animPath, false)) + m_SkinnedMeshInstance = null; + } + } + else + { + m_SkinnedMeshInstance = null; + m_SkeletonState = null; + m_BackdropData.m_MeshPath = ""; + m_ParticleScene->ClearBackdropMesh(); + } + return true; +} + +//---------------------------------------------------------------------------- + +bool CAAEScene::Render(SAAEIOData &AAEData) +{ + if (_CheckRenderAbort(&AAEData)) + return true; + + CPopcornFXWorld &pkfxWorld = CPopcornFXWorld::Instance(); + + // our render specific context (one per thread) + PAAERenderContext currentRenderContext = pkfxWorld.GetCurrentRenderContext(); + if (!PK_VERIFY(currentRenderContext != null)) + return false; + + RHI::PApiManager apiManager = currentRenderContext->GetAEGraphicContext()->GetApiManager(); + + if (_CheckRenderAbort(&AAEData)) + return true; + + if (!(currentRenderContext->AERenderFrameBegin(AAEData, !m_BackdropData.m_BackgroundUsesEnvironmentMap))) + return true; + + if (_CheckRenderAbort(&AAEData)) + { + PK_VERIFY(currentRenderContext->AERenderFrameEnd(AAEData)); + return true; + } + + _RenderLastCollectedFrame(); + + // Update scene info + { + PKSample::Utils::SetupSceneInfoData(m_SceneInfoData, m_Camera, CCoordinateFrame::GlobalFrame()); + if (!PK_VERIFY(currentRenderContext->GetCurrentSceneRenderer()->SetSceneInfo(m_SceneInfoData, CCoordinateFrame::GlobalFrame()))) + { + PK_VERIFY(currentRenderContext->AERenderFrameEnd(AAEData)); + return false; + } + } + + //// Flush all graphical resources + PKSample::CRendererCacheInstance_UpdateThread::RenderThread_FlushAllResources(); + + PKSample::SParticleSceneOptions sceneOptions; + + AAEToPK(m_EffectDesc->m_Rendering, sceneOptions); + currentRenderContext->SetPostFXOptions(sceneOptions); + + currentRenderContext->SetBackgroundOptions(m_EffectDesc->m_IsAlphaBGOverride, m_EffectDesc->m_AlphaBGOverride); + + // Render ------------------------------------------------------------------------------------------ + { + PKSample::CRHIParticleSceneRenderHelper *renderHelper = currentRenderContext->GetCurrentSceneRenderer(); + CUint2 vpSize = currentRenderContext->GetViewportSize(); + // + PK_ASSERT(renderHelper != null); + PK_ASSERT(vpSize.x() != 0 || vpSize.y() != 0); + + RHI::PCommandBuffer preRenderCmdBuff = apiManager->CreateCommandBuffer(RHI::SRHIResourceInfos("PK-RHI Pre Render command buffer")); + RHI::PCommandBuffer postRenderCmdBuff = apiManager->CreateCommandBuffer(RHI::SRHIResourceInfos("PK-RHI Post Render command buffer")); + + renderHelper->SetupPostFX_Bloom(sceneOptions.m_Bloom, false, false); + renderHelper->SetupPostFX_Distortion(sceneOptions.m_Distortion, false); + renderHelper->SetupPostFX_ToneMapping(sceneOptions.m_ToneMapping, sceneOptions.m_Vignetting, sceneOptions.m_Dithering, false, false); + renderHelper->SetupPostFX_FXAA(sceneOptions.m_FXAA, false, false); + renderHelper->SetupShadows(); + renderHelper->SetCurrentPackResourceManager(m_ResourceManager); + renderHelper->SetBackdropInfo(m_BackdropData, ECoordinateFrame::Frame_User1); + + // Fill the command buffer + preRenderCmdBuff->Start(); + + if (!m_BackdropData.m_EnvironmentMapPath.Empty()) + { + renderHelper->GetEnvironmentMap().GenerateCubemap(preRenderCmdBuff); + + PKSample::SBackdropsData &data = renderHelper->GetBackDropsData(); + data.m_BackgroundUsesEnvironmentMap = m_BackdropData.m_BackgroundUsesEnvironmentMap; + data.m_EnvironmentMapAffectsAmbient = true; + } + + // Copy the particle count for the indirect draws: + PK_FOREACH(copy, m_DrawOutputs.m_CopyCommands) + { + if (!PK_VERIFY(preRenderCmdBuff->CopyBuffer(copy->m_SrcBuffer, copy->m_DstBuffer, copy->m_SrcOffset, copy->m_DstOffset, copy->m_SizeToCopy))) + { + CLog::Log(PK_ERROR, "preRenderCmdBuff->CopyBuffer() failed."); + PK_VERIFY(currentRenderContext->AERenderFrameEnd(AAEData)); + return false; + } + } + preRenderCmdBuff->SetViewport({ 0, 0 }, vpSize, { 0, 1 }); + preRenderCmdBuff->SetScissor({ 0, 0 }, vpSize); + + preRenderCmdBuff->Stop(); + apiManager->SubmitCommandBufferDirect(preRenderCmdBuff); + postRenderCmdBuff->Start(); + if (!PK_VERIFY(renderHelper->RenderScene(AAEToPK(m_EffectDesc->m_Rendering.m_Type), m_DrawOutputs, 0))) + { + CLog::Log(PK_ERROR, "renderHelper->RenderScene() failed."); + PK_VERIFY(currentRenderContext->AERenderFrameEnd(AAEData)); + return false; + } + + if (!PK_VERIFY(postRenderCmdBuff->Stop())) + { + CLog::Log(PK_ERROR, "postRenderCmdBuff->Stop() failed."); + PK_VERIFY(currentRenderContext->AERenderFrameEnd(AAEData)); + return false; + } + apiManager->SubmitCommandBufferDirect(postRenderCmdBuff); + if (!PK_VERIFY(currentRenderContext->AERenderFrameEnd(AAEData))) + return false; + } + return true; +} + +//---------------------------------------------------------------------------- + +bool CAAEScene::ResetEffect(bool unload) +{ + bool hasUnloaded = false; + + m_EffectLastInstance = null; + if (m_ParticleMediumCollection != null) + m_ParticleMediumCollection->Clear(); + m_Effect = null; + if (unload && m_EffectFile != null) + { + m_EffectFile->Unload(); + hasUnloaded = true; + m_EffectFile = null; + } + return hasUnloaded; +} + +//---------------------------------------------------------------------------- + +void CAAEScene::SetSkinnedBackdropParams(bool enabled, bool weightedSampling, u32 colorStreamID, u32 weightStreamID) +{ + bool update = false; + if (m_HasBoundBackdrop != enabled || m_IsWeightedSampling != weightedSampling || m_ColorStreamID != colorStreamID || m_WeightStreamID != weightStreamID) + update = true; + m_HasBoundBackdrop = enabled; + m_IsWeightedSampling = weightedSampling; + m_ColorStreamID = colorStreamID; + m_WeightStreamID = weightStreamID; + + if (update && m_SkinnedMeshInstance != null && m_ResourceMesh != null && m_ResourceMesh->BatchList().Count() > 0) + { + m_SkinnedMeshInstance->WaitAsyncUpdateSkin(); + + m_SkinnedMeshInstance->SetupAttributeSampler(m_ResourceMesh->BatchList()[0]->RawMesh(), + m_IsWeightedSampling, + m_ColorStreamID, + m_WeightStreamID); + } + +} + +//---------------------------------------------------------------------------- + +bool CAAEScene::UpdateLight(SLayerHolder *layer) +{ + PK_ASSERT(layer != null); + PK_ASSERT(layer->m_SpawnedEmitter.m_Desc != null); + + SLightDesc &light = layer->m_SpawnedEmitter.m_Desc->m_Light; + + if (light.m_Internal) + { + if (m_BackdropData.m_Lights.Count() == 0) + { + m_BackdropData.m_Lights.Resize(2); + } + m_BackdropData.m_Lights[0].SetAmbient(AAEToPK(light.m_Ambient), light.m_Intensity); + m_BackdropData.m_Lights[1].SetDirectional(AAEToPK(light.m_Direction), AAEToPK(light.m_Color), light.m_Intensity); + } + if (!light.m_Internal) + { + TArray lights; + A_Time time; + + time.value = layer->m_CurrentTime; + time.scale = layer->m_TimeScale; + if (!CAEUpdater::GetLightsAtTime(layer, time, lights)) + return false; + + if (lights.Count() != m_BackdropData.m_Lights.Count()) + m_BackdropData.m_Lights.Resize(lights.Count()); + for (u32 i = 0; i < lights.Count(); ++i) + { + if (lights[i].m_Type == AEGP_LightType_PARALLEL) + { + m_BackdropData.m_Lights[i].SetDirectional(AAEToPK(lights[i].m_Direction), AAEToPK(lights[i].m_Color), lights[i].m_Intensity); + } + else if (lights[i].m_Type == AEGP_LightType_AMBIENT) + { + m_BackdropData.m_Lights[i].SetAmbient(AAEToPK(lights[i].m_Color), lights[i].m_Intensity); + } + else if (lights[i].m_Type == AEGP_LightType_SPOT) + { + m_BackdropData.m_Lights[i].SetSpot(AAEToPK(lights[i].m_Position), AAEToPK(lights[i].m_Direction), lights[i].m_Angle, lights[i].m_Feather, AAEToPK(lights[i].m_Color), lights[i].m_Intensity); + } + else if (lights[i].m_Type == AEGP_LightType_POINT) + { + m_BackdropData.m_Lights[i].SetPoint(AAEToPK(lights[i].m_Position), AAEToPK(lights[i].m_Color), lights[i].m_Intensity); + } + } + } + + return false; +} + +//---------------------------------------------------------------------------- + +bool CAAEScene::_LateInitializeIFN() +{ + if (m_Initialized == true) + return true; + // Medium collection + if (m_ParticleMediumCollection == null) + { + if (_SetupMediumCollection() == false) + return false; + } + // Render data factory + { + CPopcornFXWorld &pkfxWorld = CPopcornFXWorld::Instance(); + + PK_SCOPEDLOCK(pkfxWorld.GetRenderLock()); + RHI::PApiManager apiManager = pkfxWorld.GetCurrentRenderContext()->GetAEGraphicContext()->GetApiManager(); + const RHI::SGPUCaps &caps = apiManager->GetApiContext()->m_GPUCaps; // We get the GPU caps to know what is supported by the GPU and fallback IFN + m_ParticleRenderDataFactory.UpdateThread_Initialize(apiManager->ApiName(), m_HBOContext, caps, Drawers::BillboardingLocation_CPU); + } + // Frame collector + { + const u32 enabledRenderers = (1U << ERendererClass::Renderer_Billboard) | (1U << ERendererClass::Renderer_Ribbon) | (1U << ERendererClass::Renderer_Mesh) | (1U << ERendererClass::Renderer_Light) | (1U << ERendererClass::Renderer_Triangle); + + // Initialize the frame collector with the factory and required renderers (see CPopcornScene::CollectCurrentFrame() for more detail) + CFrameCollector::SFrameCollectorInit init(&m_ParticleRenderDataFactory, enabledRenderers); + if (!m_FrameCollector.UpdateThread_Initialize(init)) + { + return CAELog::TryLogErrorWindows("Failed to initialize the frame collector."); + } + // Hook this frame collector to the medium collection. It will "listen" to each medium insertion (see rh_frame_collector.inl) + m_FrameCollector.UpdateThread_InstallToMediumCollection(m_ParticleMediumCollection); + + m_FrameCollector.SetDrawCallsSortMethod(m_DCSortMethod); + } + m_Initialized = true; + return true; +} + +//---------------------------------------------------------------------------- + +bool CAAEScene::_SetupMediumCollection() +{ + PK_ASSERT(m_ParticleMediumCollection == null); + + CPopcornFXWorld &pkfxWorld = CPopcornFXWorld::Instance(); + + PK_SCOPEDLOCK(pkfxWorld.GetRenderLock()); + + PAAERenderContext renderContext = pkfxWorld.GetCurrentRenderContext(); + + CParticleUpdateManager_Auto *updateManager = null; + +#if PK_PARTICLES_UPDATER_USE_D3D12 != 0 + if (pkfxWorld.GetRenderApi() == RHI::GApi_D3D12) + updateManager = PopcornFX::CParticleUpdateManager_Auto::New(EGPUContext::ContextD3D12); +#endif + +#if PK_PARTICLES_UPDATER_USE_D3D11 != 0 + if (pkfxWorld.GetRenderApi() == RHI::GApi_D3D11) + updateManager = PopcornFX::CParticleUpdateManager_Auto::New(EGPUContext::ContextD3D11); +#endif + + m_ParticleMediumCollection = PK_NEW(CParticleMediumCollection(m_ParticleScene, updateManager)); + if (!PK_VERIFY(m_ParticleMediumCollection != null)) + return false; + + m_ViewSlotInMediumCollection = m_ParticleMediumCollection->RegisterView(); + if (!PK_VERIFY(m_ViewSlotInMediumCollection.Valid())) + return false; + + m_ParticleMediumCollection->m_OnUpdateComplete += FastDelegate(this, &CAAEScene::_OnUpdateComplete); + + m_ParticleMediumCollection->EnableBounds(true); + m_ParticleMediumCollection->EnableLocalizedPages(true, false); + +#if 0 +#if PK_PARTICLES_UPDATER_USE_D3D12 != 0 + if (pkfxWorld.GetRenderApi() == RHI::GApi_D3D12) + { + CAAED3D12Context *D3D12Context = static_cast(renderContext->GetAEGraphicContext()); + + if (D3D12Context != null) + { + m_OriginViewport = renderContext->GetContextSize(); + // Small struct describing the D3D12 device used to build command lists, the root signature and the callback for submitting tasks to the engine + // g_D3D12SerializeRootSignature is PFN_D3D12_SERIALIZE_ROOT_SIGNATURE + PopcornFX::SD3D12Context context(D3D12Context->m_D3D12Context->m_Device, D3D12Context->m_D3D12Context->m_SerializeRootSignatureFunc, PopcornFX::CParticleUpdateManager_D3D12::CbEnqueueTask(this, &CAAEScene::D3D12_EnqueueTask), D3D12_COMMAND_LIST_TYPE_DIRECT); + + if (updateManager->GetUpdateManager_GPU()->BindContext(context)) + { + // Enables GPU simulation but does not force it + + m_ParticleMediumCollection->SetSimDispatchMaskCallback(CParticleMediumCollection::CbSimDispatchMask(&SimDispatchMask)); + } + } + } +#endif + +#if PK_PARTICLES_UPDATER_USE_D3D11 != 0 + if (pkfxWorld.GetRenderApi() == RHI::GApi_D3D11) + { + CAAED3D11Context *D3D11Context = static_cast(renderContext->GetAEGraphicContext()); + + if (D3D11Context != null) + { + m_OriginViewport = renderContext->GetContextSize(); + PopcornFX::SD3D11Context context(D3D11Context->m_D3D11Context->m_Device, D3D11Context->m_D3D11Context->m_ImmediateDeviceContext); + + CParticleUpdateManager_D3D11 *updateManagerD3D11 = checked_cast(updateManager->GetUpdateManager_GPU()); + if (updateManagerD3D11) + { + updateManagerD3D11->SetOwner(m_ParticleMediumCollection); + if (!updateManagerD3D11->BindContext(context)) + { + return false; + } + } + } + } +#endif +#endif + return true; +} + +//---------------------------------------------------------------------------- + +void CAAEScene::_FastForwardSimulation(SAAEIOData &AAEData, float timeTarget) +{ + (void)AAEData; + + if (m_Effect == null) + { + m_FrameAbortedDuringSeeking = A_Err_GENERIC; + return; + } + if (!PK_VERIFY(m_ParticleMediumCollection != null)) + return; + + CTimer updateTimer; + + updateTimer.Start(); + + const float maxUpdateTime = 30.0f; + + if (!PK_VERIFY(m_Effect->FeatureFlagsAll() & SParticleDeclaration::FeatureFlag_Determinism)) // if at least one layer doesn't have the flag, fail. + CAELog::TryLogErrorWindows("Effect is baked with Determinism disabled."); + + ParticleToolbox::SSeekingContextNew seekingCtx(timeTarget, m_DT, m_DT, maxUpdateTime, 0.0f, m_Effect.Get(), m_EmitterTransformsCurrent); + + ParticleToolbox::SSeekingContextNew::SInstanceInfo instInfo; + PK_ASSERT(m_Effect != null); + instInfo.m_Effect = m_Effect.Get(); + instInfo.m_CurTransforms = m_EmitterTransformsCurrent; + instInfo.m_SpawnTime = 0.0f; + PK_VERIFY(seekingCtx.m_InstancesToSpawn.PushBack(instInfo).Valid()); + + seekingCtx.m_LoadAndRunEffectDelegate = FastDelegate(this, &CAAEScene::_SeekingLoadAndRunEffect); + seekingCtx.m_UpdateEffectDelegate = FastDelegate(this, &CAAEScene::_SeekingUpdateEffect); + seekingCtx.m_WaitForUpdateFenceDelegate = FastDelegate(this, &CAAEScene::_SeekingWaitForUpdateFence); + + seekingCtx.m_PrecisionEpsilon = m_DT / 10.0f; // Arbitrary value for precision issues + seekingCtx.m_ForceRestartWhenNoUpdateNeeded = true; // Restarts when the elapsed time is equal to the target time + seekingCtx.m_ForceRestartFromZero = m_ForceRestartSeeking; + + m_AAEDataForSeeking = &AAEData; + PF_PROGRESS(m_AAEDataForSeeking->m_InData, 0, 1000); + ParticleToolbox::SSeekingContextNew::SeekToTargetTime(seekingCtx, m_ParticleMediumCollection); + m_AAEDataForSeeking = null; + m_Stats_SimulationTime = (float)updateTimer.Stop(); +} + +//---------------------------------------------------------------------------- + +void CAAEScene::_SeekingLoadAndRunEffect( CParticleMediumCollection *mediumCollection, + const CParticleEffect *effect, + const CFloat4x4 &transform, + float timeFromStartOfFrame, + float timeToEndOfFrame, + float elapsedTime) +{ + (void)timeFromStartOfFrame; + (void)timeToEndOfFrame; + (void)transform; + (void)effect; + (void)mediumCollection; + m_FrameAbortedDuringSeeking |= CAEUpdater::UpdateLayerAtTime(m_LayerHolder, elapsedTime, true); + SetupScene(true, false); + m_FrameAbortedDuringSeeking |= CAEUpdater::UpdateLayerAtTime(m_LayerHolder, elapsedTime, true); +} + +//---------------------------------------------------------------------------- + +bool CAAEScene::_SeekingUpdateEffect(float dt, float elapsedTime, float timeTarget, u32 curUpdateIdx, u32 totalUpdatesCount) +{ + (void)dt; + (void)elapsedTime; + (void)timeTarget; + + if (totalUpdatesCount != 0) + { + PF_Err res = PF_Err_NONE; + res = PF_PROGRESS(m_AAEDataForSeeking->m_InData, curUpdateIdx, totalUpdatesCount); + if (res != PF_Err_NONE) + { + m_AAEDataForSeeking->m_ReturnCode = res; + return false; + } + } + m_FrameAbortedDuringSeeking |= CAEUpdater::UpdateLayerAtTime(m_LayerHolder, elapsedTime, curUpdateIdx != totalUpdatesCount); + + if (m_SkinnedMeshInstance != null) + { + if (elapsedTime == 0.0f) + m_SkinnedMeshInstance->ResetAnimationCursor(); + const CFloat4x4 &backdropTransforms = (m_ParticleScene != null) ? m_ParticleScene->BackdropMeshTransforms() : CFloat4x4::IDENTITY; + m_SkinnedMeshInstance->SetBackdropXForms(backdropTransforms); + m_SkinnedMeshInstance->Update(dt); + m_SkinnedMeshInstance->StartAsyncUpdateSkin(dt); + m_SkinnedMeshInstance->WaitAsyncUpdateSkin(); + } + _UpdateCamera(); + _UpdateEmitter(dt); + _UpdateMediumCollectionView(); + return m_FrameAbortedDuringSeeking == A_Err_NONE; +} + +//---------------------------------------------------------------------------- + +bool CAAEScene::_SeekingWaitForUpdateFence(CTimer *waitTimer, float customMaxUpdateTime) +{ + (void)waitTimer; + + const u32 kMaxWaitTimeMs = 100;//ms max wait time + const float kMaxUpdateTimeSecsSetting = 1000;//ms + bool updateInProgress = true; + float maxUpdateTimeSecs = customMaxUpdateTime >= 0.0f ? customMaxUpdateTime : kMaxUpdateTimeSecsSetting; + CTimer ignoreTimer; + + ignoreTimer.Start(); + ignoreTimer.Pause(); + while (updateInProgress) + { + updateInProgress = m_ParticleMediumCollection->UpdateFence(kMaxWaitTimeMs); + if (updateInProgress || maxUpdateTimeSecs <= 0.0f) + { + } + } + return true; +} + +//---------------------------------------------------------------------------- + +u32 CAAEScene::_PickNewEffectSeed() +{ + return (u32)m_AEEmitterSeed; +} + +//---------------------------------------------------------------------------- + +bool CAAEScene::_UpdateShapeSampler(SPendingAttribute &samplerData, SAttributeSamplerDesc *descriptor) +{ + if (!PK_VERIFY(descriptor != null) || + !PK_VERIFY(samplerData.m_PKDesc != null)) + return false; + + SSamplerShape *pkDesc = static_cast(samplerData.m_PKDesc); + SShapeSamplerDescriptor *aeDesc = static_cast(descriptor->m_Descriptor); + + if (aeDesc == null) + return false; + + pkDesc->UpdateShape(aeDesc); + + CParticleSamplerDescriptor_Shape_Default *shapeSmpDesc = null; + if (aeDesc->m_BindToBackdrop && m_SkinnedMeshInstance != null && m_SkinnedMeshInstance->m_ShapeDescOverride != null) + shapeSmpDesc = static_cast(m_SkinnedMeshInstance->m_ShapeDescOverride.Get()); + else + shapeSmpDesc = static_cast(pkDesc->m_SamplerDescriptor.Get()); + m_EffectLastInstance->SetAttributeSampler(descriptor->m_Name.data(), shapeSmpDesc); + return true; +} + +//---------------------------------------------------------------------------- + +bool CAAEScene::_UpdateTextSampler(SPendingAttribute &samplerData, SAttributeSamplerDesc *descriptor) +{ + if (!PK_VERIFY(descriptor != null) || + !PK_VERIFY(samplerData.m_PKDesc != null)) + return false; + SSamplerText *pkDesc = static_cast(samplerData.m_PKDesc); + STextSamplerDescriptor *aeDesc = static_cast(descriptor->m_Descriptor); + + if (aeDesc == null) + return false; + + pkDesc->UpdateText(aeDesc); + + CParticleSamplerDescriptor_Text_Default *textSmpDesc = static_cast(pkDesc->m_SamplerDescriptor.Get()); + + if (!PK_VERIFY(m_EffectLastInstance->SetAttributeSampler(descriptor->m_Name.data(), textSmpDesc))) + return false; + return true; +} + +//---------------------------------------------------------------------------- + +bool CAAEScene::_UpdateImageSampler(SPendingAttribute &samplerData, SAttributeSamplerDesc *descriptor) +{ + if (!PK_VERIFY(descriptor != null) || + !PK_VERIFY(samplerData.m_PKDesc != null)) + return false; + SSamplerImage *pkDesc = static_cast(samplerData.m_PKDesc); + SImageSamplerDescriptor *aeDesc = static_cast(descriptor->m_Descriptor); + + if (aeDesc == null) + return false; + if (pkDesc->m_Dirty) + { + pkDesc->UpdateImage(aeDesc); + } + + CParticleSamplerDescriptor_Image_Default *imageSmpDesc = static_cast(pkDesc->m_SamplerDescriptor.Get()); + + if (!PK_VERIFY(m_EffectLastInstance->SetAttributeSampler(descriptor->m_Name.data(), imageSmpDesc))) + return false; + return true; +} + +//---------------------------------------------------------------------------- + +bool CAAEScene::_UpdateAudioSampler(SPendingAttribute &samplerData, SAttributeSamplerDesc *descriptor) +{ + if (!PK_VERIFY(descriptor != null) || + !PK_VERIFY(samplerData.m_PKDesc != null)) + return false; + + SSamplerAudio *pkDesc = static_cast(samplerData.m_PKDesc); + + pkDesc->m_BuiltThisFrame = false; + m_ActiveAudioSamplers.PushBack(pkDesc); + return true; +} + +//---------------------------------------------------------------------------- + +bool CAAEScene::_UpdateVectorFieldSampler(SPendingAttribute &samplerData, SAttributeSamplerDesc *descriptor) +{ + if (!PK_VERIFY(descriptor != null) || + !PK_VERIFY(samplerData.m_PKDesc != null)) + return false; + + SSamplerVectorField *pkDesc = static_cast(samplerData.m_PKDesc); + SVectorFieldSamplerDescriptor *aeDesc = static_cast(descriptor->m_Descriptor); + + if (aeDesc == null) + return false; + pkDesc->UpdateVectorField(aeDesc); + + CParticleSamplerDescriptor_VectorField_Grid *turbulenceSmpDesc = static_cast(pkDesc->m_SamplerDescriptor.Get()); + + if (!PK_VERIFY(m_EffectLastInstance->SetAttributeSampler(descriptor->m_Name.data(), turbulenceSmpDesc))) + return false; + + return true; +} + +//---------------------------------------------------------------------------- + +bool CAAEScene::_LoadScene(const SSimpleSceneDef &sceneDef) +{ + m_EffectLastInstance = null; + + if (!_LoadEffectIFN(sceneDef)) + return false; + + m_EffectLastInstance = _InstantiateEffect(); + PK_ASSERT(m_EffectLastInstance != null); + if (m_EffectLastInstance == null) // failed instantiating + return false; + m_EffectDesc->m_Name = sceneDef.m_EffectPath.Data(); + if (sceneDef.m_BackdropMeshPath.Data() != null) + m_EffectDesc->m_BackdropMesh.m_Path = sceneDef.m_BackdropMeshPath.Data(); + + if (m_SkinnedMeshInstance != null) + { + m_SkinnedMeshInstance->Update(0.0f); + m_SkinnedMeshInstance->StartAsyncUpdateSkin(0.0f); + m_SkinnedMeshInstance->WaitAsyncUpdateSkin(); + + m_SkinnedMeshInstance->SetupAttributeSampler(m_ResourceMesh->BatchList()[0]->RawMesh(), + m_IsWeightedSampling, + m_ColorStreamID, + m_WeightStreamID); + } + return true; +} + +//---------------------------------------------------------------------------- + +void CAAEScene::_CollectCurrentFrame() +{ + PK_SCOPEDPROFILE(); + m_FrameCollector.m_CullingFrustums = TMemoryView(m_Camera.ViewFrustum()); + + if (m_FrameCollector.UpdateThread_BeginCollectFrame()) + { + m_FrameCollector.UpdateThread_CollectFrame(m_ParticleMediumCollection); + } +} + +//---------------------------------------------------------------------------- + +void CAAEScene::_RenderLastCollectedFrame() +{ + TSceneView view; + + CFloat4x4 matW2P = m_Camera.m_ViewInv;//AE Axis System + + matW2P.Axis(1) *= -1; //AE Y-down to PopcornFX Y-up + matW2P.Axis(2) *= -1; //AE Z-foward to PopcornFX Z-backward + view.m_InvViewMatrix = matW2P; + view.m_NeedsSortedIndices = true; + + m_FrameCollector.BuildNewFrame(m_FrameCollector.UpdateThread_GetLastCollectedFrame()); + m_DrawOutputs.Clear(); + + // Build necessary renderer caches + CPopcornFXWorld &pkfxWorld = CPopcornFXWorld::Instance(); + PAAERenderContext currentRenderContext = pkfxWorld.GetCurrentRenderContext(); + + m_ParticleRenderDataFactory.RenderThread_BuildPendingCaches(currentRenderContext->GetAEGraphicContext()->GetApiManager()); + + // Do not release last collected frame when billboarding is finished + // We release frame before updating the medium collection (avoids handling of special cases when sim is paused) + const bool releaseLastCollectedFrame = false; + + PKSample::SRenderContext context(PKSample::SRenderContext::EPass_RenderThread, currentRenderContext->GetAEGraphicContext()->GetApiManager()); + + if (m_FrameCollector.BeginCollectingDrawCalls(context, TMemoryView(view))) + m_FrameCollector.EndCollectingDrawCalls(context, m_DrawOutputs, releaseLastCollectedFrame); +} + +//---------------------------------------------------------------------------- + +void CAAEScene::_UpdateEmitter(float dt) +{ + CQuaternion quat = Transforms::Quaternion::FromEuler(m_AEEmitterRotation); + + if (m_EmitterTransformType == ETransformType_2D) //If project coordinate to match 2D Widget + { + //normalize to -1;1 + const CFloat2 viewportDimensions = CFloat2(m_SAAEWorldData.m_WorldWidth, m_SAAEWorldData.m_WorldHeight); + const CFloat2 normalizedViewportCoords = (m_AEEmitterPosition.xy() / CFloat2(viewportDimensions)) * CFloat2(2, 2) - 1; + + const CFloat4x4 viewProj = m_Camera.m_View * m_Camera.m_Proj; + const CFloat4x4 viewProjInv = viewProj.Inverse(); + + const CFloat4 clipPos = CFloat4(normalizedViewportCoords, 0, 1); + const CFloat4 worldPosOnNearPlaneH = viewProjInv.TransformVector(clipPos); + const CFloat3 worldPosOnNearPlane = worldPosOnNearPlaneH.xyz() / worldPosOnNearPlaneH.w(); + const CFloat3 worldOrigin = m_Camera.m_View.Inverse().StrippedTranslations(); + const CFloat3 worldDirection = (worldPosOnNearPlane - worldOrigin).Normalized(); + + m_EmitterTransformsPrevious = m_EmitterTransformsCurrent; + m_EmitterTransformsCurrent = Transforms::Matrix::FromQuaternion(quat, CFloat4(worldOrigin + worldDirection * m_AEEmitterPosition.z(), 1.0f)); + } + else + { + CFloat3 pos(m_AEEmitterPosition.x(), m_AEEmitterPosition.y(), m_AEEmitterPosition.z()); + + m_EmitterTransformsPrevious = m_EmitterTransformsCurrent; + m_EmitterTransformsCurrent = Transforms::Matrix::FromQuaternion(quat, CFloat4(pos, 1.0f)); + } + if (m_TeleportEmitter == true) + { + m_EmitterTransformsPrevious = m_EmitterTransformsCurrent; + m_TeleportEmitter = false; + } + + m_EmitterVelPrevious = m_EmitterVelCurrent; + if (dt > 1.0e-6f) + { + const float invDt = PKRcp(dt); + const CFloat3 posDelta = m_EmitterTransformsCurrent.StrippedTranslations() - m_EmitterTransformsPrevious.StrippedTranslations(); + m_EmitterVelCurrent = posDelta * invDt; + } + + if (m_LayerHolder->m_SpawnedEmitter.m_Desc->m_SimStatePrev != m_LayerHolder->m_SpawnedEmitter.m_Desc->m_SimState) + { + if (m_LayerHolder->m_SpawnedEmitter.m_Desc->m_SimState) + m_EffectLastInstance = _InstantiateEffect(0, 0); + else if (m_EffectLastInstance != null) + m_EffectLastInstance->Stop(); + } +} + +//---------------------------------------------------------------------------- + +void CAAEScene::_UpdateCamera() +{ + CFloat4 cameraPos = m_AECameraPos; + + m_Camera.m_View = m_AEViewMatrix ; + if (m_EmitterTransformType == ETransformType_2D)//If project coordinate to match 2D Widget + { + { + //normalize to -1;1 + m_EmitterPositionNormalized_Debug = CFloat4(cameraPos.x() - (m_SAAEWorldData.m_WorldWidth / 2.0f), + cameraPos.y() - (m_SAAEWorldData.m_WorldHeight / 2.0f), + cameraPos.z(), + 1.0f); + m_Camera.m_Position = m_EmitterPositionNormalized_Debug.xyz(); + } + + m_Camera.m_View.WAxis() = CFloat4(m_Camera.m_Position.x(), m_Camera.m_Position.y(), m_Camera.m_Position.z(), 1.0f); + } + else + m_Camera.m_Position = cameraPos.xyz(); + + if (m_SAAEWorldData.m_WorldWidth > 0 && m_SAAEWorldData.m_WorldHeight > 0) + { + if (m_EmitterTransformType == ETransformType_2D) + { + float ratio = Units::DegreesToRadians((((m_AECameraZoom) * 2.0f) / (m_SAAEWorldData.m_WorldWidth))); + float HFov = 2.0f * (1.0f / tan(ratio)); + + _SetProj(HFov, CFloat2(m_SAAEWorldData.m_WorldWidth, m_SAAEWorldData.m_WorldHeight), m_EffectDesc->m_Camera.m_Near, m_EffectDesc->m_Camera.m_Far); + } + else + { + double tanTheta = (((double)m_SAAEWorldData.m_WorldHeight) / (double)(2.0 * m_AECameraZoom)); + double halfFOV = Units::RadiansToDegrees(atan(tanTheta)); + float FOVDeg = (float)(halfFOV * 2.0); + + _SetProj(FOVDeg, CFloat2(m_SAAEWorldData.m_WorldWidth, m_SAAEWorldData.m_WorldHeight), m_EffectDesc->m_Camera.m_Near, m_EffectDesc->m_Camera.m_Far); + } + } + else + { + PK_ASSERT_NOT_REACHED(); + } + m_Camera.Update(); +} + +//---------------------------------------------------------------------------- + +void CAAEScene::_UpdateMediumCollectionView() +{ + const CFloat4x4 matW2V = m_Camera.m_View; //AE Axis system + const CFloat4x4 matW2P = matW2V * m_Camera.m_Proj; //RHYUP + + PK_ASSERT(m_ViewSlotInMediumCollection.Valid()); + m_ParticleMediumCollection->UpdateView(m_ViewSlotInMediumCollection, matW2V, matW2P, m_Camera.m_WinSize); +} + +//---------------------------------------------------------------------------- + +void CAAEScene::_OnUpdateComplete(CParticleMediumCollection *collection) +{ + (void)collection; + for (u32 i = 0; i < m_ActiveAudioSamplers.Count(); ++i) + { + m_ActiveAudioSamplers[i]->ReleaseAEResources(); + } + m_ActiveAudioSamplers.Clear(); +} + +//---------------------------------------------------------------------------- + +bool CAAEScene::_LoadEffectIFN(const SSimpleSceneDef &sceneDef) +{ + CPopcornFXWorld &world = CPopcornFXWorld::Instance(); + + if (m_LayerHolder->m_LayerProperty == null) + world.CreateLayerPropertyIFP(m_LayerHolder); + + if (m_Effect != null && sceneDef.m_Refresh == false) + return true; + + for (u32 i = 0; i < m_OverridableProperties.Count(); ++i) + PK_SAFE_DELETE(m_OverridableProperties[i]); + m_OverridableProperties.Clean(); + if (sceneDef.m_EffectPath == null) + { + CLog::Log(PK_ERROR, "empty effect path."); + return false; + } + + CLog::Log(PK_INFO, "Loading Effect : %s", sceneDef.m_EffectPath.Data()); + + IFileSystem *fileSystem = File::DefaultFileSystem(); + + // Method #1 for loading: Pass down your own memory buffer to the load function + u32 rawFileSize = 0; // will be filled by 'Bufferize' call below + u8 *rawFileBuffer = fileSystem->Bufferize(m_LoadedPack->Path() / sceneDef.m_EffectPath, &rawFileSize, true); + if (rawFileBuffer != null) + { + CConstMemoryStream memoryFileView(rawFileBuffer, rawFileSize); + + PBaseObjectFile objFile = m_HBOContext->LoadFileFromStream(memoryFileView, sceneDef.m_EffectPath); + + if (!PK_VERIFY(objFile != null)) + { + CLog::Log(PK_ERROR, "Loading file from stream failed: %s", sceneDef.m_EffectPath.Data()); + return false; + } + + if (m_LayerHolder->m_LayerProperty != null) + { + for (auto obj : objFile->ObjectList()) + { + PLayerCompileCache srcLayer = HBO::Cast(obj.Get()); + + if (srcLayer != null) + { + for (auto &srcRenderer : srcLayer->Renderers()) + { + for (u32 pidx = 0; pidx < srcRenderer->Properties().Count(); ++pidx) + { + CLayerCompileCacheRendererProperty *srcProp = srcRenderer->Properties()[pidx]; + + if (srcProp->PropertyType() == PropertyType_TexturePath) + { + SRendererProperties *prop = PK_NEW(SRendererProperties(srcProp->PropertyName(), srcProp->PropertyValueStr(), srcLayer->LayerName(), srcLayer->UID(), CStringId(m_EffectDesc->m_UUID.c_str()), srcRenderer->UID(), srcProp->UID())); + if (!PK_VERIFY(m_OverridableProperties.PushBack(prop).Valid())) + return false; + + for (u32 i = 0; i < m_LayerHolder->m_LayerProperty->RendererProperties().Count(); ++i) + { + if (srcRenderer->UID() == m_LayerHolder->m_LayerProperty->RendererProperties()[i]->RendererID() && + srcProp->UID() == m_LayerHolder->m_LayerProperty->RendererProperties()[i]->PropertyID()) + { + srcProp->SetPropertyValueStr(m_LayerHolder->m_LayerProperty->RendererProperties()[i]->Value()); + prop->m_Value = srcProp->PropertyValueStr(); + } + } + } + } + } + } + } + + if (m_EffectFile != null) + { + m_Effect = null; + m_EffectFile->Unload(); + m_EffectFile = null; + } + } + if (m_Effect == null) + m_Effect = CParticleEffect::Load(objFile); + + PK_FREE(rawFileBuffer); + + if (!PK_VERIFY(m_Effect != null)) + { + CLog::Log(PK_ERROR, "Failed loading effect \"%s\"", sceneDef.m_EffectPath.Data()); + return false; + } + if (!m_Effect->Install(m_ParticleMediumCollection)) + { + CLog::Log(PK_ERROR, "Failed Install effect \"%s\"", sceneDef.m_EffectPath.Data()); + return false; + } + m_AttributesList = m_Effect->AttributeFlatList().Get(); + if (!PK_VERIFY(m_AttributesList != null)) + { + CLog::Log(PK_WARN, "no attributes descriptor"); + return false; + } + if (!_RebuildAttributes(sceneDef)) + { + CLog::Log(PK_ERROR, "_RebuildAttributes failed"); + return false; + } + m_AttributesList = null; + } + + m_EffectPath = sceneDef.m_EffectPath; + return true; +} + +//---------------------------------------------------------------------------- + +PParticleEffectInstance CAAEScene::_InstantiateEffect() +{ + _UpdateCamera(); + _UpdateEmitter(m_DT); + return _InstantiateEffect(0, 0); +} + +//---------------------------------------------------------------------------- +// This version if 'InstantiateEffect' takes two time arguments to pinpoint with accuracy +// where during the frame the instantiation happened. If you don't care, just pass zero in both parameters. + +PParticleEffectInstance CAAEScene::_InstantiateEffect(float timeFromStartOfFrame, float timeToEndOfFrame) +{ + PK_ASSERT(m_Effect != null); + PK_ASSERT(timeFromStartOfFrame >= 0.0f); + PK_ASSERT(timeToEndOfFrame >= 0.0f); + + // CParticleEffect::Instantiate() returns an effect instance, registered into the specified medium collection + PParticleEffectInstance instance = m_Effect->Instantiate_AlreadyInstalled(m_ParticleMediumCollection); + + if (instance != null) + { + // The death notifier will be called as soon as the instance dies. See the comment above the 'm_DeathNotifier' member in + instance->m_DeathNotifier += FastDelegate(this, &CAAEScene::_OnInstanceDeath); + + instance->EnableSeed(true); + instance->Seed(m_LayerHolder->m_SpawnedEmitter.m_Desc->m_Seed); + + SEffectStartCtl effectStartCtl; + effectStartCtl.m_TimeFromStartOfFrame = timeFromStartOfFrame; + effectStartCtl.m_TimeToEndOfFrame = timeToEndOfFrame; + effectStartCtl.m_SpawnTransformsPack.m_WorldTr_Current = &m_EmitterTransformsCurrent; + effectStartCtl.m_SpawnTransformsPack.m_WorldTr_Previous = &m_EmitterTransformsPrevious; + effectStartCtl.m_SpawnTransformsPack.m_WorldVel_Current = &m_EmitterVelCurrent; + effectStartCtl.m_SpawnTransformsPack.m_WorldVel_Previous = &m_EmitterVelPrevious; + + // Start the instance. (Frame start/end times are optional, you can call 'instance->Start(xforms)' if you don't care) + instance->Start(effectStartCtl); + } + + return instance; +} + +//---------------------------------------------------------------------------- + +void CAAEScene::_OnInstanceDeath(const PParticleEffectInstance &instance) +{ + PK_ASSERT(instance != null); + // This callback will be called from worker threads + + // Not strictly necessary to -= the callback, the instance is getting destroyed anyway. + instance->m_DeathNotifier -= FastDelegate(this, &CAAEScene::_OnInstanceDeath); + if (instance == m_EffectLastInstance) + { + instance->KillImmediate(); + m_EffectLastInstance = null; + } +} + +//---------------------------------------------------------------------------- + +bool CAAEScene::_RebuildAttributes(const SSimpleSceneDef &sceneDef) +{ + (void)sceneDef; + + auto &attributeList = m_AttributesList->AttributeList(); + auto &samplerList = m_AttributesList->SamplerList(); + const u32 samplerCount = samplerList.Count(); + const u32 attrCount = attributeList.Count(); + + TArray attrOrder; + + for (u32 i = 0; i < attrCount; ++i) + { + CParticleAttributeDeclaration *attrDecl = attributeList[i]; + + PK_ASSERT(attrDecl != null); + + CString category = attrDecl->CategoryName().MapENG().ToAscii(); + SAttributeDesc *attrDesc = new SAttributeDesc(attrDecl->ExportedName().Data(), (const char*)category.Data(), AttributePKToAAE((EBaseTypeID)attrDecl->ExportedType()), AttributePKToAAE(attrDecl->GetEffectiveDataSemantic())); + + SAttributesContainer_SAttrib value = attrDecl->GetDefaultValue(); + SAttributesContainer_SAttrib valueMin = attrDecl->GetMinValue(); + SAttributesContainer_SAttrib valueMax = attrDecl->GetMaxValue(); + + attrDesc->m_HasMax = attrDecl->HasMax(); + attrDesc->m_HasMin = attrDecl->HasMin(); + EAttributeType type = attrDesc->m_Type; + if (type >= AttributeType_Bool1 && type <= AttributeType_Bool4) + { + attrDesc->SetValue(value.Get()); + attrDesc->SetDefaultValue(value.Get()); + attrDesc->SetMinValue(valueMin.Get()); + attrDesc->SetMaxValue(valueMax.Get()); + } + if (type >= AttributeType_Int1 && type <= AttributeType_Int4) + { + attrDesc->SetValue(value.Get()); + attrDesc->SetDefaultValue(value.Get()); + attrDesc->SetMinValue(valueMin.Get()); + attrDesc->SetMaxValue(valueMax.Get()); + } + if (type >= AttributeType_Float1 && type <= AttributeType_Float4) + { + attrDesc->SetValue(value.Get()); + attrDesc->SetDefaultValue(value.Get()); + attrDesc->SetMinValue(valueMin.Get()); + attrDesc->SetMaxValue(valueMax.Get()); + } + attrDesc->m_IsDefaultValue = true; + + if (!PK_VERIFY(attrOrder.PushBack(attrDesc).Valid())) + return false; + } + + for (u32 i = 0; i < samplerCount; ++i) + { + CParticleAttributeSamplerDeclaration *samplerDecl = samplerList[i]; + PK_ASSERT(samplerDecl != null); + + CString category = samplerDecl->CategoryName().MapENG().ToAscii(); + SAttributeSamplerDesc *smplrDesc = new SAttributeSamplerDesc(samplerDecl->ExportedName().Data(), (const char*)category.Data(), AttributeSamplerPKToAAE((SParticleDeclaration::SSampler::ESamplerType)samplerDecl->ExportedType())); + + switch (smplrDesc->m_Type) + { + case AttributeSamplerType_Geometry: + smplrDesc->m_Descriptor = new SShapeSamplerDescriptor(); + break; + case AttributeSamplerType_Text: + smplrDesc->m_Descriptor = new STextSamplerDescriptor(); + break; + case AttributeSamplerType_Image: + smplrDesc->m_Descriptor = new SImageSamplerDescriptor(); + break; + case AttributeSamplerType_Audio: + { + smplrDesc->m_Descriptor = new SAudioSamplerDescriptor(); + + CResourceDescriptor_Audio *nodeSamplerData = HBO::Cast(samplerDecl->AttribSamplerDefaultValue().Get()); + if (PK_VERIFY(nodeSamplerData != null)) + ((SAudioSamplerDescriptor*)smplrDesc->m_Descriptor)->m_ChannelGroup = nodeSamplerData->ChannelGroup().Data(); + break; + } + case AttributeSamplerType_VectorField: + smplrDesc->m_Descriptor = new SVectorFieldSamplerDescriptor(); + break; + default: + smplrDesc->m_Descriptor = null; + break; + } + if (smplrDesc->m_Descriptor) + smplrDesc->m_Descriptor->m_UsageFlags = samplerDecl->UsageFlags(); + + if (!PK_VERIFY(attrOrder.PushBack(smplrDesc).Valid())) + return false; + } + + typedef TArray::Iterator attrDescIt; + + struct SSortAttributesPolicy + { + PK_FORCEINLINE static bool Less(const attrDescIt &it0, const attrDescIt &it1) + { + int cmpCategoryRes = (*it0)->m_CategoryName.compare((*it1)->m_CategoryName); + + if (cmpCategoryRes < 0) + return true; + if (cmpCategoryRes > 0) + return false; + if (cmpCategoryRes == 0) + { + if ((*it0)->m_Name.compare((*it1)->m_Name) < 0) + return true; + else + return false; + } + return false; + } + + PK_FORCEINLINE static bool Equal(const attrDescIt &it0, const attrDescIt &it1) + { + int cmpCategoryRes = (*it0)->m_CategoryName.compare((*it1)->m_CategoryName); + int cmpNameRes = (*it0)->m_Name.compare((*it1)->m_Name); + return cmpCategoryRes == 0 && cmpNameRes == 0; + } + }; + + QuickSort(attrOrder.Begin(), attrOrder.End()); + + CPopcornFXWorld::Instance().HandleNewAttributes(attrOrder, m_EffectRef, m_LayerHolder, false); + return true; +} + +//---------------------------------------------------------------------------- + +void CAAEScene::_ExtractAEFrameInfo(SAAEIOData &AAEData) +{ + u32 targetFrame = AAEData.m_InData->current_time / AAEData.m_InData->local_time_step; + if (m_FrameNumber + 1 != targetFrame) + m_ForceRestartSeeking = true; + else + m_ForceRestartSeeking = false; + m_FrameNumber = targetFrame; + + m_DT = (float)((double)AAEData.m_InData->local_time_step / (double)AAEData.m_InData->time_scale); + m_PreviousTimeSec = m_CurrentTimeSec; + m_CurrentTimeSec = (float)((double)AAEData.m_InData->current_time / (double)AAEData.m_InData->time_scale); +} + +//---------------------------------------------------------------------------- + +bool CAAEScene::_CheckRenderAbort(SAAEIOData *AAEData) +{ + if (AAEData == null) + { + CLog::Log(PK_INFO, "RenderAbort"); + return true; + } + PF_Err res = PF_Err_NONE; + res = PF_ABORT(AAEData->m_InData); + if (res != PF_Err_NONE) + { + AAEData->m_ReturnCode = res; + CLog::Log(PK_INFO, "RenderAbort"); + return true; + } + return false; +} + +//---------------------------------------------------------------------------- + +void CAAEScene::_SetProj(float fovydegree, const CFloat2 &winDimPixel, float zNear, float zFar) +{ + float fX, fY; + + m_Camera.m_ProjNear = zNear; + m_Camera.m_ProjFar = zFar; + m_Camera.m_WinSize = winDimPixel; + if (m_EmitterTransformType == ETransformType_2D) + { + const float aspect = winDimPixel.y() / winDimPixel.x(); + fX = 1.f / tanf(Units::DegreesToRadians(fovydegree) * 0.5f); + fY = fX / aspect; + } + else + { + m_Camera.m_ProjFovy = fovydegree; + const float aspect = winDimPixel.x() / winDimPixel.y(); + fY = 1.f / tanf(Units::DegreesToRadians(fovydegree * 0.5f)); + fX = fY / aspect; + } + + const float kRcpRange = 1.0f / (zNear - zFar); + const float kA = (zFar + zNear) * kRcpRange; + const float kB = (zFar * zNear) * kRcpRange; + + RHI::EGraphicalApi api = CPopcornFXWorld::Instance().GetRenderApi(); + if (api == RHI::GApi_D3D11 || api == RHI::GApi_D3D12 || api == RHI::GApi_Metal) + { + // GApi_D3D11: GApi_D3D12 + m_Camera.m_Proj = CFloat4x4(fX, 0, 0, 0, + 0, -fY, 0, 0, + 0, 0, 0.5f * kA - 0.5f, -1, + 0, 0, kB, 0); + } + else + { + PK_ASSERT_NOT_REACHED_MESSAGE("No projection matrix for this API"); + } + + CFloat4x4 current2RHYUp = CFloat4x4::IDENTITY; + CCoordinateFrame::BuildTransitionFrame(CCoordinateFrame::GlobalFrame(), Frame_RightHand_Y_Up, current2RHYUp); + + m_Camera.m_Proj = current2RHYUp * m_Camera.m_Proj; +} + +//---------------------------------------------------------------------------- + +void CAAEScene::_FillAdditionnalDataForRender() +{ + TArray &outSkinnedDatas = m_FXInstancesSkinnedData; + + outSkinnedDatas.Clear(); + + const PSkinnedMeshInstance instance = m_SkinnedMeshInstance; + if (instance == null) + return; + if (!PK_VERIFY(outSkinnedDatas.PushBack().Valid())) + { + outSkinnedDatas.Clear(); + return; + } + + SSkinnedDataSimple &skinnedDataSimple = outSkinnedDatas.Last(); + + skinnedDataSimple.m_Valid = (instance->m_SkinnedMesh != null && instance->m_SkinnedMesh->Valid() && instance->m_SkinnedMesh->HasGeometry()); + if (skinnedDataSimple.m_Valid) + { + if (!PK_VERIFY(skinnedDataSimple.m_SubMeshes.Resize(instance->m_SkinnedMesh->SubMeshCount()))) + { + skinnedDataSimple.m_SubMeshes.Clear(); + return; + } + for (u32 smidx = 0, smCount = instance->m_SkinnedMesh->SubMeshCount(); smidx < smCount; smidx++) + { + auto &submesh = skinnedDataSimple.m_SubMeshes[smidx]; + submesh.m_SubMeshID = smidx; + submesh.m_Positions = instance->m_SkinnedMesh->Positions(smidx); + submesh.m_Normals = instance->m_SkinnedMesh->Normals(smidx); + } + for (u32 smidx = 0; smidx < skinnedDataSimple.m_SubMeshes.Count(); smidx++) + { + auto &submesh = skinnedDataSimple.m_SubMeshes[smidx]; + if (submesh.m_Positions.Empty() && + submesh.m_Normals.Empty()) + skinnedDataSimple.m_SubMeshes.Remove(smidx--); + } + } + + if (!PK_VERIFY(m_BackdropData.m_FXInstancesSkinnedDatas.Resize(1))) + return; + + for (u32 iInstance = 0; iInstance < 1; ++iInstance) + { + const SSkinnedDataSimple &skinnedData = m_FXInstancesSkinnedData[iInstance]; + PKSample::SSkinnedMeshData &skinnedDataForRender = m_BackdropData.m_FXInstancesSkinnedDatas[iInstance]; + + skinnedDataForRender.m_Valid = false; + + if (!skinnedData.m_Valid || + skinnedData.m_SubMeshes.Empty() || + !PK_VERIFY(skinnedDataForRender.m_SubMeshes.Resize(skinnedData.m_SubMeshes.Count()))) + { + skinnedDataForRender.m_SubMeshes.Clear(); + continue; + } + + skinnedDataForRender.m_Valid = skinnedData.m_Valid; + + for (u32 smidx = 0; smidx < skinnedData.m_SubMeshes.Count(); smidx++) + { + const auto &submesh = skinnedData.m_SubMeshes[smidx]; + auto &submeshForRender = skinnedDataForRender.m_SubMeshes[smidx]; + + submeshForRender.m_SubMeshID = submesh.m_SubMeshID; + + // skinned data is 0x10 aligned, submeshForRender has same alignment as final vb so we can memcpy + const u32 posCount = submesh.m_Positions.Count(); + const u32 pnStride = sizeof(CFloat3); + const u32 posSizeInBytes = posCount * pnStride; + const u32 totalSizeInBytes = posSizeInBytes + submesh.m_Normals.Count() * pnStride; + PK_ASSERT(totalSizeInBytes > 0); + PK_ASSERT(posCount == submesh.m_Normals.Count() || submesh.m_Normals.Empty()); + if (!PK_VERIFY(submeshForRender.m_RawData.Resize(totalSizeInBytes))) + { + submeshForRender.m_RawData.Clear(); + continue; + } + + CFloat3 *dstData = reinterpret_cast(submeshForRender.m_RawData.RawDataPointer()); + TStridedMemoryView dstPositions(dstData, posCount, pnStride); + TStridedMemoryView dstNormals(dstData + posCount, posCount, pnStride); + + Mem::CopyStreamToStream(dstPositions, submesh.m_Positions); + Mem::CopyStreamToStream(dstNormals, submesh.m_Normals); + } + } +} + +//---------------------------------------------------------------------------- + +#if (PK_PARTICLES_UPDATER_USE_D3D12 != 0 || PK_PARTICLES_UPDATER_USE_D3D11 != 0) +bool CAAEScene::SimDispatchMask(const PopcornFX::CParticleDescriptor *descriptor, PopcornFX::SSimDispatchHint &outHint) +{ + const PopcornFX::SParticleDeclaration &decl = descriptor->ParticleDeclaration(); + // Tell PopcornFX Runtime that our code does not handle any of the following renderers on GPU: + // if a particle layer contain any of those, even if the simulation graph has compute shader bytecodes, it will fallback on CPU. + if (!decl.m_LightRenderers.Empty() || + !decl.m_SoundRenderers.Empty() || + !decl.m_RibbonRenderers.Empty() || + !decl.m_TriangleRenderers.Empty() || + !decl.m_DecalRenderers.Empty()) + { + outHint.m_AllowedDispatchMask &= ~(1 << PopcornFX::SSimDispatchHint::Location_GPU); // can't draw any of these on the GPU + } + // if we are allowed on GPU, prefer GPU, otherwise prefer CPU: + if (outHint.m_AllowedDispatchMask & (1 << PopcornFX::SSimDispatchHint::Location_GPU)) + outHint.m_PreferredDispatchMask = (1 << PopcornFX::SSimDispatchHint::Location_GPU); + else + outHint.m_PreferredDispatchMask = (1 << PopcornFX::SSimDispatchHint::Location_CPU); + return true; +} + +//---------------------------------------------------------------------------- + +void CAAEScene::D3D12_EnqueueTask(const PopcornFX::PParticleUpdaterTaskD3D12 &task) +{ + CPopcornFXWorld &pkfxWorld = CPopcornFXWorld::Instance(); + PAAERenderContext renderContext = pkfxWorld.GetCurrentRenderContext(); + CAAED3D12Context *D3D12Context = static_cast(renderContext->GetAEGraphicContext()); + + if (D3D12Context != null && D3D12Context->m_D3D12Context->m_CommandQueue != null) // Your ID3D12CommandQueue (can be D3D12_COMMAND_LIST_TYPE_DIRECT or D3D12_COMMAND_LIST_TYPE_COMPUTE) + task->Execute(D3D12Context->m_D3D12Context->m_CommandQueue); // Internally calls commandQueue->ExecuteCommandLists and fences +} +#endif + +//---------------------------------------------------------------------------- + +__AEGP_PK_END diff --git a/AE_GeneralPlugin/Sources/AEGP_SkinnedMesh.cpp b/AE_GeneralPlugin/Sources/AEGP_SkinnedMesh.cpp new file mode 100644 index 00000000..74a3c7d1 --- /dev/null +++ b/AE_GeneralPlugin/Sources/AEGP_SkinnedMesh.cpp @@ -0,0 +1,451 @@ +//---------------------------------------------------------------------------- +// Copyright Persistant Studios, SARL. All Rights Reserved. https://www.popcornfx.com/terms-and-conditions/ +//---------------------------------------------------------------------------- +#include "ae_precompiled.h" +#include "AEGP_SkinnedMesh.h" + +#include // for random XForms tests +#include // for 'Skin_PostProcess' +#include // for CMeshSurfaceSamplerStructuresRandom && CMeshVolumeSamplerStructuresRandom + +// For skinned mesh backdrops +#include +#include +#include + +__AEGP_PK_BEGIN + +//---------------------------------------------------------------------------- +// +// Skinned mesh instance wrapper implementation +// +//---------------------------------------------------------------------------- + +CSkinnedMesh::CSkinnedMesh() + : m_SkinDt(0) + , m_FirstFrame(false) + , m_SamplingChannels(0) +{ +} + +//---------------------------------------------------------------------------- + +CSkinnedMesh::~CSkinnedMesh() +{ + Reset(); +} + +//---------------------------------------------------------------------------- + +void CSkinnedMesh::Reset() +{ + WaitAsyncUpdateSkin(); + + m_SubMeshes.Clear(); + + m_SkinDt = 0; + m_FirstFrame = 0; + m_SamplingChannels = 0; + + m_Timeline = CTimeline(); // must reset before clearing m_SkeletonState + m_SkeletonState = null; +} + +//---------------------------------------------------------------------------- + +bool CSkinnedMesh::Init(const TResourcePtr &meshResource, u32 samplingChannels, const PSkeletonState &srcSkeletonState) +{ + const bool success = _Init_Impl(meshResource, samplingChannels, srcSkeletonState); + if (!success) + Reset(); + return success; +} + +//---------------------------------------------------------------------------- + +bool CSkinnedMesh::_Init_Impl(const TResourcePtr &meshResource, u32 samplingChannels, const PSkeletonState &srcSkeletonState) +{ + WaitAsyncUpdateSkin(); + + m_FirstFrame = true; + m_SamplingChannels = samplingChannels; + + if (meshResource == null || srcSkeletonState == null) + return false; + + for (auto &mesh : m_SubMeshes) + { + mesh.m_SkeletalMesh = null; + mesh.m_SkeletonState = null; + } + + m_Timeline = CTimeline(); // must reset before clearing m_SkeletonState + m_SkeletonState = null; + + // create and copy skeleton state if necessary: + if (m_SkeletonState == null) + { + m_SkeletonState = PK_NEW(CSkeletonState); + if (m_SkeletonState == null) + return false; + } + + if (!m_SkeletonState->DeepCopy(*srcSkeletonState)) + return false; + + m_SkeletonState->SetTimeline(&m_Timeline); + + const u32 kLodLevel = 0; + TMemoryView batchList = meshResource->BatchList(kLodLevel); + if (!PK_VERIFY(m_SubMeshes.Resize(batchList.Count()))) + return false; + + for (u32 batchId = 0; batchId < m_SubMeshes.Count(); batchId++) + { + SSubMesh &mesh = m_SubMeshes[batchId]; + + // grab the desired skeletal mesh: + mesh.m_SkeletalMesh = batchList[batchId].Get(); + if (!PK_VERIFY(mesh.m_SkeletalMesh != null)) + return false; + + // FIXME: Handle when some submeshes aren't skinned + if (!mesh.m_SkeletalMesh->IsSkinned()) + { + mesh.m_SkeletalMesh = null; + mesh.m_SkeletonState = null; + continue; + } + + mesh.m_SkeletonState = m_SkeletonState; + + // grab the raw geometry: + const CMeshTriangleBatch &srcGeomBatch = mesh.m_SkeletalMesh->RawMesh()->TriangleBatch(); + const CMeshVStream &srcVStream = srcGeomBatch.m_VStream; + if (srcVStream.Empty()) + return false; + + // do we need to create or resize our locally skinned vertex streams? + if (mesh.m_RawSkinnedDataElementCount != srcVStream.VertexCount()) + { + // nedds initial alloc, or resize + const u32 vertexCount = srcVStream.VertexCount(); + const u32 offsetPos = 0; + const u32 offsetNor = Mem::Align(offsetPos + vertexCount * u32(sizeof(CFloat4))); // pad Positions & Normals to Float4 for fast aligned SIMD processing + const u32 offsetTan = Mem::Align(offsetNor + vertexCount * u32(sizeof(CFloat4))); + const u32 offsetOld = Mem::Align(offsetTan + vertexCount * u32(sizeof(CFloat4))); + const u32 offsetVel = Mem::Align(offsetOld + vertexCount * u32(sizeof(CFloat4))); + const u32 offsetEnd = Mem::Align(offsetVel + vertexCount * u32(sizeof(CFloat4))); + + const u32 totalStreamsFootprint = offsetEnd; + void *rawDataPtr = PK_REALLOC_ALIGNED(mesh.m_RawSkinnedData, totalStreamsFootprint, Memory::CacheLineSize); // alloc or grow existing buffer + if (rawDataPtr == null) + { + PK_FREE(mesh.m_RawSkinnedData); + mesh.m_RawSkinnedData = null; + mesh.m_Positions = TStridedMemoryView(); + mesh.m_Normals = TStridedMemoryView(); + mesh.m_Tangents = TStridedMemoryView(); + mesh.m_OldPositions = TStridedMemoryView(); + mesh.m_Velocities = TStridedMemoryView(); + return false; + } + + mesh.m_RawSkinnedDataElementCount = vertexCount; + mesh.m_RawSkinnedData = rawDataPtr; + + // build views into the memory we just (re)allocated: + mesh.m_Positions = TStridedMemoryView(static_cast(Mem::AdvanceRawPointer(mesh.m_RawSkinnedData, offsetPos)), vertexCount, sizeof(CFloat4)); + mesh.m_Normals = TStridedMemoryView(static_cast(Mem::AdvanceRawPointer(mesh.m_RawSkinnedData, offsetNor)), vertexCount, sizeof(CFloat4)); + mesh.m_Tangents = TStridedMemoryView(static_cast(Mem::AdvanceRawPointer(mesh.m_RawSkinnedData, offsetTan)), vertexCount, sizeof(CFloat4)); + mesh.m_OldPositions = TStridedMemoryView(static_cast(Mem::AdvanceRawPointer(mesh.m_RawSkinnedData, offsetOld)), vertexCount, sizeof(CFloat4)); + mesh.m_Velocities = TStridedMemoryView(static_cast(Mem::AdvanceRawPointer(mesh.m_RawSkinnedData, offsetVel)), vertexCount, sizeof(CFloat4)); + + mesh.m_SampleSourceOverride.m_PositionsOverride = TStridedMemoryView(); + mesh.m_SampleSourceOverride.m_NormalsOverride = TStridedMemoryView(); + mesh.m_SampleSourceOverride.m_TangentsOverride = TStridedMemoryView(); + mesh.m_SampleSourceOverride.m_VelocitiesOverride = TStridedMemoryView(); + } + + if (samplingChannels & Channel_Position) + mesh.m_SampleSourceOverride.m_PositionsOverride = mesh.m_Positions; + + if (samplingChannels & Channel_Velocity) + mesh.m_SampleSourceOverride.m_VelocitiesOverride = mesh.m_Velocities; + + if (samplingChannels & Channel_Normal) + mesh.m_SampleSourceOverride.m_NormalsOverride = mesh.m_Normals; + + if (samplingChannels & Channel_Tangent) + mesh.m_SampleSourceOverride.m_TangentsOverride = mesh.m_Tangents; + + PK_ASSERT(mesh.m_RawSkinnedData != null); + + // copy source vertex-buffer streams to dst + // Note: here we only copy the tangents. the 'w' components of the tangents will not be touched by the skinner, and have to be valid in the dst streams + // (this might change in the future, where no initial copy necessary at all) +#ifdef PK_SAMPLE_SKIN_TANGENTS + TStridedMemoryView srcVbTangents = srcVStream.Tangents(); + PK_ASSERT(srcVbTangents.Count() == srcVStream.VertexCount()); + PK_ASSERT(srcVbTangents.Count() == mesh.m_RawSkinnedDataElementCount); + PK_ASSERT(mesh.m_Tangents.Stride() == sizeof(CFloat4)); + + if (srcVbTangents.Stride() == mesh.m_Tangents.Stride()) + { + // common-case fast-path + Mem::Copy(mesh.m_Tangents.Data(), srcVbTangents.Data(), mesh.m_RawSkinnedDataElementCount * sizeof(CFloat4)); + } + else + { + // do a slow copy (should not happen, except if we've got AOS VBs (we shouldn't, skinner will take a monstruous perf hit) + for (u32 i = 0; i < mesh.m_RawSkinnedDataElementCount; i++) + mesh.m_Tangents[i] = srcVbTangents[i]; + } +#endif + } + + return true; +} + +//---------------------------------------------------------------------------- + +bool CSkinnedMesh::Play(const PSkeletonAnimationInstance &animInstance) +{ + if (m_SkeletonState != null) + { + if (m_SkeletonState->__TMP_GORE_PlayAnim(animInstance) == null) // FIXME: gore + return false; + } + return true; +} + +//---------------------------------------------------------------------------- + +void CSkinnedMesh::Stop() +{ + if (m_SkeletonState != null) + m_SkeletonState->__TMP_GORE_StopAnim(); // FIXME: gore +} + +//---------------------------------------------------------------------------- + +void CSkinnedMesh::Update(float dt) +{ + m_Timeline.Update(dt); + if (m_SkeletonState != null) + m_SkeletonState->Update(dt); +} + +//---------------------------------------------------------------------------- + +#if 0 +void CSkinnedMesh::Render() +{ + m_Renderer.AnimMesh(m_Positions); + m_Renderer.Render(); +} +#endif + +//---------------------------------------------------------------------------- + +void CSkinnedMesh::StartAsyncUpdateSkin(float dt) +{ + if (m_SkeletonState == null) + return; + + const u32 samplingChannels = SamplingChannels(); + if (samplingChannels & Channel_Velocity) + m_SkinDt = dt; + + for (auto &mesh : m_SubMeshes) + { + if (mesh.Empty()) + continue; + + SSkinContext asyncSkinContext; + + const CMeshVStream *vStream = &mesh.m_SkeletalMesh->RawMesh()->TriangleBatch().m_VStream; + + asyncSkinContext.m_SkinningStreams = mesh.m_SkeletalMesh->m_OptimizedStreams; + + // Skinner always expects positions, even if the effect won't be sampling them + asyncSkinContext.m_SrcPositions = vStream->Positions(); + asyncSkinContext.m_DstPositions = mesh.m_Positions; + + // The rendering may need normals (in fact, the most of the cases) + //if (samplingChannels & Channel_Normal) + { + asyncSkinContext.m_SrcNormals = vStream->Normals(); + asyncSkinContext.m_DstNormals = mesh.m_Normals; + } + + // The rendering may need tangents (not for now, as skined mesh does not have normal-map) + // for tangents, they are in fact a CFloat4 stream, with the 'w' component containing a sign telling if the tangent basis is mirrored. + // we are only interested in skinning the float3 part, and we need to keep the 'w' component intact for correct tangent-space reconstruction in the shaders. + if (samplingChannels & Channel_Tangent) + { + asyncSkinContext.m_SrcTangents = vStream->Tangents(); + asyncSkinContext.m_DstTangents = mesh.m_Tangents; + } + + if (samplingChannels & Channel_Velocity) + { + // hook our pre-skin callback where we'll copy the positions to m_OldPositions so that the skin job can correctly + // differentiate the two and compute the instantaneous mesh surface velocities using 'asyncSkinContext.m_SrcDt' + asyncSkinContext.m_CustomProcess_PreSkin = SSkinContext::CbCustomProcess(&mesh, &SSubMesh::Skin_PreProcess); + asyncSkinContext.m_CustomProcess_PostSkin = SSkinContext::CbCustomProcess(&mesh, &SSubMesh::Skin_PostProcess); + } + + asyncSkinContext.m_SkinFlags = SkinFlags_UseMultipassSkinning; + // If you handle unskinned verts in the PostSkin pass, you can set the following flag, + // it'll avoid unnecessary copies in the skinner jobs: +// asyncSkinContext.m_SkinFlags = SkinFlags_DontCopyUnskinnedVerts; + + mesh.m_SkinDt = m_SkinDt; + mesh.m_FirstFrame = m_FirstFrame; + + CSkeletalSkinnerSimple::AsyncSkinStart(mesh.m_SkinUpdateContext, m_SkeletonState->View(), asyncSkinContext); + } +} + +//---------------------------------------------------------------------------- + +void CSkinnedMesh::SSubMesh::Skin_PreProcess(u32 vertexStart, u32 vertexCount, const SSkinContext &ctx) +{ + (void)ctx; + if (m_SkeletonState == null) + return; + + TStridedMemoryView src = m_Positions.Slice(vertexStart, vertexCount); + TStridedMemoryView dst = m_OldPositions.Slice(vertexStart, vertexCount); + + PK_ASSERT(src.Stride() == 0x10 && dst.Stride() == 0x10); + Mem::Copy(dst.Data(), src.Data(), dst.Count() * dst.Stride()); +} + +//---------------------------------------------------------------------------- + +void CSkinnedMesh::SSubMesh::Skin_PostProcess(u32 vertexStart, u32 vertexCount, const SSkinContext &ctx) +{ + if (m_SkeletonState == null) + return; + + PK_SCOPEDPROFILE(); // record this function in the visual profiler + + // compute instantaneous surface velocities IFN: + TStridedMemoryView vel = m_Velocities.Slice(vertexStart, vertexCount); + TStridedMemoryView posCur = ctx.m_DstPositions.Slice(vertexStart, vertexCount); + TStridedMemoryView posOld = m_OldPositions.Slice(vertexStart, vertexCount); + const float dt = m_SkinDt; + + const bool continuousAnim = true;//(m_Skeleton != null) && (m_Skeleton->LastUpdateFrameID() == m_LastSkinnedSkeletonFrameID + 1); + if ((m_FirstFrame || !continuousAnim) && !vel.Empty()) + { + Mem::Clear(vel.Data(), vel.CoveredBytes()); + + PK_ASSERT(posCur.Stride() == posOld.Stride()); + PK_ASSERT(posCur.Count() == posOld.Count()); + PK_ASSERT(posCur.CoveredBytes() == posOld.CoveredBytes()); + if (m_FirstFrame) + { + // Avoid glitches during the first frame: our old positions will be the bindpose, + // we don't want particles to lerp between bindpose and first real frame + Mem::Copy((void*)posOld.Data(), posCur.Data(), posOld.CoveredBytes()); + } + } + else if (!posCur.Empty() && !posOld.Empty() && !vel.Empty()) + { + PK_ASSERT(posCur.Stride() == 0x10); + PK_ASSERT(posOld.Stride() == 0x10); + PK_ASSERT(vel.Stride() == 0x10); + + CFloat3 * __restrict dstVel = vel.Data(); + const CFloat3 *dstVelEnd = Mem::AdvanceRawPointer(dstVel, vertexCount * 0x10); + const CFloat3 *srcPosCur = posCur.Data(); + const CFloat3 *srcPosOld = posOld.Data(); + + PK_ASSERT(Mem::IsAligned<0x10>(dstVel)); + PK_ASSERT(Mem::IsAligned<0x10>(dstVelEnd)); + PK_ASSERT(Mem::IsAligned<0x10>(srcPosCur)); + PK_ASSERT(Mem::IsAligned<0x10>(srcPosOld)); + + const SIMD::Float4 invDt = SIMD::Float4(1.0f / dt); + dstVelEnd = Mem::AdvanceRawPointer(dstVelEnd, -0x40); + while (dstVel < dstVelEnd) + { + const SIMD::Float4 pA0 = SIMD::Float4::LoadAligned16(srcPosOld, 0x00); + const SIMD::Float4 pA1 = SIMD::Float4::LoadAligned16(srcPosOld, 0x10); + const SIMD::Float4 pA2 = SIMD::Float4::LoadAligned16(srcPosOld, 0x20); + const SIMD::Float4 pA3 = SIMD::Float4::LoadAligned16(srcPosOld, 0x30); + const SIMD::Float4 pB0 = SIMD::Float4::LoadAligned16(srcPosCur, 0x00); + const SIMD::Float4 pB1 = SIMD::Float4::LoadAligned16(srcPosCur, 0x10); + const SIMD::Float4 pB2 = SIMD::Float4::LoadAligned16(srcPosCur, 0x20); + const SIMD::Float4 pB3 = SIMD::Float4::LoadAligned16(srcPosCur, 0x30); + const SIMD::Float4 v0 = (pB0 - pA0) * invDt; + const SIMD::Float4 v1 = (pB1 - pA1) * invDt; + const SIMD::Float4 v2 = (pB2 - pA2) * invDt; + const SIMD::Float4 v3 = (pB3 - pA3) * invDt; + v0.StoreAligned16(dstVel, 0x00); + v1.StoreAligned16(dstVel, 0x10); + v2.StoreAligned16(dstVel, 0x20); + v3.StoreAligned16(dstVel, 0x30); + + dstVel = Mem::AdvanceRawPointer(dstVel, 0x40); + srcPosCur = Mem::AdvanceRawPointer(srcPosCur, 0x40); + srcPosOld = Mem::AdvanceRawPointer(srcPosOld, 0x40); + } + dstVelEnd = Mem::AdvanceRawPointer(dstVelEnd, +0x40); + + while (dstVel < dstVelEnd) + { + const SIMD::Float4 pA = SIMD::Float4::LoadAligned16(srcPosOld); + const SIMD::Float4 pB = SIMD::Float4::LoadAligned16(srcPosCur); + const SIMD::Float4 v = (pB - pA) * invDt; + v.StoreAligned16(dstVel); + + dstVel = Mem::AdvanceRawPointer(dstVel, 0x10); + srcPosCur = Mem::AdvanceRawPointer(srcPosCur, 0x10); + srcPosOld = Mem::AdvanceRawPointer(srcPosOld, 0x10); + } + } +} + +//---------------------------------------------------------------------------- + +bool CSkinnedMesh::WaitAsyncUpdateSkin() +{ + if (m_SkeletonState == null) + return true; + + for (auto &mesh : m_SubMeshes) + { + if (mesh.Empty()) + continue; + CAABB dummy; + if (!CSkeletalSkinnerSimple::AsyncSkinWait(mesh.m_SkinUpdateContext, &dummy, true)) + return false; + + if (mesh.m_FirstFrame && !mesh.m_Velocities.Empty()) + Mem::Clear(mesh.m_Velocities.Data(), mesh.m_Velocities.CoveredBytes()); + + mesh.m_FirstFrame = false; + } + + m_FirstFrame = false; + return true; +} + +//---------------------------------------------------------------------------- + +void CSkinnedMesh::ClearVelocities() +{ + for (auto &mesh : m_SubMeshes) + { + if (!mesh.Empty()) + Mem::Clear(mesh.m_Velocities.Data(), mesh.m_Velocities.CoveredBytes()); + } +} + +//---------------------------------------------------------------------------- + +__AEGP_PK_END diff --git a/AE_GeneralPlugin/Sources/AEGP_SkinnedMeshInstance.cpp b/AE_GeneralPlugin/Sources/AEGP_SkinnedMeshInstance.cpp new file mode 100644 index 00000000..a2cb4370 --- /dev/null +++ b/AE_GeneralPlugin/Sources/AEGP_SkinnedMeshInstance.cpp @@ -0,0 +1,261 @@ +//---------------------------------------------------------------------------- +// Copyright Persistant Studios, SARL. All Rights Reserved. https://www.popcornfx.com/terms-and-conditions/ +//---------------------------------------------------------------------------- +#include "ae_precompiled.h" + +#include "AEGP_SkinnedMeshInstance.h" +#include "AEGP_SkinnedMesh.h" + +#include +#include +#include +#include // for random XForms tests +#include // for 'Skin_PostProcess' +#include // for CMeshSurfaceSamplerStructuresRandom && CMeshVolumeSamplerStructuresRandom +// For skinned mesh backdrops +#include +#include + +__AEGP_PK_BEGIN + +//---------------------------------------------------------------------------- + +CSkinnedMeshInstance::CSkinnedMeshInstance() + : m_SkeletonAnimationInstance(null) + , m_CurrentAnimationPath(CString::EmptyString) + , m_SkinnedMesh(null) + , m_CurMeshTransformScaled(CFloat4x4::IDENTITY) + , m_CurMeshTransform(CFloat4x4::IDENTITY) + , m_PrevMeshTransform(CFloat4x4::IDENTITY) +{ + +} + +//---------------------------------------------------------------------------- + +CSkinnedMeshInstance::~CSkinnedMeshInstance() +{ + if (m_SurfaceSamplingStruct != null) + PK_DELETE(m_SurfaceSamplingStruct); + if (m_VolumeSamplingStruct != null) + PK_DELETE(m_VolumeSamplingStruct); + + // order matters + m_SkeletonAnimationInstance = null; + m_SkinnedMesh = null; + +} + +//---------------------------------------------------------------------------- + +CSkinnedMeshInstance &CSkinnedMeshInstance::operator=(const CSkinnedMeshInstance &other) +{ + if (m_SurfaceSamplingStruct != null) + PK_SAFE_DELETE(m_SurfaceSamplingStruct); + if (m_VolumeSamplingStruct != null) + PK_SAFE_DELETE(m_VolumeSamplingStruct); + + m_CurrentAnimationPath = other.m_CurrentAnimationPath; + m_SkinnedMesh = other.m_SkinnedMesh; + m_ShapeDescOverride = other.m_ShapeDescOverride; + + m_CurMeshTransformScaled = other.m_CurMeshTransformScaled; + m_CurMeshTransform = other.m_CurMeshTransform; + m_PrevMeshTransform = other.m_PrevMeshTransform; + + PK_ASSERT(other.m_SurfaceSamplingStruct == null && + other.m_VolumeSamplingStruct == null); + return *this; +} + +//---------------------------------------------------------------------------- + +void CSkinnedMeshInstance::ResetXForms(const CFloat4x4 &backdropXForm) +{ + SetBackdropXForms(backdropXForm); + +} + +//---------------------------------------------------------------------------- + +void CSkinnedMeshInstance::SetBackdropXForms(const CFloat4x4 &backdropXForm) +{ + m_CurMeshTransform = backdropXForm; + m_PrevMeshTransform = backdropXForm; + m_CurMeshTransformScaled = m_CurMeshTransform; + + // Fix #5336: Scaled mesh backdrops also scale their sampled normals. Should not + // Here we need to remove the scale of the transforms and instead apply it in the mesh descriptor with 'SetScale' + const CFloat3 scale = m_CurMeshTransform.ScalingFactors(); + m_CurMeshTransform.RemoveScale(); + m_PrevMeshTransform.RemoveScale(); + + // Apply scale + if (m_ShapeDescOverride != null) + { + CParticleSamplerDescriptor_Shape_Default *def = checked_cast(m_ShapeDescOverride.Get()); + if (PK_VERIFY(def->m_Shape != null && def->m_Shape->ShapeType() == CShapeDescriptor::ShapeMesh)) + { + CShapeDescriptor_Mesh *shapeDescMesh = const_cast(checked_cast(def->m_Shape.Get())); + if (PK_VERIFY(shapeDescMesh != null)) + shapeDescMesh->SetScale(scale); + } + } +} + +//---------------------------------------------------------------------------- + +void CSkinnedMeshInstance::ResetAnimationCursor() +{ + if (m_SkeletonAnimationInstance != null) + m_SkeletonAnimationInstance->SeekTo(0.0f); +} + +//---------------------------------------------------------------------------- + +void CSkinnedMeshInstance::Update(float dt) +{ + if (m_SkinnedMesh != null) + m_SkinnedMesh->Update(dt); +} + +//---------------------------------------------------------------------------- + +void CSkinnedMeshInstance::StartAsyncUpdateSkin(float dt) +{ + if (m_SkinnedMesh != null) + m_SkinnedMesh->StartAsyncUpdateSkin(dt); +} + +//---------------------------------------------------------------------------- + +bool CSkinnedMeshInstance::WaitAsyncUpdateSkin() +{ + if (m_SkinnedMesh != null) + return m_SkinnedMesh->WaitAsyncUpdateSkin(); + return true; +} + +//---------------------------------------------------------------------------- + +void CSkinnedMeshInstance::ClearSkinnedMesh() +{ + m_SkeletonAnimationInstance = null; + if (m_SkinnedMesh != null) + m_SkinnedMesh->Reset(); +} + +//---------------------------------------------------------------------------- + +bool CSkinnedMeshInstance::LoadSkinnedMeshIFN(const TResourcePtr &meshResource, u32 samplingChannels, const PSkeletonState &scrSkeletonState) +{ + m_SkeletonAnimationInstance = null; + if (meshResource == null) + { + if (m_SkinnedMesh != null) + m_SkinnedMesh->Reset(); + return true; + } + + if (m_SkinnedMesh == null) + { + m_SkinnedMesh = PK_NEW(CSkinnedMesh); + if (m_SkinnedMesh == null) + return false; + } + + if (!m_SkinnedMesh->Init(meshResource, samplingChannels, scrSkeletonState)) + { + m_SkinnedMesh->Reset(); + return false; + } + return true; +} + +//---------------------------------------------------------------------------- + +bool CSkinnedMeshInstance::LoadAnimationIFN(HBO::CContext *context, const CString &pksaPath, bool forceReload) +{ + m_SkeletonAnimationInstance = null; + if (m_SkinnedMesh == null || !m_SkinnedMesh->HasGeometry()) + return true; + + if (pksaPath.Empty()) + { + m_SkeletonAnimationInstance = null; + m_CurrentAnimationPath = null; + m_SkinnedMesh->Stop(); + return true; + } + + if (m_SkeletonAnimationInstance == null || m_CurrentAnimationPath != pksaPath) // if not already loaded or different anim + { + m_SkeletonAnimationInstance = CSkeletonAnimationInstance::NewInstance(context, pksaPath, m_SkinnedMesh->SkeletonState().Get(), forceReload); + if (m_SkeletonAnimationInstance == null) + { + CLog::Log(PK_ERROR, "failed loading animation"); + m_SkinnedMesh->Stop(); + return false; + } + + m_CurrentAnimationPath = pksaPath; + } + + // reset playback parameters + m_SkeletonAnimationInstance->SetPlaybackMode(CSkeletonAnimationInstance::Playback_Loop); + m_SkeletonAnimationInstance->SeekTo(0.0f); + m_SkeletonAnimationInstance->SetSpeed(1.0f); + m_SkinnedMesh->Play(m_SkeletonAnimationInstance); + return true; +} + +//---------------------------------------------------------------------------- + +bool CSkinnedMeshInstance::SetupAttributeSampler(CMeshNew *srcMesh, bool weightedSampling, u32 weightedSamplingColorStreamId, u32 weightedSamplingChannelId) +{ + PK_ASSERT(m_SkinnedMesh != null); + CShapeDescriptor_Mesh *shapeDescMesh = PK_NEW(CShapeDescriptor_Mesh); + if (!PK_VERIFY(shapeDescMesh != null)) + return false; + + SSamplerSourceOverride *samplerSourceOverride = null; + const u32 samplingSubMeshId = 0; + if (samplingSubMeshId < m_SkinnedMesh->SubMeshCount()) + samplerSourceOverride = m_SkinnedMesh->SamplerSourceOverride(samplingSubMeshId); + shapeDescMesh->SetMesh(srcMesh, samplerSourceOverride); + + shapeDescMesh->SetScale(m_CurMeshTransformScaled.ScalingFactors()); + + if (weightedSampling) + { + if (m_SurfaceSamplingStruct == null) + m_SurfaceSamplingStruct = PK_NEW(CMeshSurfaceSamplerStructuresRandom); + if (m_SurfaceSamplingStruct != null) + srcMesh->SetupSurfaceSamplingAccelStructs(weightedSamplingColorStreamId, weightedSamplingChannelId, *m_SurfaceSamplingStruct); + + if (m_VolumeSamplingStruct == null) + m_VolumeSamplingStruct = PK_NEW(CMeshVolumeSamplerStructuresRandom); + if (m_VolumeSamplingStruct != null) + srcMesh->SetupVolumeSamplingAccelStructs(*m_VolumeSamplingStruct); + + shapeDescMesh->SetSamplingStructs(m_SurfaceSamplingStruct, m_VolumeSamplingStruct); + } + + PParticleSamplerDescriptor_Shape_Default desc = PK_NEW(CParticleSamplerDescriptor_Shape_Default(shapeDescMesh)); + if (!PK_VERIFY(desc != null)) + { + PK_DELETE(shapeDescMesh); + return false; + } + desc->m_Angular_Velocity = &CFloat3::ZERO; + desc->m_Linear_Velocity = &CFloat3::ZERO; + desc->m_WorldTr_Current = &m_CurMeshTransform; + desc->m_WorldTr_Previous = &m_PrevMeshTransform; + m_ShapeDescOverride = desc; + return true; + +} + +//---------------------------------------------------------------------------- + +__AEGP_PK_END diff --git a/AE_GeneralPlugin/Sources/AEGP_System.cpp b/AE_GeneralPlugin/Sources/AEGP_System.cpp new file mode 100644 index 00000000..5c3291c4 --- /dev/null +++ b/AE_GeneralPlugin/Sources/AEGP_System.cpp @@ -0,0 +1,276 @@ +//---------------------------------------------------------------------------- +// Copyright Persistant Studios, SARL. All Rights Reserved. https://www.popcornfx.com/terms-and-conditions/ +//---------------------------------------------------------------------------- + +#include "ae_precompiled.h" +#include "AEGP_System.h" +#include "AEGP_Define.h" + +#if defined(PK_WINDOWS) +#include "AEGP_WinSystem.h" +#endif + +#include "pk_toolkit/include/pk_toolkit_process.h" + +#if defined(PK_WINDOWS) +# include + +#elif defined(PK_LINUX) || defined(PK_MACOSX) +# include +# include +# include +#endif + +#if defined(PK_LINUX) +# include +#elif defined(PK_MACOSX) +# include +#endif + +#include "AEGP_Log.h" + +__AEGP_PK_BEGIN + +//---------------------------------------------------------------------------- +// HardwareID +//---------------------------------------------------------------------------- + +u16 CSystemHelper::_GetMacHash() +{ + u16 hash = 0; + + //for (const QNetworkInterface &interface : QNetworkInterface::allInterfaces()) + //{ + // if (interface.isValid() && !interface.flags().testFlag(QNetworkInterface::IsLoopBack)) + // { + // const QStringList macAddr = interface.hardwareAddress().split(":"); + // + // for (int i = 0; i < macAddr.length(); ++i) + // hash += (macAddr[i].toInt() << ((i & 1) * 8)); + // } + //} + + return hash; +} + +//---------------------------------------------------------------------------- + +#if defined(PK_LINUX) +static void _getCpuid(u32 *p, u32 ax) +{ + __asm __volatile + ("movl %%ebx, %%esi\n\t" + "cpuid\n\t" + "xchgl %%ebx, %%esi" + : "=a" (p[0]), "=S" (p[1]), + "=c" (p[2]), "=d" (p[3]) + : "0" (ax) + ); +} +#endif + +//---------------------------------------------------------------------------- + +u16 CSystemHelper::_GetCPUHash() +{ + u16 hash = 0; + +#if defined(PK_WINDOWS) + int cpuinfo[4] = { 0, 0, 0, 0 }; + + __cpuid(cpuinfo, 0); + + u16 *ptr = (u16*)(&cpuinfo[0]); + for (u32 i = 0; i < 8; i++) + hash += ptr[i]; + +#elif defined(PK_LINUX) + + u32 cpuinfo[4] = { 0, 0, 0, 0 }; + + _getCpuid(cpuinfo, 0); + + u32 *ptr = (&cpuinfo[0]); + + for (u32 i = 0; i < 4; i++) + hash += (ptr[i] & 0xFFFF) + (ptr[i] >> 16); + +#elif defined(PK_MACOSX) + + const NXArchInfo *info = NXGetLocalArchInfo(); + + hash += u16(info->cputype); + hash += u16(info->cpusubtype); + +#else + PK_ASSERT_NOT_REACHED(); +#endif + + return hash; +} + +//---------------------------------------------------------------------------- + +const char *CSystemHelper::_GetMachineName() +{ +#if defined(PK_WINDOWS) + static char computerName[1024]; + DWORD size = 1024; + + GetComputerName(computerName, &size); + + return computerName; + +#elif defined(PK_LINUX) || defined(PK_MACOSX) + static struct utsname u; + + if (uname(&u) < 0) + return "unknown"; + + return u.nodename; +#else + PK_ASSERT_NOT_REACHED(); +#endif +} + +//---------------------------------------------------------------------------- + +static const u16 kSmearMask[3] = { 0x4e25, 0xf4a1, 0x5437 }; + +//---------------------------------------------------------------------------- + +void CSystemHelper::_Smear(u16 *id) +{ + for (u32 i = 0; i < 3; i++) + { + for (u32 j = i; j < 3; j++) + { + if (i != j) + id[i] ^= id[j]; + } + } + + for (u32 i = 0; i < 3; i++) + id[i] ^= kSmearMask[i]; +} + +//---------------------------------------------------------------------------- + +void CSystemHelper::_Unsmear(u16 *id) +{ + for (u32 i = 0; i < 3; i++) + id[i] ^= kSmearMask[i]; + + for (u32 i = 0; i < 3; i++) + { + for (u32 j = 0; j < i; j++) + { + if (i != j) + id[2 - i] ^= id[2 - j]; + } + } +} + +//---------------------------------------------------------------------------- + +u16 *CSystemHelper::_ComputeSystemUniqueId() +{ + static u16 id[3]; + static bool computed = false; + + if (!computed) + { + id[0] = _GetCPUHash(); + id[2] = _GetMacHash(); + id[1] = id[0] + id[2]; + + _Smear(id); + + computed = true; + } + + return id; +} + +//---------------------------------------------------------------------------- + +const CString CSystemHelper::GetUniqueHardwareID() +{ + CString hId; + + u16 *id = _ComputeSystemUniqueId(); + for (u32 i = 0; i < 3; i++) + hId += CString::Format("%04x", id[i]); + + return hId.ToUppercase(); +} + +//---------------------------------------------------------------------------- + +const CString CSystemHelper::GetUniqueHardwareIDForHuman() +{ + CString hId = _GetMachineName(); + + u16 *id = _ComputeSystemUniqueId(); + for (u32 i = 0; i < 3; i++) + hId += CString::Format("-%04x", id[i]); + + return hId.ToUppercase(); +} + +bool CSystemHelper::LaunchEditorAsPopup() +{ + SEngineVersion version{ PK_VERSION_MAJOR, PK_VERSION_MINOR, PK_VERSION_PATCH, PK_VERSION_REVID }; +#if defined(PK_WINDOWS) + SEditorExecutable application = CWinSystemHelper::GetMatchingEditor(version); +#else + SEditorExecutable application; +#endif + if (application.m_BinaryPath.Empty()) + { + return CAELog::TryLogErrorWindows("No installed versions of the PopcornFX editor were found\nPlease visit: https://auth.popcornfx.com/ws/latest?channel=pkfx-stable&v=2 and download the latest PopcornFX editor"); + } + + CProcess process; + + TArray commandline; + + if (!commandline.PushBack("--aeass").Valid()) + return false; + if (!commandline.PushBack("toto").Valid()) + return false; + if (!process.Start(application.m_BinaryPath, commandline, true)) + { + return CAELog::TryLogErrorWindows("No installed versions of the PopcornFX editor were found\nPlease visit: https://auth.popcornfx.com/ws/latest?channel=pkfx-stable&v=2 and download the latest PopcornFX editor"); + } + CString output; + +#if defined(PK_WINDOWS) + TArray errorIgnoreList; + errorIgnoreList.PushBack(ERROR_NO_MORE_FILES); +#endif + + process.WaitForExit(); + + output = process.GetProcessStandardOutput(); + if (output != null && !output.Empty()) + { + CLog::Log(PK_INFO, "%s", output.Data()); + output.Clear(); + } + else + { +#if defined(PK_WINDOWS) + CString errorstr = CWinSystemHelper::GetLastErrorAsString(errorIgnoreList); + if (!errorstr.Empty()) + { + CLog::Log(PK_INFO, "%s", errorstr.Data()); + return false; + } +#endif + } + return true; +} + +//---------------------------------------------------------------------------- +__AEGP_PK_END diff --git a/AE_GeneralPlugin/Sources/AEGP_UpdateAEState.cpp b/AE_GeneralPlugin/Sources/AEGP_UpdateAEState.cpp new file mode 100644 index 00000000..392d0dac --- /dev/null +++ b/AE_GeneralPlugin/Sources/AEGP_UpdateAEState.cpp @@ -0,0 +1,1233 @@ +//---------------------------------------------------------------------------- +// Copyright Persistant Studios, SARL. All Rights Reserved. https://www.popcornfx.com/terms-and-conditions/ +//---------------------------------------------------------------------------- +#include "ae_precompiled.h" + +#include "AEGP_UpdateAEState.h" + +#include "AEGP_World.h" +#include "AEGP_LayerHolder.h" +#include "AEGP_AEPKConversion.h" + +#include + +#include + +__AEGP_PK_BEGIN + + +int CAEUpdater::s_AttributeIndexes[__Attribute_Parameters_Count]; +int CAEUpdater::s_EmitterIndexes[__Effect_Parameters_Count]; +int CAEUpdater::s_SamplerIndexes[__AttributeSamplerType_Parameters_Count]; + +//---------------------------------------------------------------------------- + +CAEUpdater::CAEUpdater() +{ +} + +//---------------------------------------------------------------------------- + +CAEUpdater::~CAEUpdater() +{ +} + +//---------------------------------------------------------------------------- + +A_Err CAEUpdater::UpdateLayerAtTime(SLayerHolder *targetLayer, float time, bool isSeeking /*=false*/) +{ + s32 targetTime = (s32)(time * (float)targetLayer->m_TimeScale); + s32 toEndOfFrame = targetTime % targetLayer->m_TimeStep; + A_Time AETime; + + if (targetTime < 0) + AETime.value = 0; + else if ((u32)toEndOfFrame > (targetLayer->m_TimeStep / 2)) + AETime.value = targetTime + (targetLayer->m_TimeStep - toEndOfFrame); // Round to next frame + else + AETime.value = targetTime - toEndOfFrame; // Round to previous frame + AETime.scale = targetLayer->m_TimeScale; + return _UpdateLayerAtTime(targetLayer, AETime, isSeeking); +} + +//---------------------------------------------------------------------------- + +A_Err CAEUpdater::_UpdateLayerAtTime(SLayerHolder *targetLayer, A_Time &AETime, bool isSeeking /*=false*/) +{ + PK_ASSERT(targetLayer != null); + + PK_SCOPEDPROFILE(); + + A_Err frameAborted = A_Err_NONE; + CFloat4x4 viewMatrix; + CFloat4 cameraPos; + CPopcornFXWorld &PKFXWorld = CPopcornFXWorld::Instance(); + AEGP_SuiteHandler suites(PKFXWorld.GetAESuites()); + + float cameraZoom = 0.f; + GetCameraViewMatrixAtTime(targetLayer, viewMatrix, cameraPos, AETime, cameraZoom); + targetLayer->m_Scene->SetCameraViewMatrix(viewMatrix, cameraPos, cameraZoom); + + A_long effectCount = 0; + + frameAborted |= suites.EffectSuite4()->AEGP_GetLayerNumEffects(targetLayer->m_EffectLayer, &effectCount); + + for (A_long j = effectCount - 1; j >= 0; --j) + { + AEGP_EffectRefH effectRef = null; + AEGP_InstalledEffectKey installedKey; + + frameAborted |= suites.EffectSuite4()->AEGP_GetLayerEffectByIndex(PKFXWorld.GetPluginID(), targetLayer->m_EffectLayer, j, &effectRef); + frameAborted |= suites.EffectSuite4()->AEGP_GetInstalledKeyFromLayerEffect(effectRef, &installedKey); + + if (installedKey == PKFXWorld.GetPluginEffectKey(EPKChildPlugins::EMITTER)) + { + frameAborted |= _UpdateEmitterAtTime(targetLayer, effectRef, AETime, isSeeking); + if (frameAborted != A_Err_NONE) + return frameAborted; + } + else if (installedKey == PKFXWorld.GetPluginEffectKey(EPKChildPlugins::ATTRIBUTE)) + { + CStringId id = PKFXWorld.GetAttributeID(effectRef); + if (targetLayer->m_SpawnedAttributes.Contains(id)) + { + SPendingAttribute *attribute = targetLayer->m_SpawnedAttributes[id]; + + PK_ASSERT(attribute != null); + frameAborted |= _UpdateAttributeAtTime(targetLayer, attribute, effectRef, AETime, isSeeking); + if (frameAborted != A_Err_NONE) + return frameAborted; + } + } + else if (installedKey == PKFXWorld.GetPluginEffectKey(EPKChildPlugins::SAMPLER)) + { + CStringId id = PKFXWorld.GetAttributeSamplerID(effectRef); + if (targetLayer->m_SpawnedAttributesSampler.Contains(id)) + { + SPendingAttribute *smplr = targetLayer->m_SpawnedAttributesSampler[id]; + + PK_ASSERT(smplr != null); + PK_ASSERT(smplr->m_Desc != null); + + SAttributeSamplerDesc *samplerDescriptor = static_cast(smplr->m_Desc); + + if (smplr->m_PKDesc == null) + { + switch (samplerDescriptor->m_Type) + { + case AttributeSamplerType_Geometry: + smplr->m_PKDesc = PK_NEW(SSamplerShape); + break; + case AttributeSamplerType_Text: + smplr->m_PKDesc = PK_NEW(SSamplerText); + break; + case AttributeSamplerType_Image: + smplr->m_PKDesc = PK_NEW(SSamplerImage); + break; + case AttributeSamplerType_Audio: + { + SSamplerAudio *sampler = PK_NEW(SSamplerAudio); + smplr->m_PKDesc = sampler; + sampler->m_Name = CStringId(((SAudioSamplerDescriptor*)samplerDescriptor->m_Descriptor)->m_ChannelGroup.c_str()); + break; + } + case AttributeSamplerType_VectorField: + smplr->m_PKDesc = PK_NEW(SSamplerVectorField); + break; + default: + break; + } + } + PK_ASSERT(smplr->m_PKDesc != null); + frameAborted |= _UpdateSamplerAtTime(targetLayer, smplr, effectRef, AETime, isSeeking); + if (frameAborted != A_Err_NONE) + return frameAborted; + } + } + frameAborted |= suites.EffectSuite4()->AEGP_DisposeEffect(effectRef); + } + if (!PK_VERIFY(frameAborted == A_Err_NONE)) + return frameAborted; + if (!targetLayer->m_Scene->UpdateAttributes(targetLayer)) + return A_Err_GENERIC; + return A_Err_NONE; +} + +//---------------------------------------------------------------------------- + +bool CAEUpdater::GetCameraViewMatrixAtTime(SLayerHolder *layer, CFloat4x4 &view, CFloat4 &pos, A_Time &AETime, float &cameraZoom) +{ + PK_SCOPEDPROFILE(); + + CPopcornFXWorld &PKFXWorld = CPopcornFXWorld::Instance(); + AEGP_SuiteHandler suites(PKFXWorld.GetAESuites()); + AEGP_LayerH camera_layerH = null; + A_Matrix4 matrix; + PF_Err result = A_Err_NONE; + CFloat4x4 viewMatrix = CFloat4x4::IDENTITY; + SEmitterDesc *emitter = layer->m_SpawnedEmitter.m_Desc; + + camera_layerH = layer->m_CameraLayer; + if (!result && camera_layerH) + { + result |= suites.LayerSuite5()->AEGP_GetLayerToWorldXform(camera_layerH, &AETime, &matrix); + if (!result) + { + emitter->m_Camera.m_AECameraPresent = true; + AEGP_StreamVal stream_val; + AEFX_CLR_STRUCT(stream_val); + + result |= suites.StreamSuite2()->AEGP_GetLayerStreamValue(camera_layerH, + AEGP_LayerStream_ZOOM, + AEGP_LTimeMode_CompTime, + &AETime, + FALSE, + &stream_val, + null); + cameraZoom = (float)stream_val.one_d; + AAEToPK(matrix, viewMatrix); + + pos = viewMatrix.WAxis(); +#if defined(PK_SCALE_DOWN) + pos.xyz() = pos.xyz() / layer->m_ScaleFactor; + viewMatrix.WAxis() = pos; +#endif + viewMatrix.Invert(); + view = viewMatrix; + } + } + if (!PK_VERIFY(result == A_Err_NONE)) + return false; + return true; +} + +//---------------------------------------------------------------------------- + +bool CAEUpdater::_SetupAudioSampler(SLayerHolder *targetLayer, AEGP_LayerIDVal layerID, A_Time &AETime, SSamplerAudio *samplerAudio, bool isSeeking) +{ + (void)isSeeking; + CPopcornFXWorld &PKFXWorld = CPopcornFXWorld::Instance(); + AEGP_SuiteHandler suites(PKFXWorld.GetAESuites()); + A_Err frameAborted = A_Err_NONE; + + if (layerID != AEGP_LayerIDVal_NONE) + { + AEGP_LayerH layer; + AEGP_CompH compH; + AEGP_ItemH layerItem = null; + AEGP_SoundDataFormat soundFormat; + AEGP_SoundDataH soundData = null; + A_Time duration; + A_Time layerTime; + + frameAborted |= suites.LayerSuite5()->AEGP_GetLayerParentComp(targetLayer->m_EffectLayer, &compH); + frameAborted |= suites.LayerSuite7()->AEGP_GetLayerFromLayerID(compH, layerID, &layer); + frameAborted |= suites.LayerSuite5()->AEGP_GetLayerSourceItem(layer, &layerItem); + frameAborted |= suites.LayerSuite5()->AEGP_ConvertCompToLayerTime(layer, &AETime, &layerTime); + + if (layerItem == null) + return false; + + soundFormat.encoding = AEGP_SoundEncoding_FLOAT; + soundFormat.num_channelsL = 1; + soundFormat.sample_rateF = 48000.0; + + // We compute the expected timestep to get 2048 values (We are using 2x the number of samples in the PopcornFX editor to get proper spectrum analysis): + A_FpLong secondsToSample = 2048.0 / soundFormat.sample_rateF; + + duration.value = static_cast(secondsToSample * static_cast(targetLayer->m_TimeScale)) + 1; + duration.scale = targetLayer->m_TimeScale; + frameAborted |= suites.RenderSuite5()->AEGP_RenderNewItemSoundData(layerItem, &layerTime, &duration, &soundFormat, null, null, &soundData); + + if (soundData != null) + { + void *audioSamples; + A_long numSamples = 0; + + frameAborted |= suites.SoundDataSuite1()->AEGP_LockSoundDataSamples(soundData, &audioSamples); + frameAborted |= suites.SoundDataSuite1()->AEGP_GetNumSamples(soundData, &numSamples); + + if (!PK_VERIFY(frameAborted == A_Err_NONE)) + { + frameAborted |= suites.SoundDataSuite1()->AEGP_UnlockSoundDataSamples(soundData); + frameAborted |= suites.SoundDataSuite1()->AEGP_DisposeSoundData(soundData); + } + else + { + samplerAudio->m_SoundData = soundData; + // Align to the previous power of 2: + const int alignedSampleCount = 1 << IntegerTools::Log2(numSamples); + samplerAudio->m_InputSampleCount = alignedSampleCount; + samplerAudio->m_Waveform = (float*)audioSamples; + samplerAudio->m_Dirty = true; + return true; + } + } + } + samplerAudio->m_SoundData = null; + samplerAudio->m_InputSampleCount = 0; + samplerAudio->m_Waveform = null; + return false; +} + +//---------------------------------------------------------------------------- + +A_Err CAEUpdater::_UpdateSamplerAtTime(SLayerHolder *targetLayer, SPendingAttribute *sampler, AEGP_EffectRefH effectRef, A_Time &AETime, bool isSeeking /*=false*/) +{ + if (sampler == null || sampler->m_Desc == null) + return A_Err_NONE; + PK_SCOPEDPROFILE(); + A_Err frameAborted = A_Err_NONE; + CPopcornFXWorld &PKFXWorld = CPopcornFXWorld::Instance(); + AEGP_SuiteHandler suites(PKFXWorld.GetAESuites()); + SAttributeSamplerDesc *samplerDescriptor = static_cast(sampler->m_Desc); + SBaseSamplerDescriptor *AEdescriptor = samplerDescriptor->m_Descriptor; + SSamplerBase *PKdescriptor = sampler->m_PKDesc; + + if (!PK_VERIFY(AEdescriptor != null)) + return A_Err_GENERIC; + + switch (samplerDescriptor->m_Type) + { + case AttributeSamplerType_Geometry: + { + SShapeSamplerDescriptor *shapeDescriptor = static_cast(AEdescriptor); + ESamplerShapeType shapeType; + double value; + double dimension[3] = { 0.0, 0.0, 0.0 }; + + frameAborted |= _GetParamsStreamValueAtTime(AttributeSamplerType_Parameters_Shapes, effectRef, AETime, value); + shapeType = (ESamplerShapeType)(int)(value - 1); // Because AE Popup are weird. + + if (shapeType == SamplerShapeType_Box) + { + frameAborted |= _GetParamsStreamValueAtTime(AttributeSamplerType_Parameters_Box_Size_X, effectRef, AETime, dimension[0]); + frameAborted |= _GetParamsStreamValueAtTime(AttributeSamplerType_Parameters_Box_Size_Y, effectRef, AETime, dimension[1]); + frameAborted |= _GetParamsStreamValueAtTime(AttributeSamplerType_Parameters_Box_Size_Z, effectRef, AETime, dimension[2]); + } + else if (shapeType == SamplerShapeType_Sphere) + { + frameAborted |= _GetParamsStreamValueAtTime(AttributeSamplerType_Parameters_Sphere_Radius, effectRef, AETime, dimension[0]); + frameAborted |= _GetParamsStreamValueAtTime(AttributeSamplerType_Parameters_Sphere_InnerRadius, effectRef, AETime, dimension[1]); + } + else if (shapeType == SamplerShapeType_Ellipsoid) + { + frameAborted |= _GetParamsStreamValueAtTime(AttributeSamplerType_Parameters_Ellipsoid_Radius, effectRef, AETime, dimension[0]); + frameAborted |= _GetParamsStreamValueAtTime(AttributeSamplerType_Parameters_Ellipsoid_InnerRadius, effectRef, AETime, dimension[1]); + } + else if (shapeType == SamplerShapeType_Cylinder) + { + frameAborted |= _GetParamsStreamValueAtTime(AttributeSamplerType_Parameters_Cylinder_Radius, effectRef, AETime, dimension[0]); + frameAborted |= _GetParamsStreamValueAtTime(AttributeSamplerType_Parameters_Cylinder_Height, effectRef, AETime, dimension[1]); + frameAborted |= _GetParamsStreamValueAtTime(AttributeSamplerType_Parameters_Cylinder_InnerRadius, effectRef, AETime, dimension[2]); + } + else if (shapeType == SamplerShapeType_Capsule) + { + frameAborted |= _GetParamsStreamValueAtTime(AttributeSamplerType_Parameters_Capsule_Radius, effectRef, AETime, dimension[0]); + frameAborted |= _GetParamsStreamValueAtTime(AttributeSamplerType_Parameters_Capsule_Height, effectRef, AETime, dimension[1]); + frameAborted |= _GetParamsStreamValueAtTime(AttributeSamplerType_Parameters_Capsule_InnerRadius, effectRef, AETime, dimension[2]); + } + else if (shapeType == SamplerShapeType_Cone) + { + frameAborted |= _GetParamsStreamValueAtTime(AttributeSamplerType_Parameters_Cone_Radius, effectRef, AETime, dimension[0]); + frameAborted |= _GetParamsStreamValueAtTime(AttributeSamplerType_Parameters_Cone_Height, effectRef, AETime, dimension[1]); + } + else if (shapeType == SamplerShapeType_Mesh) + { + frameAborted |= _GetParamsStreamValueAtTime(AttributeSamplerType_Parameters_Mesh_Scale, effectRef, AETime, dimension[0]); + } + shapeDescriptor->m_Type = shapeType; + shapeDescriptor->m_Dimension[0] = (float)dimension[0]; + shapeDescriptor->m_Dimension[1] = (float)dimension[1]; + shapeDescriptor->m_Dimension[2] = (float)dimension[2]; + if (shapeType == SamplerShapeType_Mesh) + { + if (shapeDescriptor->m_Path.compare(samplerDescriptor->m_ResourcePath)) + { + shapeDescriptor->m_Path = samplerDescriptor->m_ResourcePath; + PKdescriptor->m_Dirty = true; + } + + double doubleValue; + frameAborted |= _GetParamsStreamValueAtTime(AttributeSamplerType_Parameters_Mesh_Bind_Backdrop, effectRef, AETime, doubleValue); + shapeDescriptor->m_BindToBackdrop = (bool)doubleValue; + if (shapeDescriptor->m_BindToBackdrop) + { + frameAborted |= _GetParamsStreamValueAtTime(AttributeSamplerType_Parameters_Mesh_Bind_Backdrop_Weighted_Enabled, effectRef, AETime, doubleValue); + shapeDescriptor->m_WeightedSampling = (bool)doubleValue; + + frameAborted |= _GetParamsStreamValueAtTime(AttributeSamplerType_Parameters_Mesh_Bind_Backdrop_ColorStreamID, effectRef, AETime, doubleValue); + shapeDescriptor->m_ColorStreamID = (unsigned int)doubleValue; + + frameAborted |= _GetParamsStreamValueAtTime(AttributeSamplerType_Parameters_Mesh_Bind_Backdrop_WeightStreamID, effectRef, AETime, doubleValue); + shapeDescriptor->m_WeightStreamID = (unsigned int)doubleValue; + } + targetLayer->m_Scene->SetSkinnedBackdropParams(shapeDescriptor->m_BindToBackdrop, shapeDescriptor->m_WeightedSampling, shapeDescriptor->m_ColorStreamID, shapeDescriptor->m_WeightStreamID); + + } + else + PKdescriptor->m_Dirty = true; + break; + } + case AttributeSamplerType_Text: + { + STextSamplerDescriptor *textDesc = static_cast(AEdescriptor); + + AEGP_LayerIDVal layerID; + frameAborted |= _GetParamsStreamValueAtTime(AttributeSamplerType_Layer_Pick, effectRef, AETime, layerID); + + if (layerID != AEGP_LayerIDVal_NONE) + { + AEGP_LayerH textLayer; + AEGP_CompH compH; + + frameAborted |= suites.LayerSuite5()->AEGP_GetLayerParentComp(targetLayer->m_EffectLayer, &compH); + frameAborted |= suites.LayerSuite7()->AEGP_GetLayerFromLayerID(compH, layerID, &textLayer); + + AEGP_StreamValue2 streamValue; + AEGP_StreamType streamType; + AEGP_ObjectType layerType; + AEGP_StreamRefH textStream = null; + + frameAborted |= suites.LayerSuite8()->AEGP_GetLayerObjectType(textLayer, &layerType); + if (!PK_VERIFY(frameAborted == A_Err_NONE) || layerType != AEGP_ObjectType_TEXT) + break; + + frameAborted |= suites.StreamSuite5()->AEGP_GetNewLayerStream(PKFXWorld.GetPluginID(), textLayer, AEGP_LayerStream_SOURCE_TEXT, &textStream); + frameAborted |= suites.StreamSuite5()->AEGP_GetNewStreamValue(PKFXWorld.GetPluginID(), textStream, AEGP_LTimeMode_LayerTime, &AETime, TRUE, &streamValue); + frameAborted |= suites.StreamSuite2()->AEGP_GetStreamType(textStream, &streamType); + if (!PK_VERIFY(frameAborted == A_Err_NONE) || streamType != AEGP_StreamType_TEXT_DOCUMENT) + break; + + AEGP_MemHandle textHandle = null; + frameAborted |= suites.TextDocumentSuite1()->AEGP_GetNewText(PKFXWorld.GetPluginID(), streamValue.val.text_documentH, &textHandle); + + aechar_t *retrievedText; + CString text = ""; + + if (textHandle != null) + { + frameAborted |= suites.MemorySuite1()->AEGP_LockMemHandle(textHandle, reinterpret_cast(&retrievedText)); + + WCharToCString(retrievedText, &text); + + frameAborted |= suites.MemorySuite1()->AEGP_UnlockMemHandle(textHandle); + frameAborted |= suites.MemorySuite1()->AEGP_FreeMemHandle(textHandle); + + textDesc->m_Data = text.Data(); + PKdescriptor->m_Dirty = true; + } + frameAborted |= suites.StreamSuite5()->AEGP_DisposeStreamValue(&streamValue); + frameAborted |= suites.StreamSuite5()->AEGP_DisposeStream(textStream); + } + else + textDesc->m_Data = ""; + break; + } + case AttributeSamplerType_Image: + { + SSamplerImage *pkImageDesc = static_cast(PKdescriptor); + + if (!PK_VERIFY(pkImageDesc != null)) + break; + + double boolValue; + bool sampleOnSeek = false, sampleOnce = false; + frameAborted |= _GetParamsStreamValueAtTime(AttributeSamplerType_Layer_Sample_Once, effectRef, AETime, boolValue); + sampleOnce = (bool)boolValue; + frameAborted |= _GetParamsStreamValueAtTime(AttributeSamplerType_Layer_Sample_Seeking, effectRef, AETime, boolValue); + sampleOnSeek = (bool)boolValue; + + double intValue; + int downSampleX; + int downSampleY; + frameAborted |= _GetParamsStreamValueAtTime(AttributeSamplerType_Layer_Sample_Downsampling_X, effectRef, AETime, intValue); + downSampleX = (int)intValue; + frameAborted |= _GetParamsStreamValueAtTime(AttributeSamplerType_Layer_Sample_Downsampling_Y, effectRef, AETime, intValue); + downSampleY = (int)intValue; + + if ((!sampleOnSeek && isSeeking) || + (sampleOnce && pkImageDesc->m_TextureData != null && pkImageDesc->m_TextureData->DataSizeInBytes() != 0)) + { + pkImageDesc->m_Dirty = false; + break; + } + + AEGP_LayerIDVal layerID; + frameAborted |= _GetParamsStreamValueAtTime(AttributeSamplerType_Layer_Pick, effectRef, AETime, layerID); + + if (layerID != AEGP_LayerIDVal_NONE) + { + AEGP_LayerH imageLayer; + AEGP_CompH compH; + AEGP_LayerRenderOptionsH renderOptions = null; + AEGP_WorldType worldType = AEGP_WorldType_NONE; + AEGP_FrameReceiptH inputFrame = null; + AEGP_WorldH inputworld = null; + A_Time layerDuration, layerInPoint; + + frameAborted |= suites.LayerSuite5()->AEGP_GetLayerParentComp(targetLayer->m_EffectLayer, &compH); + frameAborted |= suites.LayerSuite7()->AEGP_GetLayerFromLayerID(compH, layerID, &imageLayer); + + frameAborted |= suites.LayerSuite8()->AEGP_GetLayerInPoint(imageLayer, AEGP_LTimeMode_CompTime, &layerInPoint); + frameAborted |= suites.LayerSuite8()->AEGP_GetLayerDuration(imageLayer, AEGP_LTimeMode_CompTime, &layerDuration); + + if (!PK_VERIFY(frameAborted == A_Err_NONE)) + return frameAborted; + + double aeTime = (double)AETime.value / (double)AETime.scale; + double layInPtTime = (double)layerInPoint.value / (double)layerInPoint.scale; + double layDurTime = (double)layerDuration.value / (double)layerDuration.scale; + + if ((aeTime >= layInPtTime) && + (aeTime < (layInPtTime + layDurTime))) + { + A_Time layerTime; + + layerTime.scale = AETime.scale; + layerTime.value = AETime.value - layerInPoint.value; + frameAborted |= suites.LayerRenderOptionsSuite2()->AEGP_NewFromLayer(PKFXWorld.GetPluginID(), imageLayer, &renderOptions); + frameAborted |= suites.LayerRenderOptionsSuite2()->AEGP_GetWorldType(renderOptions, &worldType); + + frameAborted |= suites.LayerRenderOptionsSuite2()->AEGP_SetTime(renderOptions, layerTime); + + frameAborted |= suites.LayerRenderOptionsSuite2()->AEGP_SetDownsampleFactor(renderOptions, (A_short)downSampleX, (A_short)downSampleY); + + if (frameAborted != A_Err_NONE) + return frameAborted; + + // This fails if the frame is cancelled: + frameAborted |= suites.RenderSuite5()->AEGP_RenderAndCheckoutLayerFrame(renderOptions, null, null, &inputFrame); + + if (frameAborted != A_Err_NONE) + return frameAborted; + + frameAborted |= suites.RenderSuite5()->AEGP_GetReceiptWorld(inputFrame, &inputworld); + if (inputworld != null) + { + A_long width, height; + A_u_long rowbyte; + + frameAborted |= suites.WorldSuite3()->AEGP_GetSize(inputworld, &width, &height); + frameAborted |= suites.WorldSuite3()->AEGP_GetRowBytes(inputworld, &rowbyte); + + if (worldType == AEGP_WorldType_32) + { + PF_Pixel32 *worldData = null; + + pkImageDesc->m_PixelFormat = CImage::EFormat::Format_Fp32RGBA; + pkImageDesc->m_Width = width; + pkImageDesc->m_Height = height; + pkImageDesc->m_SizeInBytes = width * height * sizeof(PF_Pixel32); + pkImageDesc->m_TextureData = CRefCountedMemoryBuffer::AllocAligned(pkImageDesc->m_SizeInBytes, 0x10); + + frameAborted |= suites.WorldSuite3()->AEGP_GetBaseAddr32(inputworld, &worldData); + + if (worldData != null) + { + //input is ARGB; + u8 *sptr = (u8*)worldData; + u8 *dptr = (u8*)pkImageDesc->m_TextureData->Data(); + + for (s32 i = 0; i < height; ++i) + { + for (s32 j = 0; j < width; ++j) + { + PF_Pixel32 *dst = (PF_Pixel32*)&(dptr[j * sizeof(PF_Pixel32) + i * width * sizeof(PF_Pixel32)]); + PF_Pixel32 *src = (PF_Pixel32*)&(sptr[j * sizeof(PF_Pixel32) + i * rowbyte]); + + CFloat4 value = CFloat4(PKSample::ConvertSRGBToLinear(CFloat3(src->red, src->green, src->blue)), src->alpha); + + value = PKSaturate(value); + + /*0*/dst->alpha = value.x(); + /*1*/dst->red = value.y(); + /*2*/dst->green = value.z(); + /*3*/dst->blue = value.w(); + } + } + } + } + else if (worldType == AEGP_WorldType_16) + { + PF_Pixel16 *worldData = null; + + pkImageDesc->m_PixelFormat = CImage::EFormat::Format_Fp16RGBA; + pkImageDesc->m_Width = width; + pkImageDesc->m_Height = height; + pkImageDesc->m_SizeInBytes = width * height * sizeof(PF_Pixel16); + pkImageDesc->m_TextureData = CRefCountedMemoryBuffer::AllocAligned(pkImageDesc->m_SizeInBytes, 0x10); + + frameAborted |= suites.WorldSuite3()->AEGP_GetBaseAddr16(inputworld, &worldData); + + if (worldData != null) + { + //input is ARGB; + u8 *sptr = (u8*)worldData; + u8 *dptr = (u8*)pkImageDesc->m_TextureData->Data(); + + for (s32 i = 0; i < height; ++i) + { + for (s32 j = 0; j < width; ++j) + { + PF_Pixel16 *dst = (PF_Pixel16*)&(dptr[j * sizeof(PF_Pixel16) + i * width * sizeof(PF_Pixel16)]); + PF_Pixel16 *src = (PF_Pixel16*)&(sptr[j * sizeof(PF_Pixel16) + i * rowbyte]); + + CFloat4 value = CFloat4(PKSample::ConvertSRGBToLinear(CFloat3(src->red, src->green, src->blue)), src->alpha); + + value = PKSaturate(value); + /*0*/dst->alpha = (A_u_short)value.x(); + /*1*/dst->red = (A_u_short)value.y(); + /*2*/dst->green = (A_u_short)value.z(); + /*3*/dst->blue = (A_u_short)value.w(); + } + } + } + } + else if (worldType == AEGP_WorldType_8) + { + PF_Pixel8 *worldData = null; + + pkImageDesc->m_PixelFormat = CImage::EFormat::Format_BGRA8; + pkImageDesc->m_Width = width; + pkImageDesc->m_Height = height; + pkImageDesc->m_SizeInBytes = width * height * sizeof(PF_Pixel8); + pkImageDesc->m_TextureData = CRefCountedMemoryBuffer::AllocAligned(pkImageDesc->m_SizeInBytes, 0x10); + + frameAborted |= suites.WorldSuite3()->AEGP_GetBaseAddr8(inputworld, &worldData); + + if (worldData != null) + { + //input is ARGB; + u8 *sptr = (u8*)worldData; + u8 *dptr = (u8*)pkImageDesc->m_TextureData->Data(); + + for (s32 i = 0; i < height; ++i) + { + for (s32 j = 0; j < width; ++j) + { + PF_Pixel8 *dst = (PF_Pixel8*)&(dptr[j * sizeof(PF_Pixel8) + i * width * sizeof(PF_Pixel8)]); + PF_Pixel8 *src = (PF_Pixel8*)&(sptr[j * sizeof(PF_Pixel8) + i * rowbyte]); + + CUbyte4 value = CUbyte4(/*PKSample::ConvertSRGBToLinear*/(CUbyte3(src->blue, src->green, src->red)), src->alpha); + + value = PKClamp(value, CUbyte4::ZERO, CUbyte4(255)); + /*0*/dst->alpha = value.x(); + /*1*/dst->red = value.y(); + /*2*/dst->green = value.z(); + /*3*/dst->blue = value.w(); + } + } + } + } + } + + frameAborted |= suites.RenderSuite5()->AEGP_CheckinFrame(inputFrame); + frameAborted |= suites.LayerRenderOptionsSuite2()->AEGP_Dispose(renderOptions); + } + else if (pkImageDesc->m_Width != 1 || pkImageDesc->m_Height != 1) + { + pkImageDesc->m_PixelFormat = CImage::EFormat::Format_BGRA8; + pkImageDesc->m_Width = 1; + pkImageDesc->m_Height = 1; + pkImageDesc->m_SizeInBytes = sizeof(PF_Pixel8); + pkImageDesc->m_TextureData = CRefCountedMemoryBuffer::AllocAligned(pkImageDesc->m_SizeInBytes, 0x10); + + u8 *dptr = (u8*)pkImageDesc->m_TextureData->Data(); + PF_Pixel8 *dst = (PF_Pixel8*)&(dptr[0]); + /*0*/dst->alpha = 0; + /*1*/dst->red = 0; + /*2*/dst->green = 0; + /*3*/dst->blue = 0; + } + + if (!PK_VERIFY(frameAborted == A_Err_NONE)) + break; + pkImageDesc->m_Dirty = true; + } + else if (pkImageDesc->m_Width != 1 || pkImageDesc->m_Height != 1) + { + pkImageDesc->m_PixelFormat = CImage::EFormat::Format_BGRA8; + pkImageDesc->m_Width = 1; + pkImageDesc->m_Height = 1; + pkImageDesc->m_SizeInBytes = sizeof(PF_Pixel8); + pkImageDesc->m_TextureData = CRefCountedMemoryBuffer::AllocAligned(pkImageDesc->m_SizeInBytes, 0x10); + + u8 *dptr = (u8*)pkImageDesc->m_TextureData->Data(); + PF_Pixel8 *dst = (PF_Pixel8*)&(dptr[0]); + /*0*/dst->alpha = 0; + /*1*/dst->red = 0; + /*2*/dst->green = 0; + /*3*/dst->blue = 0; + + pkImageDesc->m_Dirty = true; + } + break; + } + case AttributeSamplerType_Audio: + { + SSamplerAudio *pkAudioDesc = static_cast(PKdescriptor); + + if (!PK_VERIFY(pkAudioDesc != null)) + break; + + double value; + bool sampleOnSeek = false; + + frameAborted |= _GetParamsStreamValueAtTime(AttributeSamplerType_Layer_Sample_Seeking, effectRef, AETime, value); + sampleOnSeek = (bool)value; + + if ((!sampleOnSeek && isSeeking)) + { + pkAudioDesc->m_Dirty = false; + break; + } + AEGP_LayerIDVal layerID; + frameAborted |= _GetParamsStreamValueAtTime(AttributeSamplerType_Layer_Pick, effectRef, AETime, layerID); + _SetupAudioSampler(targetLayer, layerID, AETime, pkAudioDesc, isSeeking); + break; + } + case AttributeSamplerType_VectorField: + { + SVectorFieldSamplerDescriptor *vfDescriptor = static_cast(AEdescriptor); + { + AEGP_StreamRefH streamHandler; + AEGP_StreamValue2 value; + + frameAborted |= suites.StreamSuite3()->AEGP_GetNewEffectStreamByIndex(PKFXWorld.GetPluginID(), effectRef, AttributeSamplerType_Parameters_VectorField_Position, &streamHandler); + AEFX_CLR_STRUCT(value); + frameAborted |= suites.StreamSuite3()->AEGP_GetNewStreamValue(PKFXWorld.GetPluginID(), streamHandler, AEGP_LTimeMode_CompTime, &AETime, false, &value); + vfDescriptor->m_Position = A_FloatPoint3{ value.val.three_d.x, value.val.three_d.y, value.val.three_d.z }; + frameAborted |= suites.StreamSuite3()->AEGP_DisposeStreamValue(&value); + frameAborted |= suites.StreamSuite3()->AEGP_DisposeStream(streamHandler); + } + double value; + frameAborted |= _GetParamsStreamValueAtTime(AttributeSamplerType_Parameters_VectorField_Strength, effectRef, AETime, value); + vfDescriptor->m_Strength = (float)value; + + frameAborted |= _GetParamsStreamValueAtTime(AttributeSamplerType_Parameters_VectorField_Interpolation, effectRef, AETime, value); + EInterpolationType interpolation = (EInterpolationType)(int)value; + if (vfDescriptor->m_Interpolation != interpolation) + { + vfDescriptor->m_Interpolation = interpolation; + vfDescriptor->m_ResourceUpdate = true; + } + + std::string vectorfieldPath = samplerDescriptor->m_ResourcePath.c_str(); + if (vectorfieldPath != vfDescriptor->m_Path) + vfDescriptor->m_Path = vectorfieldPath; + PKdescriptor->m_Dirty = true; + break; + } + default: + break; + } + return frameAborted; +} + +//---------------------------------------------------------------------------- + +A_Err CAEUpdater::_UpdateAttributeAtTime(SLayerHolder *targetLayer, SPendingAttribute *attribute, AEGP_EffectRefH effectRef, A_Time &AETime, bool isSeeking /*=false*/) +{ + PK_SCOPEDPROFILE(); + (void)targetLayer; + (void)isSeeking; + + A_Err result = A_Err_NONE; + CPopcornFXWorld &PKFXWorld = CPopcornFXWorld::Instance(); + AEGP_SuiteHandler suites(PKFXWorld.GetAESuites()); + + if (attribute->m_Desc && attribute->m_Desc->m_IsAttribute) + { + SAttributeDesc *desc = static_cast(attribute->m_Desc); + if (desc->m_AttributeSemantic == AttributeSemantic_Color) + { + float floatValues[4]; + + AEGP_StreamRefH streamHandler; + AEGP_StreamValue2 value; + + result |= suites.StreamSuite3()->AEGP_GetNewEffectStreamByIndex(PKFXWorld.GetPluginID(), effectRef, Attribute_Parameters_Color_RGB, &streamHandler); + AEFX_CLR_STRUCT(value); + result |= suites.StreamSuite3()->AEGP_GetNewStreamValue(PKFXWorld.GetPluginID(), streamHandler, AEGP_LTimeMode_CompTime, &AETime, false, &value); + floatValues[0] = (float)value.val.color.redF; + floatValues[1] = (float)value.val.color.greenF; + floatValues[2] = (float)value.val.color.blueF; + + result |= suites.StreamSuite3()->AEGP_DisposeStreamValue(&value); + result |= suites.StreamSuite3()->AEGP_DisposeStream(streamHandler); + + if (desc->m_Type == AttributeType_Float4 || + desc->m_Type == AttributeType_Int4) + { + double floatValue; + result |= _GetParamsStreamValueAtTime(Attribute_Parameters_Color_A, effectRef, AETime, floatValue); + floatValues[3] = (float)(floatValue / 100.0f); + } + if (desc->m_Type >= AttributeType_Int1 && desc->m_Type <= AttributeType_Int4) + { + for (u32 i = 0; i < 4; ++i) + floatValues[i] *= 255; + } + desc->SetValue(&floatValues); + } + else + { + switch (desc->m_Type) + { + case AttributeType_Bool1: + case AttributeType_Bool2: + case AttributeType_Bool3: + case AttributeType_Bool4: + { + bool boolValues[4]; + for (s32 i = 0; i < (desc->m_Type + 1) - AttributeType_Bool1; ++i) + { + double boolValue; + + result |= _GetParamsStreamValueAtTime(AttributeType_Bool1 + i, effectRef, AETime, boolValue); + boolValues[i] = (bool)boolValue; + } + desc->SetValue(&boolValues); + break; + } + case AttributeType_Int1: + case AttributeType_Int2: + case AttributeType_Int3: + case AttributeType_Int4: + { + int intValues[4]; + for (s32 i = 0; i < (desc->m_Type + 1) - AttributeType_Int1; ++i) + { + double intValue; + + result |= _GetParamsStreamValueAtTime(AttributeType_Int1 + i, effectRef, AETime, intValue); + intValues[i] = (int)intValue; + } + desc->SetValue(&intValues); + break; + } + case AttributeType_Float1: + case AttributeType_Float2: + case AttributeType_Float3: + case AttributeType_Float4: + { + float floatValues[4]; + for (s32 i = 0; i < (desc->m_Type + 1) - AttributeType_Float1; ++i) + { + double floatValue; + + result |= _GetParamsStreamValueAtTime(AttributeType_Float1 + i, effectRef, AETime, floatValue); + floatValues[i] = (float)floatValue; + } + desc->SetValue(&floatValues); + break; + } + default: + break; + } + } + } + if (!PK_VERIFY(result == A_Err_NONE)) + return false; + return result; +} + + +//---------------------------------------------------------------------------- + +A_Err CAEUpdater::_UpdateEmitterAtTime(SLayerHolder *layer, AEGP_EffectRefH effectRef, A_Time &AETime, bool isSeeking) +{ + PK_SCOPEDPROFILE(); + (void)isSeeking; + CPopcornFXWorld &PKFXWorld = CPopcornFXWorld::Instance(); + AEGP_SuiteHandler suites(PKFXWorld.GetAESuites()); + A_Err result = A_Err_NONE; + AEGP_StreamRefH streamHandler; + AEGP_StreamValue2 value; + SPendingEmitter &emitter = layer->m_SpawnedEmitter; + + if (!PK_VERIFY(effectRef != null)) + { + return A_Err_GENERIC; + } + { //Emitter + { + result |= suites.StreamSuite3()->AEGP_GetNewEffectStreamByIndex(PKFXWorld.GetPluginID(), effectRef, s_EmitterIndexes[Effect_Parameters_TransformType], &streamHandler); + PK_ASSERT(result == A_Err_NONE); + AEFX_CLR_STRUCT(value); + result |= suites.StreamSuite3()->AEGP_GetNewStreamValue(PKFXWorld.GetPluginID(), streamHandler, AEGP_LTimeMode_CompTime, &AETime, false, &value); + PK_ASSERT(result == A_Err_NONE); + emitter.m_Desc->m_TransformType = ((ETransformType)(int)value.val.one_d); + result |= suites.StreamSuite3()->AEGP_DisposeStreamValue(&value); + PK_ASSERT(result == A_Err_NONE); + result |= suites.StreamSuite3()->AEGP_DisposeStream(streamHandler); + PK_ASSERT(result == A_Err_NONE); + if (result != A_Err_NONE) + return result; + + if (emitter.m_Desc->m_TransformType == ETransformType_3D) + { + result |= suites.StreamSuite3()->AEGP_GetNewEffectStreamByIndex(PKFXWorld.GetPluginID(), effectRef, s_EmitterIndexes[Effect_Parameters_Position], &streamHandler); + PK_ASSERT(result == A_Err_NONE); + AEFX_CLR_STRUCT(value); + result |= suites.StreamSuite3()->AEGP_GetNewStreamValue(PKFXWorld.GetPluginID(), streamHandler, AEGP_LTimeMode_CompTime, &AETime, false, &value); + PK_ASSERT(result == A_Err_NONE); + emitter.m_Desc->m_Position = A_FloatPoint3{ value.val.three_d.x, value.val.three_d.y, value.val.three_d.z }; +#if defined(PK_SCALE_DOWN) + emitter.m_Desc->m_Position.x = emitter.m_Desc->m_Position.x / layer->m_ScaleFactor; + emitter.m_Desc->m_Position.y = emitter.m_Desc->m_Position.y / layer->m_ScaleFactor; + emitter.m_Desc->m_Position.z = emitter.m_Desc->m_Position.z / layer->m_ScaleFactor; +#endif + layer->m_Scene->SetEmitterPosition(AAEToPK(emitter.m_Desc->m_Position), emitter.m_Desc->m_TransformType); + result |= suites.StreamSuite3()->AEGP_DisposeStreamValue(&value); + PK_ASSERT(result == A_Err_NONE); + result |= suites.StreamSuite3()->AEGP_DisposeStream(streamHandler); + PK_ASSERT(result == A_Err_NONE); + if (result != A_Err_NONE) + return result; + } + else if (emitter.m_Desc->m_TransformType == ETransformType_2D) + { + result |= suites.StreamSuite3()->AEGP_GetNewEffectStreamByIndex(PKFXWorld.GetPluginID(), effectRef, s_EmitterIndexes[Effect_Parameters_Position_2D], &streamHandler); + PK_ASSERT(result == A_Err_NONE); + AEFX_CLR_STRUCT(value); + result |= suites.StreamSuite3()->AEGP_GetNewStreamValue(PKFXWorld.GetPluginID(), streamHandler, AEGP_LTimeMode_CompTime, &AETime, false, &value); + PK_ASSERT(result == A_Err_NONE); + + emitter.m_Desc->m_Position.x = value.val.two_d.x; + emitter.m_Desc->m_Position.y = value.val.two_d.y; + + result |= suites.StreamSuite3()->AEGP_GetNewEffectStreamByIndex(PKFXWorld.GetPluginID(), effectRef, s_EmitterIndexes[Effect_Parameters_Position_2D_Distance], &streamHandler); + PK_ASSERT(result == A_Err_NONE); + AEFX_CLR_STRUCT(value); + result |= suites.StreamSuite3()->AEGP_GetNewStreamValue(PKFXWorld.GetPluginID(), streamHandler, AEGP_LTimeMode_CompTime, &AETime, false, &value); + PK_ASSERT(result == A_Err_NONE); + + emitter.m_Desc->m_Position.z = value.val.one_d; + layer->m_Scene->SetEmitterPosition(AAEToPK(emitter.m_Desc->m_Position), emitter.m_Desc->m_TransformType); + } + } + { + float rotation[3]; + for (u32 i = 0; i < 3; ++i) + { + result |= suites.StreamSuite3()->AEGP_GetNewEffectStreamByIndex(PKFXWorld.GetPluginID(), effectRef, s_EmitterIndexes[Effect_Parameters_Rotation_X + i], &streamHandler); + PK_ASSERT(result == A_Err_NONE); + AEFX_CLR_STRUCT(value); + result |= suites.StreamSuite3()->AEGP_GetNewStreamValue(PKFXWorld.GetPluginID(), streamHandler, AEGP_LTimeMode_CompTime, &AETime, false, &value); + PK_ASSERT(result == A_Err_NONE); + rotation[i] = (float)value.val.one_d; + result |= suites.StreamSuite3()->AEGP_DisposeStreamValue(&value); + PK_ASSERT(result == A_Err_NONE); + result |= suites.StreamSuite3()->AEGP_DisposeStream(streamHandler); + PK_ASSERT(result == A_Err_NONE); + if (result != A_Err_NONE) + return result; + } + emitter.m_Desc->m_Rotation = A_FloatPoint3{ rotation[0], rotation[1], rotation[2] }; + layer->m_Scene->SetEmitterRotation(AngleAAEToPK(emitter.m_Desc->m_Rotation)); + } + } + + { //Camera + + result |= suites.StreamSuite3()->AEGP_GetNewEffectStreamByIndex(PKFXWorld.GetPluginID(), effectRef, s_EmitterIndexes[Effect_Parameters_Camera], &streamHandler); + PK_ASSERT(result == A_Err_NONE); + AEFX_CLR_STRUCT(value); + result |= suites.StreamSuite3()->AEGP_GetNewStreamValue(PKFXWorld.GetPluginID(), streamHandler, AEGP_LTimeMode_CompTime, &AETime, false, &value); + PK_ASSERT(result == A_Err_NONE); + result |= suites.StreamSuite3()->AEGP_DisposeStreamValue(&value); + PK_ASSERT(result == A_Err_NONE); + result |= suites.StreamSuite3()->AEGP_DisposeStream(streamHandler); + PK_ASSERT(result == A_Err_NONE); + if (result != A_Err_NONE) + return result; + + result |= suites.StreamSuite3()->AEGP_GetNewEffectStreamByIndex(PKFXWorld.GetPluginID(), effectRef, s_EmitterIndexes[Effect_Parameters_Camera_Near], &streamHandler); + PK_ASSERT(result == A_Err_NONE); + AEFX_CLR_STRUCT(value); + result |= suites.StreamSuite3()->AEGP_GetNewStreamValue(PKFXWorld.GetPluginID(), streamHandler, AEGP_LTimeMode_CompTime, &AETime, false, &value); + PK_ASSERT(result == A_Err_NONE); + emitter.m_Desc->m_Camera.m_Near = (float)value.val.one_d; + result |= suites.StreamSuite3()->AEGP_DisposeStreamValue(&value); + PK_ASSERT(result == A_Err_NONE); + result |= suites.StreamSuite3()->AEGP_DisposeStream(streamHandler); + PK_ASSERT(result == A_Err_NONE); + if (result != A_Err_NONE) + return result; + + result |= suites.StreamSuite3()->AEGP_GetNewEffectStreamByIndex(PKFXWorld.GetPluginID(), effectRef, s_EmitterIndexes[Effect_Parameters_Camera_Far], &streamHandler); + PK_ASSERT(result == A_Err_NONE); + AEFX_CLR_STRUCT(value); + result |= suites.StreamSuite3()->AEGP_GetNewStreamValue(PKFXWorld.GetPluginID(), streamHandler, AEGP_LTimeMode_CompTime, &AETime, false, &value); + PK_ASSERT(result == A_Err_NONE); + emitter.m_Desc->m_Camera.m_Far = (float)value.val.one_d; + result |= suites.StreamSuite3()->AEGP_DisposeStreamValue(&value); + PK_ASSERT(result == A_Err_NONE); + result |= suites.StreamSuite3()->AEGP_DisposeStream(streamHandler); + PK_ASSERT(result == A_Err_NONE); + if (result != A_Err_NONE) + return result; + } + + //Background Override + { + result |= suites.StreamSuite3()->AEGP_GetNewEffectStreamByIndex(PKFXWorld.GetPluginID(), effectRef, s_EmitterIndexes[Effect_Parameters_Background_Toggle], &streamHandler); + PK_ASSERT(result == A_Err_NONE); + AEFX_CLR_STRUCT(value); + result |= suites.StreamSuite3()->AEGP_GetNewStreamValue(PKFXWorld.GetPluginID(), streamHandler, AEGP_LTimeMode_CompTime, &AETime, false, &value); + PK_ASSERT(result == A_Err_NONE); + emitter.m_Desc->m_IsAlphaBGOverride = (bool)value.val.one_d; + result |= suites.StreamSuite3()->AEGP_DisposeStreamValue(&value); + PK_ASSERT(result == A_Err_NONE); + result |= suites.StreamSuite3()->AEGP_DisposeStream(streamHandler); + PK_ASSERT(result == A_Err_NONE); + if (result != A_Err_NONE) + return result; + + result |= suites.StreamSuite3()->AEGP_GetNewEffectStreamByIndex(PKFXWorld.GetPluginID(), effectRef, s_EmitterIndexes[Effect_Parameters_Background_Opacity], &streamHandler); + PK_ASSERT(result == A_Err_NONE); + AEFX_CLR_STRUCT(value); + result |= suites.StreamSuite3()->AEGP_GetNewStreamValue(PKFXWorld.GetPluginID(), streamHandler, AEGP_LTimeMode_CompTime, &AETime, false, &value); + PK_ASSERT(result == A_Err_NONE); + emitter.m_Desc->m_AlphaBGOverride = (float)value.val.one_d / 100.0f; + result |= suites.StreamSuite3()->AEGP_DisposeStreamValue(&value); + PK_ASSERT(result == A_Err_NONE); + result |= suites.StreamSuite3()->AEGP_DisposeStream(streamHandler); + PK_ASSERT(result == A_Err_NONE); + if (result != A_Err_NONE) + return result; + } + { //BackdropMesh + result |= suites.StreamSuite3()->AEGP_GetNewEffectStreamByIndex(PKFXWorld.GetPluginID(), effectRef, s_EmitterIndexes[Effect_Parameters_BackdropMesh_Enable_Rendering], &streamHandler); + PK_ASSERT(result == A_Err_NONE); + AEFX_CLR_STRUCT(value); + result |= suites.StreamSuite3()->AEGP_GetNewStreamValue(PKFXWorld.GetPluginID(), streamHandler, AEGP_LTimeMode_CompTime, &AETime, false, &value); + PK_ASSERT(result == A_Err_NONE); + emitter.m_Desc->m_BackdropMesh.m_EnableRendering = (int)value.val.one_d; + result |= suites.StreamSuite3()->AEGP_DisposeStreamValue(&value); + PK_ASSERT(result == A_Err_NONE); + result |= suites.StreamSuite3()->AEGP_DisposeStream(streamHandler); + PK_ASSERT(result == A_Err_NONE); + if (result != A_Err_NONE) + return result; + + result |= suites.StreamSuite3()->AEGP_GetNewEffectStreamByIndex(PKFXWorld.GetPluginID(), effectRef, s_EmitterIndexes[Effect_Parameters_BackdropMesh_Enable_Collisions], &streamHandler); + PK_ASSERT(result == A_Err_NONE); + AEFX_CLR_STRUCT(value); + result |= suites.StreamSuite3()->AEGP_GetNewStreamValue(PKFXWorld.GetPluginID(), streamHandler, AEGP_LTimeMode_CompTime, &AETime, false, &value); + PK_ASSERT(result == A_Err_NONE); + emitter.m_Desc->m_BackdropMesh.m_EnableCollisions = (int)value.val.one_d; + result |= suites.StreamSuite3()->AEGP_DisposeStreamValue(&value); + PK_ASSERT(result == A_Err_NONE); + result |= suites.StreamSuite3()->AEGP_DisposeStream(streamHandler); + PK_ASSERT(result == A_Err_NONE); + if (result != A_Err_NONE) + return result; + + result |= suites.StreamSuite3()->AEGP_GetNewEffectStreamByIndex(PKFXWorld.GetPluginID(), effectRef, s_EmitterIndexes[Effect_Parameters_BackdropMesh_Enable_Animation], &streamHandler); + PK_ASSERT(result == A_Err_NONE); + AEFX_CLR_STRUCT(value); + result |= suites.StreamSuite3()->AEGP_GetNewStreamValue(PKFXWorld.GetPluginID(), streamHandler, AEGP_LTimeMode_CompTime, &AETime, false, &value); + PK_ASSERT(result == A_Err_NONE); + emitter.m_Desc->m_BackdropMesh.m_EnableAnimations = (int)value.val.one_d; + result |= suites.StreamSuite3()->AEGP_DisposeStreamValue(&value); + PK_ASSERT(result == A_Err_NONE); + result |= suites.StreamSuite3()->AEGP_DisposeStream(streamHandler); + PK_ASSERT(result == A_Err_NONE); + if (result != A_Err_NONE) + return result; + + if (emitter.m_Desc->m_BackdropMesh.m_EnableCollisions) + { + { + result |= suites.StreamSuite3()->AEGP_GetNewEffectStreamByIndex(PKFXWorld.GetPluginID(), effectRef, s_EmitterIndexes[Effect_Parameters_BackdropMesh_Position], &streamHandler); + PK_ASSERT(result == A_Err_NONE); + AEFX_CLR_STRUCT(value); + result |= suites.StreamSuite3()->AEGP_GetNewStreamValue(PKFXWorld.GetPluginID(), streamHandler, AEGP_LTimeMode_CompTime, &AETime, false, &value); + PK_ASSERT(result == A_Err_NONE); + emitter.m_Desc->m_BackdropMesh.m_Position = A_FloatPoint3{ value.val.three_d.x, value.val.three_d.y, value.val.three_d.z }; +#if defined(PK_SCALE_DOWN) + emitter.m_Desc->m_BackdropMesh.m_Position.x = emitter.m_Desc->m_BackdropMesh.m_Position.x / layer->m_ScaleFactor; + emitter.m_Desc->m_BackdropMesh.m_Position.y = emitter.m_Desc->m_BackdropMesh.m_Position.y / layer->m_ScaleFactor; + emitter.m_Desc->m_BackdropMesh.m_Position.z = emitter.m_Desc->m_BackdropMesh.m_Position.z / layer->m_ScaleFactor; +#endif + layer->m_Scene->UpdateBackdropTransform(emitter.m_Desc); + result |= suites.StreamSuite3()->AEGP_DisposeStreamValue(&value); + PK_ASSERT(result == A_Err_NONE); + result |= suites.StreamSuite3()->AEGP_DisposeStream(streamHandler); + PK_ASSERT(result == A_Err_NONE); + if (result != A_Err_NONE) + return result; + } + { + float rotation[3]; + for (u32 i = 0; i < 3; ++i) + { + result |= suites.StreamSuite3()->AEGP_GetNewEffectStreamByIndex(PKFXWorld.GetPluginID(), effectRef, s_EmitterIndexes[Effect_Parameters_BackdropMesh_Rotation_X + i], &streamHandler); + PK_ASSERT(result == A_Err_NONE); + AEFX_CLR_STRUCT(value); + result |= suites.StreamSuite3()->AEGP_GetNewStreamValue(PKFXWorld.GetPluginID(), streamHandler, AEGP_LTimeMode_CompTime, &AETime, false, &value); + PK_ASSERT(result == A_Err_NONE); + rotation[i] = DegToRad((float)value.val.one_d); + result |= suites.StreamSuite3()->AEGP_DisposeStreamValue(&value); + PK_ASSERT(result == A_Err_NONE); + result |= suites.StreamSuite3()->AEGP_DisposeStream(streamHandler); + PK_ASSERT(result == A_Err_NONE); + if (result != A_Err_NONE) + return result; + } + emitter.m_Desc->m_BackdropMesh.m_Rotation = A_FloatPoint3{ rotation[0], rotation[1], rotation[2] }; + } + { + float scale[3]; + for (u32 i = 0; i < 3; ++i) + { + result |= suites.StreamSuite3()->AEGP_GetNewEffectStreamByIndex(PKFXWorld.GetPluginID(), effectRef, s_EmitterIndexes[Effect_Parameters_BackdropMesh_Scale_X + i], &streamHandler); + PK_ASSERT(result == A_Err_NONE); + AEFX_CLR_STRUCT(value); + result |= suites.StreamSuite3()->AEGP_GetNewStreamValue(PKFXWorld.GetPluginID(), streamHandler, AEGP_LTimeMode_CompTime, &AETime, true, &value); + PK_ASSERT(result == A_Err_NONE); + scale[i] = (float)value.val.one_d; + result |= suites.StreamSuite3()->AEGP_DisposeStreamValue(&value); + PK_ASSERT(result == A_Err_NONE); + result |= suites.StreamSuite3()->AEGP_DisposeStream(streamHandler); + PK_ASSERT(result == A_Err_NONE); + if (result != A_Err_NONE) + return result; + } + emitter.m_Desc->m_BackdropMesh.m_Scale = A_FloatPoint3{ scale[0], scale[1], scale[2] }; + } + } + result |= suites.StreamSuite3()->AEGP_GetNewEffectStreamByIndex(PKFXWorld.GetPluginID(), effectRef, s_EmitterIndexes[Effect_Parameters_Simulation_State], &streamHandler); + PK_ASSERT(result == A_Err_NONE); + AEFX_CLR_STRUCT(value); + result |= suites.StreamSuite3()->AEGP_GetNewStreamValue(PKFXWorld.GetPluginID(), streamHandler, AEGP_LTimeMode_CompTime, &AETime, false, &value); + PK_ASSERT(result == A_Err_NONE); + emitter.m_Desc->m_SimStatePrev = emitter.m_Desc->m_SimState; + emitter.m_Desc->m_SimState = (int)value.val.one_d; + + result |= suites.StreamSuite3()->AEGP_DisposeStreamValue(&value); + PK_ASSERT(result == A_Err_NONE); + result |= suites.StreamSuite3()->AEGP_DisposeStream(streamHandler); + PK_ASSERT(result == A_Err_NONE); + if (result != A_Err_NONE) + return result; + } + + // Update audio backdrop: + AEGP_LayerIDVal layerID; + CAEUpdater::_GetParamsStreamValueAtTime(s_EmitterIndexes[Effect_Parameters_Audio], effectRef, AETime, layerID); + + if (layer->m_BackdropAudioSpectrum == null) + layer->m_BackdropAudioSpectrum = PK_NEW(SSamplerAudio); + if (layer->m_BackdropAudioWaveform == null) + layer->m_BackdropAudioWaveform = PK_NEW(SSamplerAudio); + + if (!_SetupAudioSampler(layer, layerID, AETime, layer->m_BackdropAudioSpectrum, isSeeking)) + PK_SAFE_DELETE(layer->m_BackdropAudioSpectrum); + if (!_SetupAudioSampler(layer, layerID, AETime, layer->m_BackdropAudioWaveform, isSeeking)) + PK_SAFE_DELETE(layer->m_BackdropAudioWaveform); + if (!PK_VERIFY(result == A_Err_NONE)) + return result; + return A_Err_NONE; +} + +//---------------------------------------------------------------------------- + +bool CAEUpdater::GetLightsAtTime(SLayerHolder *layer, A_Time &AETime, TArray &lights) +{ + CPopcornFXWorld &PKFXWorld = CPopcornFXWorld::Instance(); + AEGP_SuiteHandler suites(PKFXWorld.GetAESuites()); + A_Err result = A_Err_NONE; + AEGP_CompH compH = null; + AEGP_LayerH layerH = null; + A_long layerNbr = 0; + + A_Boolean layerActive = false; + + result |= suites.LayerSuite5()->AEGP_GetLayerParentComp(layer->m_EffectLayer, &compH); + result |= suites.LayerSuite5()->AEGP_GetCompNumLayers(compH, &layerNbr); + + for (s32 i = 0; i < layerNbr; ++i) + { + AEGP_ObjectType layerType = AEGP_ObjectType_NONE; + + result |= suites.LayerSuite5()->AEGP_GetCompLayerByIndex(compH, i, &layerH); + result |= suites.LayerSuite5()->AEGP_GetLayerObjectType(layerH, &layerType); + + result |= suites.LayerSuite5()->AEGP_IsVideoActive(layerH, AEGP_LTimeMode_CompTime, &AETime, &layerActive); + if (layerType == AEGP_ObjectType_LIGHT && layerActive == (A_Boolean)TRUE) + { + SLightDesc light; + AEGP_LightType type; + AEGP_StreamVal streamValColor, streamValIntensity; + + result |= suites.LightSuite2()->AEGP_GetLightType(layerH, &type); + result |= suites.StreamSuite2()->AEGP_GetLayerStreamValue(layerH, AEGP_LayerStream_COLOR, AEGP_LTimeMode_CompTime, &AETime, false, &streamValColor, null); + result |= suites.StreamSuite2()->AEGP_GetLayerStreamValue(layerH, AEGP_LayerStream_INTENSITY, AEGP_LTimeMode_CompTime, &AETime, false, &streamValIntensity, null); + + light.m_Type = type; + light.m_Color.x = streamValColor.color.redF; + light.m_Color.y = streamValColor.color.greenF; + light.m_Color.z = streamValColor.color.blueF; + light.m_Intensity = (float)(streamValIntensity.one_d) / 100.0f; + + if (light.m_Type == AEGP_LightType_PARALLEL) + { + AEGP_StreamVal streamValPos, streamValAnchor; + + result |= suites.StreamSuite2()->AEGP_GetLayerStreamValue(layerH, AEGP_LayerStream_POSITION, AEGP_LTimeMode_CompTime, &AETime, false, &streamValPos, null); + result |= suites.StreamSuite2()->AEGP_GetLayerStreamValue(layerH, AEGP_LayerStream_ANCHORPOINT, AEGP_LTimeMode_CompTime, &AETime, false, &streamValAnchor, null); + + CFloat3 direction = { (float)(streamValAnchor.three_d.x - streamValPos.three_d.x), (float)(streamValAnchor.three_d.y - streamValPos.three_d.y), (float)(streamValAnchor.three_d.z - streamValPos.three_d.z) }; + direction.Normalize(); + light.m_Direction = PKToAAE(direction); + } + else if (light.m_Type == AEGP_LightType_SPOT) + { + AEGP_StreamVal streamValPos, streamValAnchor, streamValConeAngle, streamValConeFeather; + + result |= suites.StreamSuite2()->AEGP_GetLayerStreamValue(layerH, AEGP_LayerStream_POSITION, AEGP_LTimeMode_CompTime, &AETime, false, &streamValPos, null); + CFloat3 position = { (float)(streamValPos.three_d.x), (float)(streamValPos.three_d.y), (float)(streamValPos.three_d.z) }; + light.m_Position = PKToAAE(position); +#if defined(PK_SCALE_DOWN) + light.m_Position.x = light.m_Position.x / layer->m_ScaleFactor; + light.m_Position.y = light.m_Position.y / layer->m_ScaleFactor; + light.m_Position.z = light.m_Position.z / layer->m_ScaleFactor; +#endif + result |= suites.StreamSuite2()->AEGP_GetLayerStreamValue(layerH, AEGP_LayerStream_ANCHORPOINT, AEGP_LTimeMode_CompTime, &AETime, false, &streamValAnchor, null); + result |= suites.StreamSuite2()->AEGP_GetLayerStreamValue(layerH, AEGP_LayerStream_CONE_ANGLE, AEGP_LTimeMode_CompTime, &AETime, false, &streamValConeAngle, null); + result |= suites.StreamSuite2()->AEGP_GetLayerStreamValue(layerH, AEGP_LayerStream_CONE_FEATHER, AEGP_LTimeMode_CompTime, &AETime, false, &streamValConeFeather, null); + + CFloat3 direction = { (float)(streamValAnchor.three_d.x - streamValPos.three_d.x), (float)(streamValAnchor.three_d.y - streamValPos.three_d.y), (float)(streamValAnchor.three_d.z - streamValPos.three_d.z) }; + direction.Normalize(); + light.m_Direction = PKToAAE(direction); + + light.m_Angle = (float)streamValConeAngle.one_d; + light.m_Feather = (float)(streamValConeFeather.one_d / 100.0f); + } + else if (light.m_Type == AEGP_LightType_POINT) + { + AEGP_StreamVal streamValPos; + result |= suites.StreamSuite2()->AEGP_GetLayerStreamValue(layerH, AEGP_LayerStream_POSITION, AEGP_LTimeMode_CompTime, &AETime, false, &streamValPos, null); + + CFloat3 position = { (float)(streamValPos.three_d.x), (float)(streamValPos.three_d.y), (float)(streamValPos.three_d.z) }; + light.m_Position = PKToAAE(position); +#if defined(PK_SCALE_DOWN) + light.m_Position.x = light.m_Position.x / layer->m_ScaleFactor; + light.m_Position.y = light.m_Position.y / layer->m_ScaleFactor; + light.m_Position.z = light.m_Position.z / layer->m_ScaleFactor; +#endif + } + if (!lights.PushBack(light).Valid()) + return false; + } + } + if (!PK_VERIFY(result == A_Err_NONE)) + return false; + return true; +} + +__AEGP_PK_END diff --git a/AE_GeneralPlugin/Sources/AEGP_VaultHandler.cpp b/AE_GeneralPlugin/Sources/AEGP_VaultHandler.cpp new file mode 100644 index 00000000..896827c6 --- /dev/null +++ b/AE_GeneralPlugin/Sources/AEGP_VaultHandler.cpp @@ -0,0 +1,492 @@ +//---------------------------------------------------------------------------- +// Copyright Persistant Studios, SARL. All Rights Reserved. https://www.popcornfx.com/terms-and-conditions/ +//---------------------------------------------------------------------------- +#include "ae_precompiled.h" + +#include "AEGP_VaultHandler.h" + +#include "AEGP_FileWatcher.h" +#include "AEGP_World.h" +#include "AEGP_AEPKConversion.h" +#include "AEGP_Log.h" + +#include "AEGP_AssetBaker.h" + +#if defined(PK_WINDOWS) +# include +#endif + +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +__AEGP_PK_BEGIN +//---------------------------------------------------------------------------- + +const char *CVaultHandler::k_VaultFolderMainName = "Persistant Studios/AfterEffects/Vault"; +const char *CVaultHandler::k_VaultFolderAssetsName = "Assets"; +const char *CVaultHandler::k_VaultFolderCacheName = "Cache"; +const char *CVaultHandler::k_VaultFolderLogsName = "Logs"; + +//---------------------------------------------------------------------------- + +CVaultHandler::CVaultHandler() +{ +} + +//---------------------------------------------------------------------------- + +CVaultHandler::~CVaultHandler() +{ +} + +//---------------------------------------------------------------------------- + +bool CVaultHandler::InitializeIFN() +{ + if (m_Initialized == true) + return true; + m_Initialized = true; + + m_InternalPack = File::DefaultFileSystem()->MountPack(CPopcornFXWorld::Instance().GetInternalPackPath()); + + if (!PK_VERIFY(_SetupVault())) + return false; + + CString logPath = m_VaultPathLogs / "popcorn.htm"; + + m_AELogFileListener = PK_NEW(CLogListenerFile(logPath.Data(), "popcorn-engine logfile"); + CLog::AddGlobalListener(m_AELogFileListener)); + +#if 0 + m_FileWatcher = PK_NEW(CFileWatcher()); + if (!PK_VERIFY(m_FileWatcher != null)) + return false; + m_FileWatcher->SetNotifierAdd(&CVaultHandler::FileAdded); + m_FileWatcher->SetNotifierRemove(&CVaultHandler::FileRemoved); + m_FileWatcher->SetNotifierModify(&CVaultHandler::FileChanged); + m_FileWatcher->SetNotifierRename(&CVaultHandler::FileRenamed); + + bool watchPackSucceed = m_FileWatcher->SetWatchPack(""); + + if (!watchPackSucceed) + return false; +#endif + return false; +} + +//---------------------------------------------------------------------------- + +bool CVaultHandler::ShutdownIFN() +{ + if (m_Initialized == false) + return true; + if (m_AELogFileListener != null) + { + CLog::RemoveGlobalListener(m_AELogFileListener); + m_AELogFileListener = null; + } + + return true; +} + +//---------------------------------------------------------------------------- + +void CVaultHandler::FileAdded(const CString &path) +{ + (void)path; +} + +//---------------------------------------------------------------------------- + +void CVaultHandler::FileRemoved(const CString &path) +{ + (void)path; +} + +//---------------------------------------------------------------------------- + +void CVaultHandler::FileChanged(const CString &path) +{ + (void)path; +} + +//---------------------------------------------------------------------------- + +void CVaultHandler::FileChangedRelativePath(const CString &path) +{ + (void)path; +} + +//---------------------------------------------------------------------------- + +void CVaultHandler::FileRenamed(const CString &oldPath, const CString &newPath) +{ + (void)oldPath; + (void)newPath; +} + +//---------------------------------------------------------------------------- + +bool CVaultHandler::IsBakedAssetLatestVersion(const CString &srcPath, const CString &dstPath) +{ + IFileSystem *fs = File::DefaultFileSystem(); + + if (!fs->Exists(dstPath, true)) + return false; + + SFileTimes srcTimes, dstTimes; + + fs->Timestamps(srcPath, srcTimes, true); + fs->Timestamps(dstPath, dstTimes, true); + + if (srcTimes.m_LastWriteTime > dstTimes.m_LastWriteTime) + return false; + return true; +} + +//---------------------------------------------------------------------------- + +bool CVaultHandler::LoadEffectIntoVault(const CString &srcPackPath, CString &effectPath, const CString &pkprojPath, bool &refresh) +{ + IFileSystem *fs = File::DefaultFileSystem(); + //Check if pack exist in cache + + PFilePack dstPack = GetVaultPackFromPath(srcPackPath); + CString dstPackPath = dstPack->Path(); + CString bakedName = CFilePath::StripExtension(effectPath) + ".pkb"; + CString sourceName = CFilePath::StripExtension(effectPath) + ".pkfx"; + CString sourcePath = srcPackPath / sourceName; + + if (!fs->Exists(dstPackPath, true)) + { + if (!fs->CreateDirectoryChainIFN(dstPackPath, true)) + return false; + } + if (!refresh) + { + if (IsBakedAssetLatestVersion(sourcePath, dstPackPath / bakedName)) + return true; + } + + TArray effectsPath; + + CEffectBaker baker; + + baker.Initialize(srcPackPath, dstPackPath, pkprojPath); + + CString rootDir = baker.GetSourcePackRootPath(); + if (!rootDir.Empty() && sourceName.StartsWith(rootDir)) + { + sourceName = sourceName.Extract(rootDir.Length() + 1, sourceName.Length()); + effectPath = sourceName; + } + effectsPath.PushBack(sourceName); + + baker.ReimportAssets(effectsPath); + baker.ClearBakedPaths(); + + while (baker.PopFileChanges() != 0) + { + } + baker.Clear(); + refresh = true; + return true; +} + +//---------------------------------------------------------------------------- + +CString CVaultHandler::ImportResource(const CString resourcePath) +{ + IFileSystem *fs = File::DefaultFileSystem(); + CString filename = CFilePath::ExtractFilename(resourcePath); + CString sourcePath = resourcePath; + CString targetPath = m_VaultPathAssets / filename; + + if (IsBakedAssetLatestVersion(resourcePath, targetPath)) + return targetPath; + CFilePath::Purify(sourcePath); + if (!PK_VERIFY(fs->FileCopy(sourcePath, targetPath, true))) + return null; + return targetPath; +} + +//---------------------------------------------------------------------------- + +CString CVaultHandler::BakeVectorField(const CString resourcePath, const CString targetPath, const SResourceBakeConfig &config) +{ + (void)config; + IFileSystem *fs = File::DefaultFileSystem(); + CFilePackPath filePackPath = CFilePackPath::FromPhysicalPath(resourcePath, fs); + + PFilePack srcPack = null; + if (filePackPath.Empty()) + { + srcPack = fs->MountPack(CFilePath::StripFilename(resourcePath)); + filePackPath = CFilePackPath::FromPhysicalPath(resourcePath, fs); + } + if (!filePackPath.Empty()) + { + TArray effectsPath; + + effectsPath.PushBack(CFilePath::ExtractFilename(resourcePath)); + + CEffectBaker baker; + + baker.Initialize(filePackPath.Pack()->Path(), m_VaultPathAssets, ""); + baker.ReimportAssets(effectsPath, false); + baker.ClearBakedPaths(); + + while (baker.PopFileChanges() != 0) + { + } + baker.Clear(); + } + if (srcPack != null) + fs->UnmountPack(srcPack.Get()); + return targetPath; +} + +//---------------------------------------------------------------------------- + +CString CVaultHandler::BakeMesh(const CString resourcePath, const CString targetPath, const SResourceBakeConfig &config) +{ + IFileSystem *fs = File::DefaultFileSystem(); + CFilePackPath filePackPath = CFilePackPath::FromPhysicalPath(resourcePath, fs); + bool unload = false; + CString targetExtension = ".pkmm"; + + PFilePack srcPack = null; + if (filePackPath.Empty()) + { + srcPack = fs->MountPack(CFilePath::StripFilename(resourcePath)); + filePackPath = CFilePackPath::FromPhysicalPath(resourcePath, fs); + unload = true; + } + if (!filePackPath.Empty()) + { + class CMeshCodecMessageStreamBaker : public CMeshCodecMessageStream + { + virtual void NotifyProgressMessage(const CString &msg) override // called from time to time to tell what's being loaded + { + (void)msg; +#ifdef PK_DEBUG + printf(" Mesh Importer log: %s\n", msg.Data()); // only display these in debug +#endif + }; + virtual void NotifyError(const CString &msg) override { printf(" Mesh Importer ERROR: %s\n", msg.Data()); } + virtual void NotifyWarning(const CString &msg) override { printf(" Mesh Importer WARNING: %s\n", msg.Data()); } + }; + CMessageStream outBakeReport; + CMeshCodecMessageStreamBaker notifier; + SMeshImportSettings importSettings; + + importSettings.m_ImportGeometry = true; + + importSettings.m_ImportSkeleton = true; + if (config.m_IsAnimTrack) + { + importSettings.m_ImportAnimation = true; + importSettings.m_ImportSkeleton = false; + targetExtension = ".pkan"; + } + if (config.m_IsSkeletalAnim) + { + importSettings.m_ImportAnimation = true; + importSettings.m_ImportSkeleton = true; + targetExtension = ".pksa"; + } + importSettings.m_WriteAccelSampling = true; + importSettings.m_WriteAccelUV2PC = true; + importSettings.m_WriteKdTree = true; + importSettings.m_Positions = SVStreamCode::Type_F32; + importSettings.m_Normals = SVStreamCode::Type_F32; + importSettings.m_Tangents = SVStreamCode::Type_F32; + importSettings.m_Texcoords = SVStreamCode::Type_F32; + + importSettings.m_RemapToZero = true; + + importSettings.m_ResourcePath = filePackPath.Path(); + importSettings.m_ResourceManager = Resource::DefaultManager(); + + PMeshImportOut outFbxImport = CResourceMesh::ImportFromFile(notifier, outBakeReport, &importSettings); + + if (outFbxImport != null) + { + if (!outFbxImport->Write(fs, targetPath + ".pkmm", targetPath + ".pkan", targetPath + ".pksa", outBakeReport)) + CLog::Log(PK_ERROR, "The fbx import failed"); + } + } + if (unload) + fs->UnmountPack(srcPack.Get()); + return targetPath + targetExtension; +} + +//---------------------------------------------------------------------------- + +CString CVaultHandler::CopyResource(const CString resourcePath) +{ + IFileSystem *fs = File::DefaultFileSystem(); + CString filename = CFilePath::ExtractFilename(resourcePath); + CString extension = CFilePath::ExtractExtension(filename); + CString targetPath = m_VaultPathAssets / filename;; + CString sourcePath = resourcePath; + + + if (IsBakedAssetLatestVersion(resourcePath, targetPath)) + return targetPath; + CFilePath::Purify(sourcePath); + if (!PK_VERIFY(fs->FileCopy(sourcePath, targetPath, true))) + return null; + return targetPath; +} + +//---------------------------------------------------------------------------- + +CString CVaultHandler::BakeResource(const CString resourcePath, const SResourceBakeConfig &config) +{ + IFileSystem *fs = File::DefaultFileSystem(); + CString filename = CFilePath::ExtractFilename(resourcePath); + CString extension = CFilePath::ExtractExtension(filename); + CString sourcePath = resourcePath; + + CFilePath::StripExtensionInPlace(filename); + + CString targetPath = m_VaultPathAssets / filename; + + if (!config.m_StraightCopy && extension.Compare("fbx", CaseInsensitive)) + { + CString targetExt = ".pkmm"; + if (config.m_IsAnimTrack) + targetExt = ".pkan"; + if (config.m_IsSkeletalAnim) + targetExt = ".pksa"; + if (IsBakedAssetLatestVersion(resourcePath, targetPath + targetExt)) + return targetPath + targetExt; + + return BakeMesh(resourcePath, targetPath, config); + } + if (!config.m_StraightCopy && extension.Compare("fga", CaseInsensitive)) + { + targetPath += ".pkvf"; + if (IsBakedAssetLatestVersion(resourcePath, targetPath)) + return targetPath; + + return BakeVectorField(resourcePath, targetPath, config); + } + else //Wildcard + { + targetPath += "." + extension; + + if (IsBakedAssetLatestVersion(resourcePath, targetPath)) + return targetPath; + CFilePath::Purify(sourcePath); + if (!PK_VERIFY(fs->FileCopy(sourcePath, targetPath, true))) + return null; + } + return targetPath; +} + +//---------------------------------------------------------------------------- + +PFilePack CVaultHandler::GetVaultPackFromPath(CString path) +{ + PK_ASSERT(path != null); + PK_ASSERT(!path.Empty()); + + IFileSystem *fs = File::DefaultFileSystem(); + + CString packName = CFilePath::ExtractFilename(path); + + u32 pathHash = (u32)std::hash{}(path.Data()); + CString vaultPath = m_VaultPathCache / packName + CString::Format("_%u", pathHash); + + if (fs->Exists(vaultPath, true)) + { + return fs->MountPack(vaultPath); + } + + fs->CreateDirectoryChainIFN(vaultPath, true); + + return fs->MountPack(vaultPath); +} + +//---------------------------------------------------------------------------- + +bool CVaultHandler::_SetupVault() +{ + CString localPathString; +#if defined(PK_WINDOWS) + + aechar_t *userFolder = null; + HRESULT result = 0; + + result = SHGetKnownFolderPath(FOLDERID_LocalAppData, 0, NULL, (PWSTR*)&userFolder); + if (FAILED(result)) + return false; + WCharToCString(userFolder, &localPathString); + CoTaskMemFree(static_cast(userFolder)); + +#elif defined(PK_MACOSX) + const char *homeFolder = getenv("HOME"); + if (!PK_VERIFY(homeFolder != null)) + return false; + localPathString = CString(homeFolder) / "Library" / "Application Support"; +#endif + CFilePath::Purify(localPathString); + + IFileSystem *fs = File::DefaultFileSystem(); + + m_VaultPathRoot = localPathString + "/"+ k_VaultFolderMainName; + m_VaultPathAssets = m_VaultPathRoot + "/" + k_VaultFolderAssetsName; + m_VaultPathCache = m_VaultPathRoot + "/" + k_VaultFolderCacheName; + m_VaultPathLogs = m_VaultPathRoot + "/" + k_VaultFolderLogsName; + + if (!fs->CreateDirectoryChainIFN(m_VaultPathRoot, true) || + !fs->CreateDirectoryChainIFN(m_VaultPathAssets, true) || + !fs->CreateDirectoryChainIFN(m_VaultPathCache, true) || + !fs->CreateDirectoryChainIFN(m_VaultPathLogs, true)) + return false; + + class CPKFolderWalker : public CFileDirectoryWalker + { + public: + TArray m_Folders; + + CPKFolderWalker(const CString &rootDir) + : CFileDirectoryWalker(rootDir, IgnoreVirtualFS) + { + } + + virtual bool DirectoryNotifier(const CFilePack *, const char *fullPath, u32 ) override + { + m_Folders.PushBack(fullPath); + return false; + } + + }; + + CPKFolderWalker walker(m_VaultPathCache); + + walker.Walk(); + + for (u32 i = 0; i < walker.m_Folders.Count(); ++i) + { + fs->MountPack(walker.m_Folders[i]); + } + + fs->MountPack(m_VaultPathAssets); + return true; +} + +//---------------------------------------------------------------------------- + +__AEGP_PK_END diff --git a/AE_GeneralPlugin/Sources/AEGP_WinFileDialog.cpp b/AE_GeneralPlugin/Sources/AEGP_WinFileDialog.cpp new file mode 100644 index 00000000..3c79070c --- /dev/null +++ b/AE_GeneralPlugin/Sources/AEGP_WinFileDialog.cpp @@ -0,0 +1,183 @@ +//---------------------------------------------------------------------------- +// Copyright Persistant Studios, SARL. All Rights Reserved. https://www.popcornfx.com/terms-and-conditions/ +//---------------------------------------------------------------------------- +#include + +#if defined(PK_WINDOWS) + +#include "AEGP_WinFileDialog.h" + +#include +#include + +#ifndef WIN32_LEAN_AND_MEAN +#define WIN32_LEAN_AND_MEAN +#endif + +#include +#include +#include +#include + +#include +#include + +#include + +#include + +#include "AEGP_World.h" + +//---------------------------------------------------------------------------- + +class CDialogEventHandler : public IFileDialogEvents, + public IFileDialogControlEvents +{ +public: + // IUnknown methods + IFACEMETHODIMP QueryInterface(REFIID riid, void** ppv) + { +#pragma warning(disable:4838) + static const QITAB qit[] = { + QITABENT(CDialogEventHandler, IFileDialogEvents), + QITABENT(CDialogEventHandler, IFileDialogControlEvents), + { 0 }, + }; + return QISearch(this, qit, riid, ppv); + +#pragma warning(default:4838) + } + + IFACEMETHODIMP_(ULONG) AddRef() + { + return InterlockedIncrement(&_cRef); + } + + IFACEMETHODIMP_(ULONG) Release() + { + long cRef = InterlockedDecrement(&_cRef); + if (!cRef) + delete this; + return cRef; + } + + // IFileDialogEvents methods + IFACEMETHODIMP OnFileOk(IFileDialog *) { return S_OK; }; + IFACEMETHODIMP OnFolderChange(IFileDialog *) { return S_OK; }; + IFACEMETHODIMP OnFolderChanging(IFileDialog *, IShellItem *) { return S_OK; }; + IFACEMETHODIMP OnHelp(IFileDialog *) { return S_OK; }; + IFACEMETHODIMP OnSelectionChange(IFileDialog *) { return S_OK; }; + IFACEMETHODIMP OnShareViolation(IFileDialog *, IShellItem *, FDE_SHAREVIOLATION_RESPONSE *) { return S_OK; }; + IFACEMETHODIMP OnTypeChange(IFileDialog *) { return S_OK; }; + IFACEMETHODIMP OnOverwrite(IFileDialog *, IShellItem *, FDE_OVERWRITE_RESPONSE *) { return S_OK; }; + + // IFileDialogControlEvents methods + IFACEMETHODIMP OnItemSelected(IFileDialogCustomize *, DWORD, DWORD) { return S_OK; }; + IFACEMETHODIMP OnButtonClicked(IFileDialogCustomize *, DWORD) { return S_OK; }; + IFACEMETHODIMP OnCheckButtonToggled(IFileDialogCustomize *, DWORD, BOOL) { return S_OK; }; + IFACEMETHODIMP OnControlActivating(IFileDialogCustomize *, DWORD) { return S_OK; }; + + CDialogEventHandler() : _cRef(1) { }; +private: + ~CDialogEventHandler() { }; + long _cRef; +}; + +//---------------------------------------------------------------------------- + +// Instance creation helper +HRESULT CDialogEventHandler_CreateInstance(REFIID riid, void **ppv) +{ + *ppv = NULL; + CDialogEventHandler *pDialogEventHandler = new (std::nothrow) CDialogEventHandler(); + HRESULT hr = pDialogEventHandler ? S_OK : E_OUTOFMEMORY; + if (SUCCEEDED(hr)) + { + hr = pDialogEventHandler->QueryInterface(riid, ppv); + pDialogEventHandler->Release(); + } + return hr; +} + +//---------------------------------------------------------------------------- + +HRESULT WinBasicFileOpen(SWinFileOpenData &data) +{ + IFileDialog *pfd = NULL; + AEGP_SuiteHandler suites(AEGPPk::CPopcornFXWorld::Instance().GetAESuites()); + HWND winHandle = null; + + suites.UtilitySuite6()->AEGP_GetMainHWND(&winHandle); + + HRESULT hr = CoCreateInstance(CLSID_FileOpenDialog, + NULL, + CLSCTX_INPROC_SERVER, + IID_PPV_ARGS(&pfd)); + if (SUCCEEDED(hr)) + { + IFileDialogEvents *pfde = NULL; + hr = CDialogEventHandler_CreateInstance(IID_PPV_ARGS(&pfde)); + if (SUCCEEDED(hr)) + { + DWORD dwCookie; + hr = pfd->Advise(pfde, &dwCookie); + if (SUCCEEDED(hr)) + { + DWORD dwFlags; + hr = pfd->GetOptions(&dwFlags); + if (SUCCEEDED(hr)) + { + hr = pfd->SetOptions(dwFlags | FOS_FORCEFILESYSTEM); + if (SUCCEEDED(hr)) + { + TArray filters; + for (u32 i = 0; i < data.m_Filters.Count(); i++) + filters.PushBack(data.m_Filters[i].m_Spec); + + hr = pfd->SetFileTypes(filters.Count(), filters.RawDataPointer()); + if (SUCCEEDED(hr)) + { + hr = pfd->SetFileTypeIndex(0); + if (SUCCEEDED(hr)) + { + hr = pfd->SetDefaultExtension(L"*.pkproj"); + if (SUCCEEDED(hr)) + { + hr = pfd->Show(winHandle); + if (SUCCEEDED(hr)) + { + IShellItem *psiResult; + hr = pfd->GetResult(&psiResult); + if (SUCCEEDED(hr)) + { + wchar_t *pszFilePath = NULL; + hr = psiResult->GetDisplayName(SIGDN_FILESYSPATH, &pszFilePath); + if (SUCCEEDED(hr)) + { + char result[1024]; + CString stringResult; + wcstombs(result, pszFilePath, 1024); + stringResult = result; + + data.m_Cb(stringResult); + } + psiResult->Release(); + } + } + } + } + } + } + } + pfd->Unadvise(dwCookie); + } + pfde->Release(); + } + pfd->Release(); + } + return hr; +} + +//---------------------------------------------------------------------------- + +#endif diff --git a/AE_GeneralPlugin/Sources/AEGP_WinSystem.cpp b/AE_GeneralPlugin/Sources/AEGP_WinSystem.cpp new file mode 100644 index 00000000..3f44a946 --- /dev/null +++ b/AE_GeneralPlugin/Sources/AEGP_WinSystem.cpp @@ -0,0 +1,216 @@ +//---------------------------------------------------------------------------- +// Copyright Persistant Studios, SARL. All Rights Reserved. https://www.popcornfx.com/terms-and-conditions/ +//---------------------------------------------------------------------------- +#include + +#include "AEGP_WinSystem.h" +#include "PopcornFX_Suite.h" + +#include "AEGP_System.h" + +#include + +#if defined(PK_WINDOWS) + +#include +#include +#include +#include +#include +#include +#include +#include + + +__AEGP_PK_BEGIN + +//---------------------------------------------------------------------------- + +CString CWinSystemHelper::GetLastErrorAsString() +{ + TArray error; + return GetLastErrorAsString(error); +} + +//---------------------------------------------------------------------------- + +CString CWinSystemHelper::GetLastErrorAsString(TArray &ignore) +{ + //Get the error message ID, if any. + DWORD errorMessageID = ::GetLastError(); + if (errorMessageID == 0 || ignore.Contains(errorMessageID)) + return CString(); + + LPSTR messageBuffer = nullptr; + + //Ask Win32 to give us the string version of that message ID. + //The parameters we pass in, tell Win32 to create the buffer that holds the message for us (because we don't yet know how long the message string will be). + size_t size = FormatMessageA(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, + NULL, errorMessageID, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPSTR)&messageBuffer, 0, NULL); + + //Copy the error message into a std::string. + CString message(messageBuffer, (u32)size); + + //Free the Win32's string's buffer. + LocalFree(messageBuffer); + + return message; +} + +//---------------------------------------------------------------------------- + +CString CWinSystemHelper::_GetWindowsInstallDir() +{ + CString appFolderPath; + + aechar_t dstPath[MAX_PATH]; + if (::ExpandEnvironmentStringsW(L"%ProgramW6432%", (LPWSTR)dstPath, PK_ARRAY_COUNT(dstPath)) != 0) + { + std::string dest; + dstPath[PK_ARRAY_COUNT(dstPath) - 1] = 0; + WCharToString(dstPath, &dest); + appFolderPath = dest.c_str(); + appFolderPath = appFolderPath + (appFolderPath.EndsWith("/") ? "" : "/") + "Persistant Studios/"; + } + return appFolderPath; +} + +//---------------------------------------------------------------------------- + +TArray CWinSystemHelper::_FindInstalledVersions(const CString &baseSearchPath) +{ + WIN32_FIND_DATA ffd; + TCHAR szDir[MAX_PATH]; + HANDLE hFind = INVALID_HANDLE_VALUE; + DWORD dwError = 0; + + // we expect 'baseSearchPath' to be the root 'Persistant Studios' install dir, + // inside which are located PopcornFX editor executables of the form 'PopcornFX-X.Y/Binaries_Release/PK-Editor.exe' + TArray paths; + + // Prepare string for use with FindFile functions. First, copy the + // string to a buffer, then append '\*' to the directory name. + StringCchCopy(szDir, MAX_PATH, baseSearchPath.Data()); + StringCchCat(szDir, MAX_PATH, TEXT("\\*")); + + // Find the first file in the directory. + hFind = FindFirstFile(szDir, &ffd); + + if (INVALID_HANDLE_VALUE == hFind) + { + CString error = GetLastErrorAsString(); + CLog::Log(PK_ERROR, "%s", error.Data()); + return paths; + } + + // List all the files in the directory with some info about them. + do + { + if (ffd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) + { + const CString entryName = ffd.cFileName; + if (entryName.StartsWith("PopcornFX-")) + { + const CString editorVersionDir = baseSearchPath + entryName; + const CString editorExecPathV2 = editorVersionDir + "/bin/PK-Editor.exe"; + const CString editorExecPathUn = editorVersionDir + "/Uninstall.exe"; + + DWORD dwAttrib = GetFileAttributes(TEXT(editorExecPathV2.Data())); + if (dwAttrib != INVALID_FILE_ATTRIBUTES) + { + const SDllVersion version = PKTKGetFileVersionInfo(editorExecPathV2.Data()); + if (!paths.PushBack(SEditorExecutable(editorExecPathV2, "", SEngineVersion(version.Major, version.Minor, version.Patch, version.RevID))).Valid()) + { + CLog::Log(PK_ERROR, "TArray Alloc Failed"); + return paths; + } + + } + } + } + } while (FindNextFile(hFind, &ffd) != 0); + + dwError = GetLastError(); + if (dwError != ERROR_NO_MORE_FILES) + { + CString error = GetLastErrorAsString(); + CLog::Log(PK_ERROR, "%s", error.Data()); + } + + FindClose(hFind); + return paths; +} + +//---------------------------------------------------------------------------- + +SEditorExecutable CWinSystemHelper::GetMatchingEditor(const SEngineVersion &version) +{ + PK_ASSERT(version.Major() == 2); + + CGuid bestVerPatch; + CGuid bestVer; + + TArray execList = _FindInstalledVersions(_GetWindowsInstallDir()); + for (u32 i = 0; i < execList.Count(); i++) + { + const SEditorExecutable &execVer = execList[i]; + + if (execVer.m_Version.Equal_IgnoreRevID(version)) + { + // Exact version, always the best option. + // This assumes there's always a single version installed at the same patch, + // and there can't be multiple versions with the same major.minor.patch version. + // Otherwise, when there are multiple similar versions installed, + // it'll take the first one in the list. Do we care? + // Do we want to handle that better and actually return the one with + // the closest revid ? + CLog::Log(PK_INFO, "Running exact match editor : %s", execVer.m_BinaryPath.Data()); + return execVer; // Exact version + } + if (execVer.m_Version.Equal_IgnorePatch(version)) + { + // Within the same minor version, this is the best candidate + if (!bestVerPatch.Valid()) + bestVerPatch = i; + else + { + const u32 patchPrev = execList[bestVerPatch].m_Version.Patch(); + const u32 patchNew = execVer.m_Version.Patch(); + { + if (patchNew >= patchPrev) + bestVerPatch = i; + } + } + } + else if (execVer.m_Version >= version) + { + // Minor version higher than project + if (!bestVer.Valid()) + bestVer = i; + else + { + if (execVer.m_Version < execList[bestVer].m_Version) // if it's closer to the target project version + bestVer = i; + } + } + } + if (bestVerPatch.Valid()) + return execList[bestVerPatch]; + if (bestVer.Valid()) + return execList[bestVer]; + + SEditorExecutable ret; +#if _DEBUG + ret.m_BinaryPath = "%PK_SDK_ROOT%\\Tools\\Poped\\build_vs2019\\PK-Editor_d.exe"; +#else + ret.m_BinaryPath = "%PK_SDK_ROOT%\\Tools\\Poped\\build_vs2019\\PK-Editor_r.exe"; +#endif + CLog::Log(PK_INFO, "Running default path dev: %s", ret.m_BinaryPath.Data()); + return ret; +} + +//---------------------------------------------------------------------------- + +__AEGP_PK_END + +#endif // PK_WINDOWS diff --git a/AE_GeneralPlugin/Sources/AEGP_World.cpp b/AE_GeneralPlugin/Sources/AEGP_World.cpp new file mode 100644 index 00000000..2786e0ae --- /dev/null +++ b/AE_GeneralPlugin/Sources/AEGP_World.cpp @@ -0,0 +1,2674 @@ +//---------------------------------------------------------------------------- +// Copyright Persistant Studios, SARL. All Rights Reserved. https://www.popcornfx.com/terms-and-conditions/ +//---------------------------------------------------------------------------- +#include "ae_precompiled.h" + +#include "AEGP_World.h" + +#include "AEGP_PopcornFXPlugins.h" +#include "AEGP_Scene.h" +#include "AEGP_AEPKConversion.h" + +#include "AEGP_AssetBaker.h" +#include "AEGP_Log.h" + +//Suite +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +//StartUp Runtime +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include // for PRNG +#include // for CPlane in CParticleSceneBasic + +#include +#include + +//RHI +#include +#include +#include +//Sample +#include +#include + +#include + +//AE +#include +#include + +#include "AEGP_LayerHolder.h" +#include "AEGP_UpdateAEState.h" + +#include "Panels/AEGP_PanelQT.h" + +#include "AEGP_System.h" + +#include +#include + +#include + +//---------------------------------------------------------------------------- + +PK_LOG_MODULE_DECLARE(); + +template <> +const A_char* SuiteTraits::i_name = kAEGPPanelSuite; +template <> +const int32_t SuiteTraits::i_version = kAEGPPanelSuiteVersion1; + +template <> +const A_char* SuiteTraits::i_name = kPFAppSuite; +template <> +const int32_t SuiteTraits::i_version = kPFAppSuiteVersion4; + +//---------------------------------------------------------------------------- + +__AEGP_PK_BEGIN + +//TODO OS Specific code +static PAAERenderContext s_AAEThreadRenderContexts = null; +static PKSample::CShaderLoader *s_ShaderLoader = null; + +//---------------------------------------------------------------------------- + +const char *SAEPreferenciesKeys::GetGraphicsApiAsCharPtr(EApiValue value) +{ + return kApiNames[value]; + +} + +//---------------------------------------------------------------------------- + +const char *SAEPreferenciesKeys::GetGraphicsApiAsCharPtr(RHI::EGraphicalApi value) +{ + return GetGraphicsApiAsCharPtr(RHIApiToAEApi(value)); +} + +//---------------------------------------------------------------------------- +// +//---------------------------------------------------------------------------- + +HBO_CLASS_DEFINITION_BEGIN(CAEPProjectProperties) + .HBO_FIELD_DEFINITION(ProjectName) + .HBO_FIELD_DEFINITION(LayerProperties) +HBO_CLASS_DEFINITION_END + +CAEPProjectProperties::CAEPProjectProperties() + : HBO_CONSTRUCT(CAEPProjectProperties) +{ +} + +//---------------------------------------------------------------------------- + +CAEPProjectProperties::~CAEPProjectProperties() +{ +} + +//---------------------------------------------------------------------------- +// +//---------------------------------------------------------------------------- + +CPopcornFXWorld *CPopcornFXWorld::m_Instance = null; + +CPopcornFXWorld::CPopcornFXWorld() + : m_Initialized(false) + , m_AAETreadID(0) + , m_GraphicsApi(RHI::GApi_Null) + , m_AELogFileListener(null) +{ +} + +//---------------------------------------------------------------------------- + +CPopcornFXWorld::~CPopcornFXWorld() +{ + if (s_AAEThreadRenderContexts != null) + { + s_AAEThreadRenderContexts->Destroy(); + s_AAEThreadRenderContexts = null; + } + PK_SAFE_DELETE(s_ShaderLoader); +} + +//---------------------------------------------------------------------------- + +CPopcornFXWorld &CPopcornFXWorld::Instance() +{ + if (CPopcornFXWorld::m_Instance == null) + { + m_Instance = new CPopcornFXWorld(); + } + return *m_Instance; +} + +//---------------------------------------------------------------------------- + +static Threads::PAbstractPool _CreateCustomThreadPool() +{ + bool success = true; + CThreadManager::EPriority workersPriority = CThreadManager::Priority_High; + PWorkerThreadPool pool = PK_NEW(CWorkerThreadPool); + + if (PK_VERIFY(pool != null)) + { + // Let the OS shedule our workers + // leave 2 core for main thread and render thread + u32 processorCount = PKMin(PKMax(CPU::Caps().ProcessAffinity().NumBitsSet(), (u32)4) - (u32)3, (u32)12); + + CPopcornFXWorld::Instance().SetWorkerCount(processorCount); + success = pool->AddFullAffinityWorkers(processorCount, CPU::Caps().ProcessAffinity(), workersPriority); + + if (!success) + return null; + + pool->StartWorkers(); + } + return pool; +} + +//---------------------------------------------------------------------------- + +bool CPopcornFXWorld::Setup(SPBasicSuite *pica_basicP, AEGP_PluginID id) +{ + PK_SCOPEDLOCK(m_Lock); + m_AEGPID = id; + m_Suites = pica_basicP; + + AEGP_SuiteHandler suites(m_Suites); + A_Err err = A_Err_NONE; + // AE SETUP + { + AEGP_InstalledEffectKey key = AEGP_InstalledEffectKey_NONE; + u32 effectInstalled; + A_char effectName[AEGP_MAX_EFFECT_MATCH_NAME_SIZE] = { '\0' }; + u32 pluginsFound = 0; + + suites.EffectSuite4()->AEGP_GetNumInstalledEffects((A_long*)&effectInstalled); + + for (u32 i = 0; i < effectInstalled; ++i) + { + suites.EffectSuite4()->AEGP_GetNextInstalledEffect(key, &key); + suites.EffectSuite4()->AEGP_GetEffectMatchName(key, effectName); + + if (strcmp(effectName, "ADBE PopcornFX Emitter") == 0) + { + m_PKInstalledPluginKeys[EPKChildPlugins::EMITTER] = key; + ++pluginsFound; + } + else if (strcmp(effectName, "ADBE PopcornFX Attribute") == 0) + { + m_PKInstalledPluginKeys[EPKChildPlugins::ATTRIBUTE] = key; + ++pluginsFound; + } + else if (strcmp(effectName, "ADBE PopcornFX Sampler") == 0) + { + m_PKInstalledPluginKeys[EPKChildPlugins::SAMPLER] = key; + ++pluginsFound; + } + + if (pluginsFound == EPKChildPlugins::_PLUGIN_COUNT) + break; + } + PK_RELEASE_ASSERT(pluginsFound == EPKChildPlugins::_PLUGIN_COUNT); + } + + //POPCORN FX INIT + SDllVersion engineVersion; + CPKKernel::Config configKernel; + + configKernel.m_CreateThreadPool = &_CreateCustomThreadPool; + + if (engineVersion.Major != PK_VERSION_MAJOR || engineVersion.Minor != PK_VERSION_MINOR) + { + PK_ASSERT_NOT_REACHED(); + } + + if (!CPKKernel::Startup(engineVersion, configKernel) || + !CPKBaseObject::Startup(engineVersion, CPKBaseObject::Config()) || + !CPKEngineUtils::Startup(engineVersion, CPKEngineUtils::Config()) || + !CPKCompiler::Startup(engineVersion, CPKCompiler::Config()) || + !CPKGeometrics::Startup(engineVersion, CPKGeometrics::Config()) || + !CPKImaging::Startup(engineVersion, CPKImaging::Config()) || + !CPKParticles::Startup(engineVersion, CPKParticles::Config()) || + !ParticleToolbox::Startup() || + !CPKRHI::Startup(engineVersion, CPKRHI::Config()) || + !CPKRenderHelpers::Startup(engineVersion, CPKRenderHelpers::Config()) || + !CPKSample::Startup(engineVersion, CPKSample::Config()) || // Only necessary if your engine links/relies on PKSample + !PK_VERIFY(Kernel::CheckStaticConfigFlags(Kernel::g_BaseStaticConfig, SKernelConfigFlags()))) + { + return false; + } + + PK_LOG_MODULE_INIT_START; + + CAEPProjectProperties::RegisterHandler(); + CLayerProperty::RegisterHandler(); + CGraphicOverride::RegisterHandler(); + CEditorAssetEffect::RegisterHandler(); + + PK_LOG_MODULE_INIT_END; + + CAELog::SetPKLogState(true); + +#if 0 + _GetAEPath(AEGP_GetPathTypes_PLUGIN, m_PluginPath); < --Not implemented by AE +#endif + if (!PK_VERIFY(_GetAEPath(AEGP_GetPathTypes_USER_PLUGIN, m_UserPluginPath)) || + !PK_VERIFY(_GetAEPath(AEGP_GetPathTypes_ALLUSER_PLUGIN, m_AllUserPluginPath)) || + !PK_VERIFY(_GetAEPath(AEGP_GetPathTypes_APP, m_AEPath))) + return false; + + CFilePath::Purify(m_AEPath); + + CCoordinateFrame::SetupFrame(ECoordinateFrame::Frame_User1, EAbsoluteAxis::Axis_Right, EAbsoluteAxis::Axis_Down, EAbsoluteAxis::Axis_Forward); + CCoordinateFrame::SetGlobalFrame(ECoordinateFrame::Frame_User1); + + if (!PK_VERIFY(PopcornRegisterPlugins(EPlugin_Default | EPlugin_MeshCodecFBX) == true)) + return CAELog::TryLogErrorWindows("Could not load PopcornFX plugins"); + + AEGP_PersistentBlobH blobH = NULL; + AEGP_PersistentDataSuite4 *persistentDataSuite = suites.PersistentDataSuite4(); + + if (persistentDataSuite != null) + { + err |= persistentDataSuite->AEGP_GetApplicationBlob(AEGP_PersistentType_MACHINE_SPECIFIC, &blobH); + if (err == A_Err_NONE && blobH != null) + { + u32 targetApi; +#if defined(PK_WINDOWS) + A_long defaultApi = EApiValue::D3D11; +#elif defined(PK_MACOSX) + A_long defaultApi = EApiValue::Metal; +#endif + err |= persistentDataSuite->AEGP_GetLong(blobH, + SAEPreferenciesKeys::kSection, + SAEPreferenciesKeys::kApi, + defaultApi, + (A_long*)&targetApi); + if (err == A_Err_NONE) + { + m_GraphicsApi = AEApiToRHIApi(static_cast(targetApi)); + } + } + } + if (!PK_VERIFY(err == A_Err_NONE)) + return false; + + CPanelBaseGUI *panel = CPanelBaseGUI::GetInstance(); + if (!PK_VERIFY(panel->InitializeIFN())) + return false; + + return true; +} + +//---------------------------------------------------------------------------- + +bool CPopcornFXWorld::FetchAEProject() +{ + AEGP_SuiteHandler suites(m_Suites); + A_Err err = A_Err_NONE; + A_long numProj = 0; + + err |= suites.ProjSuite6()->AEGP_GetNumProjects(&numProj); + + if (numProj > 0) + { + AEGP_ProjectH projPH; + + err |= suites.ProjSuite6()->AEGP_GetProjectByIndex(0, &projPH); + + if (err == A_Err_NONE && projPH != null) + { + AEGP_MemHandle handle; + aechar_t *retrievedPath; + CString path = ""; + + err |= suites.ProjSuite6()->AEGP_GetProjectPath(projPH, &handle); + err |= suites.MemorySuite1()->AEGP_LockMemHandle(handle, reinterpret_cast(&retrievedPath)); + + WCharToCString(retrievedPath, &path); + + err |= suites.MemorySuite1()->AEGP_UnlockMemHandle(handle); + err |= suites.MemorySuite1()->AEGP_FreeMemHandle(handle); + if (path != null) + { + m_AEProjectFilename = CFilePath::ExtractFilename(path.Data()); + CFilePath::StripExtensionInPlace(m_AEProjectFilename); + path = CFilePath::StripFilename(path.Data()); + CFilePath::Purify(path); + bool newPath = false; + + //Create log file in AEP directory + if (m_AEProjectPath != path) + { + newPath = true; + m_AEProjectPath = path; + + CString logPath = path / "popcorn.htm"; + + if (m_AELogFileListener != null) + { + CLog::RemoveGlobalListener(m_AELogFileListener); + m_AELogFileListener = null; + } + m_AELogFileListener = PK_NEW(CLogListenerFile(path.Data(), "popcorn-engine logfile"); + CLog::AddGlobalListener(m_AELogFileListener)); + } + //CreateINF Project conf file or reload it if AEP changed + if (m_ProjectConfFile == null || newPath) + { + IFileSystem *fileSystem = File::DefaultFileSystem(); + + if (m_ProjectPack != null) + fileSystem->UnmountPack(m_ProjectPack.Get()); + if (m_ProjectConfFile != null) + { + m_ProjectConfFile->Unload(); + for (auto *layers : m_Layers) + layers->m_LayerProperty = null; + } + + CString projectPropFilename = m_AEProjectFilename + ".pkbo"; + + m_ProjectPack = fileSystem->MountPack(path); + m_ProjectConfFile = HBO::g_Context->LoadFile_AndCreateIFN_Pure(projectPropFilename.View(), false); + + } + if (m_ProjectConfFile != null) + { + PAEPProjectProperties projectProp = m_ProjectConfFile->FindFirstOf(); + + if (projectProp != null) + { + if (!projectProp->ProjectName().Compare(m_AEProjectFilename))//project change: unload file and let the next frame recreate it + { + m_ProjectConfFile->Unload(); + m_ProjectConfFile = null; + } + } + else //or a new project + { + projectProp = HBO::g_Context->NewObject(m_ProjectConfFile.Get()); + projectProp->SetProjectName(m_AEProjectFilename); + + WriteProjectFileModification(); + } + m_ProjectProperty = projectProp; + } + } + } + } + if (!PK_VERIFY(err == A_Err_NONE)) + return false; + return true; +} + +//---------------------------------------------------------------------------- + +bool CPopcornFXWorld::_GetAEPath(AEGP_GetPathTypes type, CString &dst) +{ + AEGP_MemHandle handle; + A_Err err = A_Err_NONE; + aechar_t *retrievedPath; + AEGP_SuiteHandler suites(m_Suites); + + err = suites.UtilitySuite6()->AEGP_GetPluginPaths(m_AEGPID, type, &handle); + if (!PK_VERIFY(err == A_Err_NONE)) + return false; + suites.MemorySuite1()->AEGP_LockMemHandle(handle, reinterpret_cast(&retrievedPath)); + + dst.Clear(); + WCharToCString(retrievedPath, &dst); + + err |= suites.MemorySuite1()->AEGP_UnlockMemHandle(handle); + err |= suites.MemorySuite1()->AEGP_FreeMemHandle(handle); + + if (!PK_VERIFY(err == A_Err_NONE)) + return false; + return true; +} + +//---------------------------------------------------------------------------- + +bool CPopcornFXWorld::SetCommandHandle(AEGP_Command &command, const char *name) +{ + m_CommandName = name; + m_Command = command; + return true; +} + +//---------------------------------------------------------------------------- + +AEGP_PluginID CPopcornFXWorld::GetPluginID() +{ + return m_AEGPID; +} + +//---------------------------------------------------------------------------- + +SPBasicSuite *CPopcornFXWorld::GetAESuites() +{ + return m_Suites; +} + +//---------------------------------------------------------------------------- + +RHI::EGraphicalApi CPopcornFXWorld::GetRenderApi() +{ + PK_ASSERT(m_GraphicsApi != RHI::GApi_Null); + return m_GraphicsApi; +} + +//---------------------------------------------------------------------------- + +void CPopcornFXWorld::SetRenderApi(EApiValue AEGraphicsApi) +{ + A_Err err = A_Err_NONE; + AEGP_SuiteHandler suites(m_Suites); + AEGP_PersistentBlobH blobH = NULL; + AEGP_PersistentDataSuite4 *persistentDataSuite = suites.PersistentDataSuite4(); + + if (persistentDataSuite != null) + { + err |= persistentDataSuite->AEGP_GetApplicationBlob(AEGP_PersistentType_MACHINE_SPECIFIC, &blobH); + if (err == A_Err_NONE && blobH != null) + { + err |= persistentDataSuite->AEGP_SetLong(blobH, + SAEPreferenciesKeys::kSection, + SAEPreferenciesKeys::kApi, + (A_long)AEGraphicsApi); + PK_ASSERT(err == A_Err_NONE); + } + } + CAELog::TryLogInfoWindows("Graphics Api changed, restart After Effects to apply change."); +} + +//---------------------------------------------------------------------------- + +bool CPopcornFXWorld::InitializeIFN(SAAEIOData &AAEData) +{ + (void)AAEData; + FetchAEProject(); + if (m_Initialized == true) + return true; + PK_SCOPEDLOCK(m_Lock); + + m_ClassName = "PKPluginInterface"; + + m_VaultHandler.InitializeIFN(); + m_Initialized = true; + for (u32 i = 0; i < __Effect_Parameters_Count; ++i) + CAEUpdater::s_EmitterIndexes[i] = i; + for (u32 i = 0; i < __Attribute_Parameters_Count; ++i) + CAEUpdater::s_AttributeIndexes[i] = i; + for (u32 i = 0; i < __AttributeSamplerType_Parameters_Count; ++i) + CAEUpdater::s_SamplerIndexes[i] = i; + return true; +} + +//---------------------------------------------------------------------------- + +bool CPopcornFXWorld::ShutdownIFN() +{ + bool result = true; + + m_VaultHandler.ShutdownIFN(); + { + PK_SCOPEDLOCK(m_Lock); + if (m_Panel) + { + m_Panel->DestroyInstance(); + m_Panel = null; + } + + for (s32 j = m_Layers.Count() - 1; j >= 0; --j) + { + SLayerHolder &layer = *m_Layers[j]; + + result = layer.Clear(m_Suites); + PK_ASSERT(result); + PK_DELETE(m_Layers[j]); + } + m_Layers.Clear(); + HBO::g_Context->UnloadAllFiles(); + + CAAEScene::ShutdownPopcornFX(); + m_Suites = null; + if (m_AAETreadID.Count() != 0) + { + for (u32 i = 0; i < m_AAETreadID.Count(); ++i) + { + PopcornFX::CThreadManager::UnsafeUnregisterUserThread(m_AAETreadID[i]); + } + m_AAETreadID.Clear(); + } + if (m_AELogFileListener != null) + { + CLog::RemoveGlobalListener(m_AELogFileListener); + m_AELogFileListener = null; + } + IFileSystem *fileSystem = File::DefaultFileSystem(); + if (PK_VERIFY(fileSystem != null)) + fileSystem->UnmountAllPacks(); + m_Initialized = false; + } + delete m_Instance; + + PopcornUnregisterPlugins(); + CAELog::SetPKLogState(false); + + PK_LOG_MODULE_RELEASE_START; + + CAEPProjectProperties::UnregisterHandler(); + CLayerProperty::UnregisterHandler(); + CGraphicOverride::UnregisterHandler(); + CEditorAssetEffect::UnregisterHandler(); + + PK_LOG_MODULE_RELEASE_END; + + CPKSample::Shutdown(); + CPKRenderHelpers::Shutdown(); + CPKRHI::Shutdown(); + ParticleToolbox::Shutdown(); + CPKParticles::Shutdown(); + CPKImaging::Shutdown(); + CPKGeometrics::Shutdown(); + CPKCompiler::Shutdown(); + CPKEngineUtils::Shutdown(); + CPKBaseObject::Shutdown(); + CPKKernel::Shutdown(); + return result; +} + +//---------------------------------------------------------------------------- + +void CPopcornFXWorld::SetProfilingState(bool state) +{ +#if (KR_PROFILER_ENABLED != 0) + Profiler::CProfiler *profiler = Profiler::MainEngineProfiler(); + if (profiler == null) + return; + profiler->GrabCallstacks(false); + profiler->Activate(state); + profiler->Reset(); + + if (!state) + { + CString path = m_VaultHandler.VaultPathRoot() / "profilerReport.pkpr"; + CDynamicMemoryStream stream = CDynamicMemoryStream(); + Profiler::CProfilerReport report; + profiler->BuildReport(&report); + Profiler::WriteProfileReport(report, stream); + FILE *f = fopen(path.Data(), "wb"); + if (f != null) + { + u32 size = 0; + u8 *buffer = stream.ExportDataAndClose(size); + fwrite(buffer, size, 1, f); + fclose(f); + PK_FREE(buffer); + } + else + CLog::Log(PK_ERROR, "Failed to write profile report to %s", path.Data()); + stream.Close(); + } +#endif +} + +//---------------------------------------------------------------------------- + +void CPopcornFXWorld::SetParametersIndexes(const int *indexes, EPKChildPlugins plugin) +{ + if (plugin == EPKChildPlugins::EMITTER) + { + for (u32 i = 0; i < __Effect_Parameters_Count; ++i) + { + CAEUpdater::s_EmitterIndexes[i] = indexes[i]; + PK_ASSERT(CAEUpdater::s_EmitterIndexes[i] >= 0); + } + } + else if (plugin == EPKChildPlugins::ATTRIBUTE) + { + for (u32 i = 0; i < __Attribute_Parameters_Count; ++i) + { + CAEUpdater::s_AttributeIndexes[i] = indexes[i]; + PK_ASSERT(CAEUpdater::s_AttributeIndexes[i] >= 0); + } + } + else if (plugin == EPKChildPlugins::SAMPLER) + { + for (u32 i = 0; i < __AttributeSamplerType_Parameters_Count; ++i) + { + CAEUpdater::s_SamplerIndexes[i] = indexes[i]; + PK_ASSERT(CAEUpdater::s_SamplerIndexes[i] >= 0); + } + } +} + +//---------------------------------------------------------------------------- + +bool CPopcornFXWorld::SetDefaultLayerPosition(SAAEIOData& AAEData, AEGP_LayerH layer) +{ + if (layer == null) + return false; + + AEGP_SuiteHandler suites(m_Suites); + A_Err result = A_Err_NONE; + AEGP_StreamRefH stream = null; + A_Time time; + + time.value = AAEData.m_InData->current_time; + time.scale = AAEData.m_InData->time_scale; + + result |= suites.StreamSuite2()->AEGP_GetNewLayerStream(m_AEGPID, layer, AEGP_LayerStream_POSITION, &stream); + if (result != A_Err_NONE || stream == null) + return false; + + AEGP_StreamValue value; + + result |= suites.StreamSuite2()->AEGP_GetNewStreamValue(m_AEGPID, stream, AEGP_LTimeMode_LayerTime, &time, false, &value); + if (result != A_Err_NONE) + return false; + value.val.three_d.x = AAEData.m_InData->width / 2.0f; + value.val.three_d.y = AAEData.m_InData->height / 2.0f; + + result |= suites.StreamSuite2()->AEGP_SetStreamValue(m_AEGPID, stream, &value); + if (result != A_Err_NONE) + return false; + return true; +} + +//---------------------------------------------------------------------------- + +bool CPopcornFXWorld::MoveEffectIntoCurrentView(SAAEIOData &AAEData, SEmitterDesc *descriptor) +{ + SLayerHolder *layer = GetLayerForSEmitterDesc(descriptor); + + if (layer == null && layer->m_SpawnedEmitter.m_Desc == null) + return false; + + CAABB bounds; + CFloat4x4 view; + CFloat4 pos; + float zoom; + A_Time AETime; + + AETime.scale = AAEData.m_InData->time_scale; + AETime.value = AAEData.m_InData->current_time; + if (!layer->m_Scene->GetEmitterBounds(bounds) || + !CAEUpdater::GetCameraViewMatrixAtTime(layer, view, pos, AETime, zoom)) + return false; + + + CFloat3 forward = view.Inverse().StrippedZAxis().Normalized(); + + float extends = bounds.Extent().HighestComponent(); + CFloat3 newPos = pos.xyz() + forward * (extends * 2.0f); + + AEGP_SuiteHandler suites(m_Suites); + A_Err result = A_Err_NONE; + AEGP_StreamRefH streamPos = null; + AEGP_EffectRefH effectRef = null; + + result = suites.PFInterfaceSuite1()->AEGP_GetNewEffectForEffect(m_AEGPID, AAEData.m_InData->effect_ref, &effectRef); + if (result != A_Err_NONE || effectRef == null) + return false; + + result |= suites.StreamSuite5()->AEGP_GetNewEffectStreamByIndex(m_AEGPID, effectRef, CAEUpdater::s_EmitterIndexes[Effect_Parameters_Position], &streamPos); + PK_ASSERT(result == A_Err_NONE); + if (result != A_Err_NONE || streamPos == null) + { + return false; + } + AEGP_StreamValue2 value; + result |= suites.StreamSuite5()->AEGP_GetNewStreamValue(m_AEGPID, streamPos, AEGP_LTimeMode_LayerTime, &AETime, false, &value); + if (result != A_Err_NONE) + { + result |= suites.EffectSuite4()->AEGP_DisposeEffect(effectRef); + return false; + } + value.val.three_d.x = newPos.x(); + value.val.three_d.y = newPos.y(); + value.val.three_d.z = newPos.z(); + result |= suites.StreamSuite5()->AEGP_SetStreamValue(m_AEGPID, streamPos, &value); + if (result != A_Err_NONE) + { + result |= suites.EffectSuite4()->AEGP_DisposeEffect(effectRef); + return false; + } + result |= suites.StreamSuite5()->AEGP_DisposeStreamValue(&value); + result |= suites.StreamSuite5()->AEGP_DisposeStream(streamPos); + + return true; +} + +//---------------------------------------------------------------------------- + +bool CPopcornFXWorld::IdleUpdate() +{ + if (m_Initialized == false) + return false; + + PK_SCOPEDPROFILE(); + + AEGP_SuiteHandler suites(m_Suites); + AEGP_EffectSuite4 *effectSuite = suites.EffectSuite4(); + A_Err result = A_Err_NONE; + bool updateEmitterPanel = false; + + if (effectSuite == null) + return false; + + CAELog::ClearIOData(); + FetchAEProject(); + + CString compositionName; + + GetMostRecentCompName(compositionName); + if (m_MostRecentCompName != compositionName) + { + if (m_Panel) + m_Panel->UpdateScenesModel(); + m_MostRecentCompName = compositionName; + } + for (s32 l = m_Layers.Count() - 1; l >= 0; --l) + { + SLayerHolder &layer = *m_Layers[l]; + + if (!layer.m_LayerLock.TryLock()) + continue; + + A_long count = 0; + u32 emitterCount = 0; + + if (layer.m_SpawnedEmitter.m_Desc != null) + { + result = effectSuite->AEGP_GetLayerNumEffects(layer.m_EffectLayer, &count); + if (result != A_Err_NONE) + { + CLog::Log(PK_INFO, "AEGP_GetLayerNumEffects failed"); + layer.m_LayerLock.Unlock(); + continue; + } + + //Start the fuckery to handle Layer deletion + AEGP_CompH compH; + AEGP_LayerIDVal layerID; + AEGP_LayerH layerFromComp; + result = suites.LayerSuite5()->AEGP_GetLayerParentComp(layer.m_EffectLayer, &compH); + if (result != A_Err_NONE) + { + CLog::Log(PK_INFO, "AEGP_GetLayerNumEffects failed"); + layer.m_LayerLock.Unlock(); + continue; + } + result = suites.LayerSuite7()->AEGP_GetLayerID(layer.m_EffectLayer, &layerID); + result = suites.LayerSuite7()->AEGP_GetLayerFromLayerID(compH, layerID, &layerFromComp); + if (result != A_Err_NONE) //Layer is deleted but still on the undo stack + { + updateEmitterPanel = layer.m_Deleted != true ? true : updateEmitterPanel; + layer.m_Deleted = true; + } + else + { + updateEmitterPanel = layer.m_Deleted != false ? true : updateEmitterPanel; + layer.m_Deleted = false; + } + + for (A_long j = count - 1; j >= 0; --j) + { + AEGP_EffectRefH effectRef = null; + AEGP_InstalledEffectKey installedKey; + + result = suites.EffectSuite4()->AEGP_GetLayerEffectByIndex(m_AEGPID, layer.m_EffectLayer, j, &effectRef); + result = suites.EffectSuite4()->AEGP_GetInstalledKeyFromLayerEffect(effectRef, &installedKey); + + if (!PK_VERIFY(result == A_Err_NONE)) + { + CLog::Log(PK_INFO, "AEGP_GetLayerEffectByIndex failed"); + layer.m_LayerLock.Unlock(); + continue; + } + if (installedKey == m_PKInstalledPluginKeys[EPKChildPlugins::ATTRIBUTE]) + { + } + else if (installedKey == m_PKInstalledPluginKeys[EPKChildPlugins::EMITTER]) + { + emitterCount += 1; + if (layer.m_ForceRender) + { + layer.m_ForceRender = false; + if (!InvalidateEmitterRender(&layer, effectRef)) + { + layer.m_LayerLock.Unlock(); + return false; + } + } + } + result = suites.EffectSuite4()->AEGP_DisposeEffect(effectRef); + } + if (emitterCount == 0) + { + layer.Clear(m_Suites); + m_Layers.RemoveElement(&layer); + layer.m_LayerLock.Unlock(); + PK_DELETE(&layer); + updateEmitterPanel = true; + continue; + } + } + if (_ExecClearAttributes(&layer) != 0) //Clear attribute did work, give time to AE to reorder internals. + { + layer.m_LayerLock.Unlock(); + continue; + } + + if (_ExecSPendingEmitters(&layer) < 0) + { + updateEmitterPanel = true; + layer.m_LayerLock.Unlock(); + continue; + } + + if (_ExecSPendingAttributes(&layer) < 0) + { + layer.m_LayerLock.Unlock(); + continue; + } + + layer.m_LayerLock.Unlock(); + } + { + PK_SCOPEDLOCK(m_UIEventLock); + for (u32 i = 0; i < m_UIEvents.Count(); ++i) + { + SUIEvent *event = m_UIEvents[i]; + + event->Exec(); + PK_DELETE(event); + } + m_UIEvents.Clear(); + } + if (m_Panel != null) + { + if (updateEmitterPanel) + m_Panel->UpdateScenesModel(); + } +#if defined(PK_MACOSX) + if (m_Panel != null) + m_Panel->IdleUpdate(); +#endif + if (!PK_VERIFY(result == A_Err_NONE)) + return false; + return true; +} + +//---------------------------------------------------------------------------- + +bool CPopcornFXWorld::HandleNewEmitterEvent(AAePk::SAAEIOData &AAEData, SEmitterDesc *desc) +{ + A_Err result = A_Err_NONE; + AEGP_SuiteHandler suites(m_Suites); + AEGP_LayerH layerH; + A_long dstID = 0, existingID; + s32 existingLayerID = -1; + + FetchAEProject(); + PK_SCOPEDLOCK(m_Lock); + result |= suites.PFInterfaceSuite1()->AEGP_GetEffectLayer(AAEData.m_InData->effect_ref, &layerH); + result |= suites.LayerSuite8()->AEGP_GetLayerID(layerH, &dstID); + + if (!PK_VERIFY(result == A_Err_NONE)) + return false; + + for (u32 i = 0; i < m_Layers.Count(); ++i) + { + result |= suites.LayerSuite8()->AEGP_GetLayerID(m_Layers[i]->m_EffectLayer, &existingID); + if (dstID == existingID) + { + existingLayerID = i; + break; + } + } + SLayerHolder *layerHolder = null; + + if (existingLayerID >= 0) + { + layerHolder = m_Layers[existingLayerID]; + layerHolder->m_Scene->Quit(); + layerHolder->m_Scene = null; + } + else + { + layerHolder = PK_NEW(SLayerHolder); + if (!PK_VERIFY(m_Layers.PushBack(layerHolder).Valid())) + return false; + existingLayerID = m_Layers.Count() - 1; + } + if (!PK_VERIFY(layerHolder != null)) + return false; + + layerHolder->m_EffectLayer = layerH; + layerHolder->ID = existingLayerID; + + if (!SetLayerName(layerHolder)) + return false; + if (!SetLayerCompName(layerHolder)) + return false; + CreateLayerPropertyIFP(layerHolder); + + layerHolder->m_Scene = PK_NEW(CAAEScene); + if (!PK_VERIFY(layerHolder->m_Scene != null)) + return false; + layerHolder->m_Scene->SetLayerHolder(layerHolder); + layerHolder->m_ViewMatrix = CFloat4x4::IDENTITY; + layerHolder->m_CameraPos = CFloat4::ZERO; + layerHolder->m_CurrentTime = AAEData.m_InData->current_time; + layerHolder->m_TimeScale = AAEData.m_InData->time_scale; + layerHolder->m_TimeStep = AAEData.m_InData->local_time_step; + + if (layerHolder->m_Scene->Init(AAEData) == false) + return false; + layerHolder->m_Scene->SetEffectDescriptor(desc); + if (layerHolder->m_SpawnedEmitter.m_Desc != null) + { + layerHolder->m_SpawnedEmitter.m_EffectHandle = AAEData.m_InData->effect_ref; + layerHolder->m_SpawnedEmitter.m_Desc = desc; + } + else + { + if (!layerHolder->m_SPendingEmitters.PushBack(SPendingEmitter{ AAEData.m_InData->effect_ref, desc }).Valid()) + return false; + } + if (!PK_VERIFY(result == A_Err_NONE)) + return false; + return true; +} + +//---------------------------------------------------------------------------- + +bool CPopcornFXWorld::HandleDeleteEmitterEvent(AAePk::SAAEIOData &AAEData, SEmitterDesc *desc) +{ + (void)AAEData; + + SLayerHolder *layer = GetLayerForSEmitterDesc(desc); + + if (layer) + { + layer->Clear(m_Suites); + + u32 idx = m_Layers.IndexOf(layer); + m_Layers.Remove(idx); + + PK_DELETE(layer); + if (m_Panel != null) + m_Panel->UpdateScenesModel(); + } + return true; +} + +//---------------------------------------------------------------------------- + +bool CPopcornFXWorld::HandleNewAttributeEvent(PF_ProgPtr &effectRef, SAttributeDesc *desc, bool asyncMerge /*= true*/, SLayerHolder *layer /*=null*/) +{ + (void)asyncMerge; + AEGP_SuiteHandler suites(m_Suites); + + PK_SCOPEDLOCK(m_Lock); + + if (layer == null) + { + PK_ASSERT(false); + return false; + } + if (layer != null) + { + CStringId id = GetAttributeID(desc); + if (layer->m_SpawnedAttributes.Contains(id)) + { + SPendingAttribute *attr = layer->m_SpawnedAttributes[id]; + attr->m_ParentEffectPtr = effectRef; + + if (attr->m_Desc != null) + { + *(attr->m_Desc) = *desc; + delete (desc); + } + else + { + attr->m_Desc = desc; + } + } + else //Not yet spawned in AE, must do an async merge due to SDK limitations. + { + if (!PK_VERIFY(layer->m_SPendingAttributes.PushBack(SPendingAttribute(effectRef, desc, null)).Valid())) + return false; + } + } + return true; +} + +//---------------------------------------------------------------------------- + +bool CPopcornFXWorld::HandleNewAttributeSamplerEvent(PF_ProgPtr &effectRef, SAttributeSamplerDesc *desc, bool asyncMerge, SLayerHolder *layer) +{ + (void)asyncMerge; + AEGP_SuiteHandler suites(m_Suites); + + PK_SCOPEDLOCK(m_Lock); + + if (layer == null) + { + PK_ASSERT(false); + return false; + } + + if (layer != null) + { + CStringId id = GetAttributeID(desc); + if (layer->m_SpawnedAttributesSampler.Contains(id)) + { + SPendingAttribute *attr = layer->m_SpawnedAttributesSampler[id]; + attr->m_ParentEffectPtr = effectRef; + if (attr->m_Desc != null) + { + SAttributeSamplerDesc *descriptor = static_cast(attr->m_Desc); + if (descriptor->m_Descriptor != null) + { + delete(descriptor->m_Descriptor); + descriptor->m_Descriptor = null; + attr->m_Desc->m_IsDeleted = true; + } + *(static_cast(attr->m_Desc)) = *(static_cast(desc)); + delete (desc); + } + else + { + attr->m_Desc = desc; + } + } + else //Not yet spawned in AE, must do an async merge due to SDK limitations. + { + if (!PK_VERIFY(layer->m_SPendingAttributes.PushBack(SPendingAttribute(effectRef, desc, null)).Valid())) + return false; + } + } + return true; +} + +//---------------------------------------------------------------------------- + +bool CPopcornFXWorld::HandleNewAttributes(TArray &attributes, PF_ProgPtr &effectRef, SLayerHolder *layer, bool asyncMerge) +{ + for (u32 i = 0; i < attributes.Count(); ++i) + { + attributes[i]->m_Order = attributes.Count() - i - 1; + if (attributes[i]->m_IsAttribute == true) + HandleNewAttributeEvent(effectRef, static_cast(attributes[i]), asyncMerge, layer); + else + HandleNewAttributeSamplerEvent(effectRef, static_cast(attributes[i]), asyncMerge, layer); + + } + return true; +} + +//---------------------------------------------------------------------------- + +SLayerHolder *CPopcornFXWorld::GetLayerForSEmitterDesc(SEmitterDesc *desc) +{ + return GetLayerForSEmitterDescID(CStringId(desc->m_UUID.c_str())); +} + +//---------------------------------------------------------------------------- + +SLayerHolder *CPopcornFXWorld::GetLayerForSEmitterDescID(CStringId id) +{ + for (u32 i = 0; i < m_Layers.Count(); ++i) + { + SLayerHolder &layer = *m_Layers[i]; + if (layer.m_SpawnedEmitter.m_Desc && CStringId(layer.m_SpawnedEmitter.m_Desc->m_UUID.c_str()) == id) + { + return &layer; + } + } + return null; +} + +//---------------------------------------------------------------------------- + +bool CPopcornFXWorld::CheckEmitterValidity(AAePk::SAAEIOData &AAEData, AAePk::SEmitterDesc *descriptor) +{ + (void)AAEData; + SLayerHolder *layer = GetLayerForSEmitterDesc(descriptor); + + if (layer == null) + return false; + return true; +} + +//---------------------------------------------------------------------------- + +bool CPopcornFXWorld::UpdateScene(SAAEIOData &AAEData, SEmitterDesc *desc) +{ + PK_SCOPEDPROFILE(); + if (!InitializeIFN(AAEData)) + return false; + if (m_Layers.Count() == 0) + return true; + if (!PopcornFX::CCurrentThread::IsRegistered()) + { + if (!m_AAETreadID.PushBack(PopcornFX::CCurrentThread::RegisterUserThread()).Valid()) + return false; + } + + SLayerHolder *layer = GetLayerForSEmitterDesc(desc); + AEGP_SuiteHandler suites(m_Suites); + PF_Err result = A_Err_NONE; + A_Time AETime; + + if (layer == null) + return true; + + PK_SCOPEDLOCK(layer->m_LayerLock); + + layer->m_CurrentTime = AAEData.m_InData->current_time; + layer->m_TimeScale = AAEData.m_InData->time_scale; + //Sync Params with current frame + result |= suites.PFInterfaceSuite1()->AEGP_ConvertEffectToCompTime(AAEData.m_InData->effect_ref, layer->m_CurrentTime, layer->m_TimeScale, &AETime); + + AEGP_LayerH cameraLayer = null; + + result |= suites.PFInterfaceSuite1()->AEGP_GetEffectCamera(AAEData.m_InData->effect_ref, &AETime, &cameraLayer); + layer->m_CameraLayer = cameraLayer; + if (desc->m_Name.empty()) + return true; + + A_long dstID = 0; + result |= suites.LayerSuite8()->AEGP_GetLayerID(layer->m_EffectLayer, &dstID); + +#if 1 // Fix for copy paste break everything... + + if (desc->m_LayerID != dstID) + { + AEGP_LayerH layerH = null; + result |= suites.PFInterfaceSuite1()->AEGP_GetEffectLayer(AAEData.m_InData->effect_ref, &layerH); + if (!PK_VERIFY(result == A_Err_NONE)) + return false; + + if (layerH != null) + { + desc->m_LayerID = dstID; + layer->m_EffectLayer = layerH; + + A_long count = 0; + result |= suites.EffectSuite4()->AEGP_GetLayerNumEffects(layer->m_EffectLayer, &count); + + for (A_long j = count - 1; j >= 0; --j) + { + bool disposeEffect = true; + AEGP_EffectRefH effectRef = null; + AEGP_InstalledEffectKey installedKey; + + result |= suites.EffectSuite4()->AEGP_GetLayerEffectByIndex(m_AEGPID, layer->m_EffectLayer, j, &effectRef); + result |= suites.EffectSuite4()->AEGP_GetInstalledKeyFromLayerEffect(effectRef, &installedKey); + + if (!PK_VERIFY(result == A_Err_NONE)) + { + return false; + } + if (installedKey == m_PKInstalledPluginKeys[EPKChildPlugins::ATTRIBUTE]) + { + CStringId id = GetAttributeID(effectRef); + if (layer->m_SpawnedAttributes.Contains(id)) + { + SPendingAttribute *attribute = layer->m_SpawnedAttributes[id]; + + result |= suites.EffectSuite4()->AEGP_DisposeEffect(attribute->m_AttributeEffectRef); + attribute->m_AttributeEffectRef = effectRef; + disposeEffect = false; + } + } + else if (installedKey == m_PKInstalledPluginKeys[EPKChildPlugins::SAMPLER]) + { + CStringId id = GetAttributeSamplerID(effectRef); + if (layer->m_SpawnedAttributesSampler.Contains(id)) + { + SPendingAttribute *sampler = layer->m_SpawnedAttributesSampler[id]; + + result |= suites.EffectSuite4()->AEGP_DisposeEffect(sampler->m_AttributeEffectRef); + sampler->m_AttributeEffectRef = effectRef; + disposeEffect = false; + } + } + else if (installedKey == m_PKInstalledPluginKeys[EPKChildPlugins::EMITTER]) + { + if (m_Panel) + { + m_Panel->UpdateScenesModel(); + } + } + if (disposeEffect) + result |= suites.EffectSuite4()->AEGP_DisposeEffect(effectRef); + } + } + } +#endif + layer->m_SpawnedEmitter.m_EffectHandle = AAEData.m_InData->effect_ref; + +#if TEST_COLOR_PROFILE & 0 + AEGP_CompH compH; + AEGP_ColorProfileP colorProfile; + A_FpShort gamma; + + result |= suites.LayerSuite5()->AEGP_GetLayerParentComp(layer->m_EffectLayer, &compH); + result |= suites.ColorSettingsSuite2()->AEGP_GetNewWorkingSpaceColorProfile(m_AEGPID, compH, &colorProfile); + result |= suites.ColorSettingsSuite2()->AEGP_GetColorProfileApproximateGamma(colorProfile, &gamma); + + //AEGP_MemHandle iccProfile = null; + //result |= suites.ColorSettingsSuite2()->AEGP_GetNewICCProfileFromColorProfile(m_AEGPID, colorProfile, &iccProfile); + //result |= suites.MemorySuite1()->AEGP_FreeMemHandle(iccProfile); + result |= suites.ColorSettingsSuite2()->AEGP_DisposeColorProfile(colorProfile); + +#endif + PAAEScene scene = layer->m_Scene; + + scene->SetLayerHolder(layer); +#if defined (PK_SCALE_DOWN) + layer->m_ScaleFactor = desc->m_ScaleFactor; +#endif + scene->UpdateLight(layer); + scene->UpdateBackdrop(layer, desc); + { + PK_SCOPEDLOCK(GetRenderLock()); + scene->Update(AAEData); + if (AAEData.m_ReturnCode == A_Err_NONE) + { + scene->Render(AAEData); + } + } + if (!PK_VERIFY(result == A_Err_NONE)) + return false; + return true; +} + +//---------------------------------------------------------------------------- + +bool CPopcornFXWorld::UpdateEmitter(SAAEIOData &AAEData, SEmitterDesc *desc) +{ + (void)AAEData; + (void)desc; + + return true; +} + +//---------------------------------------------------------------------------- + +bool CPopcornFXWorld::InvalidateEmitterRender(SLayerHolder *layer , AEGP_EffectRefH effectRef) +{ + if (layer == null) + return false; + + A_Err result = A_Err_NONE; + + AEGP_SuiteHandler suites(m_Suites); + AEGP_StreamRefH streamRef = null; + + A_Time AETime; + + AETime.scale = layer->m_TimeScale; + AETime.value = 0; + + result |= suites.StreamSuite2()->AEGP_GetNewEffectStreamByIndex(m_AEGPID, effectRef, CAEUpdater::s_EmitterIndexes[Effect_Parameters_Refresh_Render], &streamRef); + if (!PK_VERIFY(result == A_Err_NONE)) + return false; + + AEGP_StreamValue value; + + result |= suites.StreamSuite2()->AEGP_GetNewStreamValue(m_AEGPID, streamRef, AEGP_LTimeMode_LayerTime, &AETime, TRUE, &value); + if (!PK_VERIFY(result == A_Err_NONE)) + return false; + + value.val.one_d = (int)(value.val.one_d + 1) % 100; + + result |= suites.StreamSuite2()->AEGP_SetStreamValue(m_AEGPID, streamRef, &value); + result |= suites.StreamSuite2()->AEGP_DisposeStream(streamRef); + return true; +} + +//---------------------------------------------------------------------------- + +bool CPopcornFXWorld::InvalidateEmitterRender(SAAEIOData &AAEData, SEmitterDesc *desc) +{ + A_Err result = A_Err_NONE; + AEGP_SuiteHandler suites(m_Suites); + AEGP_EffectRefH effectRef = null; + + result = suites.PFInterfaceSuite1()->AEGP_GetNewEffectForEffect(m_AEGPID, AAEData.m_InData->effect_ref, &effectRef); + if (!PK_VERIFY(result == A_Err_NONE)) + return false; + bool ret = InvalidateEmitterRender(GetLayerForSEmitterDesc(desc) , effectRef); + + result = suites.EffectSuite4()->AEGP_DisposeEffect(effectRef); + if (!PK_VERIFY(result == A_Err_NONE)) + return false; + return ret; +} + +//---------------------------------------------------------------------------- + +bool CPopcornFXWorld::LaunchEditorAsPopup(AAePk::SAAEIOData &AAEData, SEmitterDesc *desc) +{ + (void)AAEData; + (void)desc; + return CSystemHelper::LaunchEditorAsPopup(); +} + +//---------------------------------------------------------------------------- + +A_Err CPopcornFXWorld::DeathHook(AEGP_GlobalRefcon pluginRefCon, AEGP_DeathRefcon refCon) +{ + (void)refCon; + (void)pluginRefCon; + + CPopcornFXWorld &instance = AEGPPk::CPopcornFXWorld::Instance(); + const A_u_char *commandName = (const A_u_char*)"PopcornFX"; + A_Err result = PF_Err_NONE; + SuiteHelper panelSuite(instance.m_Suites); + + result |= panelSuite->AEGP_UnRegisterCreatePanelHook(commandName); + + instance.ShutdownIFN(); + + if (!PK_VERIFY(result == A_Err_NONE)) + return result; + return result; +} + +//---------------------------------------------------------------------------- + +A_Err CPopcornFXWorld::IdleHook(AEGP_GlobalRefcon pluginRefCon, AEGP_IdleRefcon refCon, A_long *maxSleep) +{ + (void)maxSleep; + (void)refCon; + (void)pluginRefCon; + + A_Err err = A_Err_NONE; + CPopcornFXWorld &instance = AEGPPk::CPopcornFXWorld::Instance(); + + instance.IdleUpdate(); + return err; +} + +//---------------------------------------------------------------------------- + +void CPopcornFXWorld::CreatePanel(AEGP_PlatformViewRef container, AEGP_PanelH panelH, AEGP_PanelFunctions1 *outFunctionTable, AEGP_PanelRefcon *outRefcon) +{ + (void)container; + (void)panelH; + (void)outFunctionTable; + (void)outRefcon; + + CPanelBaseGUI *panel = CPanelBaseGUI::GetInstance(); + + panel->CreatePanel(m_Suites, panelH, container, outFunctionTable); + *outRefcon = reinterpret_cast(panel); +} + +//---------------------------------------------------------------------------- + +void CPopcornFXWorld::Command( AEGP_Command command, + AEGP_HookPriority hookPriority, + A_Boolean alreadyHandled, + A_Boolean *handledP) +{ + (void)handledP; + (void)alreadyHandled; + (void)hookPriority; + + if (command == m_Command) + { + SuiteHelper panelSuites(m_Suites); + + A_Boolean shown = false; + A_Boolean topLevel = false; + + panelSuites->AEGP_IsShown((const A_u_char*)m_CommandName.Data(), &shown, &topLevel); + if (!shown || !topLevel) + panelSuites->AEGP_ToggleVisibility((const A_u_char*)m_CommandName.Data()); + *handledP = true; + } +} + +//---------------------------------------------------------------------------- + +void CPopcornFXWorld::UpdateMenu(AEGP_WindowType activeWindow) +{ + (void)activeWindow; + + SuiteHelper panelSuites(m_Suites); + AEGP_SuiteHandler suites(m_Suites); + + suites.CommandSuite1()->AEGP_EnableCommand(m_Command); + + A_Boolean thumbIsShown = false; + A_Boolean panelIsFront = false; + + panelSuites->AEGP_IsShown((const A_u_char*)m_CommandName.Data(), &thumbIsShown, &panelIsFront); + suites.CommandSuite1()->AEGP_CheckMarkMenuCommand(m_Command, thumbIsShown && panelIsFront); +} + +//---------------------------------------------------------------------------- + +void CPopcornFXWorld::ClearAttributesAndSamplers(SLayerHolder *layer) +{ + PK_ASSERT(layer != null); + + AEGP_SuiteHandler suites(m_Suites); + + for (auto it = layer->m_SpawnedAttributes.Begin(); it != layer->m_SpawnedAttributes.End(); ++it) + { + layer->m_DeletedAttributes.Insert(it.Key(), *it); + it->m_AttributeEffectRef = null; + } + layer->m_SpawnedAttributes.Clear(); + for (auto it = layer->m_SpawnedAttributesSampler.Begin(); it != layer->m_SpawnedAttributesSampler.End(); ++it) + { + layer->m_DeletedAttributesSampler.Insert(it.Key(), *it); + it->m_AttributeEffectRef = null; + } + layer->m_SpawnedAttributesSampler.Clear(); +} + +//---------------------------------------------------------------------------- + +CStringId CPopcornFXWorld::GetAEEffectID(AEGP_EffectRefH &effect, s32 paramIdx) +{ + A_Err result = A_Err_NONE; + AEGP_SuiteHandler suites(m_Suites); + AEGP_StreamRefH streamRef = null; + AEGP_MemHandle nameHandle; + + result |= suites.StreamSuite2()->AEGP_GetNewEffectStreamByIndex(m_AEGPID, effect, paramIdx, &streamRef); + if (!PK_VERIFY(result == A_Err_NONE)) + return CStringId::Null; + + result |= suites.StreamSuite5()->AEGP_GetStreamName(m_AEGPID, streamRef, false, &nameHandle); + if (!PK_VERIFY(result == A_Err_NONE)) + return CStringId::Null; + result |= suites.StreamSuite2()->AEGP_DisposeStream(streamRef); + if (!PK_VERIFY(result == A_Err_NONE)) + return CStringId::Null; + streamRef = null; + + aechar_t *wname; + CString name; + + result |= suites.MemorySuite1()->AEGP_LockMemHandle(nameHandle, reinterpret_cast(&wname)); + if (!PK_VERIFY(result == A_Err_NONE)) + return CStringId::Null; + WCharToCString(wname, &name); + + result |= suites.MemorySuite1()->AEGP_UnlockMemHandle(nameHandle); + result |= suites.MemorySuite1()->AEGP_FreeMemHandle(nameHandle); + + if (!PK_VERIFY(result == A_Err_NONE)) + return CStringId::Null; + if (!PK_VERIFY(name.Length() != 0)) + return CStringId::Null; + return CStringId(name.Data()); +} + +//---------------------------------------------------------------------------- + +CStringId CPopcornFXWorld::GetAttributeID(AEGP_EffectRefH &effect) +{ + return GetAEEffectID(effect, Attribute_Parameters_Infernal_Name); +} + +//---------------------------------------------------------------------------- + +CStringId CPopcornFXWorld::GetAttributeSamplerID(AEGP_EffectRefH &effect) +{ + return GetAEEffectID(effect, AttributeSamplerType_Parameters_Infernal_Name); +} + +//---------------------------------------------------------------------------- + +CStringId CPopcornFXWorld::GetAttributeID(SAttributeBaseDesc *desc) +{ + return CStringId(desc->GetAttributePKKey().data()); +} + +//---------------------------------------------------------------------------- + +s32 CPopcornFXWorld::_ExecSPendingEmitters(SLayerHolder *layer) +{ + PK_SCOPEDPROFILE(); + s32 emittersCount = 0; + A_Err result = A_Err_NONE; + AEGP_SuiteHandler suites(m_Suites); + + for (s32 i = layer->m_SPendingEmitters.Count() - 1; i >= 0; --i) + { + A_long count; + SPendingEmitter &emitter = layer->m_SPendingEmitters[i]; + AEGP_LayerFlags flags = AEGP_LayerFlag_NONE; + + result |= suites.LayerSuite8()->AEGP_GetLayerFlags(layer->m_EffectLayer, &flags); + if ((flags & AEGP_LayerFlag_LOCKED) != AEGP_LayerFlag_NONE) + continue; + + result |= suites.EffectSuite4()->AEGP_GetLayerNumEffects(layer->m_EffectLayer, &count); + + for (A_long j = count - 1; j >= 0; --j) + { + AEGP_EffectRefH effectRef = null; + AEGP_InstalledEffectKey installedKey; + PAAEScene scene = layer->m_Scene; + A_Time fake_timeT = { 0, 100 }; + bool releaseEffectHandle = true; + + result |= suites.EffectSuite4()->AEGP_GetLayerEffectByIndex(m_AEGPID, layer->m_EffectLayer, j, &effectRef); + result |= suites.EffectSuite4()->AEGP_GetInstalledKeyFromLayerEffect(effectRef, &installedKey); + + if (installedKey == m_PKInstalledPluginKeys[EPKChildPlugins::EMITTER]) + { + if (_SetupAutoRender(effectRef) == false) + return -1; + + layer->m_SpawnedEmitter = emitter; + scene->SetEmitterTeleport(); + scene->SetEmitterPosition(AAEToPK(emitter.m_Desc->m_Position), emitter.m_Desc->m_TransformType); + scene->SetEmitterRotation(AngleAAEToPK(emitter.m_Desc->m_Rotation)); + + if (!emitter.m_Desc->m_PathSource.empty()) + SetDestinationPackFromPath(*layer, CString(emitter.m_Desc->m_PathSource.c_str())); + + bool forceRefresh = false; + if (!emitter.m_Desc->m_PathSource.empty()) + { + CString sourcePackPath(emitter.m_Desc->m_PathSource.data()); + if (!CFilePath::IsAbsolute(emitter.m_Desc->m_PathSource.data())) + sourcePackPath = m_AEProjectPath / sourcePackPath; + + CFilePath::Purify(sourcePackPath); + CProjectSettingsFinder walker(sourcePackPath); + walker.Walk(); + + CString effectName = emitter.m_Desc->m_Name.data(); + if (!m_VaultHandler.LoadEffectIntoVault(sourcePackPath, effectName, walker.ProjectSettingsPath(), forceRefresh)) + return false; + emitter.m_Desc->m_Name = effectName.Data(); + } + scene->RefreshAssetList(); + scene->SetLayerHolder(layer); + scene->SetPack(layer->m_BakedPack, forceRefresh); + scene->SetSelectedEffect(CString(emitter.m_Desc->m_Name.c_str()), forceRefresh); + result |= suites.EffectSuite4()->AEGP_EffectCallGeneric(m_AEGPID, effectRef, &fake_timeT, PF_Cmd_COMPLETELY_GENERAL, emitter.m_Desc); + + SGetEmitterInfos infos; + + result |= suites.EffectSuite4()->AEGP_EffectCallGeneric(m_AEGPID, effectRef, &fake_timeT, PF_Cmd_COMPLETELY_GENERAL, &infos); + + CLog::Log(PK_INFO, "%s", infos.m_PathSource); + } + if (releaseEffectHandle) + result |= suites.EffectSuite4()->AEGP_DisposeEffect(effectRef); + } + ++emittersCount; + } + layer->m_SPendingEmitters.Clear(); + + if (!PK_VERIFY(result == A_Err_NONE)) + return -1; + return emittersCount; +} + +//---------------------------------------------------------------------------- + +s32 CPopcornFXWorld::_ExecClearAttributes(SLayerHolder *layer) +{ + PK_SCOPEDPROFILE(); + s32 count = 0; + A_Err result = A_Err_NONE; + AEGP_SuiteHandler suites(m_Suites); + A_long effectCount = 0; + + PK_ASSERT(layer->m_EffectLayer != null); + + result |= suites.EffectSuite4()->AEGP_GetLayerNumEffects(layer->m_EffectLayer, &effectCount); + + for (A_long j = effectCount - 1; j >= 0; --j) + { + AEGP_EffectRefH effectRef = null; + AEGP_InstalledEffectKey installedKey; + + result |= suites.EffectSuite4()->AEGP_GetLayerEffectByIndex(m_AEGPID, layer->m_EffectLayer, j, &effectRef); + result |= suites.EffectSuite4()->AEGP_GetInstalledKeyFromLayerEffect(effectRef, &installedKey); + + if (installedKey == m_PKInstalledPluginKeys[EPKChildPlugins::ATTRIBUTE]) + { + CStringId id = GetAttributeID(effectRef); + + if (layer->m_DeletedAttributes.Contains(id)) + { + SPendingAttribute *attr = layer->m_DeletedAttributes[id]; + + if (!_ExecDeleteAttribute(attr, effectRef)) + result |= A_Err_GENERIC; + ++count; + } + else if (layer->m_SpawnedAttributes.Contains(id)) + { + SPendingAttribute *attr = layer->m_SpawnedAttributes[id]; + + if (attr->m_Deleted) + { + if (!_ExecDeleteAttribute(attr, effectRef)) + result |= A_Err_GENERIC; + layer->m_SpawnedAttributes.Remove(id); + } + } + } + else if (installedKey == m_PKInstalledPluginKeys[EPKChildPlugins::SAMPLER]) + { + CStringId id = GetAttributeSamplerID(effectRef); + + if (layer->m_DeletedAttributesSampler.Contains(id)) + { + SPendingAttribute *attr = layer->m_DeletedAttributesSampler[id]; + + if (!_ExecDeleteAttributeSampler(attr, effectRef)) + result |= A_Err_GENERIC; + ++count; + } + else if (layer->m_SpawnedAttributesSampler.Contains(id)) + { + SPendingAttribute *attr = layer->m_SpawnedAttributesSampler[id]; + + if (attr->m_Deleted) + { + if (!_ExecDeleteAttributeSampler(attr, effectRef)) + result |= A_Err_GENERIC; + layer->m_SpawnedAttributesSampler.Remove(id); + } + } + } + result |= suites.EffectSuite4()->AEGP_DisposeEffect(effectRef); + } + layer->m_DeletedAttributes.Clear(); + layer->m_DeletedAttributesSampler.Clear(); + + if (!PK_VERIFY(result == A_Err_NONE)) + return -1; + return count; +} + +//---------------------------------------------------------------------------- + +bool CPopcornFXWorld::_ExecDeleteAttribute(SPendingAttribute *attribute, AEGP_EffectRefH &effectRef) +{ + A_Err result = A_Err_NONE; + AEGP_SuiteHandler suites(m_Suites); + + if (attribute->m_Desc) + attribute->m_Desc->m_IsDeleted = true; + + if (attribute->m_AttributeEffectRef != null) + { + A_Time fake_timeT = { 0, 100 }; + result |= suites.EffectSuite4()->AEGP_EffectCallGeneric(m_AEGPID, attribute->m_AttributeEffectRef, &fake_timeT, PF_Cmd_COMPLETELY_GENERAL, attribute->m_Desc); + result |= suites.EffectSuite4()->AEGP_DisposeEffect(attribute->m_AttributeEffectRef); + attribute->m_AttributeEffectRef = null; + } + result |= suites.EffectSuite4()->AEGP_DeleteLayerEffect(effectRef); + + if (!PK_VERIFY(result == A_Err_NONE)) + return false; + return result == A_Err_NONE; +} + +//---------------------------------------------------------------------------- + +bool CPopcornFXWorld::_ExecDeleteAttributeSampler(SPendingAttribute *attribute, AEGP_EffectRefH &effectRef) +{ + A_Err result = A_Err_NONE; + AEGP_SuiteHandler suites(m_Suites); + + if (attribute->m_Desc) + attribute->m_Desc->m_IsDeleted = true; + + if (attribute->m_AttributeEffectRef != null) + { + A_Time fake_timeT = { 0, 100 }; + result |= suites.EffectSuite4()->AEGP_EffectCallGeneric(m_AEGPID, attribute->m_AttributeEffectRef, &fake_timeT, PF_Cmd_COMPLETELY_GENERAL, attribute->m_Desc); + result |= suites.EffectSuite4()->AEGP_DisposeEffect(attribute->m_AttributeEffectRef); + attribute->m_AttributeEffectRef = null; + PK_SAFE_DELETE(attribute->m_PKDesc); + } + result |= suites.EffectSuite4()->AEGP_DeleteLayerEffect(effectRef); + + if (!PK_VERIFY(result == A_Err_NONE)) + return false; + return result == A_Err_NONE; +} + +//---------------------------------------------------------------------------- + +s32 CPopcornFXWorld::_ExecSPendingAttributes(SLayerHolder *layer) +{ + PK_SCOPEDPROFILE(); + A_Err result = A_Err_NONE; + AEGP_SuiteHandler suites(m_Suites); + A_Time fake_timeT = { 0, 100 }; + u32 spawned = 0; + + PK_ASSERT(layer != null); + + for (s32 i = layer->m_SPendingAttributes.Count() - 1; i >= 0 ; --i) + { + SPendingAttribute &attribute = layer->m_SPendingAttributes[i]; + CStringId id = GetAttributeID(layer->m_SPendingAttributes[i].m_Desc); + A_long count; + bool allreadySpawned = false; + + result |= suites.EffectSuite4()->AEGP_GetLayerNumEffects(layer->m_EffectLayer, &count); + + for (A_long j = count - 1; j >= 0; --j) + { + AEGP_EffectRefH attributeRef = null; + AEGP_InstalledEffectKey installedKey; + PAAEScene scene = layer->m_Scene; + + result |= suites.EffectSuite4()->AEGP_GetLayerEffectByIndex(m_AEGPID, layer->m_EffectLayer, j, &attributeRef); + result |= suites.EffectSuite4()->AEGP_GetInstalledKeyFromLayerEffect(attributeRef, &installedKey); + + if (installedKey == m_PKInstalledPluginKeys[EPKChildPlugins::ATTRIBUTE]) + { + CStringId spawnedID = GetAttributeID(attributeRef); + + if (spawnedID.ToString() == "AttributeName") //Default value, leave time to after effects to get its thing together. + { + result |= suites.EffectSuite4()->AEGP_DisposeEffect(attributeRef); + return 0; + } + if (spawnedID == id) + { + attribute.m_AttributeEffectRef = attributeRef; + + if (layer->m_SpawnedAttributes.Contains(id)) + { + if (layer->m_SpawnedAttributes[id]->m_AttributeEffectRef) + result |= suites.EffectSuite4()->AEGP_DisposeEffect(attributeRef); + if (layer->m_SpawnedAttributes[id]->m_Desc) + delete layer->m_SpawnedAttributes[id]->m_Desc; + layer->m_SpawnedAttributes[id]->m_Desc = attribute.m_Desc; + } + else + layer->m_SpawnedAttributes.Insert(id, attribute); + layer->m_SPendingAttributes[i].m_AttributeEffectRef = null; + PK_ASSERT(attribute.m_Desc != null); + + result |= suites.EffectSuite4()->AEGP_EffectCallGeneric(m_AEGPID, layer->m_SpawnedAttributes[id]->m_AttributeEffectRef, &fake_timeT, PF_Cmd_COMPLETELY_GENERAL, attribute.m_Desc); + + layer->m_SPendingAttributes.Remove(i); + allreadySpawned = true; + break; + } + } + else if (installedKey == m_PKInstalledPluginKeys[EPKChildPlugins::SAMPLER]) + { + CStringId spawnedID = GetAttributeSamplerID(attributeRef); + + if (spawnedID.ToString() == "AttributeSamplerName") //Default value, leave time to after effects to get it's thing together. + { + result |= suites.EffectSuite4()->AEGP_DisposeEffect(attributeRef); + return 0; + } + if (spawnedID == id) + { + attribute.m_AttributeEffectRef = attributeRef; + + if (layer->m_SpawnedAttributesSampler.Contains(id)) + { + if (layer->m_SpawnedAttributesSampler[id]->m_AttributeEffectRef) + result |= suites.EffectSuite4()->AEGP_DisposeEffect(attributeRef); + if (layer->m_SpawnedAttributesSampler[id]->m_Desc) + delete layer->m_SpawnedAttributesSampler[id]->m_Desc; + layer->m_SpawnedAttributesSampler[id]->m_Desc = attribute.m_Desc; + } + else + layer->m_SpawnedAttributesSampler.Insert(id, attribute); + layer->m_SPendingAttributes[i].m_AttributeEffectRef = null; + + PK_ASSERT(attribute.m_Desc != null); + + result |= suites.EffectSuite4()->AEGP_EffectCallGeneric(m_AEGPID, layer->m_SpawnedAttributesSampler[id]->m_AttributeEffectRef, &fake_timeT, PF_Cmd_COMPLETELY_GENERAL, attribute.m_Desc); + allreadySpawned = true; + layer->m_SPendingAttributes.Remove(i); + break; + } + } + result |= suites.EffectSuite4()->AEGP_DisposeEffect(attributeRef); + } + if (allreadySpawned) + continue; + + + if ((attribute.m_Desc->m_IsAttribute && layer->m_SpawnedAttributes.Contains(id)) || + (!attribute.m_Desc->m_IsAttribute && layer->m_SpawnedAttributesSampler.Contains(id))) + continue; + + AEGP_EffectRefH effectRef = null; + + AEGP_LayerFlags flags = AEGP_LayerFlag_NONE; + result |= suites.LayerSuite8()->AEGP_GetLayerFlags(layer->m_EffectLayer, &flags); + + if (attribute.m_Desc->m_IsAttribute) + result |= suites.EffectSuite4()->AEGP_ApplyEffect(m_AEGPID, layer->m_EffectLayer, m_PKInstalledPluginKeys[EPKChildPlugins::ATTRIBUTE], &effectRef); + else + result |= suites.EffectSuite4()->AEGP_ApplyEffect(m_AEGPID, layer->m_EffectLayer, m_PKInstalledPluginKeys[EPKChildPlugins::SAMPLER], &effectRef); + if (result != A_Err_NONE || effectRef == null) + return count; + result |= suites.EffectSuite4()->AEGP_ReorderEffect(effectRef, layer->m_SPendingAttributes[i].m_Desc->m_Order); + result |= suites.EffectSuite4()->AEGP_EffectCallGeneric(m_AEGPID, effectRef, &fake_timeT, PF_Cmd_COMPLETELY_GENERAL, layer->m_SPendingAttributes[i].m_Desc); + attribute.m_AttributeEffectRef = effectRef; + + if (attribute.m_Desc->m_IsAttribute) + layer->m_SpawnedAttributes.Insert(id, attribute); + else + layer->m_SpawnedAttributesSampler.Insert(id, attribute); + attribute.m_AttributeEffectRef = null; + spawned += 1; + } +#if _DEBUG + for (u32 i = 0; i < layer->m_SPendingAttributes.Count(); ++i) + { + PK_ASSERT(!layer->m_SPendingAttributes[i].m_AttributeEffectRef); + } +#endif + layer->m_SPendingAttributes.Clear(); + + if (!PK_VERIFY(result == A_Err_NONE)) + return -1; + return spawned; +} + +//---------------------------------------------------------------------------- + +bool CPopcornFXWorld::_SetupAutoRender(AEGP_EffectRefH &effect) +{ + A_Err result = A_Err_NONE; + AEGP_SuiteHandler suites(m_Suites); + AEGP_StreamRefH streamRef = null; + AEGP_AddKeyframesInfoH KeyFrameOperationHandle; + A_Time start, end; + A_long outIndex; + AEGP_StreamValue2 keyValue; + + result |= suites.StreamSuite2()->AEGP_GetNewEffectStreamByIndex(m_AEGPID, effect, CAEUpdater::s_EmitterIndexes[Effect_Parameters_Infernal_Autorender], &streamRef); + if (!PK_VERIFY(result == A_Err_NONE)) + return false; + start.value = 0; + start.scale = 1; + PK_TODO("Handle Max time correctly"); + end.value = 1000; + end.scale = 1; + + result |= suites.KeyframeSuite4()->AEGP_StartAddKeyframes(streamRef, &KeyFrameOperationHandle); + if (!PK_VERIFY(result == A_Err_NONE)) + return false; + if (KeyFrameOperationHandle) + { + //Start + result |= suites.KeyframeSuite4()->AEGP_AddKeyframes(KeyFrameOperationHandle, AEGP_LTimeMode_CompTime, &start, &outIndex); + //End + result |= suites.KeyframeSuite4()->AEGP_AddKeyframes(KeyFrameOperationHandle, AEGP_LTimeMode_CompTime, &end, &outIndex); + result |= suites.KeyframeSuite4()->AEGP_EndAddKeyframes(true, KeyFrameOperationHandle); + } + keyValue.streamH = streamRef; + keyValue.val.one_d = 0; + result |= suites.KeyframeSuite4()->AEGP_SetKeyframeValue(streamRef, 0, &keyValue); + keyValue.val.one_d = 1000; + result |= suites.KeyframeSuite4()->AEGP_SetKeyframeValue(streamRef, 1, &keyValue); + result |= suites.StreamSuite2()->AEGP_DisposeStream(streamRef); + streamRef = null; + if (!PK_VERIFY(result == A_Err_NONE)) + return false; + return true; +} + +//---------------------------------------------------------------------------- + +bool CPopcornFXWorld::SetDestinationPackFromPath(SLayerHolder &layer, const CString &packPath) +{ + if (packPath.Empty()) + return false; + CString absolutePath = packPath; + if (!CFilePath::IsAbsolute(packPath)) + { + absolutePath = m_AEProjectPath / absolutePath; + CFilePath::Purify(absolutePath); + } + + layer.m_BakedPack = m_VaultHandler.GetVaultPackFromPath(absolutePath); + PK_ASSERT(layer.m_BakedPack != null); + return true; +} + +//---------------------------------------------------------------------------- + +CString CPopcornFXWorld::GetInternalPackPath() +{ + return GetResourcesPath() + "PopcornFXInternals"; +} + +//---------------------------------------------------------------------------- + +CString CPopcornFXWorld::GetResourcesPath() +{ +#if defined(PK_WINDOWS) + return GetPluginInstallationPath(); +#elif defined(PK_MACOSX) + return GetPluginInstallationPath() + "AE_GeneralPlugin.plugin/Contents/Resources/"; +#endif +} + +//---------------------------------------------------------------------------- + +CString CPopcornFXWorld::GetPluginVersion() const +{ + CString version = PK_VERSION_CURRENT_STRING; + return version; +} + +//---------------------------------------------------------------------------- + +AEGP_InstalledEffectKey CPopcornFXWorld::GetPluginEffectKey(EPKChildPlugins type) const +{ + return m_PKInstalledPluginKeys[type]; +} + +//---------------------------------------------------------------------------- + +CString CPopcornFXWorld::GetPluginInstallationPath() +{ + return m_AEPath / "Plug-ins/PopcornFX/"; +} + +//---------------------------------------------------------------------------- + +void CPopcornFXWorld::RefreshAssetList() +{ + for (u32 i = 0; i < m_Layers.Count(); ++i) + { + PAAEScene scene = m_Layers[i]->m_Scene; + scene->RefreshAssetList(); + } +} + +//---------------------------------------------------------------------------- + +bool CPopcornFXWorld::SetSelectedEffectFromPath(SEmitterDesc *desc, CString path, bool forceReload) +{ + CFilePath::Purify(path); + + //Doesn't work with absolute path + //if (!CFilePath::IsValidPath(path)) + // return false; + + CString root = CFilePath::StripFilename(path); + CString pkprojPath = ""; + + if (!CFilePath::IsAbsolute(root)) + { + root = m_AEProjectPath / root; + CFilePath::Purify(root); + } + if (!CFilePath::IsAbsolute(path)) + { + path = m_AEProjectPath / path; + CFilePath::Purify(path); + } + + while (root != "") + { + CProjectSettingsFinder walker(root); + + walker.Walk(); + + if (!walker.ProjectSettingsPath().Empty()) + { + pkprojPath = walker.ProjectSettingsPath(); + + root = CFilePath::StripFilename(pkprojPath); + CLog::Log(PK_INFO, "Pkproj found"); + break; + } + CFilePath::StripFilenameInPlace(root); + } + if (!root.Empty()) + { + CString effectPath; + + effectPath = CFilePath::Relativize(root.Data(), path.Data()); + + TArray unload; + bool needUnload = true; + for (u32 i = 0; i < m_Layers.Count(); ++i) + { + if (m_Layers[i]->m_SpawnedEmitter.m_Desc == null) + continue; + if (effectPath.Compare(m_Layers[i]->m_SpawnedEmitter.m_Desc->m_Name.c_str(), CaseInsensitive) == true) + { + if (!PK_VERIFY(unload.PushBack(m_Layers[i]).Valid())) + return false; + PK_SCOPEDLOCK(m_Layers[i]->m_LayerLock); + needUnload = m_Layers[i]->m_Scene->ResetEffect(needUnload); + } + } + PK_ASSERT(effectPath != null); + bool needRefresh = forceReload; + if (!m_VaultHandler.LoadEffectIntoVault(root, effectPath, pkprojPath, needRefresh)) + return false; + + CString pathDest = (m_VaultHandler.VaultPathCache() / CFilePath::ExtractFilename(root)).Data(); + + for (u32 i = 0; i < unload.Count(); ++i) + { + SLayerHolder *layer = unload[i]; + + if (layer != null) + { + CString relativeSrcPath = CFilePath::Relativize(m_AEProjectPath.Data(), root.Data()); + + desc->m_PathSource = !relativeSrcPath.Empty() ? relativeSrcPath.Data() : root.Data(); + desc->m_ReloadEffect = forceReload; + SetSelectedEffect(layer, effectPath); + } + } + SLayerHolder *layer = GetLayerForSEmitterDesc(desc); + if (layer != null && !unload.Contains(layer)) + { + if (layer != null) + { + CString relativeSrcPath = CFilePath::Relativize(m_AEProjectPath.Data(), root.Data()); + + desc->m_PathSource = !relativeSrcPath.Empty() ? relativeSrcPath.Data() : root.Data(); + desc->m_ReloadEffect = forceReload; + SetSelectedEffect(layer, effectPath); + } + } + } + return true; +} + +//---------------------------------------------------------------------------- + +bool CPopcornFXWorld::SetSelectedEffectAsync(SLayerHolder *targetLayer, CString &name) +{ + PK_ASSERT(targetLayer != null); + + PK_SCOPEDLOCK(m_UIEventLock); + + SUIEventString *event = PK_NEW(SUIEventString); + + event->m_TargetLayer = targetLayer; + event->m_Cb = FastDelegate(this, &CPopcornFXWorld::SetSelectedEffect); + event->m_Data = name; + + return m_UIEvents.PushBack(event).Valid(); +} + +//---------------------------------------------------------------------------- + +bool CPopcornFXWorld::SetEffectDefaultTransform(SLayerHolder *layer, const CFloat3 &position, const CFloat3 &rotation) +{ + (void)rotation; + if (layer == null) + return false; + + AEGP_SuiteHandler suites(m_Suites); + A_Err result = A_Err_NONE; + A_Time time; + + time.value = 0; + time.scale = layer->m_TimeScale; + + A_long effectCount = 0; + result |= suites.EffectSuite4()->AEGP_GetLayerNumEffects(layer->m_EffectLayer, &effectCount); + + for (A_long j = effectCount - 1; j >= 0; --j) + { + AEGP_EffectRefH effectRef = null; + AEGP_InstalledEffectKey installedKey; + + result |= suites.EffectSuite4()->AEGP_GetLayerEffectByIndex(m_AEGPID, layer->m_EffectLayer, j, &effectRef); + result |= suites.EffectSuite4()->AEGP_GetInstalledKeyFromLayerEffect(effectRef, &installedKey); + + if (installedKey == GetPluginEffectKey(EPKChildPlugins::EMITTER)) + { + CFloat4x4 viewMatrix; + CFloat4 cameraPos; + float cameraZoom = 0.f; + + CAEUpdater::GetCameraViewMatrixAtTime(layer, viewMatrix, cameraPos, time, cameraZoom); + + CFloat3 forward = viewMatrix.Inverse().StrippedZAxis().Normalized(); + + CFloat3 emitterPos = cameraPos.xyz() + forward * position.Length(); + + AEGP_StreamRefH streamPos = null; + result |= suites.StreamSuite5()->AEGP_GetNewEffectStreamByIndex(m_AEGPID, effectRef, CAEUpdater::s_EmitterIndexes[Effect_Parameters_Position], &streamPos); + PK_ASSERT(result == A_Err_NONE); + if (result != A_Err_NONE || streamPos == null) + { + result |= suites.EffectSuite4()->AEGP_DisposeEffect(effectRef); + return false; + } + AEGP_StreamValue2 value; + result |= suites.StreamSuite5()->AEGP_GetNewStreamValue(m_AEGPID, streamPos, AEGP_LTimeMode_LayerTime, &time, false, &value); + if (result != A_Err_NONE) + { + result |= suites.EffectSuite4()->AEGP_DisposeEffect(effectRef); + return false; + } + value.val.three_d.x = emitterPos.x(); + value.val.three_d.y = emitterPos.y(); + value.val.three_d.z = emitterPos.z(); + result |= suites.StreamSuite5()->AEGP_SetStreamValue(m_AEGPID, streamPos, &value); + if (result != A_Err_NONE) + { + result |= suites.EffectSuite4()->AEGP_DisposeEffect(effectRef); + return false; + } + result |= suites.StreamSuite5()->AEGP_DisposeStreamValue(&value); + result |= suites.StreamSuite5()->AEGP_DisposeStream(streamPos); + } + result |= suites.EffectSuite4()->AEGP_DisposeEffect(effectRef); + + } + return true; +} + + +//---------------------------------------------------------------------------- + +bool CPopcornFXWorld::SetBackdropMeshDefaultTransform(SLayerHolder *layer) +{ + if (layer == null) + return false; + + AEGP_SuiteHandler suites(m_Suites); + A_Err result = A_Err_NONE; + A_Time time; + + time.value = 0; + time.scale = layer->m_TimeScale; + + A_long effectCount = 0; + result |= suites.EffectSuite4()->AEGP_GetLayerNumEffects(layer->m_EffectLayer, &effectCount); + + for (A_long j = effectCount - 1; j >= 0; --j) + { + AEGP_EffectRefH effectRef = null; + AEGP_InstalledEffectKey installedKey; + + result |= suites.EffectSuite4()->AEGP_GetLayerEffectByIndex(m_AEGPID, layer->m_EffectLayer, j, &effectRef); + result |= suites.EffectSuite4()->AEGP_GetInstalledKeyFromLayerEffect(effectRef, &installedKey); + + if (installedKey == GetPluginEffectKey(EPKChildPlugins::EMITTER)) + { + A_FloatPoint3 emitterPos = layer->m_SpawnedEmitter.m_Desc->m_Position; + + AEGP_StreamRefH streamPos = null; + result |= suites.StreamSuite5()->AEGP_GetNewEffectStreamByIndex(m_AEGPID, effectRef, CAEUpdater::s_EmitterIndexes[Effect_Parameters_BackdropMesh_Position], &streamPos); + PK_ASSERT(result == A_Err_NONE); + if (result != A_Err_NONE || streamPos == null) + { + result |= suites.EffectSuite4()->AEGP_DisposeEffect(effectRef); + return false; + } + AEGP_StreamValue2 value; + result |= suites.StreamSuite5()->AEGP_GetNewStreamValue(m_AEGPID, streamPos, AEGP_LTimeMode_LayerTime, &time, false, &value); + if (result != A_Err_NONE) + { + result |= suites.EffectSuite4()->AEGP_DisposeEffect(effectRef); + return false; + } + value.val.three_d.x = emitterPos.x; + value.val.three_d.y = emitterPos.y; + value.val.three_d.z = emitterPos.z; + result |= suites.StreamSuite5()->AEGP_SetStreamValue(m_AEGPID, streamPos, &value); + if (result != A_Err_NONE) + { + result |= suites.EffectSuite4()->AEGP_DisposeEffect(effectRef); + return false; + } + result |= suites.StreamSuite5()->AEGP_DisposeStreamValue(&value); + result |= suites.StreamSuite5()->AEGP_DisposeStream(streamPos); + } + result |= suites.EffectSuite4()->AEGP_DisposeEffect(effectRef); + + } + return true; +} + +//---------------------------------------------------------------------------- + +bool CPopcornFXWorld::SetSelectedEffect(SLayerHolder *layer, CString &fileName) +{ + if (layer != null) + { + PK_SCOPEDLOCK(layer->m_LayerLock); + SEmitterDesc *desc = layer->m_SpawnedEmitter.m_Desc; + CString name = CFilePath::StripExtension(fileName); + if (desc) + { + bool setTransform = false; + CString oldName = CFilePath::StripExtension(CString(desc->m_Name.c_str())); + if (!name.Compare(oldName)) + { + setTransform = true; + ClearAttributesAndSamplers(layer); + if (layer->m_LayerProperty != null) + { + CLayerProperty::_TypeOfRendererProperties overrides = layer->m_LayerProperty->RendererProperties(); + + overrides.Clear(); + layer->m_LayerProperty->SetRendererProperties(overrides); + } + } + + SetDestinationPackFromPath(*layer, layer->m_SpawnedEmitter.m_Desc->m_PathSource.data()); + if (!layer->m_Scene->SetPack(layer->m_BakedPack, desc->m_ReloadEffect)) + return false; + + //Set Default Effect position according to the Editor + { + //Load Editor information into the effect + if (setTransform) + { + IFileSystem *fileSystem = File::DefaultFileSystem(); + CString pkboPath = layer->m_BakedPack->Path() / name + ".pkbo"; + u32 rawFileSize = 0; + u8 *rawFileBuffer = fileSystem->Bufferize(pkboPath, &rawFileSize, true); + if (rawFileBuffer != null) + { + CConstMemoryStream memoryFileView(rawFileBuffer, rawFileSize); + + PBaseObjectFile pkboFile = layer->m_Scene->GetContext()->LoadFileFromStream(memoryFileView, pkboPath); + PEditorAssetEffect editorProp = pkboFile->FindFirstOf(); + + CFloat3 emitterDefaultPosition = -editorProp->StartCameraPosition(); + CFloat3 emitterDefaultOrientation = -editorProp->StartCameraOrientation(); + + SetEffectDefaultTransform(layer, emitterDefaultPosition, emitterDefaultOrientation); + } + } + } + + + if (!layer->m_Scene->SetSelectedEffect(fileName, desc->m_ReloadEffect)) + return false; + + desc->m_Name = fileName.Data(); + desc->m_Update = true; + return true; + } + } + return true; +} + +//---------------------------------------------------------------------------- + +// - OpenGL resources are restricted per thread, mimicking the OGL driver +// - The filter will eliminate all TLS (Thread Local Storage) at PF_Cmd_GLOBAL_SETDOWN +PAAERenderContext CPopcornFXWorld::GetCurrentRenderContext() +{ + // Lazy init: + if (s_AAEThreadRenderContexts == null) + { + s_AAEThreadRenderContexts = PK_NEW(CAAERenderContext); + s_ShaderLoader = PK_NEW(PKSample::CShaderLoader); + + if (!PK_VERIFY(s_AAEThreadRenderContexts != null && s_ShaderLoader != null)) + return null; + + s_AAEThreadRenderContexts->SetShaderLoader(s_ShaderLoader); + + if (!PK_VERIFY(s_AAEThreadRenderContexts->InitializeIFN(GetRenderApi(), CString::Format("PopcornFXRendering")))) + return null; + } + return s_AAEThreadRenderContexts; +} + +//---------------------------------------------------------------------------- + +bool CPopcornFXWorld::SetPanelInstance(CPanelBaseGUI *panel) +{ + m_Panel = panel; + return true; +} + +//---------------------------------------------------------------------------- + +A_Err CPopcornFXWorld::CreatePanelHook( AEGP_GlobalRefcon pluginRefconP, + AEGP_CreatePanelRefcon refconP, + AEGP_PlatformViewRef container, + AEGP_PanelH panelH, + AEGP_PanelFunctions1 *outFunctionTable, + AEGP_PanelRefcon *outRefcon) +{ + (void)pluginRefconP; + (void)refconP; + + CPopcornFXWorld &instance = AEGPPk::CPopcornFXWorld::Instance(); + + instance.CreatePanel(container, panelH, outFunctionTable, outRefcon); + return A_Err_NONE; +} + +//---------------------------------------------------------------------------- + +A_Err CPopcornFXWorld::CommandHook( AEGP_GlobalRefcon plugin_refconP, + AEGP_CommandRefcon refconP, + AEGP_Command command, + AEGP_HookPriority hook_priority, + A_Boolean already_handledB, + A_Boolean *handledPB) +{ + (void)refconP; + (void)plugin_refconP; + + CPopcornFXWorld &instance = AEGPPk::CPopcornFXWorld::Instance(); + + instance.Command(command, hook_priority, already_handledB, handledPB); + return A_Err_NONE; +} + +//---------------------------------------------------------------------------- + +A_Err CPopcornFXWorld::UpdateMenuHook(AEGP_GlobalRefcon pluginRefconP, + AEGP_UpdateMenuRefcon refconP, + AEGP_WindowType activeWindow) +{ + (void)refconP; + (void)pluginRefconP; + + CPopcornFXWorld &instance = AEGPPk::CPopcornFXWorld::Instance(); + + instance.UpdateMenu(activeWindow); + return A_Err_NONE; +} + +//---------------------------------------------------------------------------- + +void CPopcornFXWorld::OnEndSetupScene() +{ + if (m_Panel) + { + m_Panel->UpdateScenesModel(); + } +} + +const PBaseObjectFile &CPopcornFXWorld::GetProjectConfFile() +{ + return m_ProjectConfFile; +} + +//---------------------------------------------------------------------------- + +bool CPopcornFXWorld::GetMostRecentCompName(CString &compName) +{ + AEGP_SuiteHandler suites(m_Suites); + AEGP_CompH compH = null; + AEGP_ItemH itemH = null; + AEGP_MemHandle memH = null; + aechar_t *compositionNameAE = null; + CString compositionName = ""; + PF_Err result = A_Err_NONE; + result |= suites.CompSuite11()->AEGP_GetMostRecentlyUsedComp(&compH); + if (result != A_Err_NONE) + return false; + if (compH != null) + { + result |= suites.CompSuite11()->AEGP_GetItemFromComp(compH, &itemH); + if (result != A_Err_NONE) + return false; + result |= suites.ItemSuite9()->AEGP_GetItemName(m_AEGPID, itemH, &memH); + + result |= suites.MemorySuite1()->AEGP_LockMemHandle(memH, reinterpret_cast(&compositionNameAE)); + + WCharToCString(compositionNameAE, &compositionName); + + result |= suites.MemorySuite1()->AEGP_UnlockMemHandle(memH); + result |= suites.MemorySuite1()->AEGP_FreeMemHandle(memH); + + compName = compositionName; + } + return true; +} + +//---------------------------------------------------------------------------- + +bool CPopcornFXWorld::SetLayerName(SLayerHolder *layer) +{ + A_Err result = A_Err_NONE; + AEGP_SuiteHandler suites(m_Suites); + AEGP_ItemH itemH = null; + AEGP_MemHandle memH = null; + aechar_t *layerNameAE = null; + CString layerName = ""; + + result |= suites.LayerSuite8()->AEGP_GetLayerSourceItem(layer->m_EffectLayer, &itemH); + if (result != A_Err_NONE) + return false; + + result |= suites.ItemSuite9()->AEGP_GetItemName(m_AEGPID, itemH, &memH); + if (result != A_Err_NONE) + return false; + + result |= suites.MemorySuite1()->AEGP_LockMemHandle(memH, reinterpret_cast(&layerNameAE)); + if (result != A_Err_NONE) + return false; + + WCharToCString(layerNameAE, &layerName); + + result |= suites.MemorySuite1()->AEGP_UnlockMemHandle(memH); + if (result != A_Err_NONE) + return false; + result |= suites.MemorySuite1()->AEGP_FreeMemHandle(memH); + if (result != A_Err_NONE) + return false; + + layer->m_LayerName = layerName; + + return true; +} + +//---------------------------------------------------------------------------- + +bool CPopcornFXWorld::SetLayerCompName(SLayerHolder *layer) +{ + A_Err result = A_Err_NONE; + AEGP_SuiteHandler suites(m_Suites); + AEGP_CompH compH = null; + AEGP_ItemH itemH = null; + AEGP_MemHandle memH = null; + aechar_t *compositionNameAE = null; + CString compositionName = ""; + result |= suites.LayerSuite5()->AEGP_GetLayerParentComp(layer->m_EffectLayer, &compH); + if (result != A_Err_NONE) + return false; + result |= suites.CompSuite11()->AEGP_GetItemFromComp(compH, &itemH); + if (result != A_Err_NONE) + return false; + result |= suites.ItemSuite9()->AEGP_GetItemName(m_AEGPID, itemH, &memH); + if (result != A_Err_NONE) + return false; + result |= suites.MemorySuite1()->AEGP_LockMemHandle(memH, reinterpret_cast(&compositionNameAE)); + if (result != A_Err_NONE) + return false; + WCharToCString(compositionNameAE, &compositionName); + + result |= suites.MemorySuite1()->AEGP_UnlockMemHandle(memH); + if (result != A_Err_NONE) + return false; + result |= suites.MemorySuite1()->AEGP_FreeMemHandle(memH); + if (result != A_Err_NONE) + return false; + layer->m_CompositionName = compositionName; + if (m_MostRecentCompName != compositionName) + { + if (m_Panel) + m_Panel->UpdateScenesModel(); + m_MostRecentCompName = compositionName; + } + return true; +} + +//---------------------------------------------------------------------------- + +bool CPopcornFXWorld::CreateLayerPropertyIFP(SLayerHolder *layer) +{ + if (m_ProjectProperty == null) + return false; + + // Go through all objects in file: + for (const auto &obj : m_ProjectProperty->LayerProperties()) + { + if (obj->ID() == layer->ID && + obj->CompName() == layer->m_CompositionName) + layer->m_LayerProperty = obj.Get(); + + } + if (layer->m_LayerProperty == null) + { + CAEPProjectProperties::_TypeOfLayerProperties LayerProps = m_ProjectProperty->LayerProperties(); + PLayerProperty prop = m_ProjectProperty->File()->Context()->NewObject(m_ProjectConfFile.Get()); + + if (!LayerProps.PushBack(prop).Valid()) + return false; + layer->m_LayerProperty = prop; + + prop->SetCompName(layer->m_CompositionName); // Useless ? + prop->SetID(layer->ID); + + m_ProjectProperty->SetLayerProperties(LayerProps); + } + return true; +} + +//---------------------------------------------------------------------------- + +bool CPopcornFXWorld::SetResourceOverride(CStringId layerID, u32 rdrID, u32 propID, const CString &value) +{ + IFileSystem *fileSystem = File::DefaultFileSystem(); + SLayerHolder *layerHolder = GetLayerForSEmitterDescID(layerID); + + if (layerHolder == null || layerHolder->m_LayerProperty == null) + return false; + + PK_SCOPEDLOCK(layerHolder->m_LayerLock); + CLayerProperty::_TypeOfRendererProperties overrides = layerHolder->m_LayerProperty->RendererProperties(); + CGraphicOverride *existingOverride = null; + bool updated = false; + for (const auto &entry : overrides) + { + if (entry->RendererID() == rdrID && entry->PropertyID() == propID) + { + existingOverride = entry.Get(); + if (value.Empty()) + { + overrides.RemoveElementFromRawPointerInArray_AndKeepOrder(&entry); + layerHolder->m_LayerProperty->SetRendererProperties(overrides); + updated = true; + } + break; + } + } + + if (!value.Empty()) + { + AEGPPk::SResourceBakeConfig bakeConfig; + bakeConfig.m_StraightCopy = true; + CString virtualPath = fileSystem->PhysicalToVirtual(value); + if (virtualPath == null) //Not in loaded packs, bake into resources folder + { + virtualPath = fileSystem->PhysicalToVirtual(GetVaultHandler().BakeResource(value, bakeConfig)); + } + if (existingOverride != null) + { + if (!existingOverride->Value().Compare(virtualPath)) + { + existingOverride->SetValue(virtualPath); + updated = true; + } + } + else + { + PGraphicOverride prop = m_ProjectProperty->File()->Context()->NewObject(m_ProjectConfFile.Get()); + + prop->SetRendererID(rdrID); + prop->SetPropertyID(propID); + prop->SetValue(virtualPath); + + if (!overrides.PushBack(prop).Valid()) + return false; + + layerHolder->m_LayerProperty->SetRendererProperties(overrides); + updated = true; + } + } + if (updated) + { + layerHolder->m_ForceRender = true; + WriteProjectFileModification(); + layerHolder->m_Scene->SetupScene(true, true); + + } + return true; +} + +//---------------------------------------------------------------------------- + +bool CPopcornFXWorld::WriteProjectFileModification() +{ + if (m_ProjectConfFile == null) + return false; + IFileSystem *fs = File::DefaultFileSystem(); + + if (fs->Exists(m_AEProjectPath, true)) + { + if (!PK_VERIFY(HBO::g_Context->WriteFile(m_ProjectConfFile.Get(), m_ProjectConfFile->Path()))) + return false; + } + return true; +} + +//---------------------------------------------------------------------------- +__AEGP_PK_END diff --git a/AE_GeneralPlugin/Sources/AE_GeneralPlugin.plugin-Info.plist b/AE_GeneralPlugin/Sources/AE_GeneralPlugin.plugin-Info.plist new file mode 100644 index 00000000..129eef34 --- /dev/null +++ b/AE_GeneralPlugin/Sources/AE_GeneralPlugin.plugin-Info.plist @@ -0,0 +1,24 @@ + + + + + CFBundleExecutable + Main + CFBundleIdentifier + com.PersistantStudio.PopcornFX.Main + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + AE_GeneralPlugin + CFBundlePackageType + AEgx + CFBundleSignature + FXTC + LSRequiresCarbon + + NSAppleScriptEnabled + No + NSHumanReadableCopyright + © PersistantStudio PopcornFX + + diff --git a/AE_GeneralPlugin/Sources/AE_GeneralPlugin_PiPL.r b/AE_GeneralPlugin/Sources/AE_GeneralPlugin_PiPL.r new file mode 100644 index 00000000..bb8ce5ab --- /dev/null +++ b/AE_GeneralPlugin/Sources/AE_GeneralPlugin_PiPL.r @@ -0,0 +1,41 @@ +#include "AEConfig.h" +#include "AE_EffectVers.h" + +#ifndef AE_OS_WIN + #include +#endif + +resource 'PiPL' (16000) { + { /* array properties: 7 elements */ + /* [1] */ + Kind { + AEGP + }, + /* [2] */ + Name { + "PopcornFX" + }, + /* [3] */ + Category { + "Particle Plugin" + }, + /* [4] */ + Version { + 65536 + }, + /* [5] */ +#ifdef AE_OS_WIN + #ifdef AE_PROC_INTELx64 + CodeWin64X86 {"EntryPointFunc"}, + #else + CodeWin32X86 {"EntryPointFunc"}, + #endif +#else + #ifdef AE_OS_MAC + CodeMachOPowerPC {"EntryPointFunc"}, + CodeMacIntel32 {"EntryPointFunc"}, + CodeMacIntel64 {"EntryPointFunc"}, + #endif +#endif + } +}; diff --git a/AE_GeneralPlugin/Sources/Panels/AEGP_GraphicalResourcesTreeModel.cpp b/AE_GeneralPlugin/Sources/Panels/AEGP_GraphicalResourcesTreeModel.cpp new file mode 100644 index 00000000..fa26bb72 --- /dev/null +++ b/AE_GeneralPlugin/Sources/Panels/AEGP_GraphicalResourcesTreeModel.cpp @@ -0,0 +1,931 @@ +//---------------------------------------------------------------------------- +// Copyright Persistant Studios, SARL. All Rights Reserved. https://www.popcornfx.com/terms-and-conditions/ +//---------------------------------------------------------------------------- +#include + +#include "Panels/AEGP_GraphicalResourcesTreeModel.h" +#include "AEGP_World.h" +#include "AEGP_Scene.h" +#include "AEGP_LayerHolder.h" +#include "AEGP_AEPKConversion.h" + +#include + +#include + +//---------------------------------------------------------------------------- + +__AEGP_PK_BEGIN + +const QSize kGraphicResourceThumbSize = QSize(35, 35); +const QSize kResetButtonSize = QSize(16, 16); + +//---------------------------------------------------------------------------- + +CGraphicResetButtonView::CGraphicResetButtonView() +{ + m_Pixmap = QPixmap(":/icons/reset.png"); +} + +//---------------------------------------------------------------------------- + +void CGraphicResetButtonView::paint(QPainter *painter, const QRect &rect, const QPalette &palette, bool hover) const +{ + (void)palette; + (void)hover; + const QRect displayRect = QRect(QPoint(rect.x(), rect.y()), sizeHint()).adjusted(1, 1, -1, -1); + painter->drawPixmap(displayRect, m_Pixmap); +} + +//---------------------------------------------------------------------------- + +QSize CGraphicResetButtonView::sizeHint() const +{ + return kResetButtonSize + QSize(2, 2); +} + +//---------------------------------------------------------------------------- +// +//---------------------------------------------------------------------------- + +CGraphicResourceView::CGraphicResourceView() + : m_Type(CGraphicResourceView::ViewType::ViewType_Effect) +{ + +} + +//---------------------------------------------------------------------------- + +CGraphicResourceView::CGraphicResourceView(CGraphicResourceView::ViewType type) + : m_Type(type) +{ + +} + +//---------------------------------------------------------------------------- + +CGraphicResourceView::CGraphicResourceView(CGraphicResourceView::ViewType type, const QPixmap &pixmap) + : m_Type(type) + , m_Pixmap(pixmap) +{ + +} + +//---------------------------------------------------------------------------- + +static s32 _Align(s32 v, s32 alignment) +{ + return v - v % alignment; +} + +//---------------------------------------------------------------------------- + +static void _DrawCheckerboard( QPainter &painter, const QRect &displayRect, const QRect &visibleRect, + const QColor &baseColor, const QColor &alternateColor, s32 patternSize) +{ + PK_ASSERT(patternSize > 0); + const s32 offsetX = displayRect.left(); + const s32 offsetY = displayRect.top(); + for (s32 py = visibleRect.top(), stopY = visibleRect.bottom(); py <= stopY; ) + { + const s32 startY = py; + const s32 endY = PKMin(stopY + 1, _Align(startY - offsetY + patternSize, patternSize) + offsetY); + for (s32 px = visibleRect.left(), stopX = visibleRect.right(); px <= stopX; ) + { + const s32 startX = px; + const s32 endX = PKMin(stopX + 1, _Align(startX - offsetX + patternSize, patternSize) + offsetX); + + const s32 tileIdX = (px - offsetX) / patternSize; + const s32 tileIdY = (py - offsetY) / patternSize; + const bool evenTile = ((tileIdX ^ tileIdY) & 1) != 0; + + const QRect tileRect(startX, startY, endX - startX, endY - startY); + const QColor tileColor = evenTile ? baseColor : alternateColor; + painter.fillRect(tileRect, tileColor); + + px = endX; + } + py = endY; + } +} + +void CGraphicResourceView::paint(QPainter *painter, const QRect &rect, const QPalette &palette, bool hover) const +{ + (void)palette; + + if (m_Type == ViewType::ViewType_PathResource) + { + if (hover) + { + QPixmap pix = QPixmap(sizeHint()); + pix.fill(QColor(255, 255, 255, 128)); + const QRect displayRect = QRect(QPoint(rect.x(), rect.y()), sizeHint()); + painter->drawPixmap(displayRect, pix); + } + + // Display a checkerboard background + const QColor chkColorA = QColor(0x30, 0x30, 0x30, 0xFF); + const QColor chkColorB = QColor(0x40, 0x40, 0x40, 0xFF); + const QRect displayRect = QRect(QPoint(rect.x(), rect.y()), sizeHint()).adjusted(1, 1, -1, -1); + const QRect visibleRect = displayRect & rect; + + _DrawCheckerboard(*painter, displayRect, visibleRect, chkColorA, chkColorB, 5); + + painter->drawPixmap(displayRect, m_Pixmap); + } +} + +//---------------------------------------------------------------------------- + +QSize CGraphicResourceView::sizeHint() const +{ + if (m_Type == ViewType::ViewType_PathResource) + return kGraphicResourceThumbSize + QSize(2, 2); + + return 0.1f/*PaintingScaleFactor*/ * QSize(1, 1); +} + +//---------------------------------------------------------------------------- +// +//---------------------------------------------------------------------------- + +void CGraphicResourceDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const +{ + if (index.data().canConvert()) + { + CGraphicResourceView item = qvariant_cast(index.data()); + item.paint(painter, option.rect, option.palette, option.state & QStyle::State_MouseOver); + } + if (index.data().canConvert()) + { + CGraphicResetButtonView item = qvariant_cast(index.data()); + item.paint(painter, option.rect, option.palette, option.state & QStyle::State_MouseOver); + } + else + { + //Remove Selected and MouseOver state for visual + QStyleOptionViewItem modifiedOption = option; + modifiedOption.state &= ~QStyle::State_Selected; + modifiedOption.state &= ~QStyle::State_MouseOver; + modifiedOption.state &= ~QStyle::State_HasFocus; + + QStyledItemDelegate::paint(painter, modifiedOption, index); + } +} + +//---------------------------------------------------------------------------- + +QSize CGraphicResourceDelegate::sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const +{ + if (index.data().canConvert()) + { + CGraphicResourceView item = qvariant_cast(index.data()); + return item.sizeHint(); + } + return QStyledItemDelegate::sizeHint(option, index); +} + +//---------------------------------------------------------------------------- +// +//---------------------------------------------------------------------------- + +CGraphicalResourcesTreeItem::CGraphicalResourcesTreeItem() + : m_ParentItem(null) +{ +} + +//---------------------------------------------------------------------------- + +CGraphicalResourcesTreeItem::CGraphicalResourcesTreeItem(const QVector &data, CGraphicalResourcesTreeItem *parentItem) + : m_ItemData(data) + , m_ParentItem(parentItem) +{ +} + +//---------------------------------------------------------------------------- + +CGraphicalResourcesTreeItem::~CGraphicalResourcesTreeItem() +{ + qDeleteAll(m_ChildItems); +} + +//---------------------------------------------------------------------------- + +void CGraphicalResourcesTreeItem::AppendChild(CGraphicalResourcesTreeItem *child) +{ + m_ChildItems.append(child); +} + +//---------------------------------------------------------------------------- + +void CGraphicalResourcesTreeItem::InsertChild(CGraphicalResourcesTreeItem *child, int index) +{ + m_ChildItems.insert(index, child); +} + +//---------------------------------------------------------------------------- + +CGraphicalResourcesTreeItem *CGraphicalResourcesTreeItem::Child(int row) +{ + if (row < 0 || row >= m_ChildItems.size()) + return nullptr; + return m_ChildItems.at(row); +} + +//---------------------------------------------------------------------------- + +int CGraphicalResourcesTreeItem::ChildCount() const +{ + return m_ChildItems.count(); +} + +//---------------------------------------------------------------------------- + +int CGraphicalResourcesTreeItem::ColumnCount() const +{ + return m_ItemData.count(); +} + +//---------------------------------------------------------------------------- + +QVariant CGraphicalResourcesTreeItem::Data(int column) const +{ + //Crash on close + if (column < 0 || column >= m_ItemData.size()) + return QVariant(); + return m_ItemData.at(column); +} + +//---------------------------------------------------------------------------- + +int CGraphicalResourcesTreeItem::Row() const +{ + if (m_ParentItem) + return m_ParentItem->m_ChildItems.indexOf(const_cast(this)); // yuck, ugly + + return 0; +} + +//---------------------------------------------------------------------------- + +CGraphicalResourcesTreeItem *CGraphicalResourcesTreeItem::ParentItem() +{ + return m_ParentItem; +} + +//---------------------------------------------------------------------------- + +void CGraphicalResourcesTreeItem::ClearChildren() +{ + qDeleteAll(m_ChildItems); + m_ChildItems.clear(); +} + +//---------------------------------------------------------------------------- + +void CGraphicalResourcesTreeItem::RemoveChild(int index) +{ + delete m_ChildItems[index]; + m_ChildItems.remove(index); +} + +//---------------------------------------------------------------------------- + +void CGraphicalResourcesTreeItem::RemoveChildren(int from, int count) +{ + for (int i = from; i < from + count; ++i) + delete m_ChildItems[i]; + m_ChildItems.remove(from, count); +} + +//---------------------------------------------------------------------------- + +void CGraphicalResourcesTreeItem::SetData(int column, const QVariant &data) +{ + if (column < 0 || column >= m_ItemData.size()) + return; + m_ItemData[column] = data; +} + +//---------------------------------------------------------------------------- +// +//---------------------------------------------------------------------------- + +CGraphicalResourcesTreeModel::CGraphicalResourcesTreeModel(QObject *parent) + : QAbstractItemModel(parent) + , m_RootItem(null) +{ + m_RootItem = new CGraphicalResourcesTreeItem({ tr("Layer"), tr("Path"), QVariant::fromValue(CGraphicResourceView(CGraphicResourceView::ViewType::ViewType_Effect)), tr("") }); +} + +//---------------------------------------------------------------------------- + +CGraphicalResourcesTreeModel::~CGraphicalResourcesTreeModel() +{ + if (m_RootItem) + delete m_RootItem; +} + +//---------------------------------------------------------------------------- + +QVariant CGraphicalResourcesTreeModel::data(const QModelIndex &index, int role) const +{ + if (!index.isValid()) + return QVariant(); + + if (role != Qt::DisplayRole) + return QVariant(); + + CGraphicalResourcesTreeItem *item = static_cast(index.internalPointer()); + + return item->Data(index.column()); +} + +//---------------------------------------------------------------------------- + +CGraphicalResourcesTreeItem *CGraphicalResourcesTreeModel::Item(const QModelIndex &index) const +{ + if (!index.isValid()) + return null; + + CGraphicalResourcesTreeItem *item = static_cast(index.internalPointer()); + + return item; +} + +//---------------------------------------------------------------------------- + +QModelIndex CGraphicalResourcesTreeModel::Index(CGraphicalResourcesTreeItem *item) const +{ + if (item == m_RootItem) + return QModelIndex(); + + return index(item->Row(), 0, Index(item->ParentItem())); +} + +//---------------------------------------------------------------------------- + +Qt::ItemFlags CGraphicalResourcesTreeModel::flags(const QModelIndex &index) const +{ + if (!index.isValid()) + return Qt::NoItemFlags; + + return QAbstractItemModel::flags(index); +} + +//---------------------------------------------------------------------------- + +QVariant CGraphicalResourcesTreeModel::headerData(int section, Qt::Orientation orientation, int role) const +{ + if (orientation == Qt::Horizontal && role == Qt::DisplayRole) + return m_RootItem->Data(section); + + return QVariant(); +} + +//---------------------------------------------------------------------------- + +QModelIndex CGraphicalResourcesTreeModel::index(int row, int column, const QModelIndex &parent) const +{ + if (!hasIndex(row, column, parent)) + return QModelIndex(); + + CGraphicalResourcesTreeItem *parentItem; + + if (!parent.isValid()) + parentItem = m_RootItem; + else + parentItem = static_cast(parent.internalPointer()); + + CGraphicalResourcesTreeItem *childItem = parentItem->Child(row); + if (childItem) + return createIndex(row, column, childItem); + return QModelIndex(); +} + +//---------------------------------------------------------------------------- + +QModelIndex CGraphicalResourcesTreeModel::parent(const QModelIndex &index) const +{ + if (!index.isValid()) + return QModelIndex(); + + CGraphicalResourcesTreeItem *childItem = static_cast(index.internalPointer()); + if (childItem == m_RootItem) + return QModelIndex(); + + CGraphicalResourcesTreeItem *parentItem = childItem->ParentItem(); + + if (parentItem == m_RootItem) + return QModelIndex(); + + return createIndex(parentItem->Row(), 0, parentItem); +} + +//---------------------------------------------------------------------------- + +int CGraphicalResourcesTreeModel::rowCount(const QModelIndex &parent) const +{ + CGraphicalResourcesTreeItem *parentItem; + if (parent.column() > 0) + return 0; + + if (!parent.isValid()) + parentItem = m_RootItem; + else + parentItem = static_cast(parent.internalPointer()); + + return parentItem->ChildCount(); +} + +//---------------------------------------------------------------------------- + +int CGraphicalResourcesTreeModel::columnCount(const QModelIndex &parent) const +{ + if (parent.isValid()) + return static_cast(parent.internalPointer())->ColumnCount(); + return m_RootItem->ColumnCount(); +} + +//---------------------------------------------------------------------------- + +void CGraphicalResourcesTreeModel::UpdateModel() +{ + if (m_RootItem == null) + return; + + CPopcornFXWorld &instance = AEGPPk::CPopcornFXWorld::Instance(); + CString compositionName = ""; + + if (!instance.GetMostRecentCompName(compositionName)) + return; + + const bool reset = compositionName != m_CompositionName; + + m_CompositionName = compositionName; + if (!reset) + _UpdateModel(); + else + _ResetModel(); +} + +//---------------------------------------------------------------------------- + +void CGraphicalResourcesTreeModel::_UpdateModel() +{ + _UnflagUpdated(m_RootItem); + + CPopcornFXWorld &instance = AEGPPk::CPopcornFXWorld::Instance(); + TArray &layers = instance.GetLayers(); + u32 effectCount = 0; + + for (u32 i = 0; i < layers.Count(); ++i) + { + PK_SCOPEDLOCK(layers[i]->m_LayerLock); + + if (layers[i]->m_Deleted == true) + continue; + if (layers[i]->m_SpawnedEmitter.m_Desc != null) + { + if (layers[i]->m_CompositionName != m_CompositionName) + continue; + + const QString layerName(layers[i]->m_LayerName.Data()); + const QString emitterName(layers[i]->m_SpawnedEmitter.m_Desc->m_Name.c_str()); + const CStringId emitterUID = CStringId(layers[i]->m_SpawnedEmitter.m_Desc->m_UUID.c_str()); + + if (emitterName.isEmpty()) + continue; + + // Find effect or create it + CGraphicalResourcesTreeItem *effect = _FindChild(m_RootItem, emitterUID.Id()); + + if (effect == null) + { + beginInsertRows(Index(m_RootItem), effectCount, effectCount); + effect = _CreateEffect(layerName, emitterName, emitterUID.Id()); + m_RootItem->InsertChild(effect, effectCount); + endInsertRows(); + } + else + { + // Update effect data + effect->SetData(0, layerName); + effect->SetData(1, emitterName); + } + effect->SetUpdated(true); + effectCount++; + + // Add properties + TArray &renderers = layers[i]->m_Scene->GetRenderers(); + THashMap effectLayers; + + for (u32 iRenderer = 0; iRenderer < renderers.Count(); ++iRenderer) + { + // Find effect layer or create it + const QString effectLayerName = renderers[iRenderer]->m_EffectLayerName.Data(); + const u32 effectLayerUID = renderers[iRenderer]->m_EffectLayerUID; + CGraphicalResourcesTreeItem *effectLayer = _FindChild(effect, effectLayerUID); + + if (effectLayer == null) + { + beginInsertRows(Index(effect), effectLayers.Count(), effectLayers.Count()); + effectLayer = _CreateEffectLayer(effectLayerName, effectLayerUID, effect); + effect->InsertChild(effectLayer, effectLayers.Count()); + endInsertRows(); + } + else + { + // Update effect layer data + effectLayer->SetData(0, effectLayerName); + } + effectLayer->SetUpdated(true); + + u32* propertyCount = effectLayers.Find(effectLayer); + if (propertyCount == null) + propertyCount = effectLayers.Insert(effectLayer, u32(0)); + + // Find renderer property or create it + const u32 propertyUID = renderers[iRenderer]->m_PropertyUID; + CGraphicalResourcesTreeItem *property = _FindChild(effectLayer, propertyUID); + + if (property == null) + { + beginInsertRows(Index(effectLayer), *propertyCount, *propertyCount); + property = _CreateRenderer(renderers[iRenderer], effectLayer); + effectLayer->InsertChild(property, *propertyCount); + endInsertRows(); + } + else + { + // Update property data + property->SetData(0, QString(renderers[iRenderer]->m_Name.Data())); + + const QString newPath = renderers[iRenderer]->m_Value.Data(); + if (property->Data(1) != newPath) + { + QPixmap pix; + if (!_LoadImageThumbnail(renderers[iRenderer]->m_Value, &pix)) + { + pix = QPixmap(kGraphicResourceThumbSize); + pix.fill(QColor(255, 0, 0, 128)); + + } + + property->SetData(1, newPath); + property->SetData(2, QVariant::fromValue(CGraphicResourceView(CGraphicResourceView::ViewType::ViewType_PathResource, pix))); + } + property->SetLayerID(renderers[iRenderer]->m_LayerID); + property->SetRendererID(renderers[iRenderer]->m_RendererUID); + } + property->SetUpdated(true); + *propertyCount++; + } + } + } + + _RemoveOldItems(m_RootItem); +} + +//---------------------------------------------------------------------------- + +void CGraphicalResourcesTreeModel::_ResetModel() +{ + CPopcornFXWorld &instance = AEGPPk::CPopcornFXWorld::Instance(); + TArray &layers = instance.GetLayers(); + + beginResetModel(); + + if (m_RootItem->ChildCount() != 0) + m_RootItem->ClearChildren(); + + for (u32 i = 0; i < layers.Count(); ++i) + { + PK_SCOPEDLOCK(layers[i]->m_LayerLock); + + if (layers[i]->m_SpawnedEmitter.m_Desc != null) + { + if (layers[i]->m_CompositionName != m_CompositionName) + continue; + + const QString layerName(layers[i]->m_LayerName.Data()); + const QString emitterName(layers[i]->m_SpawnedEmitter.m_Desc->m_Name.c_str()); + const CStringId emitterUID = CStringId(layers[i]->m_SpawnedEmitter.m_Desc->m_UUID.c_str()); + + if (emitterName.isEmpty()) + continue; + + CGraphicalResourcesTreeItem *effect = _CreateEffect(layerName, emitterName, emitterUID.Id()); + + m_RootItem->AppendChild(effect); + + TArray &renderers = layers[i]->m_Scene->GetRenderers(); + for (u32 iRenderer = 0; iRenderer < renderers.Count(); ++iRenderer) + { + const QString effectLayerName = renderers[iRenderer]->m_EffectLayerName.Data(); + const u32 effectLayerUID = renderers[iRenderer]->m_EffectLayerUID; + CGraphicalResourcesTreeItem *effectLayer = _FindChild(effect, effectLayerUID); + + if (effectLayer == null) + { + effectLayer = _CreateEffectLayer(effectLayerName, effectLayerUID, effect); + effect->AppendChild(effectLayer); + } + + CGraphicalResourcesTreeItem *rdr = _CreateRenderer(renderers[iRenderer], effectLayer); + effectLayer->AppendChild(rdr); + } + } + } + endResetModel(); + +} + +//---------------------------------------------------------------------------- + +CGraphicalResourcesTreeItem *CGraphicalResourcesTreeModel::_CreateEffect(const QString &layerName, const QString &emitterName, u32 uid) +{ + QVector effectData; + effectData.append(layerName); + effectData.append(emitterName); + effectData.append(QVariant::fromValue(CGraphicResourceView(CGraphicResourceView::ViewType::ViewType_Effect))); + effectData.append(QString("")); + + CGraphicalResourcesTreeItem *effect = new CGraphicalResourcesTreeItem(effectData, m_RootItem); + + effect->SetID(uid); + + return effect; +} + +//---------------------------------------------------------------------------- + +CGraphicalResourcesTreeItem *CGraphicalResourcesTreeModel::_CreateEffectLayer(const QString &layerName, u32 uid, CGraphicalResourcesTreeItem *effect) +{ + QVector effectData; + effectData.append(layerName); + effectData.append(QString("")); + effectData.append(QVariant::fromValue(CGraphicResourceView(CGraphicResourceView::ViewType::ViewType_Layer))); + effectData.append(QString("")); + + CGraphicalResourcesTreeItem *layer = new CGraphicalResourcesTreeItem(effectData, effect); + + layer->SetID(uid); + + return layer; +} + +//---------------------------------------------------------------------------- + +CGraphicalResourcesTreeItem *CGraphicalResourcesTreeModel::_CreateRenderer(SRendererProperties *renderer, CGraphicalResourcesTreeItem *layer) +{ + QPixmap pix; + + if (!_LoadImageThumbnail(renderer->m_Value, &pix)) + { + pix = QPixmap(kGraphicResourceThumbSize); + pix.fill(QColor(255, 0, 0, 128)); + } + + QVector rdrData; + rdrData << QString(renderer->m_Name.Data()); + rdrData << QString(renderer->m_Value.Data()); + rdrData << QVariant::fromValue(CGraphicResourceView(CGraphicResourceView::ViewType::ViewType_PathResource, pix)); + rdrData << QVariant::fromValue(CGraphicResetButtonView()); + + CGraphicalResourcesTreeItem *rdr = new CGraphicalResourcesTreeItem(rdrData, layer); + + rdr->SetLayerID(renderer->m_LayerID); + rdr->SetRendererID(renderer->m_RendererUID); + rdr->SetID(renderer->m_PropertyUID); + + return rdr; +} + +//---------------------------------------------------------------------------- + +CGraphicalResourcesTreeItem *CGraphicalResourcesTreeModel::_FindChild(CGraphicalResourcesTreeItem *parent, u32 childId) +{ + for (int i = 0; i < parent->ChildCount(); ++i) + { + CGraphicalResourcesTreeItem *item = parent->Child(i); + if (item->GetID() == childId) + return item; + } + return null; +} + +//---------------------------------------------------------------------------- + +void CGraphicalResourcesTreeModel::_UnflagUpdated(CGraphicalResourcesTreeItem* parent) +{ + + for (int i = 0; i < parent->ChildCount(); ++i) + { + CGraphicalResourcesTreeItem *item = parent->Child(i); + item->SetUpdated(false); + _UnflagUpdated(item); + } +} + +//---------------------------------------------------------------------------- + +void CGraphicalResourcesTreeModel::_RemoveOldItems(CGraphicalResourcesTreeItem* parent) +{ + QModelIndex parentIndex = Index(parent); + + for (int i = 0; i < parent->ChildCount(); ) + { + CGraphicalResourcesTreeItem *item = parent->Child(i); + if (!item->GetUpdated()) + { + beginRemoveRows(parentIndex, i, i); + parent->RemoveChild(i); + endRemoveRows(); + } + else + { + _RemoveOldItems(item); + ++i; + } + } +} + +//---------------------------------------------------------------------------- + +bool CGraphicalResourcesTreeModel::_LoadImageThumbnail(const CString &path, QPixmap *outThumbnail) +{ + const float dpr = 1.0f;// : MaxDevicePixelRatio(); + const QSize size = kGraphicResourceThumbSize * dpr; + + CResourceManager *resourceManager = Resource::DefaultManager(); + + if (!PK_VERIFY(outThumbnail != null)) + return false; + + if (!resourceManager->FileController()->Exists(path, false)) + return false; + + PImage resource; + const TResourcePtr resourcePtr = resourceManager->Load(path, false, SResourceLoadCtl(false, true)); + if (resourcePtr == null || resourcePtr->Empty()) + return false; + resource = resourcePtr.operator->(); + + if (resource == null) + return false; + + PK_ASSERT(!resource->m_Frames.Empty()); + const CImageFrame &frame = resource->m_Frames.First(); + PK_ASSERT(!frame.m_Mipmaps.Empty()); + const CImageMap &map = frame.m_Mipmaps.First(); + + CImageSurface surface(map, resource->m_Format); + QImage::Format targetFormat; + + switch (surface.m_Format) + { + case CImage::Format_BGR8: + targetFormat = QImage::Format_RGB888; + break; + case CImage::Format_BGRA8: + targetFormat = QImage::Format_RGBA8888; + break; + default: + targetFormat = QImage::Format_RGBA8888; + if (!PK_VERIFY(surface.Convert(CImage::Format_BGRA8))) + return false; + break; + } + + // Note: we do this analysis & alpha-patching before downscaling, as Qt will + // trash the RGB colors when downscaling with an alpha set to zero, for some reason... + if (targetFormat == QImage::Format_RGBA8888) + { + bool isFullyTransparent = false; + { + CUbyte4 *texels = surface.m_RawBuffer->Data(); + const CUbyte4 *texelsStop = texels + surface.m_Dimensions.x() * surface.m_Dimensions.y(); + + SIMD::Float4 texelORx4 = SIMD::Float4::Zero(); + texelsStop -= 4; + while (texels <= texelsStop) + { + texelORx4 |= SIMD::Float4::LoadAligned16(texels); + texels += 4; + } + texelsStop += 4; + + const u32 texelOR32 = texelORx4.x().AsUint() | texelORx4.y().AsUint() | texelORx4.z().AsUint() | texelORx4.w().AsUint(); + CUbyte4 texelOR = *reinterpret_cast(&texelOR32); + while (texels < texelsStop) + { + texelOR |= *texels; + texels++; + } + + isFullyTransparent = (texelOR.w() == 0); + } + + // Fix #3945: Editor propertygrid: Some cubemaps do not show-up in asset-picker preview + // Fix #4133: Content browser: Some cubemap thumbnails do not appear + if (isFullyTransparent || + (resource->m_Flags & CImage::Flag_Cubemap)) + { + // When it's a cubemap, we're only displaying part of it, and in perhaps 99+% of cases, even if the + // image format has alpha, we don't want to display alpha. (envmaps, cubemap backdrops) + // And in practise there are quite a bit of cubemaps grabbed from the web that have a BGRA8 format + // with zero alpha. Here, for preview purposes & practical reasons, force the alpha channel to 0xFF: + + CUbyte4 *texels = surface.m_RawBuffer->Data(); + const CUbyte4 *texelsStop = texels + surface.m_Dimensions.x() * surface.m_Dimensions.y(); + + const SIMD::Float4 kFullAlpha = SIMD::Float4::FromConstInt<0xFF000000>(); + texelsStop -= 4; + while (texels <= texelsStop) + { + (SIMD::Float4::LoadAligned16(texels) | kFullAlpha).StoreAligned16(texels); + texels += 4; + } + texelsStop += 4; + while (texels < texelsStop) + { + texels->w() = 0xFF; + texels++; + } + } + } + + const CUint3 &dim = surface.m_Dimensions; + const u32 channelCount = CImage::GetFormatChannelCount(surface.m_Format); + if (!PK_VERIFY(QImage::toPixelFormat(targetFormat).channelCount() == channelCount) || + !PK_VERIFY(dim.AxialProduct() * channelCount * sizeof(uchar) <= surface.m_RawBuffer->DataSizeInBytes())) + return false; + + QImage dstImage; + if (PK_VERIFY(All(dim > CUint3(0)))) + { + const u32 bytesPerLine = dim.x() * channelCount; + QImage srcImage = QImage(surface.m_RawBuffer->Data(), dim.x(), dim.y(), bytesPerLine, targetFormat).rgbSwapped(); + + const u64 fixedPoint = dim.y() * u64(size.height()); + const u64 fixedPointRatioSrc = (dim.x() * fixedPoint) / dim.y(); + const u64 fixedPointRatioDst = (size.width() * fixedPoint) / size.height(); + + if (fixedPointRatioSrc == fixedPointRatioDst) + { + dstImage = srcImage.scaled(size.width(), size.height(), Qt::IgnoreAspectRatio, Qt::SmoothTransformation); + } + else if (fixedPointRatioSrc != fixedPointRatioDst) + { + if (dim.y() == 1) + { + // We have a 1D texture, probably a gradient + dstImage = srcImage.scaled(size.width(), size.height(), Qt::IgnoreAspectRatio, Qt::SmoothTransformation); + } + else + { + u32 dstPadW = 0; + u32 dstPadH = 0; + u32 dstW = 0; + u32 dstH = 0; + + // fixedPointRatioSrc > fixedPointRatioDst : pad along y (top & bottom) + // fixedPointRatioSrc < fixedPointRatioDst : pad along x (left & right) + + if (fixedPointRatioSrc > fixedPointRatioDst) + { + dstW = size.width(); // dim.x() * size.width() / dim.x(); + dstH = PKMax(1U, dim.y() * size.height() / dim.x()); + dstPadH = (size.height() - dstH) / 2; + } + else + { + dstW = PKMax(1U, dim.x() * size.width() / dim.y()); + dstH = size.height(); // dim.y() * size.height() / dim.y(); + dstPadW = (size.width() - dstW) / 2; + } + + // First do a smooth downscale. QPainter::drawImage() does a fast downscale. + // We want the higher quality box-scale for proper thumbnail display: + QImage scaledImage = srcImage.scaled(dstW, dstH, Qt::IgnoreAspectRatio, Qt::SmoothTransformation); + + dstImage = QImage(size.width(), size.height(), srcImage.format()); + dstImage.fill(Qt::transparent); + + QPainter p(&dstImage); + p.setCompositionMode(QPainter::CompositionMode_Source); + p.drawImage(QRect(dstPadW, dstPadH, dstW, dstH), scaledImage); + } + } + } + + *outThumbnail = QPixmap::fromImage(dstImage); + outThumbnail->setDevicePixelRatio(dpr); + + return true; +} + +//---------------------------------------------------------------------------- + +__AEGP_PK_END diff --git a/AE_GeneralPlugin/Sources/Panels/AEGP_PanelQT.cpp b/AE_GeneralPlugin/Sources/Panels/AEGP_PanelQT.cpp new file mode 100644 index 00000000..71e60b95 --- /dev/null +++ b/AE_GeneralPlugin/Sources/Panels/AEGP_PanelQT.cpp @@ -0,0 +1,736 @@ +//---------------------------------------------------------------------------- +// Copyright Persistant Studios, SARL. All Rights Reserved. https://www.popcornfx.com/terms-and-conditions/ +//---------------------------------------------------------------------------- +#include + +#include "Panels/AEGP_PanelQT.h" + +#include "RenderApi/AEGP_BaseContext.h" +#include "AEGP_RenderContext.h" + +#include "AEGP_World.h" +#include "AEGP_Scene.h" +#include "AEGP_PackExplorer.h" + +#include "AEGP_AssetBaker.h" + +#include "AEGP_Log.h" +//Suite +#include + +//AE +#include +#include + +#include +#include + +#include "Panels/AEGP_GraphicalResourcesTreeModel.h" +#include "AEGP_AEPKConversion.h" + +#include "AEGP_FileDialog.h" + +#if defined(PK_WINDOWS) +#include +#include +#endif + +__AEGP_PK_BEGIN + +//---------------------------------------------------------------------------- + +template +PK_FORCEINLINE void safe_delete(_Type * & ptr) +{ + if (ptr != null) + { + delete ptr; + ptr = null; + } +} + +//---------------------------------------------------------------------------- + +#if defined(PK_WINDOWS) +const char OSWndObjectProperty[] = "CPanelPopcornFX_PlatPtr"; +#endif + +CPanelBaseGUI *CPanelBaseGUI::m_Instance = null; + +//---------------------------------------------------------------------------- + +QPanelAppSignalSink::QPanelAppSignalSink(QApplication *app, QObject *parent) + : QObject(parent) + , m_App(app) +{ +} + +//---------------------------------------------------------------------------- + +void QPanelAppSignalSink::DoExit() +{ + m_App->exit(); +} + +//---------------------------------------------------------------------------- + +QPanel::QPanel(QPanelAppSignalSink* appSignal, QApplication *application, QObject *parent /*= null*/) + : QObject(parent) + , m_AppSignal(appSignal) + , m_App(application) +{ + m_TreeModel = new CGraphicalResourcesTreeModel(); + m_TreeModel->UpdateModel(); + + QObject::connect(appSignal, &QPanelAppSignalSink::OnWindowHandlerChanged, this, &QPanel::_SetWindow); + QObject::connect(appSignal, &QPanelAppSignalSink::OnWindowSizeChanged, this, &QPanel::_SetGeometry); + QObject::connect(appSignal, &QPanelAppSignalSink::OnRenderersChanged, this, &QPanel::_UpdateModel); +} + +//---------------------------------------------------------------------------- + +QPanel::~QPanel() +{ + safe_delete(m_TreeModel); + safe_delete(m_Widget); + safe_delete(m_Window); +} + +//---------------------------------------------------------------------------- + +void QPanel::_CreateWindowContent() +{ + QVBoxLayout *container = new QVBoxLayout(); + container->setMargin(0); + m_Widget->setLayout(container); + + QTabWidget *tab = new QTabWidget(); + container->addWidget(tab); + + QWidget *rendererTab = new QWidget(); + { + QVBoxLayout *layout = new QVBoxLayout(); + layout->setMargin(0); + + QTreeView *view = new QTreeView(); + + view->setItemDelegate(new CGraphicResourceDelegate()); + + // this line cause the error "QObject::~QObject: Timers cannot be stopped from another thread" when the application quit. + // this is a known issue + // see here : https://forum.qt.io/topic/128256/timers-cannot-be-stopped-from-a-different-thread/6 + // and here : https://lists.qt-project.org/pipermail/development/2021-May/041517.html + view->setModel(m_TreeModel); + view->setColumnWidth(2, 35); + + QObject::connect(view, &QTreeView::clicked, m_TreeModel, [this](const QModelIndex &index) + { + QModelIndex targetIndex; + targetIndex = index; + + QVariant variant = this->m_TreeModel->data(targetIndex, Qt::DisplayRole); + + if (variant.canConvert()) + { + CGraphicalResourcesTreeItem *item = this->m_TreeModel->Item(targetIndex); + CGraphicResourceView view = qvariant_cast(variant); + if (view.Type() == CGraphicResourceView::ViewType::ViewType_PathResource) + { + AEGPPk::SFileDialog cbData; + +#if !defined(PK_MACOSX) + // Filter *.* not working on MacOS + cbData.AddFilter("Image file (*.*)", "*.*"); +#endif + struct SFunctor + { + void Function(const CString path) + { + if (m_Item != null) + { + m_Item->SetData(1, QString(path.Data())); + + AEGPPk::CPopcornFXWorld &world = AEGPPk::CPopcornFXWorld::Instance(); + if (!world.SetResourceOverride(m_Item->GetLayerID(), m_Item->GetRendererID(), m_Item->GetID(), path)) + { + CLog::Log(PK_ERROR, "Set resource override failed"); + return; + } + } + } + + CGraphicalResourcesTreeItem* m_Item = null; + }; + + static SFunctor functor; + + functor.m_Item = item; + cbData.SetCallback(FastDelegate(&functor, &SFunctor::Function)); + + cbData.BasicFileOpen(); + } + } + else if (variant.canConvert()) + { + CGraphicalResourcesTreeItem *item = this->m_TreeModel->Item(targetIndex); + + AEGPPk::CPopcornFXWorld &world = AEGPPk::CPopcornFXWorld::Instance(); + world.SetResourceOverride(item->GetLayerID(), item->GetRendererID(), item->GetID(), ""); + } + }); + + layout->addWidget(view); + + rendererTab->setLayout(layout); + } + tab->addTab(rendererTab, "Renderers"); + + QWidget *settingsTab = new QWidget(tab); + { + QVBoxLayout *layout = new QVBoxLayout(); + + QGridLayout *Glayout = new QGridLayout(); + Glayout->setColumnStretch(0, 1); + { + QString message = "Graphical API"; + QLabel *label = new QLabel(message); + Glayout->addWidget(label, 0, 0); + + QComboBox *graphicCombo = new QComboBox(); + + RHI::EGraphicalApi currentApi = AEGPPk::CPopcornFXWorld::Instance().GetRenderApi(); + EApiValue selectedAPI = RHIApiToAEApi(currentApi); + u32 selectedAPIIndex = 0; + for (u32 i = 0; i < PK_ARRAY_COUNT(SAEPreferenciesKeys::kSupportedAPIs); ++i) + { + if (selectedAPI == SAEPreferenciesKeys::kSupportedAPIs[i]) + selectedAPIIndex = i; + const char *apiStr = SAEPreferenciesKeys::GetGraphicsApiAsCharPtr(SAEPreferenciesKeys::kSupportedAPIs[i]); + graphicCombo->insertItem(i, apiStr); + } + graphicCombo->setCurrentIndex(selectedAPIIndex); + QObject::connect(graphicCombo, QOverload::of(&QComboBox::currentIndexChanged), [](int value) { AEGPPk::CPopcornFXWorld::Instance().SetRenderApi(SAEPreferenciesKeys::kSupportedAPIs[value]); }); + Glayout->addWidget(graphicCombo, 0, 1); + } + layout->addLayout(Glayout); + +#if defined(PK_DEBUG) + { + QString messageButton = "Reload CSS"; + QPushButton *button = new QPushButton(messageButton); + QObject::connect(button, &QPushButton::released, [this]() + { + CPopcornFXWorld &instance = AEGPPk::CPopcornFXWorld::Instance(); + QString path = instance.GetPluginInstallationPath().Data() + QString("/Stylesheet.qss"); + QFile file(path); + + if (!file.open(QFile::ReadOnly)) + return false; + QString styleSheet = QLatin1String(file.readAll()); + m_App->setStyleSheet(styleSheet); + return true; + }); + layout->addWidget(button); + } + + { + QString messageButton = "Profile"; + QCheckBox *button = new QCheckBox(messageButton); + QObject::connect(button, &QCheckBox::stateChanged, [this](int state) + { + CPopcornFXWorld &instance = AEGPPk::CPopcornFXWorld::Instance(); + + instance.SetProfilingState(state != 0); + }); + layout->addWidget(button); + } +#endif + + settingsTab->setLayout(layout); + } + tab->addTab(settingsTab, "Settings"); +} + +//---------------------------------------------------------------------------- + +void QPanel::_SetWindow(WId wid) +{ + m_PendingWindowHandle = wid; +} + +//---------------------------------------------------------------------------- + +void QPanel::_SetGeometry(const QRect &windowRect) +{ + if (m_PendingWindowHandle != 0) + { + safe_delete(m_Widget); + safe_delete(m_Window); + + m_Widget = new QWidget(null, Qt::FramelessWindowHint); + + _CreateWindowContent(); +#if defined(PK_WINDOWS) + m_Widget->setProperty("_q_embedded_native_parent_handle", QVariant(m_PendingWindowHandle)); +#else + //Create internal window + m_Widget->winId(); + m_Window = QWindow::fromWinId(m_PendingWindowHandle); + m_Widget->windowHandle()->setParent(m_Window); +#endif + } + +#if defined(PK_MACOSX) + (void)windowRect; + if (m_Window != null) + { + // In the Qt documentation of QWindow::fromWinId this is not advised to observe state changes like this + // Do it like this for mac anyway since it's working but this should be changed + // https://doc.qt.io/qt-5/qwindow.html#fromWinId + QRect newRect = QRect(0, 0, m_Window->geometry().width(), m_Window->geometry().height()); + if (m_Widget != null && m_Widget->geometry() != newRect) + m_Widget->setGeometry(newRect); + } +#else + if (m_Widget != null && m_Widget->geometry() != windowRect) + m_Widget->setGeometry(windowRect); +#endif + + if (m_PendingWindowHandle != 0) + { + m_Widget->show(); + m_PendingWindowHandle = 0; + } +} + +//---------------------------------------------------------------------------- + +void QPanel::_UpdateModel() +{ + if (m_TreeModel != null) + m_TreeModel->UpdateModel(); +} + +//---------------------------------------------------------------------------- + +CPanelApp::CPanelApp() +{ +} + +//---------------------------------------------------------------------------- + +CPanelApp::~CPanelApp() +{ + PK_ASSERT(m_QApp == null); + PK_ASSERT(m_AppSignalSink == null); + PK_ASSERT(m_Panel == null); +} + +//---------------------------------------------------------------------------- + +bool CPanelApp::Startup() +{ + CPopcornFXWorld &instance = AEGPPk::CPopcornFXWorld::Instance(); + +#if defined(PK_MACOSX) + QApplication::setAttribute(Qt::AA_MacPluginApplication, true); + CString QTPath = instance.GetPluginInstallationPath() / "AE_GeneralPlugin.plugin/Contents/PlugIns"; +#else + CString QTPath = instance.GetPluginInstallationPath() / "popcornfx.qt"; +#endif + + CLog::Log(PK_INFO, "path: %s", QTPath.Data()); + + char *argv[] = { (char *)"", (char *)"-platformpluginpath", QTPath.RawDataForWriting(), null }; + int argc = sizeof(argv) / sizeof(char*) - 1; + + m_QApp = new QApplication(argc, argv); + if (!PK_VERIFY(m_QApp != null)) + { + CLog::Log(PK_ERROR, "Could not initialize Qt"); + return false; + } + +#if defined(PK_MACOSX) + m_EventLoop = new QEventLoop(); + if (!PK_VERIFY(m_EventLoop != null)) + { + CLog::Log(PK_ERROR, "Could not initialize Qt Event Loop"); + return false; + } +#endif + + qRegisterMetaType("WId"); + + m_AppSignalSink = new QPanelAppSignalSink(m_QApp); + if (m_AppSignalSink == null) + { + CLog::Log(PK_ERROR, "Could not initialize Qt signal sink"); + Shutdown(); + return false; + } + QObject::connect(m_AppSignalSink, &QPanelAppSignalSink::OnExit, m_AppSignalSink, &QPanelAppSignalSink::DoExit, Qt::QueuedConnection); + + if (!QResource::registerResource(QString(instance.GetResourcesPath().Data()) + "Resources.rcc")) + { + CLog::Log(PK_ERROR, "Could not load Resources.rcc"); + PK_ASSERT_NOT_REACHED(); + } + + QFile stylesheetFile(QString(instance.GetResourcesPath().Data()) + "/Stylesheet.qss"); + if (!stylesheetFile.open(QFile::ReadOnly)) + { + CLog::Log(PK_ERROR, "Could not load Stylesheet.qss"); + PK_ASSERT_NOT_REACHED(); + } + + QString styleSheet = QLatin1String(stylesheetFile.readAll()); + m_QApp->setStyleSheet(styleSheet); + + m_Panel = new QPanel(m_AppSignalSink, m_QApp); + if (!PK_VERIFY(m_Panel != null)) + { + CLog::Log(PK_ERROR, "Could not initialize Qt panel"); + Shutdown(); + return false; + } + return true; +} + +//---------------------------------------------------------------------------- + +void CPanelApp::LaunchApp() +{ +#if defined(PK_WINDOWS) + m_QApp->exec(); +#else + OnWindowSizeChanged(QRect(0, 0, 0, 0)); + m_EventLoop->processEvents(); +#endif +} + +//---------------------------------------------------------------------------- + +void CPanelApp::Shutdown() +{ +#if defined(PK_MACOSX) + if (m_QApp != null) + m_QApp->quit(); + safe_delete(m_EventLoop); +#endif + safe_delete(m_Panel); + safe_delete(m_AppSignalSink); + safe_delete(m_QApp); +} + +//---------------------------------------------------------------------------- + +void CPanelApp::OnWindowHandlerChanged(WId wid) +{ + if (PK_VERIFY(m_AppSignalSink != null)) + Q_EMIT m_AppSignalSink->OnWindowHandlerChanged(wid); +} + +//---------------------------------------------------------------------------- + +void CPanelApp::OnWindowSizeChanged(const QRect &rect) +{ + if (PK_VERIFY(m_AppSignalSink != null)) + Q_EMIT m_AppSignalSink->OnWindowSizeChanged(rect); +} + +//---------------------------------------------------------------------------- + +void CPanelApp::OnRenderersChanged() +{ + if (PK_VERIFY(m_AppSignalSink != null)) + Q_EMIT m_AppSignalSink->OnRenderersChanged(); +} + +//---------------------------------------------------------------------------- + +void CPanelApp::OnExit() +{ + if (PK_VERIFY(m_AppSignalSink != null)) + Q_EMIT m_AppSignalSink->OnExit(); +} + +//---------------------------------------------------------------------------- +#if defined(PK_WINDOWS) + +CAsynchronousJob_QtThread::CAsynchronousJob_QtThread() +{ +} + +//---------------------------------------------------------------------------- + +CAsynchronousJob_QtThread::~CAsynchronousJob_QtThread() +{ +} + +//---------------------------------------------------------------------------- + +void CAsynchronousJob_QtThread::ImmediateExecute() +{ + if (!m_App.Startup()) + { + m_Initialized.Trigger(); + m_Exited.Trigger(); + return; + } + + m_Initialized.Trigger(); + + m_App.LaunchApp(); + + // VMN: Locking operation on my pc. + //m_App.Shutdown(); + + m_Exited.Trigger(); +} + +#endif +//---------------------------------------------------------------------------- + +CPanelBaseGUI::CPanelBaseGUI() +#if defined(PK_WINDOWS) + : m_Task(null) +#endif +{ +} + +//---------------------------------------------------------------------------- + +CPanelBaseGUI::~CPanelBaseGUI() +{ +#if defined(PK_WINDOWS) + if (m_Task != null) + { + m_Task->App().OnExit(); + m_Task->m_Exited.Wait(); + } +#else + m_App.Shutdown(); +#endif +} + +//---------------------------------------------------------------------------- + +CPanelBaseGUI *CPanelBaseGUI::GetInstance() +{ + if (m_Instance == null) + { + m_Instance = new CPanelBaseGUI(); + } + return m_Instance; +} + +//---------------------------------------------------------------------------- + +bool CPanelBaseGUI::DestroyInstance() +{ + if (m_Instance) + delete m_Instance; + m_Instance = null; + return true; +} + +//---------------------------------------------------------------------------- + +bool CPanelBaseGUI::InitializeIFN() +{ + if (!m_Initialized) + { + AAePk::SAAEIOData AAEData{ PF_Cmd_ABOUT, null, null, null, null }; + CPopcornFXWorld &instance = AEGPPk::CPopcornFXWorld::Instance(); + if (!instance.InitializeIFN(AAEData)) + return false; + instance.SetPanelInstance(this); + +#if defined(PK_WINDOWS) + m_Task = PK_NEW(CAsynchronousJob_QtThread()); + if (!PK_VERIFY(m_Task != null)) + return false; + m_Task->AddToPool(Scheduler::ThreadPool()); + Scheduler::ThreadPool()->KickTasks(true); + m_Task->m_Initialized.Wait(); +#else + m_App.Startup(); +#endif + + m_Initialized = true; + } + return true; +} + +//---------------------------------------------------------------------------- +#if defined(PK_MACOSX) +void CPanelBaseGUI::IdleUpdate() +{ + PK_ASSERT(m_Initialized); + + m_App.LaunchApp(); +} +#endif +//---------------------------------------------------------------------------- + +bool CPanelBaseGUI::CreatePanel(SPBasicSuite *spbP, AEGP_PanelH panelH, AEGP_PlatformViewRef platformWindowRef, AEGP_PanelFunctions1 *outFunctionTable) +{ + PK_ASSERT(m_Initialized); + + m_BasicSuite = spbP; + (void)panelH; + outFunctionTable->DoFlyoutCommand = _DoFlyoutCommand; + outFunctionTable->GetSnapSizes = _GetSnapSizes; + outFunctionTable->PopulateFlyout = _PopulateFlyout; + + { +#if defined(PK_WINDOWS) + m_Task->App().OnWindowHandlerChanged((WId)platformWindowRef); +#else + m_App.OnWindowHandlerChanged((WId)platformWindowRef); +#endif + +#if defined(PK_WINDOWS) + _SetWindowHandle((HWND)platformWindowRef); +#endif + } + return true; +} + +//---------------------------------------------------------------------------- + +void CPanelBaseGUI::SetGeometry(const QRect &rect) +{ + PK_ASSERT(m_Initialized); +#if defined(PK_WINDOWS) + m_Task->App().OnWindowSizeChanged(rect); +#else + m_App.OnWindowSizeChanged(rect); +#endif +} + +//---------------------------------------------------------------------------- + +void CPanelBaseGUI::UpdateScenesModel() +{ + PK_ASSERT(m_Initialized); +#if defined(PK_WINDOWS) + m_Task->App().OnRenderersChanged(); +#else + m_App.OnRenderersChanged(); +#endif +} + +//---------------------------------------------------------------------------- + +void CPanelBaseGUI::GetSnapSizes(A_LPoint *snapSizes, A_long *numSizesP) +{ + snapSizes[0].x = 100; + snapSizes[0].y = 100; + snapSizes[1].x = 200; + snapSizes[1].y = 400; + *numSizesP = 2; +} + +//---------------------------------------------------------------------------- + +void CPanelBaseGUI::PopulateFlyout(AEGP_FlyoutMenuItem *itemsP, A_long *in_out_numItemsP) +{ + (void)itemsP; + (void)in_out_numItemsP; +} + +//---------------------------------------------------------------------------- + +void CPanelBaseGUI::DoFlyoutCommand(AEGP_FlyoutMenuCmdID commandID) +{ + (void)commandID; +} + +//---------------------------------------------------------------------------- + +A_Err CPanelBaseGUI::_GetSnapSizes(AEGP_PanelRefcon refcon, A_LPoint *snapSizes, A_long *numSizesP) +{ + reinterpret_cast(refcon)->GetSnapSizes(snapSizes, numSizesP); + return PF_Err_NONE; +} + +//---------------------------------------------------------------------------- + +A_Err CPanelBaseGUI::_PopulateFlyout(AEGP_PanelRefcon refcon, AEGP_FlyoutMenuItem *itemsP, A_long * in_out_numItemsP) +{ + reinterpret_cast(refcon)->PopulateFlyout(itemsP, in_out_numItemsP); + return PF_Err_NONE; +} + +//---------------------------------------------------------------------------- + +A_Err CPanelBaseGUI::_DoFlyoutCommand(AEGP_PanelRefcon refcon, AEGP_FlyoutMenuCmdID commandID) +{ + reinterpret_cast(refcon)->DoFlyoutCommand(commandID); + return PF_Err_NONE; +} + +#if defined(PK_WINDOWS) + +LRESULT CALLBACK CPanelBaseGUI::StaticOSWindowWndProc( HWND hWnd, + UINT message, + WPARAM wParam, + LPARAM lParam) +{ + CPanelBaseGUI* platPtr = reinterpret_cast(::GetProp(hWnd, OSWndObjectProperty)); + if (platPtr) + { + return platPtr->OSWindowWndProc(hWnd, message, wParam, lParam); + } + else + { + return DefWindowProc(hWnd, message, wParam, lParam); + } +} + +//---------------------------------------------------------------------------- + +LRESULT CPanelBaseGUI::OSWindowWndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) +{ + PK_SCOPEDLOCK(m_HandleLock); + + bool eventHandled = false; + + if (m_WindowHandle == hwnd) // Filter events that are not for our window + { + RECT rect; + GetClientRect(hwnd, &rect); + + u32 width = rect.right - rect.left; + u32 height = rect.bottom - rect.top; + + SetGeometry(QRect(rect.left, rect.top, width, height)); + + eventHandled = true; + } + + if (m_WindowProc && !eventHandled) + return CallWindowProc(m_WindowProc, hwnd, message, wParam, lParam); + else + return DefWindowProc(hwnd, message, wParam, lParam); +} + +//---------------------------------------------------------------------------- + +void CPanelBaseGUI::_SetWindowHandle(HWND hwnd) +{ + PK_SCOPEDLOCK(m_HandleLock); + + m_WindowHandle = hwnd; + m_WindowProc = (WindowProc)GetWindowLongPtrA(m_WindowHandle, GWLP_WNDPROC); + SetWindowLongPtrA(m_WindowHandle, GWLP_WNDPROC, (LONG_PTR)CPanelBaseGUI::StaticOSWindowWndProc); + ::SetProp(m_WindowHandle, OSWndObjectProperty, (HANDLE)this); +} + +#endif // defined(PK_WINDOWS) + +//---------------------------------------------------------------------------- + +__AEGP_PK_END diff --git a/AE_GeneralPlugin/Sources/RenderApi/AEGP_BaseContext.cpp b/AE_GeneralPlugin/Sources/RenderApi/AEGP_BaseContext.cpp new file mode 100644 index 00000000..24801ae2 --- /dev/null +++ b/AE_GeneralPlugin/Sources/RenderApi/AEGP_BaseContext.cpp @@ -0,0 +1,54 @@ +//---------------------------------------------------------------------------- +// Copyright Persistant Studios, SARL. All Rights Reserved. https://www.popcornfx.com/terms-and-conditions/ +//---------------------------------------------------------------------------- +#include "ae_precompiled.h" +#include "RenderApi/AEGP_BaseContext.h" + +__AEGP_PK_BEGIN + +//---------------------------------------------------------------------------- + +CAAEBaseContext::CAAEBaseContext() + : m_ApiManager(null) + , m_ApiContext(null) + , m_CompositingTexture(null) +{ + +} + +//---------------------------------------------------------------------------- + +CAAEBaseContext::~CAAEBaseContext() +{ + PK_SAFE_DELETE(m_ApiContext); + m_ApiManager = null; + m_CompositingTexture = null; +} + +//---------------------------------------------------------------------------- + +RHI::PApiManager CAAEBaseContext::GetApiManager() +{ + PK_ASSERT(m_ApiManager != null); + return m_ApiManager; +} + +//---------------------------------------------------------------------------- + +RHI::SApiContext *CAAEBaseContext::GetApiContext() +{ + PK_ASSERT(m_ApiContext != null); + return m_ApiContext; +} + +//---------------------------------------------------------------------------- + +RHI::PTexture CAAEBaseContext::GetCompositingTexture() +{ + PK_ASSERT(m_CompositingTexture != null); + return m_CompositingTexture; +} + +//---------------------------------------------------------------------------- + +__AEGP_PK_END diff --git a/AE_GeneralPlugin/Sources/RenderApi/AEGP_CopyPixels.cpp b/AE_GeneralPlugin/Sources/RenderApi/AEGP_CopyPixels.cpp new file mode 100644 index 00000000..62a1b9de --- /dev/null +++ b/AE_GeneralPlugin/Sources/RenderApi/AEGP_CopyPixels.cpp @@ -0,0 +1,193 @@ +//---------------------------------------------------------------------------- +// Copyright Persistant Studios, SARL. All Rights Reserved. https://www.popcornfx.com/terms-and-conditions/ +//---------------------------------------------------------------------------- +#include "ae_precompiled.h" +#include "RenderApi/AEGP_CopyPixels.h" + +//Samples +#include +#include + +#include "AEGP_AEPKConversion.h" + +__AEGP_PK_BEGIN + +//---------------------------------------------------------------------------- + +CFloat4 Pixel32ToCFloat4(const PF_Pixel32 &pxl) +{ + return CFloat4(pxl.red, pxl.green, pxl.blue, pxl.alpha); +} + +//---------------------------------------------------------------------------- + +CFloat4 Pixel16ToCFloat4(const PF_Pixel16 &pxl) +{ + CFloat4 pxlValue( static_cast(pxl.red), + static_cast(pxl.green), + static_cast(pxl.blue), + static_cast(pxl.alpha)); + return pxlValue / CFloat4(static_cast(0x7FFF)); +} + +//---------------------------------------------------------------------------- + +CFloat4 Pixel8ToCFloat4(const PF_Pixel8 &pxl) +{ + CFloat4 pxlValue( static_cast(pxl.red), + static_cast(pxl.green), + static_cast(pxl.blue), + static_cast(pxl.alpha)); + return pxlValue / CFloat4(static_cast(0xFF)); +} + +//---------------------------------------------------------------------------- + +PF_Pixel32 CFloat4ToPixel32(const CFloat4 &pxl) +{ + PF_Pixel32 out = {}; + out.red = pxl.x(); + out.green = pxl.y(); + out.blue = pxl.z(); + out.alpha = pxl.w(); + return out; +} + +//---------------------------------------------------------------------------- + +PF_Pixel16 CFloat4ToPixel16(const CFloat4 &pxl) +{ + PF_Pixel16 out = {}; + out.red = static_cast(pxl.x() * static_cast(0x7FFF)); + out.green = static_cast(pxl.y() * static_cast(0x7FFF)); + out.blue = static_cast(pxl.z() * static_cast(0x7FFF)); + out.alpha = static_cast(pxl.w() * static_cast(0x7FFF)); + return out; +} + +//---------------------------------------------------------------------------- + +PF_Pixel8 CFloat4ToPixel8(const CFloat4 &pxl) +{ + PF_Pixel8 out = {}; + out.red = static_cast(pxl.x() * static_cast(0xFF)); + out.green = static_cast(pxl.y() * static_cast(0xFF)); + out.blue = static_cast(pxl.z() * static_cast(0xFF)); + out.alpha = static_cast(pxl.w() * static_cast(0xFF)); + return out; +} + +//---------------------------------------------------------------------------- + +PF_Err CopyPixelIn32( void *refcon, + A_long x, + A_long y, + PF_Pixel32 *inP, + PF_Pixel32 *) +{ + SCopyPixel *thiS = reinterpret_cast(refcon); + CFloat4 *outP = Mem::AdvanceRawPointer(thiS->m_BufferPtr->Data(), sizeof(CFloat4) * y * thiS->m_InputWorld->width + x * sizeof(CFloat4)); + CFloat4 value = Pixel32ToCFloat4(*inP); + + value.xyz() = PKSample::ConvertSRGBToLinear(value.xyz()); + value = PKSaturate(value); + *outP = value; + if (thiS->m_IsAlphaOverride) + outP->w() = static_cast(thiS->m_AlphaOverrideValue); + return PF_Err_NONE; +} + +//---------------------------------------------------------------------------- + +PF_Err CopyPixelIn16( void *refcon, + A_long x, + A_long y, + PF_Pixel16 *inP, + PF_Pixel16 *) +{ + SCopyPixel *thiS = reinterpret_cast(refcon); + CFloat4 *outP = Mem::AdvanceRawPointer(thiS->m_BufferPtr->Data(), sizeof(CFloat4) * y * thiS->m_InputWorld->width + x * sizeof(CFloat4)); + CFloat4 value = Pixel16ToCFloat4(*inP); + + value.xyz() = PKSample::ConvertSRGBToLinear(value.xyz()); + value = PKSaturate(value); + *outP = value; + if (thiS->m_IsAlphaOverride) + outP->w() = static_cast(thiS->m_AlphaOverrideValue); + return PF_Err_NONE; +} + +//---------------------------------------------------------------------------- + +PF_Err CopyPixelIn8( void *refcon, + A_long x, + A_long y, + PF_Pixel8 *inP, + PF_Pixel8 *) +{ + SCopyPixel *thiS = reinterpret_cast(refcon); + CFloat4 *outP = Mem::AdvanceRawPointer(thiS->m_BufferPtr->Data(), sizeof(CFloat4) * y * thiS->m_InputWorld->width + x * sizeof(CFloat4)); + CFloat4 value = Pixel8ToCFloat4(*inP); + + value.xyz() = PKSample::ConvertSRGBToLinear(value.xyz()); + value = PKSaturate(value); + *outP = value; + if (thiS->m_IsAlphaOverride) + outP->w() = static_cast(thiS->m_AlphaOverrideValue); + return PF_Err_NONE; +} + +//---------------------------------------------------------------------------- + +PF_Err CopyPixelOut32( void *refcon, + A_long x, + A_long y, + PF_Pixel32 *, + PF_Pixel32 *outP) +{ + SCopyPixel *thiS = reinterpret_cast(refcon); + const u32 size = sizeof(CFloat4); + const CFloat4 *inP = Mem::AdvanceRawPointer(thiS->m_BufferPtr->Data(), size * y * thiS->m_InputWorld->width + x * size); + CFloat4 value = CFloat4(PKSample::ConvertLinearToSRGB(inP->xyz()), inP->w()); + value = PKSaturate(value); + *outP = CFloat4ToPixel32(value); + return PF_Err_NONE; +} + +//---------------------------------------------------------------------------- + +PF_Err CopyPixelOut16( void *refcon, + A_long x, + A_long y, + PF_Pixel16 *, + PF_Pixel16 *outP) +{ + SCopyPixel *thiS = reinterpret_cast(refcon); + const u32 size = sizeof(CFloat4); + const CFloat4 *inP = Mem::AdvanceRawPointer(thiS->m_BufferPtr->Data(), size * y * thiS->m_InputWorld->width + x * size); + CFloat4 value = CFloat4(PKSample::ConvertLinearToSRGB(inP->xyz()), inP->w()); + value = PKSaturate(value); + *outP = CFloat4ToPixel16(value); + return PF_Err_NONE; +} + +//---------------------------------------------------------------------------- + +PF_Err CopyPixelOut8( void *refcon, + A_long x, + A_long y, + PF_Pixel8 *, + PF_Pixel8 *outP) +{ + SCopyPixel *thiS = reinterpret_cast(refcon); + const u32 size = sizeof(CFloat4); + const CFloat4 *inP = Mem::AdvanceRawPointer(thiS->m_BufferPtr->Data(), size * y * thiS->m_InputWorld->width + x * size); + CFloat4 value = CFloat4(PKSample::ConvertLinearToSRGB(inP->xyz()), inP->w()); + value = PKSaturate(value); + *outP = CFloat4ToPixel8(value); + return PF_Err_NONE; +} + +//---------------------------------------------------------------------------- +__AEGP_PK_END + diff --git a/AE_GeneralPlugin/Sources/RenderApi/AEGP_D3D11Context.cpp b/AE_GeneralPlugin/Sources/RenderApi/AEGP_D3D11Context.cpp new file mode 100644 index 00000000..f86b54c6 --- /dev/null +++ b/AE_GeneralPlugin/Sources/RenderApi/AEGP_D3D11Context.cpp @@ -0,0 +1,506 @@ +//---------------------------------------------------------------------------- +// Copyright Persistant Studios, SARL. All Rights Reserved. https://www.popcornfx.com/terms-and-conditions/ +//---------------------------------------------------------------------------- +#include "ae_precompiled.h" +#include "RenderApi/AEGP_D3D11Context.h" + +#if (PK_BUILD_WITH_D3D11_SUPPORT != 0) + +#include +#include +#include +#include + +#include + +#include + +#include + +#include "AEGP_World.h" +#include "RenderApi/AEGP_CopyTask.h" + +__AEGP_PK_BEGIN + +//---------------------------------------------------------------------------- + +struct SD3D11PlatformContext +{ + IDXGIFactory1 *m_Factory; + IDXGIAdapter1 *m_HardwareAdapter; + + TArray m_SwapChains; + +#if USE_DEBUG_DXGI + IDXGIDebug *m_Debug; +#endif + + PFN_D3D11_CREATE_DEVICE m_CreateDeviceFunc; + HMODULE m_D3DModule; + HMODULE m_DXGIModule; + + bool m_Initialized = false; + + SD3D11PlatformContext() + : m_Factory(null) + , m_HardwareAdapter(null) +#if USE_DEBUG_DXGI + , m_Debug(null) +#endif + , m_D3DModule(0) + , m_DXGIModule(0) + { + } + + ~SD3D11PlatformContext() + { + if (m_Factory != null) + m_Factory->Release(); + if (m_HardwareAdapter != null) + m_HardwareAdapter->Release(); + PK_FOREACH(swapChain, m_SwapChains) + { + if (PK_VERIFY(*swapChain != null)) + (*swapChain)->Release(); + } +#if USE_DEBUG_DXGI + if (m_Debug) + { + m_Debug->ReportLiveObjects(DXGI_DEBUG_ALL, DXGI_DEBUG_RLO_ALL); + m_Debug->Release(); + } +#endif + if (m_D3DModule != null) + FreeLibrary(m_D3DModule); + if (m_DXGIModule != null) + FreeLibrary(m_DXGIModule); + } +}; + +//---------------------------------------------------------------------------- + +CAAED3D11Context::CAAED3D11Context() + : m_Texture(null) + , m_StagingTexture(null) +{ + m_D3D11Manager = PK_NEW(RHI::CD3D11ApiManager); + m_D3D11Context = PK_NEW(RHI::SD3D11BasicContext); + m_ApiManager = m_D3D11Manager; + m_ApiContext = m_D3D11Context; + + if (m_Context == null) + m_Context = (PK_NEW(SD3D11PlatformContext)); +} + +//---------------------------------------------------------------------------- + +CAAED3D11Context::~CAAED3D11Context() +{ + if (m_Texture != null) + { + m_Texture->Release(); + m_Texture = null; + } + if (m_StagingTexture != null) + { + m_StagingTexture->Release(); + m_StagingTexture = null; + } + m_D3D11Context->m_SwapChainRenderTargets.Clear(); + if (m_D3D11Context->m_ImmediateDeviceContext != null) + { + m_D3D11Context->m_ImmediateDeviceContext->Release(); + m_D3D11Context->m_ImmediateDeviceContext = null; + } + if (m_D3D11Context->m_Device != null) + { + m_D3D11Context->m_Device->Release(); + m_D3D11Context->m_Device = null; + } + + PK_SAFE_DELETE(m_Context); + PK_SAFE_DELETE(m_D3D11Context); + + m_D3D11Manager = null; + m_ApiContext = null; + m_ApiManager = null; + + m_Tasks.Clear(); + +} + +//---------------------------------------------------------------------------- + +bool CAAED3D11Context::InitIFN() +{ + if (m_Initialized) + return true; + m_Initialized = true; + + m_WorkerCount = CPopcornFXWorld::Instance().GetWorkerCount() + 1; + m_Tasks.Resize(m_WorkerCount); + + m_ApiManager->InitApi(m_ApiContext); + return true; +} + +//---------------------------------------------------------------------------- + +bool CAAED3D11Context::BeginFrame() +{ + m_ApiManager->BeginFrame(0); + LogApiError(); + return true; +} + +//---------------------------------------------------------------------------- + +bool CAAED3D11Context::EndFrame() +{ + LogApiError(); + + m_ApiManager->EndFrame(); + + HRESULT hr = 0; + if (m_Context->m_SwapChains.Count() > 0) + { + hr = m_Context->m_SwapChains[0]->Present(0, 0); + if (FAILED(hr)) + return false; + if (hr == DXGI_ERROR_DEVICE_RESET || + hr == DXGI_ERROR_DEVICE_REMOVED) + return false; + if (hr == DXGI_STATUS_OCCLUDED) + return true; + } + return PK_D3D11_OK(hr); +} + +//---------------------------------------------------------------------------- + +void CAAED3D11Context::LogApiError() +{ +} + +//---------------------------------------------------------------------------- + +bool CAAED3D11Context::CreatePlatformContext(void *winHandle, void *deviceContext) +{ + (void)winHandle; + + HDC hdc = (HDC)deviceContext; + + int PixelFormat; + PIXELFORMATDESCRIPTOR pfd; + + ::ZeroMemory(&pfd, sizeof(pfd)); + + pfd.nSize = sizeof(PIXELFORMATDESCRIPTOR); + pfd.nVersion = 1; + pfd.dwFlags = PFD_DRAW_TO_WINDOW; // | PFD_DOUBLEBUFFER; + pfd.iPixelType = PFD_TYPE_RGBA; + pfd.cColorBits = 32; + pfd.cDepthBits = 8; + + PixelFormat = ChoosePixelFormat(hdc, &pfd); + if (PixelFormat == 0) + return false; + if (!SetPixelFormat(hdc, PixelFormat, &pfd)) + return false; + + if (m_Context == null) + return false; + if (m_Context->m_Initialized) + return true; + + m_D3D11Context->m_Api = RHI::GApi_D3D11; + m_D3D11Context->m_SwapChainCount = 0; + + if (!_LoadDynamicLibrary()) + return false; + + // try grabbing CreateDXGIFactory1: + typedef HRESULT(WINAPI *FnCreateDXGIFactory1)(REFIID riid, _COM_Outptr_ void **ppFactory); + + FnCreateDXGIFactory1 fnCreateDXGIFactory1 = (FnCreateDXGIFactory1)::GetProcAddress(m_Context->m_DXGIModule, "CreateDXGIFactory1"); + // if not found, this is not fatal, it will fallback (ie: on vista & xp) + if (fnCreateDXGIFactory1 == null) + { + CLog::Log(PK_INFO, "DXGI API 'CreateDXGIFactory1' not found, cannot create D3D11 context."); + return false; + } + m_Context->m_Initialized = true; + return PK_D3D11_OK(fnCreateDXGIFactory1(IID_PPV_ARGS(&m_Context->m_Factory))) && _CreateDevice(); +} + +//---------------------------------------------------------------------------- + +bool CAAED3D11Context::CreateRenderTarget(RHI::EPixelFormat format, CUint3 size) +{ + RHI::PD3D11RenderTarget rt = PK_NEW(RHI::CD3D11RenderTarget(RHI::SRHIResourceInfos("Render Target"))); + ID3D11Texture2D *texture2D = null; + D3D11_TEXTURE2D_DESC texDesc = {}; + + texDesc.Width = size.x(); + texDesc.Height = size.y(); + texDesc.MipLevels = 1; + texDesc.ArraySize = 1; + texDesc.Format = RHI::D3DConversion::PopcornToD3DPixelFormat(format); + texDesc.SampleDesc.Count = 1; + texDesc.Usage = D3D11_USAGE_DEFAULT; + texDesc.BindFlags = D3D11_BIND_RENDER_TARGET; + + if (PK_D3D11_FAILED(m_D3D11Context->m_Device->CreateTexture2D(&texDesc, null, &texture2D))) + return false; + texture2D->AddRef(); + rt->D3D11SetRenderTarget(texture2D, format, size.xy(), true, null, RHI::SampleCount1); + + if (m_Texture != null) + { + m_Texture->Release(); + m_Texture = null; + } + + m_Texture = texture2D; + + if (m_D3D11Context->m_SwapChainCount != 0) + { + m_D3D11Context->m_SwapChainRenderTargets.Clear(); + m_D3D11Manager->SwapChainRemoved(0); + } + + m_D3D11Context->m_SwapChainRenderTargets.PushBack(rt); + m_D3D11Context->m_SwapChainCount = 1; + + m_D3D11Manager->SwapChainAdded(); + + ID3D11Texture2D *tex = null; + D3D11_TEXTURE2D_DESC textureStagingDesc = {}; + + textureStagingDesc.Width = size.x(); + textureStagingDesc.Height = size.y(); + textureStagingDesc.MipLevels = 1; + textureStagingDesc.ArraySize = 1; + textureStagingDesc.Format = RHI::D3DConversion::PopcornToD3DPixelFormat(format); + textureStagingDesc.SampleDesc.Count = 1; + textureStagingDesc.Usage = D3D11_USAGE_STAGING; + textureStagingDesc.CPUAccessFlags = D3D11_CPU_ACCESS_READ; + if (textureStagingDesc.Format == DXGI_FORMAT_UNKNOWN || + PK_D3D11_FAILED(m_D3D11Context->m_Device->CreateTexture2D(&textureStagingDesc, null, &tex))) + return false; + + if (m_StagingTexture != null) + { + m_StagingTexture->Release(); + m_StagingTexture = null; + } + m_StagingTexture = tex; + return true; +} + +//---------------------------------------------------------------------------- + +bool CAAED3D11Context::SetAsCurrent(void *deviceContext) +{ + (void)deviceContext; + return true; +} + +//---------------------------------------------------------------------------- + +bool CAAED3D11Context::FillRenderBuffer(PRefCountedMemoryBuffer dstBuffer, RHI::PFrameBuffer srcBuffer, RHI::EPixelFormat format, u32 width, u32 height, u32 rowLength) +{ + (void)rowLength; + + PK_SCOPEDPROFILE(); + + m_D3D11Context->m_ImmediateDeviceContext->CopyResource(m_StagingTexture, m_Texture); + // Copy GPU Resource to CPU + D3D11_TEXTURE2D_DESC desc; + D3D11_MAPPED_SUBRESOURCE resource; + UINT subresource = D3D11CalcSubresource(0, 0, 0); + + m_StagingTexture->GetDesc(&desc); + //Locking Map + HRESULT hr = m_D3D11Context->m_ImmediateDeviceContext->Map(m_StagingTexture, subresource, D3D11_MAP_READ, 0, &resource); + if (FAILED(hr)) + { + CLog::Log(PK_ERROR, "D3D11Context map failure"); + return false; + } + + BYTE *sptr = reinterpret_cast(resource.pData); + BYTE *dptr = (BYTE*)dstBuffer->Data(); + + const u32 formatSize = RHI::PixelFormatHelpers::PixelFormatToPixelByteSize(format); + const u32 widthSize = (formatSize * width); + + PK_ASSERT(resource.RowPitch >= widthSize); + + u32 taskRowNumbers = height / m_WorkerCount; + u32 reminder = height % m_WorkerCount; + TAtomic counter = 0; + Threads::CEvent event; + + for (u32 i = 0; i < m_WorkerCount;++i) + { + m_Tasks[i] = PK_NEW(CAsynchronousJob_CopyTextureTask); + m_Tasks[i]->m_TargetCount = m_WorkerCount; + + m_Tasks[i]->m_Counter = &counter; + m_Tasks[i]->m_EndCB = &event; + + if (i == (m_WorkerCount - 1)) + m_Tasks[i]->m_Height = taskRowNumbers + reminder; + else + m_Tasks[i]->m_Height = taskRowNumbers; + m_Tasks[i]->m_StartOffset = i * taskRowNumbers; + m_Tasks[i]->m_DestinationPtr = dptr; + m_Tasks[i]->m_SourcePtr = sptr; + m_Tasks[i]->m_WidthSize = widthSize; + m_Tasks[i]->m_RowPitch = resource.RowPitch; + } + + for (u32 i = 1; i < m_WorkerCount; ++i) + { + m_Tasks[i]->AddToPool(Scheduler::ThreadPool()); + } + Scheduler::ThreadPool()->KickTasks(true); + + m_Tasks[0]->ImmediateExecute(); + { + PK_SCOPEDLOGGEDPROFILE("WaitMergeTask"); + + event.Wait(); + + for (u32 i = 0; i < m_WorkerCount; ++i) + { + if (!m_Tasks[i]->Done()) + i = 0; + } + } + + m_D3D11Context->m_ImmediateDeviceContext->Unmap(m_StagingTexture, subresource); + return true; +} + +//---------------------------------------------------------------------------- + +bool CAAED3D11Context::FillCompositingTexture(void *srcBuffer, RHI::EPixelFormat format, u32 width, u32 height, u32 rowLength) +{ + (void)rowLength; + + PK_SCOPEDPROFILE(); + + CImageMap image(CUint3(width, height, 1), srcBuffer, RHI::PixelFormatHelpers::PixelFormatToPixelByteSize(format) * width * height); + + PK_TODO("Optim: Use GPU Swizzle instead of CPU"); + + RHI::PTexture textureSrc = m_D3D11Manager->CreateTexture(RHI::SRHIResourceInfos("CompositingTexture"), TMemoryView(image), format); + + m_CompositingTexture = textureSrc; + return true; +} + +//---------------------------------------------------------------------------- + +TMemoryView CAAED3D11Context::GetCurrentSwapChain() +{ + return m_D3D11Context->m_SwapChainRenderTargets; +} + +//---------------------------------------------------------------------------- + +bool CAAED3D11Context::_LoadDynamicLibrary() +{ + if (m_Initialized) + return true; + PK_ASSERT(m_Context != null); + m_Context->m_D3DModule = ::LoadLibraryA("d3d11.dll"); + if (m_Context->m_D3DModule == null) + return false; + m_Context->m_DXGIModule = ::LoadLibraryA("dxgi.dll"); + if (m_Context->m_DXGIModule == null) + return false; + m_Context->m_CreateDeviceFunc = (PFN_D3D11_CREATE_DEVICE)::GetProcAddress(m_Context->m_D3DModule, "D3D11CreateDevice"); + + return m_Context->m_CreateDeviceFunc != null; +} + +//---------------------------------------------------------------------------- + +bool CAAED3D11Context::_CreateDevice() +{ + D3D_FEATURE_LEVEL featureLevels[] = + { + D3D_FEATURE_LEVEL_11_1, + D3D_FEATURE_LEVEL_11_0, + }; + if (!_PickHardwareAdapter()) + { + return false; + } + +#if defined(PK_DEBUG) + UINT deviceFlags = (D3D11_CREATE_DEVICE_DEBUG); +#else + UINT deviceFlags = 0; +#endif + + if (!PK_D3D11_OK(m_Context->m_CreateDeviceFunc( m_Context->m_HardwareAdapter, + D3D_DRIVER_TYPE_UNKNOWN, + null, + deviceFlags, + featureLevels, + _countof(featureLevels), + D3D11_SDK_VERSION, + &m_D3D11Context->m_Device, + &m_D3D11Context->m_FeatureLevel, + &m_D3D11Context->m_ImmediateDeviceContext))) + { + return false; + } + return true; +} + +//---------------------------------------------------------------------------- + +bool CAAED3D11Context::_PickHardwareAdapter() +{ + IDXGIFactory1 *&factory = m_Context->m_Factory; + IDXGIAdapter1 *&adapter = m_Context->m_HardwareAdapter; + + adapter = 0; + for (u32 idx = 0; factory->EnumAdapters1(idx, &adapter) != DXGI_ERROR_NOT_FOUND; ++idx) + { + DXGI_ADAPTER_DESC1 desc; + adapter->GetDesc1(&desc); + + if (desc.Flags & DXGI_ADAPTER_FLAG_SOFTWARE) + { + // Don't select the Basic Render Driver adapter. + // If you want a software adapter, pass in "/warp" on the command line. + continue; + } + + // Check to see if the adapter supports Direct3D 12, but don't create the + // actual device yet. + D3D_FEATURE_LEVEL featureLevels[] = + { + D3D_FEATURE_LEVEL_11_1, + D3D_FEATURE_LEVEL_11_0, + }; + if (SUCCEEDED(m_Context->m_CreateDeviceFunc(adapter, D3D_DRIVER_TYPE_UNKNOWN, null, 0, featureLevels, _countof(featureLevels), D3D11_SDK_VERSION, null, null, null))) + { + return true; + } + } + adapter = 0; + return false; +} + +//---------------------------------------------------------------------------- + +__AEGP_PK_END + +#endif diff --git a/AE_GeneralPlugin/Sources/RenderApi/AEGP_D3D12Context.cpp b/AE_GeneralPlugin/Sources/RenderApi/AEGP_D3D12Context.cpp new file mode 100644 index 00000000..f1cbfb89 --- /dev/null +++ b/AE_GeneralPlugin/Sources/RenderApi/AEGP_D3D12Context.cpp @@ -0,0 +1,712 @@ +//---------------------------------------------------------------------------- +// Copyright Persistant Studios, SARL. All Rights Reserved. https://www.popcornfx.com/terms-and-conditions/ +//---------------------------------------------------------------------------- +#include "ae_precompiled.h" +#include "RenderApi/AEGP_D3D12Context.h" + +#if (PK_BUILD_WITH_D3D12_SUPPORT != 0) + +#include +#include +#include +#include +#include +#include "pk_rhi/include/D3D12/D3D12ReadBackTexture.h" + +#include + +#include + +#include + +#include "AEGP_World.h" +#include "RenderApi/AEGP_CopyTask.h" + +#include + +#include +#include + +__AEGP_PK_BEGIN + +//---------------------------------------------------------------------------- + +class CD3D12SwapChainRT : public RHI::ID3D12SwapChain +{ +public: + CGuid m_BufferIndex; + + RHI::PD3D12RenderTarget m_RenderTargets[CAAED3D12Context::kFrameCount]; + RHI::PD3D12ReadBackTexture m_ReadbackTextures[CAAED3D12Context::kFrameCount]; + + + CD3D12SwapChainRT() + : m_BufferIndex(0) + { + } + + ~CD3D12SwapChainRT() + { + m_BufferIndex = 0; + } + + CGuid BeginFrame() + { + m_BufferIndex = (m_BufferIndex + 1) % CAAED3D12Context::kFrameCount; + return m_BufferIndex; + } + + virtual TMemoryView GetD3D12RenderTargets() const + { + return TMemoryView(m_RenderTargets); + } + + virtual TMemoryView GetRenderTargets() const + { + return TMemoryView(GetD3D12RenderTargets()); + } +}; + +//---------------------------------------------------------------------------- + +class CD3D12SwapChain : public RHI::ID3D12SwapChain +{ +public: + IDXGISwapChain3 *m_SwapChain; + CGuid m_BufferIndex; + RHI::PD3D12RenderTarget m_RenderTargets[CAAED3D12Context::kFrameCount]; + + CD3D12SwapChain() + : m_SwapChain(null) + { + } + + ~CD3D12SwapChain() + { + if (m_SwapChain != null) + m_SwapChain->Release(); + } + + CGuid BeginFrame() + { + m_BufferIndex = m_SwapChain->GetCurrentBackBufferIndex(); + return m_BufferIndex; + } + + virtual TMemoryView GetD3D12RenderTargets() const + { + return TMemoryView(m_RenderTargets); + } + + virtual TMemoryView GetRenderTargets() const + { + return TMemoryView(GetD3D12RenderTargets()); + } +}; + +//---------------------------------------------------------------------------- + +struct SD3D12PlatformContext +{ + IDXGIFactory4 *m_Factory; + IDXGIAdapter1 *m_HardwareAdapter; + + TArray m_SwapChainsRTs; + + + PFN_D3D12_CREATE_DEVICE m_CreateDeviceFunc; + PFN_D3D12_GET_DEBUG_INTERFACE m_GetDebugInterfaceFunc; + + HMODULE m_D3DModule; + HMODULE m_DXGIModule; + + SD3D12PlatformContext() + : m_Factory(null) + , m_HardwareAdapter(null) +#if USE_DEBUG_DXGI + , m_Debug(null) +#endif + , m_D3DModule(0) + , m_DXGIModule(0) + { + } + + ~SD3D12PlatformContext() + { + if (m_Factory != null) + m_Factory->Release(); + if (m_HardwareAdapter != null) + m_HardwareAdapter->Release(); + if (m_D3DModule != null) + FreeLibrary(m_D3DModule); + if (m_DXGIModule != null) + FreeLibrary(m_DXGIModule); + } +}; + +//---------------------------------------------------------------------------- + +CAAED3D12Context *CAAED3D12Context::m_Instance = null; +bool CAAED3D12Context::m_Once = false; + +//---------------------------------------------------------------------------- + +CAAED3D12Context::CAAED3D12Context() + : m_Context(PK_NEW(SD3D12PlatformContext)) +{ + for (u32 i = 0; i < kFrameCount; ++i) + { + m_Resources[i] = null; + } + m_D3D12Manager = PK_NEW(RHI::CD3D12ApiManager); + m_D3D12Context = PK_NEW(RHI::SD3D12BasicContext); + + m_ApiContext = m_D3D12Context; + m_ApiManager = m_D3D12Manager; +} + +//---------------------------------------------------------------------------- + +CAAED3D12Context::~CAAED3D12Context() +{ + ClearContextSwapchainsRT(); + m_D3D12Manager->SwapChainRemoved(0); + + m_D3D12Manager = null; + m_ApiManager = null; + + if (m_D3D12Context->m_Device != null) + m_D3D12Context->m_Device->Release(); + PK_SAFE_DELETE(m_Context); + m_ApiContext = null; + PK_SAFE_DELETE(m_D3D12Context); + m_Tasks.Clear(); +} + +//---------------------------------------------------------------------------- + +bool CAAED3D12Context::InitIFN() +{ + if (m_Initialized || m_Once) + return true; + m_Initialized = true; + m_Once = true; + + m_WorkerCount = CPopcornFXWorld::Instance().GetWorkerCount() + 1; + m_Tasks.Resize(m_WorkerCount); + + m_ApiManager->InitApi(m_ApiContext); + m_Fence = m_D3D12Manager->CreateFence(RHI::SRHIResourceInfos("Fence")); + return true; +} + +//---------------------------------------------------------------------------- + +bool CAAED3D12Context::BeginFrame() +{ + if (m_Context->m_SwapChainsRTs.Count() > 0) + m_ApiManager->BeginFrame(m_Context->m_SwapChainsRTs[0]->BeginFrame()); + else + return false; + LogApiError(); + return true; +} + +//---------------------------------------------------------------------------- + +bool CAAED3D12Context::EndFrame() +{ + LogApiError(); + + m_FrameCount += 1; + if (m_Context->m_SwapChainsRTs.Count() > 0) + { + RHI::PCommandBuffer cmdBuff = m_ApiManager->CreateCommandBuffer(RHI::SRHIResourceInfos("Command Buffer"), true); + + if (cmdBuff != null) + { + cmdBuff->Start(); + + cmdBuff->ReadBackRenderTarget(m_Context->m_SwapChainsRTs[0]->m_RenderTargets[m_Context->m_SwapChainsRTs[0]->m_BufferIndex], + m_Context->m_SwapChainsRTs[0]->m_ReadbackTextures[m_Context->m_SwapChainsRTs[0]->m_BufferIndex]); + + cmdBuff->Stop(); + m_ApiManager->SubmitCommandBufferDirect(cmdBuff); + } + else + CLog::Log(PK_ERROR, "D3D12: Create command buffer failed"); + } + m_ApiManager->EndFrame(); + //Keep that after the endframe; + m_Fence->Signal(m_FrameCount, m_D3D12Context->m_CommandQueue); + return true; +} + +//---------------------------------------------------------------------------- + +void CAAED3D12Context::LogApiError() +{ +} + +//---------------------------------------------------------------------------- + +bool CAAED3D12Context::CreateDescriptorAllocator() +{ + // Create allocators if not exists or missing + TArray & allocators = m_D3D12Context->m_DescriptorAllocators; + u32 count = allocators.Count(); + if (count < D3D12_DESCRIPTOR_HEAP_TYPE_NUM_TYPES) + { + if (!allocators.Resize(D3D12_DESCRIPTOR_HEAP_TYPE_NUM_TYPES)) + return false; + for (u32 i = 0; i < D3D12_DESCRIPTOR_HEAP_TYPE_NUM_TYPES; ++i) + { + u32 batchCount = (i >= D3D12_DESCRIPTOR_HEAP_TYPE_SAMPLER) ? 64u : 8192u; + allocators[i] = PK_NEW(RHI::CD3D12DescriptorAllocator(m_D3D12Context->m_Device, static_cast(i), batchCount)); + if (allocators[i] == null) + return false; + } + } + + return true; +} + +//---------------------------------------------------------------------------- + +bool CAAED3D12Context::LoadDynamicLibrary() +{ + PK_ASSERT(m_Context != null); + m_Context->m_D3DModule = ::LoadLibraryA("d3d12.dll"); + if (m_Context->m_D3DModule == null) + return false; + m_Context->m_DXGIModule = ::LoadLibraryA("dxgi.dll"); + if (m_Context->m_DXGIModule == null) + return false; + m_Context->m_CreateDeviceFunc = (PFN_D3D12_CREATE_DEVICE)::GetProcAddress(m_Context->m_D3DModule, "D3D12CreateDevice"); + m_D3D12Context->m_SerializeRootSignatureFunc = (PFN_D3D12_SERIALIZE_ROOT_SIGNATURE)::GetProcAddress(m_Context->m_D3DModule, "D3D12SerializeRootSignature"); + + return m_Context->m_CreateDeviceFunc != null && + m_D3D12Context->m_SerializeRootSignatureFunc != null; +} + +//---------------------------------------------------------------------------- + +bool CAAED3D12Context::CreateDevice() +{ + if (!PickHardwareAdapter()) + return false; + if (!PK_D3D_OK(m_Context->m_CreateDeviceFunc(m_Context->m_HardwareAdapter, D3D_FEATURE_LEVEL_11_0, IID_PPV_ARGS(&m_D3D12Context->m_Device)))) + { + CLog::Log(PK_ERROR, "D3D12: Couldn't create device"); + return false; + } + + D3D12_FEATURE_DATA_FEATURE_LEVELS levelFeature = {}; + const D3D_FEATURE_LEVEL levels[] = + { + D3D_FEATURE_LEVEL_11_0, + D3D_FEATURE_LEVEL_11_1, + D3D_FEATURE_LEVEL_12_0, + D3D_FEATURE_LEVEL_12_1 + }; + levelFeature.NumFeatureLevels = PK_ARRAY_COUNT(levels); + levelFeature.pFeatureLevelsRequested = levels; + m_D3D12Context->m_Device->CheckFeatureSupport(D3D12_FEATURE_FEATURE_LEVELS, &levelFeature, sizeof(levelFeature)); + + if (levelFeature.MaxSupportedFeatureLevel > D3D_FEATURE_LEVEL_11_0) + { + m_D3D12Context->m_Device->Release(); + m_D3D12Context->m_Device = null; + if (!PK_D3D_OK(m_Context->m_CreateDeviceFunc(m_Context->m_HardwareAdapter, D3D_FEATURE_LEVEL_11_0, IID_PPV_ARGS(&m_D3D12Context->m_Device)))) + { + PK_ASSERT_NOT_REACHED_MESSAGE("Internal error when creating d3d12 device."); + return false; + } + } + return true; +} + +//---------------------------------------------------------------------------- + +//Duplicate of PK-Samples\PK-SampleLib\ApiContext\D3D\D3D12Context.h::PickHardwareAdapter +bool CAAED3D12Context::PickHardwareAdapter() +{ + IDXGIFactory4 *&factory = m_Context->m_Factory; + IDXGIAdapter1 *&adapter = m_Context->m_HardwareAdapter; + adapter = 0; + HRESULT hres; + for (u32 idx = 0; (hres = factory->EnumAdapters1(idx, &adapter)) != DXGI_ERROR_NOT_FOUND; ++idx) + { + DXGI_ADAPTER_DESC1 desc; + adapter->GetDesc1(&desc); + + if (desc.Flags & DXGI_ADAPTER_FLAG_SOFTWARE) + { + // Don't select the Basic Render Driver adapter. + // If you want a software adapter, pass in "/warp" on the command line. + continue; + } + + // Check to see if the adapter supports Direct3D 12, but don't create the + // actual device yet. + HRESULT hr = m_Context->m_CreateDeviceFunc(adapter, D3D_FEATURE_LEVEL_11_0, _uuidof(ID3D12Device), null); + if (SUCCEEDED(hr)) + { + return true; + } + } + PK_ASSERT_NOT_REACHED(); + adapter = 0; + return false; +} + +//---------------------------------------------------------------------------- + +bool CAAED3D12Context::CreatePlatformContext(void *winHandle, void *deviceContext) +{ + (void)winHandle; + if (m_Once) + return true; + + HDC hdc = (HDC)deviceContext; + + int PixelFormat; + PIXELFORMATDESCRIPTOR pfd; + + ::ZeroMemory(&pfd, sizeof(pfd)); + + pfd.nSize = sizeof(PIXELFORMATDESCRIPTOR); + pfd.nVersion = 1; + pfd.dwFlags = PFD_DRAW_TO_WINDOW; // | PFD_DOUBLEBUFFER; + pfd.iPixelType = PFD_TYPE_RGBA; + pfd.cColorBits = 32; + pfd.cDepthBits = 8; + + PixelFormat = ChoosePixelFormat(hdc, &pfd); + if (PixelFormat == 0) + return false; + if (!SetPixelFormat(hdc, PixelFormat, &pfd)) + return false; + + if (m_Context == null) + return false; + m_D3D12Context->m_Api = RHI::GApi_D3D12; + m_D3D12Context->m_SwapChainCount = 0; + + if (!LoadDynamicLibrary()) + return false; + // If you want to develop with the debug layer on: + // -with DirectX Control panel(accessible via visual studio Debug->Graphics->DirectX Control panel) + // - Click on Scope->Edit List...->Add : AfterFX.exe + // - Then Direct3D / DXGI Debug Layer : Choose the `Force On` Option and voila !You got your debug logs. + +#if 0 + Microsoft::WRL::ComPtr debugController; + + m_Context->m_GetDebugInterfaceFunc = (PFN_D3D12_GET_DEBUG_INTERFACE)::GetProcAddress(m_Context->m_D3DModule, "D3D12GetDebugInterface"); + if (PK_D3D_FAILED(m_Context->m_GetDebugInterfaceFunc(IID_PPV_ARGS(&debugController)))) + return false; + debugController->EnableDebugLayer(); +#endif + + // try grabbing CreateDXGIFactory1: + typedef HRESULT(WINAPI *FnCreateDXGIFactory2)(UINT Flags, REFIID riid, _COM_Outptr_ void **ppFactory); + + FnCreateDXGIFactory2 CreateDXGIFactory2 = (FnCreateDXGIFactory2)::GetProcAddress(m_Context->m_DXGIModule, "CreateDXGIFactory2"); + // if not found, this is not fatal, it will fallback (ie: on vista & xp) + if (CreateDXGIFactory2 == null) + { + CLog::Log(PK_INFO, "DXGI API 'FnCreateDXGIFactory2' not found, cannot create D3D12 context."); + return false; + } + + UINT flags = 0; + if (!PK_D3D_OK(CreateDXGIFactory2(flags, IID_PPV_ARGS(&m_Context->m_Factory)))) + return false; + + if (!CreateDevice()) + return false; + + return CreateCommandQueue() && + CreateDescriptorAllocator();; +} + +//---------------------------------------------------------------------------- + +bool CAAED3D12Context::CreateCommandQueue() +{ + D3D12_COMMAND_QUEUE_DESC graphicsCmdQueueDesc = {}; + graphicsCmdQueueDesc.Type = D3D12_COMMAND_LIST_TYPE_DIRECT; + graphicsCmdQueueDesc.Flags = D3D12_COMMAND_QUEUE_FLAG_DISABLE_GPU_TIMEOUT; // Disable TDR for compute + graphicsCmdQueueDesc.Priority = D3D12_COMMAND_QUEUE_PRIORITY_NORMAL; + + D3D12_COMMAND_QUEUE_DESC copyCmdQueueDesc = {}; + copyCmdQueueDesc.Type = D3D12_COMMAND_LIST_TYPE_COPY; + copyCmdQueueDesc.Flags = D3D12_COMMAND_QUEUE_FLAG_DISABLE_GPU_TIMEOUT; // Disable TDR for compute + copyCmdQueueDesc.Priority = D3D12_COMMAND_QUEUE_PRIORITY_NORMAL; + + D3D12_COMMAND_QUEUE_DESC computeCmdQueueDesc = {}; + computeCmdQueueDesc.Type = D3D12_COMMAND_LIST_TYPE_COMPUTE; + computeCmdQueueDesc.Flags = D3D12_COMMAND_QUEUE_FLAG_DISABLE_GPU_TIMEOUT; // Disable TDR for compute + computeCmdQueueDesc.Priority = D3D12_COMMAND_QUEUE_PRIORITY_NORMAL; + + return PK_D3D_OK(m_D3D12Context->m_Device->CreateCommandQueue(&graphicsCmdQueueDesc, IID_PPV_ARGS(&m_D3D12Context->m_CommandQueue))) && + PK_D3D_OK(m_D3D12Context->m_Device->CreateCommandQueue(©CmdQueueDesc, IID_PPV_ARGS(&m_D3D12Context->m_CopyCommandQueue))) && + PK_D3D_OK(m_D3D12Context->m_Device->CreateCommandQueue(&computeCmdQueueDesc, IID_PPV_ARGS(&m_D3D12Context->m_ComputeCommandQueue))); +} + +//---------------------------------------------------------------------------- + +bool CAAED3D12Context::CreateRenderTarget(RHI::EPixelFormat format, CUint3 size) +{ + if (m_Context->m_SwapChainsRTs.Count() != 0) + { + ClearContextSwapchainsRT(); + m_D3D12Manager->SwapChainRemoved(0); + } + + CD3D12SwapChainRT *swapchainRT = PK_NEW(CD3D12SwapChainRT()); + const CGuid idx = m_Context->m_SwapChainsRTs.PushBack(swapchainRT); + if (!PK_VERIFY(idx.Valid())) + { + PK_DELETE(swapchainRT); + return false; + } + m_D3D12Context->m_SwapChainCount = 1; + m_D3D12Context->m_SwapChains = TMemoryView(m_Context->m_SwapChainsRTs.ViewForWriting()); + + for (u32 i = 0; i < CAAED3D12Context::kFrameCount; ++i) + { + RHI::PD3D12RenderTarget rt = PK_NEW(RHI::CD3D12RenderTarget(RHI::SRHIResourceInfos("Render Target"))); + if (rt == null) + { + CLog::Log(PK_ERROR, "D3D12Context: CD3D12RenderTarget creation failure"); + return false; + } + ID3D12Resource *resource = null; + D3D12_HEAP_PROPERTIES heapProps = { D3D12_HEAP_TYPE_DEFAULT }; + D3D12_RESOURCE_DESC resDesc = {}; + D3D12_RESOURCE_STATES initialState = (PKRHI_D3D12_SHADER_RESOURCE_STATE); + D3D12_CLEAR_VALUE defaultClearValue; + + resDesc.Dimension = D3D12_RESOURCE_DIMENSION_TEXTURE2D; + resDesc.Alignment = 0; + resDesc.Width = size.x(); + resDesc.Height = size.y(); + resDesc.DepthOrArraySize = 1; + resDesc.MipLevels = 1; + resDesc.Format = RHI::D3DConversion::PopcornToD3DPixelFormat(format); + resDesc.Flags = D3D12_RESOURCE_FLAG_ALLOW_RENDER_TARGET; + resDesc.SampleDesc.Count = 1; + resDesc.SampleDesc.Quality = 0; + + defaultClearValue.Format = RHI::D3DConversion::PopcornToD3DPixelFormat(format); + for (u32 c = 0; c < 4; ++c) + defaultClearValue.Color[c] = 0.0f; + + if (PK_D3D_FAILED(m_D3D12Context->m_Device->CreateCommittedResource(&heapProps, D3D12_HEAP_FLAG_NONE, &resDesc, initialState, null, PK_RHI_IID_PPV_ARGS(&resource)))) + { + CLog::Log(PK_ERROR, "D3D12Context: CreateCommittedResource failure"); + m_D3D12Context->m_SwapChainCount = 0; + m_D3D12Context->m_SwapChains = TMemoryView(); + ClearContextSwapchainsRT(); + return false; + } + rt->D3D12SetRenderTarget(resource, format, size.xy(), true, null, RHI::SampleCount1); + m_Resources[i] = resource; + + RHI::PReadBackTexture readbackTex = m_D3D12Manager->CreateReadBackTexture(RHI::SRHIResourceInfos("readback Texture"), rt); + + if (readbackTex == null) + { + CLog::Log(PK_ERROR, "D3D12Context: CreateReadBackTexture failure"); + return false; + } + m_Context->m_SwapChainsRTs[0]->m_RenderTargets[i] = rt; + m_Context->m_SwapChainsRTs[0]->m_ReadbackTextures[i] = CastD3D12(readbackTex); + } + m_D3D12Manager->SwapChainAdded(); + + return true; +} + +//---------------------------------------------------------------------------- + +bool CAAED3D12Context::SetAsCurrent(void *deviceContext) +{ + (void)deviceContext; + return true; +} + +//---------------------------------------------------------------------------- + +PRefCountedMemoryBuffer CAAED3D12Context::CreateBufferFromReadBackTexture(RHI::PCReadBackTexture readBackTexture) const +{ + PK_SCOPEDPROFILE(); + + u32 size = RHI::PixelFormatHelpers::PixelFormatToPixelByteSize(readBackTexture->GetFormat()) * readBackTexture->GetSize().x() * readBackTexture->GetSize().y(); + PRefCountedMemoryBuffer rawBuffer = CRefCountedMemoryBuffer::AllocAligned(size); + + if (rawBuffer == null) + { + CLog::Log(PK_ERROR, "D3D12Context: CreateBufferFromReadBackTexture alloc failure"); + return null; + } + + RHI::PCD3D12ReadBackTexture d3dReadBackTex = CastD3D12(readBackTexture); + ID3D12Resource *d3dResource = d3dReadBackTex->D3D12GetResource(); + void *mappedData; + + if (PK_D3D_FAILED(d3dResource->Map(0, null, &mappedData))) + { + CLog::Log(PK_ERROR, "D3D12Context: map failure"); + return null; + } + + const u32 rowcount = d3dReadBackTex->D3D12GetFootprint().m_RowCount; + const u32 rowpitch = d3dReadBackTex->D3D12GetFootprint().m_Footprint.Footprint.RowPitch; + const u64 rowsize = d3dReadBackTex->D3D12GetFootprint().m_RowSizeInBytes; + + for (u32 r = 0; r < rowcount; ++r) + { + Mem::Copy(Mem::AdvanceRawPointer(rawBuffer->Data(), r * rowsize), Mem::AdvanceRawPointer(mappedData, r * rowpitch), rowsize); + } + + d3dResource->Unmap(0, null); + return rawBuffer; +} + +//---------------------------------------------------------------------------- + +bool CAAED3D12Context::FillRenderBuffer(PRefCountedMemoryBuffer dstBuffer, RHI::PFrameBuffer srcBuffer, RHI::EPixelFormat format, u32 width, u32 height, u32 rowLength) +{ + (void)rowLength; + + PK_SCOPEDPROFILE(); + + { + PK_NAMEDSCOPEDPROFILE("m_Fence->Wait"); + m_Fence->Wait(m_FrameCount); + } + RHI::PReadBackTexture rbTexture = m_Context->m_SwapChainsRTs[0]->m_ReadbackTextures[m_Context->m_SwapChainsRTs[0]->m_BufferIndex]; + if (rbTexture == null) + { + CLog::Log(PK_ERROR, "D3D12Context: No readback texture in swap chain"); + return false; + } + + + { + PK_NAMEDSCOPEDPROFILE("Copy Task Creation And Kick"); + + PRefCountedMemoryBuffer buffer = CreateBufferFromReadBackTexture(rbTexture); + + if (buffer == null) + { + CLog::Log(PK_ERROR, "D3D12Context: Create buffer from readback texture failed"); + return false; + } + + BYTE *sptr = buffer->Data< BYTE>(); + BYTE *dptr = (BYTE*)dstBuffer->Data(); + + const u32 formatSize = RHI::PixelFormatHelpers::PixelFormatToPixelByteSize(format); + const u32 widthSize = (formatSize * width); + u32 taskRowNumbers = height / m_WorkerCount; + u32 reminder = height % m_WorkerCount; + TAtomic counter = 0; + Threads::CEvent event; + + for (u32 i = 0; i < m_WorkerCount; ++i) + { + m_Tasks[i] = PK_NEW(CAsynchronousJob_CopyTextureTask); + if (m_Tasks[i] == null) + { + + CLog::Log(PK_ERROR, "D3D12Context: Create task copy texture failed"); + return false; + } + m_Tasks[i]->m_TargetCount = m_WorkerCount; + + m_Tasks[i]->m_Counter = &counter; + m_Tasks[i]->m_EndCB = &event; + + if (i == (m_WorkerCount - 1)) + m_Tasks[i]->m_Height = taskRowNumbers + reminder; + else + m_Tasks[i]->m_Height = taskRowNumbers; + m_Tasks[i]->m_StartOffset = i * taskRowNumbers; + m_Tasks[i]->m_DestinationPtr = dptr; + m_Tasks[i]->m_SourcePtr = sptr; + m_Tasks[i]->m_WidthSize = widthSize; + m_Tasks[i]->m_RowPitch = formatSize * width; + } + + for (u32 i = 1; i < m_WorkerCount; ++i) + { + m_Tasks[i]->AddToPool(Scheduler::ThreadPool()); + } + + Scheduler::ThreadPool()->KickTasks(true); + + m_Tasks[0]->ImmediateExecute(); + + { + PK_NAMEDSCOPEDPROFILE("WaitMergeTask"); + + event.Wait(); + + for (u32 i = 0; i < m_WorkerCount; ++i) + { + if (!m_Tasks[i]->Done()) + i = 0; + } + } + } + return true; +} + +//---------------------------------------------------------------------------- + +bool CAAED3D12Context::FillCompositingTexture(void *srcBuffer, RHI::EPixelFormat format, u32 width, u32 height, u32 rowLength) +{ + (void)rowLength; + + PK_SCOPEDPROFILE(); + + CImageMap image(CUint3(width, height, 1), srcBuffer, RHI::PixelFormatHelpers::PixelFormatToPixelByteSize(format) * width * height); + + PK_TODO("Optim: Use GPU Swizzle instead of CPU"); + + RHI::PTexture textureSrc = m_D3D12Manager->CreateTexture(RHI::SRHIResourceInfos("CompositingTexture"), TMemoryView(image), format); + + m_CompositingTexture = textureSrc; + return true; +} + +//---------------------------------------------------------------------------- + +TMemoryView CAAED3D12Context::GetCurrentSwapChain() +{ + if (PK_VERIFY(!m_D3D12Context->m_SwapChains.Empty())) + return m_D3D12Context->m_SwapChains[0]->GetRenderTargets(); + + return TMemoryView(); +} + +//---------------------------------------------------------------------------- + +void CAAED3D12Context::ClearContextSwapchainsRT() +{ + for (u32 i = 0; i < m_Context->m_SwapChainsRTs.Count(); ++i) + { + PK_DELETE(m_Context->m_SwapChainsRTs[i]); + } + m_Context->m_SwapChainsRTs.Clear(); +} + +//---------------------------------------------------------------------------- + +__AEGP_PK_END + +#endif diff --git a/AE_GeneralPlugin/Sources/RenderApi/AEGP_MetalContext.mm b/AE_GeneralPlugin/Sources/RenderApi/AEGP_MetalContext.mm new file mode 100644 index 00000000..0feeda65 --- /dev/null +++ b/AE_GeneralPlugin/Sources/RenderApi/AEGP_MetalContext.mm @@ -0,0 +1,188 @@ +#include "ae_precompiled.h" +#include "RenderApi/AEGP_MetalContext.h" + +#if defined(PK_MACOSX) +#if (PK_BUILD_WITH_METAL_SUPPORT != 0) + +#include "AEGP_World.h" + +#include +#include +#include +#include + +#include + +#include + +#include + +__AEGP_PK_BEGIN + +CAAEMetalContext *CAAEMetalContext::m_Instance = null; + +struct SMetalPlatformContext +{ + RHI::SMetalBasicContext *m_MetalContext; + RHI::CMetalApiManager *m_MetalManager; + RHI::PMetalRenderTarget m_MetalFinalRT; + PKSample::CMetalContext::SFinalBlit m_FinalBlit; + + SMetalPlatformContext() + { + } + + ~SMetalPlatformContext() + { + m_MetalContext = null; + m_MetalManager = null; + } +}; + +CAAEMetalContext::CAAEMetalContext() +: m_Data(null) +{ + m_ApiManager = PK_NEW(RHI::CMetalApiManager); + m_ApiContext = PK_NEW(RHI::SMetalBasicContext); + m_Data = PK_NEW(SMetalPlatformContext); + m_Data->m_MetalContext = static_cast(m_ApiContext); + m_Data->m_MetalManager = static_cast(m_ApiManager.Get()); +} + +CAAEMetalContext::~CAAEMetalContext() +{ + PK_SAFE_DELETE(m_Data); + PK_SAFE_DELETE(m_ApiContext); + m_ApiManager = null; +} + +bool CAAEMetalContext::BeginFrame() +{ + m_ApiManager->BeginFrame(0); + LogApiError(); + return true; +} + +bool CAAEMetalContext::EndFrame() +{ + void *syncRenderData = m_ApiManager->EndFrame(); + if (syncRenderData == null) + return false; + m_LastFrameSyncInfo = reinterpret_cast(syncRenderData); + PKSample::CMetalContext::EndFrame( m_Data->m_MetalContext->m_Queue, + m_Data->m_MetalContext->m_SwapChains, + m_Data->m_FinalBlit, + m_LastFrameSyncInfo, + true, + m_Data->m_MetalFinalRT); + return false; + return true; +} + +void CAAEMetalContext::LogApiError() +{ +} + +bool CAAEMetalContext::InitIFN() +{ + if (m_Initialized) + return true; + m_Initialized = true; + m_ApiContext->m_Api = RHI::GApi_Metal; + id device = MTLCreateSystemDefaultDevice(); + if (!PK_VERIFY(device != null)) + return false; + id queue = [device newCommandQueue]; + if (!PK_VERIFY(queue != null)) + return false; + m_Data->m_MetalContext->m_Device = device; + m_Data->m_MetalContext->m_Queue = queue; + if (!m_Data->m_MetalManager->InitApi(m_Data->m_MetalContext)) + return false; + if (!PKSample::CMetalContext::CreateFinalBlitData(device, m_Data->m_FinalBlit, RHI::FormatFloat32RGBA)) + return false; + return true; +} + +bool CAAEMetalContext::CreateRenderTarget(RHI::EPixelFormat format, CUint3 size) +{ + RHI::PMetalRenderTarget mtlRt = PK_NEW(RHI::CMetalRenderTarget(RHI::SRHIResourceInfos("Render Target"), null)); + + if (!PK_VERIFY(mtlRt != null)) + return false; + if (!PK_VERIFY(mtlRt->MetalCreateRenderTarget(size.xy(), format, true, RHI::SampleCount1, m_Data->m_MetalContext->m_Device))) + return false; + + m_Data->m_MetalFinalRT = PKSample::CMetalContext::MetalCreateRenderTarget(m_Data->m_MetalContext->m_Device, size.xy(), RHI::FormatFloat32RGBA, true); + + if (m_Data->m_MetalContext->m_SwapChainCount != 0) + { + m_Data->m_MetalContext->m_SwapChains.Clear(); + m_Data->m_MetalManager->SwapChainRemoved(0); + } + m_Data->m_MetalContext->m_SwapChains.PushBack().Valid(); + m_Data->m_MetalContext->m_SwapChains.Last().m_RenderTarget = mtlRt; + m_Data->m_MetalContext->m_SwapChainCount = 1; + + if (!m_Data->m_MetalManager->SwapChainAdded()) + return false; + return true; +} + +bool CAAEMetalContext::FillRenderBuffer(PRefCountedMemoryBuffer dstBuffer, RHI::PFrameBuffer srcBuffer, RHI::EPixelFormat format, u32 width, u32 height, u32 rowLength) +{ + (void)rowLength; + (void)srcBuffer; + if (!PK_VERIFY(m_LastFrameSyncInfo != null)) + return false; + + const u32 formatSize = RHI::PixelFormatHelpers::PixelFormatToPixelByteSize(format); + const u32 widthSize = (formatSize * width); + const u32 bytesPerImage = RHI::PixelFormatHelpers::GetTextureBufferSize(format, CUint2(width, height)); + u8 *dstBuffBytes = (u8*)dstBuffer->Data(); + id mtlTexture = m_Data->m_MetalFinalRT->MetalGetTexture(); + + PK_ASSERT(dstBuffer->DataSizeInBytes() >= bytesPerImage); + + // Synchronize the command buffer: + { + PK_SCOPEDLOCK(m_LastFrameSyncInfo->m_SwapChainDoneCountLock); + if (m_LastFrameSyncInfo->m_SwapChainDoneCount < m_LastFrameSyncInfo->m_SwapChainToWait) + m_LastFrameSyncInfo->m_CondVar.Wait(m_LastFrameSyncInfo->m_SwapChainDoneCountLock); + m_LastFrameSyncInfo->m_SwapChainDoneCount = 0; + m_LastFrameSyncInfo->m_SwapChainToWait = 0; + } + + [mtlTexture getBytes:dstBuffBytes bytesPerRow:widthSize bytesPerImage:bytesPerImage fromRegion:MTLRegionMake2D(0, 0, width, height) mipmapLevel:0 slice:0]; + return true; +} + +bool CAAEMetalContext::FillCompositingTexture(void *srcBuffer, RHI::EPixelFormat format, u32 width, u32 height, u32 rowLength) +{ + (void)rowLength; + PK_SCOPEDPROFILE(); + + CImageMap image(CUint3(width, height, 1), srcBuffer, RHI::PixelFormatHelpers::PixelFormatToPixelByteSize(format) * width * height); + + RHI::PTexture textureSrc = m_Data->m_MetalManager->CreateTexture(RHI::SRHIResourceInfos("Texture"), TMemoryView(image), format); + + m_CompositingTexture = textureSrc; + return true; +} + +TMemoryView CAAEMetalContext::GetCurrentSwapChain() +{ + return TMemoryView(m_Data->m_MetalContext->m_SwapChains.Last().m_RenderTarget); +} + +bool CAAEMetalContext::CreatePlatformContext(void *window, void *deviceContext) +{ + (void)window; (void)deviceContext; + return true; +} + +__AEGP_PK_END + + +#endif //PK_BUILD_WITH_METAL_SUPPORT != 0 +#endif //PK_MACOSX \ No newline at end of file diff --git a/AE_Suites/PopcornFX_BasePluginInterface.h b/AE_Suites/PopcornFX_BasePluginInterface.h new file mode 100644 index 00000000..c588f829 --- /dev/null +++ b/AE_Suites/PopcornFX_BasePluginInterface.h @@ -0,0 +1,293 @@ +//---------------------------------------------------------------------------- +// Copyright Persistant Studios, SARL. All Rights Reserved. https://www.popcornfx.com/terms-and-conditions/ +//---------------------------------------------------------------------------- +#pragma once + +#ifndef __FX_BASEPLUGININTERFACE_H__ +#define __FX_BASEPLUGININTERFACE_H__ + +#include "PopcornFX_Define.h" +#include "PopcornFX_Suite.h" + +#include + +__AAEPK_BEGIN + +//---------------------------------------------------------------------------- + +const float k_MinFloat = -100000.0f; +const float k_MaxFloat = 100000.0f; + +//---------------------------------------------------------------------------- + +class CBasePluginInterface +{ +public: + virtual ~CBasePluginInterface() { } + +#if defined(PK_WINDOWS) +#pragma warning( push ) +#pragma warning( disable : 4100 ) //Disable unused parameters +#endif + + virtual PF_Err About(SAAEIOData &AAEData, PF_ParamDef *params[], PF_LayerDef *output) { (void)AAEData; (void)params; (void)output; return A_Err_NONE; }; + virtual PF_Err GlobalSetup(SAAEIOData &AAEData, PF_ParamDef *params[], PF_LayerDef *output) { (void)AAEData; (void)params; (void)output; return A_Err_NONE; }; + virtual PF_Err ParamsSetup(SAAEIOData &AAEData, PF_ParamDef *params[], PF_LayerDef *output) { (void)AAEData; (void)params; (void)output; return A_Err_NONE; }; + virtual PF_Err GlobalSetdown(SAAEIOData &AAEData, PF_ParamDef *params[], PF_LayerDef *output) { (void)AAEData; (void)params; (void)output; return A_Err_NONE; }; + virtual PF_Err SequenceSetup(SAAEIOData &AAEData, PF_ParamDef *params[], PF_LayerDef *output) { (void)AAEData; (void)params; (void)output; return A_Err_NONE; }; + virtual PF_Err SequenceReSetup(SAAEIOData &AAEData, PF_ParamDef *params[], PF_LayerDef *output) { (void)AAEData; (void)params; (void)output; return A_Err_NONE; }; + virtual PF_Err SequenceFlatten(SAAEIOData &AAEData, PF_ParamDef *params[], PF_LayerDef *output) { (void)AAEData; (void)params; (void)output; return A_Err_NONE; }; + virtual PF_Err SequenceShutdown(SAAEIOData &AAEData, PF_ParamDef *params[], PF_LayerDef *output) { (void)AAEData; (void)params; (void)output; return A_Err_NONE; }; + virtual PF_Err PreRender(SAAEIOData &AAEData) { (void)AAEData; return A_Err_NONE; }; + virtual PF_Err SmartRender(SAAEIOData &AAEData) { (void)AAEData; return A_Err_NONE; }; + virtual PF_Err ParamValueChanged(SAAEIOData &AAEData, PF_ParamDef *params[]) { (void)AAEData; (void)params; return A_Err_NONE; }; + virtual PF_Err UpdateParamsUI(SAAEIOData &AAEData, PF_ParamDef *params[]) { (void)AAEData; (void)params; return A_Err_NONE; }; + virtual PF_Err HandleDataFromAEGP(SAAEIOData &AAEData, PF_ParamDef *params[]) { (void)AAEData; (void)params; return A_Err_NONE; }; + virtual PF_Err QueryDynamicFlags(SAAEIOData &AAEData, PF_ParamDef *params[]) { (void)AAEData; (void)params; return A_Err_NONE; }; + +#if defined(PK_WINDOWS) +#pragma warning( pop ) +#endif + const int *GetParametersIndexes() + { + return m_ParametersIndexes; + }; + + PF_Err SetEffectName(SAAEIOData &AAEData, std::string &name, AEGP_EffectRefH effect = nullptr) + { + AEGP_SuiteHandler suites(AAEData.m_InData->pica_basicP); + AEGP_EffectRefH effectRef = effect; + A_UTF16Char nameUTF[64]; + AEGP_StreamRefH streamRef = nullptr; + AEGP_StreamRefH effectStreamRef = nullptr; + PF_Err result = A_Err_NONE; + + AE_VERIFY(name.size() < 64); + if (effectRef == nullptr) + { + result = suites.PFInterfaceSuite1()->AEGP_GetNewEffectForEffect(m_AAEID, AAEData.m_InData->effect_ref, &effectRef); + if (!AE_VERIFY(result == A_Err_NONE)) + return result; + } + + result |= suites.StreamSuite2()->AEGP_GetNewEffectStreamByIndex(m_AAEID, effectRef, 1, &streamRef); + if (!AE_VERIFY(result == A_Err_NONE)) + return result; + CopyCharToUTF16(name.data(), nameUTF); + + result |= suites.DynamicStreamSuite4()->AEGP_GetNewParentStreamRef(m_AAEID, streamRef, &effectStreamRef); + result |= suites.StreamSuite2()->AEGP_DisposeStream(streamRef); + streamRef = nullptr; + if (!AE_VERIFY(result == A_Err_NONE)) + return result; + result |= suites.DynamicStreamSuite4()->AEGP_SetStreamName(effectStreamRef, nameUTF); + result |= suites.StreamSuite2()->AEGP_DisposeStream(effectStreamRef); + + effectStreamRef = nullptr; + if (effect == nullptr) + { + result |= suites.EffectSuite4()->AEGP_DisposeEffect(effectRef); + } + return result; + } + + PF_Err SetParameterStreamName(SAAEIOData &AAEData, std::string &str, unsigned int index, AEGP_EffectRefH effect = nullptr) + { + AEGP_SuiteHandler suites(AAEData.m_InData->pica_basicP); + PF_Err result = PF_Err_NONE; + A_UTF16Char strUTF[256]; + AEGP_StreamRefH streamRef = nullptr; + AEGP_EffectRefH effectRef = effect; + + AE_VERIFY(str.size() < 256); + if (effectRef == nullptr) + { + result = suites.PFInterfaceSuite1()->AEGP_GetNewEffectForEffect(m_AAEID, AAEData.m_InData->effect_ref, &effectRef); + if (!AE_VERIFY(result == A_Err_NONE)) + return result; + } + CopyCharToUTF16(str.data(), strUTF); + + result |= suites.StreamSuite2()->AEGP_GetNewEffectStreamByIndex(m_AAEID, effectRef, index, &streamRef); + result |= suites.DynamicStreamSuite4()->AEGP_SetStreamName(streamRef, strUTF); + result |= suites.StreamSuite2()->AEGP_DisposeStream(streamRef); + + AAEData.m_OutData->out_flags |= PF_OutFlag_REFRESH_UI; + if (effect == nullptr) + { + result |= suites.EffectSuite4()->AEGP_DisposeEffect(effectRef); + } + return result; + } + + PF_Err GetParamsSequenceUID(SAAEIOData &AAEData, std::string &out, unsigned int index, AEGP_EffectRefH effect = nullptr) + { + AEGP_SuiteHandler suites(AAEData.m_InData->pica_basicP); + AEGP_StreamRefH streamRef = nullptr; + AEGP_EffectRefH effectRef = effect; + PF_Err result = PF_Err_NONE; + + AEGP_MemHandle nameHandle; + aechar_t *wname; + + out.clear(); + if (effectRef == nullptr) + { + result |= suites.PFInterfaceSuite1()->AEGP_GetNewEffectForEffect(m_AAEID, AAEData.m_InData->effect_ref, &effectRef); + if (!AE_VERIFY(result == A_Err_NONE)) + return result; + } + result |= suites.StreamSuite2()->AEGP_GetNewEffectStreamByIndex(m_AAEID, effectRef, index, &streamRef); + + result |= suites.StreamSuite5()->AEGP_GetStreamName(m_AAEID, streamRef, false, &nameHandle); + result |= suites.StreamSuite2()->AEGP_DisposeStream(streamRef); + streamRef = nullptr; + + result |= suites.MemorySuite1()->AEGP_LockMemHandle(nameHandle, reinterpret_cast(&wname)); + + WCharToString(wname, &out); + + result |= suites.MemorySuite1()->AEGP_UnlockMemHandle(nameHandle); + result |= suites.MemorySuite1()->AEGP_FreeMemHandle(nameHandle); + + if (effect == nullptr) + result |= suites.EffectSuite4()->AEGP_DisposeEffect(effectRef); + effectRef = nullptr; + return result; + } + + void MakeParamCopy(PF_ParamDef *actual[], PF_ParamDef copy[], A_short arraySize) + { + for (A_short iS = 0; iS < arraySize; ++iS) { + AEFX_CLR_STRUCT(copy[iS]); + copy[iS] = *actual[iS]; + } + } + + PF_Err AddAngleParameter(PF_InData *in_data, const char *name, unsigned int id, float defaultValue = 0.0f, PF_ParamFlags flags = 0, PF_ParamUIFlags uiFlags = 0) + { + PF_ParamDef def; + + AEFX_CLR_STRUCT(def); + def.flags = flags; + def.ui_flags = uiFlags; + PF_ADD_ANGLE(name, defaultValue, id); + + m_ParametersIndexes[id] = ++m_CurrentIndex; + return PF_Err_NONE; + } + + PF_Err AddPercentParameter(PF_InData *in_data, const char *name, unsigned int id, int defaultValue = 0, PF_ParamFlags flags = 0, PF_ParamUIFlags uiFlags = 0) + { + PF_ParamDef def; + + AEFX_CLR_STRUCT(def); + def.flags = flags; + def.ui_flags = uiFlags; + PF_ADD_PERCENT(name, defaultValue, id); + + m_ParametersIndexes[id] = ++m_CurrentIndex; + return PF_Err_NONE; + } + + PF_Err AddCheckBoxParameter(PF_InData *in_data, const char *name, unsigned int id, bool defaultValue = false, PF_ParamFlags flags = 0, PF_ParamUIFlags uiFlags = 0) + { + PF_ParamDef def; + + AEFX_CLR_STRUCT(def); + def.flags = flags; + def.ui_flags = uiFlags; + PF_ADD_CHECKBOX(name, "", defaultValue, flags, id); + + m_ParametersIndexes[id] = ++m_CurrentIndex; + return PF_Err_NONE; + } + + PF_Err AddFloatParameter(PF_InData *in_data, const char *name, unsigned int id, float defaultValue = 0.0f, float min = 0.0f, float max = 0.0f, PF_ParamFlags flags = 0, PF_ParamUIFlags uiFlags = 0) + { + PF_ParamDef def; + + AEFX_CLR_STRUCT(def); + def.flags = flags; + def.ui_flags = uiFlags; + PF_ADD_FLOAT_SLIDER(name, min, max, min, max, + 0/*Curve tolerance*/, defaultValue, 2/*float*/, 0/*display_flags*/, 0/*want phase*/, id); + + m_ParametersIndexes[id] = ++m_CurrentIndex; + return PF_Err_NONE; + } + + PF_Err AddFloatParameterUnbound(PF_InData *in_data, const char *name, unsigned int id, float defaultValue = 0.0f, PF_ParamFlags flags = 0, PF_ParamUIFlags uiFlags = 0) + { + PF_ParamDef def; + + AEFX_CLR_STRUCT(def); + def.flags = flags; + def.ui_flags = uiFlags; + PF_ADD_FLOAT_SLIDER(name, k_MinFloat, k_MaxFloat, k_MinFloat, k_MaxFloat, + 0/*Curve tolerance*/, defaultValue, 2/*float*/, 0/*display_flags*/, 0/*want phase*/, id); + + m_ParametersIndexes[id] = ++m_CurrentIndex; + return PF_Err_NONE; + } + + PF_Err AddIntParameter(PF_InData *in_data, const char *name, unsigned int id, int defaultValue = 0, int min = 0, int max = 0, PF_ParamFlags flags = 0, PF_ParamUIFlags uiFlags = 0) + { + PF_ParamDef def; + + AEFX_CLR_STRUCT(def); + def.flags = flags; + def.ui_flags = uiFlags; + PF_ADD_FLOAT_SLIDER(name, (PF_FpShort)min, (PF_FpShort)max, (PF_FpShort)min, (PF_FpShort)max, + 0/*Curve tolerance*/, defaultValue, 0/*int*/, 0/*display_flags*/, 0/*want phase*/, id); + + m_ParametersIndexes[id] = ++m_CurrentIndex; + return PF_Err_NONE; + } + + PF_Err AddIntParameterUnbound(PF_InData *in_data, const char *name, unsigned int id, int defaultValue = 0, PF_ParamFlags flags = 0, PF_ParamUIFlags uiFlags = 0) + { + PF_ParamDef def; + + AEFX_CLR_STRUCT(def); + def.flags = flags; + def.ui_flags = uiFlags; + PF_ADD_FLOAT_SLIDER(name, k_MinFloat, k_MaxFloat, k_MinFloat, k_MaxFloat, + 0/*Curve tolerance*/, defaultValue, 0/*int*/, 0/*display_flags*/, 0/*want phase*/, id); + + m_ParametersIndexes[id] = ++m_CurrentIndex; + return PF_Err_NONE; + } + + PF_Err StartParameterCategory(PF_InData *in_data, const char *name, unsigned int id) + { + PF_ParamDef def; + + AEFX_CLR_STRUCT(def); + PF_ADD_TOPIC(name, id); + m_ParametersIndexes[id] = ++m_CurrentIndex; + return PF_Err_NONE; + } + + PF_Err EndParameterCategory(PF_InData *in_data, unsigned int id) + { + PF_ParamDef def; + + AEFX_CLR_STRUCT(def); + PF_END_TOPIC(id); + m_ParametersIndexes[id] = ++m_CurrentIndex; + return PF_Err_NONE; + } + +protected: + AEGP_PluginID m_AAEID; + int *m_ParametersIndexes = nullptr; + int m_CurrentIndex = 0; +}; + +//---------------------------------------------------------------------------- + +__AAEPK_END + +#endif + diff --git a/AE_Suites/PopcornFX_Define.h b/AE_Suites/PopcornFX_Define.h new file mode 100644 index 00000000..1ceae62c --- /dev/null +++ b/AE_Suites/PopcornFX_Define.h @@ -0,0 +1,90 @@ +//---------------------------------------------------------------------------- +// Copyright Persistant Studios, SARL. All Rights Reserved. https://www.popcornfx.com/terms-and-conditions/ +//---------------------------------------------------------------------------- +#pragma once + +#include + +//---------------------------------------------------------------------------- + +#if (defined(MACOSX) || defined(__APPLE__) || defined(__apple__) || defined(macosx) || defined(MACOS_X)) && !defined(PK_MACOSX) +# define PK_MACOSX +#elif (defined(WIN32) || defined(_WIN32) || defined(__WIN32__) || defined(__win32__)) && !defined(PK_WINDOWS) +# define PK_WINDOWS +#endif + +//---------------------------------------------------------------------------- + +typedef unsigned char u_char; +typedef unsigned short u_short; +typedef unsigned short u_int16; +typedef unsigned long u_long; +typedef short int int16; +typedef float fpshort; + +//---------------------------------------------------------------------------- + +#define __AAEPK_BEGIN namespace AAePk { +#define __AAEPK_END } + +__AAEPK_BEGIN + +//---------------------------------------------------------------------------- + +#define PK_SCALE_DOWN 1 + +#define TEST_COLOR_PROFILE 1 + +#define PF_TABLE_BITS 12 + +#define PF_DEEP_COLOR_AWARE 1 // make sure we get 16bpc pixels; + +#define A_INTERNAL_TEST_ONE 0 + +inline bool ae_verify(bool condition) +{ +#if defined(PK_WINDOWS) + // Only breaks on windows for now + // should add a raise(SIGTRAP) for macos + if (condition == false) + __debugbreak(); +#endif + return condition; +} + +#ifndef AE_STRINGIFY +# define AE_STRINGIFY(s) __AE_STRINGIFY(s) +# define __AE_STRINGIFY(s) # s // don't directly use this one +#endif // !PK_STRINGIFY + +#define AE_MESSAGE(__msg) __pragma(message(__msg)) +#define AE_TODO(__msg) AE_MESSAGE(__FILE__ "(" AE_STRINGIFY(__LINE__) ") /!\\/!\\/!\\/!\\ TODO /!\\/!\\/!\\/!\\ " __msg) + +#define AE_VERIFY(__condition) ae_verify(__condition) + +// sub (shared) context +#ifndef WGL_CONTEXT_MAJOR_VERSION_ARB +#define WGL_CONTEXT_MAJOR_VERSION_ARB 0x2091 +#define WGL_CONTEXT_MINOR_VERSION_ARB 0x2092 +#define WGL_CONTEXT_PROFILE_MASK_ARB 0x9126 +#define WGL_CONTEXT_FLAGS_ARB 0x2094 +#define WGL_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB 0x00000002 +#define WGL_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB 0x0002 +#endif + +//---------------------------------------------------------------------------- + +__AAEPK_END + +#include + +/* Versioning information */ +#define AEPOPCORNFX_MAJOR_VERSION PK_VERSION_MAJOR +#define AEPOPCORNFX_MINOR_VERSION PK_VERSION_MINOR +#define AEPOPCORNFX_BUG_VERSION PK_VERSION_PATCH +#define AEPOPCORNFX_STAGE_VERSION PF_Stage_DEVELOP +#include "PopcornFX_Define_Version.h" + +typedef char16_t aechar_t; + +//---------------------------------------------------------------------------- diff --git a/AE_Suites/PopcornFX_Define_Version.h b/AE_Suites/PopcornFX_Define_Version.h new file mode 100644 index 00000000..94579e4b --- /dev/null +++ b/AE_Suites/PopcornFX_Define_Version.h @@ -0,0 +1,9 @@ +//---------------------------------------------------------------------------- +// Copyright Persistant Studios, SARL. All Rights Reserved. https://www.popcornfx.com/terms-and-conditions/ +//---------------------------------------------------------------------------- +#pragma once + +//---------------------------------------------------------------------------- + +#define AEPOPCORNFX_BUILD_VERSION 1 +#define AEPOPCORNFX_PIPL_VERSION 1148929 //AEPOPCORNFX_MAJOR_VERSION * 524288 + AEPOPCORNFX_MINOR_VERSION * 32768 + AEPOPCORNFX_BUG_VERSION * 2048 + AEPOPCORNFX_STAGE_VERSION * 512 + AEPOPCORNFX_BUILD_VERSION - 1 diff --git a/AE_Suites/PopcornFX_Suite.h b/AE_Suites/PopcornFX_Suite.h new file mode 100644 index 00000000..251df69d --- /dev/null +++ b/AE_Suites/PopcornFX_Suite.h @@ -0,0 +1,1407 @@ +//---------------------------------------------------------------------------- +// Copyright Persistant Studios, SARL. All Rights Reserved. https://www.popcornfx.com/terms-and-conditions/ +//---------------------------------------------------------------------------- +#pragma once + +#ifndef __POPCORNFX_SUITE_H__ +#define __POPCORNFX_SUITE_H__ + +#include "A.h" +#include + +#ifdef AE_OS_WIN +#include +#endif + +#include + +//AE +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "PopcornFX_Define.h" + +#include +#include +#include + +//---------------------------------------------------------------------------- + +#define kPopcornFXSuite1 "AEGP PopcornFX Suite" +#define kPopcornFXSuiteVersion1 1 + +__AAEPK_BEGIN + +//---------------------------------------------------------------------------- + +enum EPKChildPlugins +{ + EMITTER = 0, + ATTRIBUTE, + SAMPLER, + _PLUGIN_COUNT +}; + +#pragma region Emitter + +//---------------------------------------------------------------------------- + +enum EGaussianBlurPixelRadius +{ + GaussianBlurPixelRadius_5 = 1, + GaussianBlurPixelRadius_9, + GaussianBlurPixelRadius_13, + __GaussianBlurPixelRadius_Count = GaussianBlurPixelRadius_13 +}; + +//---------------------------------------------------------------------------- + +enum ELightCategory +{ + ELightCategory_Debug_Default = 1, + ELightCategory_Compo_Default, + ELightCategory_Compo_Custom, + __ELightCategory_Count = ELightCategory_Compo_Custom +}; + +//---------------------------------------------------------------------------- + +enum ETransformType +{ + ETransformType_3D = 1, + ETransformType_2D, + __ETransformType_Count = ETransformType_2D +}; + +//---------------------------------------------------------------------------- + +enum ECameraType +{ + ECameraType_Compo_Default = 1, + ECameraType_Compo_Custom, + __ECameraType_Count = ECameraType_Compo_Custom +}; + +//---------------------------------------------------------------------------- + +enum ERenderType +{ + RenderType_FinalCompositing = 1, + RenderType_Emissive, + RenderType_Albedo, + RenderType_Normal, + RenderType_Depth, + __RenderType_Count = RenderType_Depth +}; + +//---------------------------------------------------------------------------- + +enum EInterpolationType +{ + EInterpolationType_Point = 1, + EInterpolationType_Trilinear, + EInterpolationType_Quadrilinear, + __EInterpolationType_Count = EInterpolationType_Quadrilinear +}; + +//---------------------------------------------------------------------------- + +// Add new effect parameters at the end of this enum +enum EEffectParameterType +{ + Effect_Parameters_InputReserved = 0, + + Effect_Parameters_Infernal_Autorender, + + Effect_Parameters_Path, + Effect_Parameters_Path_Reimport, + + Effect_Parameters_Infernal_Effect_Path_Hash, + + Effect_Topic_Transform_Start, + Effect_Parameters_Position, + Effect_Parameters_Rotation_X, + Effect_Parameters_Rotation_Y, + Effect_Parameters_Rotation_Z, + Effect_Topic_Transform_End, + + Effect_Parameters_Seed, + + + Effect_Topic_Rendering_Start, + + Effect_Parameters_Background_Toggle, + Effect_Parameters_Background_Opacity, + + Effect_Parameters_Render_Type, // PF_ParamFlag_CANNOT_TIME_VARY | PF_ParamFlag_CANNOT_INTERP + + Effect_Topic_Camera_Start, + Effect_Parameters_Camera, + Effect_Parameters_Camera_Position, + Effect_Parameters_Camera_Rotation_X, + Effect_Parameters_Camera_Rotation_Y, + Effect_Parameters_Camera_Rotation_Z, + Effect_Parameters_Camera_FOV, + Effect_Parameters_Camera_Near, + Effect_Parameters_Camera_Far, + Effect_Topic_Camera_End, + + Effect_Parameters_Receive_Light, // PF_ParamFlag_CANNOT_TIME_VARY || PF_ParamFlag_CANNOT_INTERP + + Effect_Topic_PostFX_Start, + Effect_Topic_Distortion_Start, + Effect_Parameters_Distortion_Enable, // PF_ParamFlag_CANNOT_TIME_VARY || PF_ParamFlag_CANNOT_INTERP + Effect_Topic_Distortion_End, + + Effect_Topic_Bloom_Start, + Effect_Parameters_Bloom_Enable, // PF_ParamFlag_CANNOT_TIME_VARY || PF_ParamFlag_CANNOT_INTERP + Effect_Parameters_Bloom_BrightPassValue, + Effect_Parameters_Bloom_Intensity, + Effect_Parameters_Bloom_Attenuation, + Effect_Parameters_Bloom_GaussianBlur, // PF_ParamFlag_CANNOT_TIME_VARY || PF_ParamFlag_CANNOT_INTERP + Effect_Parameters_Bloom_RenderPassCount, // PF_ParamFlag_CANNOT_TIME_VARY || PF_ParamFlag_CANNOT_INTERP + Effect_Topic_Bloom_End, + + Effect_Topic_ToneMapping_Start, + Effect_Parameters_ToneMapping_Enable, // PF_ParamFlag_CANNOT_TIME_VARY || PF_ParamFlag_CANNOT_INTERP + Effect_Parameters_ToneMapping_Saturation, + Effect_Parameters_ToneMapping_Exposure, + Effect_Topic_ToneMapping_End, + Effect_Topic_PostFX_End, + + Effect_Topic_Rendering_End, + + Effect_Topic_BackdropMesh_Start, + Effect_Parameters_BackdropMesh_Enable_Rendering, + Effect_Parameters_BackdropMesh_Enable_Collisions, + Effect_Parameters_BackdropMesh_Path, + Effect_Parameters_BackdropMesh_Reset, + + Effect_Topic_BackdropMesh_Transform_Start, + Effect_Parameters_BackdropMesh_Position, + Effect_Parameters_BackdropMesh_Rotation_X, + Effect_Parameters_BackdropMesh_Rotation_Y, + Effect_Parameters_BackdropMesh_Rotation_Z, + Effect_Parameters_BackdropMesh_Scale_X, + Effect_Parameters_BackdropMesh_Scale_Y, + Effect_Parameters_BackdropMesh_Scale_Z, + Effect_Topic_BackdropMesh_Transform_End, + Effect_Parameters_BackdropMesh_Roughness, + Effect_Parameters_BackdropMesh_Metalness, + Effect_Topic_BackdropMesh_End, + + Effect_Topic_BackdropEnvMap_Start, + Effect_Parameters_BackdropEnvMap_Enable_Rendering, + Effect_Parameters_BackdropEnvMap_Path, + Effect_Parameters_BackdropEnvMap_Reset, + Effect_Parameters_BackdropEnvMap_Intensity, + Effect_Parameters_BackdropEnvMap_Color, + Effect_Topic_BackdropEnvMap_End, + + Effect_Topic_Light_Start, + Effect_Parameters_Light_Category, + Effect_Parameters_Light_Direction, + Effect_Parameters_Light_Intensity, + Effect_Parameters_Light_Color, + Effect_Parameters_Light_Ambient, + Effect_Topic_Light_End, + + Effect_Parameters_Scale_Factor, + Effect_Parameters_Refresh_Render, + + Effect_Parameters_Seeking_Toggle, + Effect_Parameters_Simulation_State, + + Effect_Parameters_BackdropMesh_Enable_Animation, + + Effect_Topic_FXAA_Start, + Effect_Parameters_FXAA_Enable, // PF_ParamFlag_CANNOT_TIME_VARY || PF_ParamFlag_CANNOT_INTERP + Effect_Topic_FXAA_End, + + Effect_Parameters_Path_Marketplace, + + Effect_Parameters_TransformType, + Effect_Parameters_Position_2D, + Effect_Parameters_Position_2D_Distance, + + Effect_Topic_BackdropAudio_Start, + Effect_Parameters_Audio, + Effect_Topic_BackdropAudio_End, + + Effect_Parameters_BringEffectIntoView, + __Effect_Parameters_Count +}; + +//---------------------------------------------------------------------------- + +struct SPostFXDistortionDesc +{ + bool m_Enable; +}; + +//---------------------------------------------------------------------------- + +struct SPostFXBloomDesc +{ + bool m_Enable; + float m_BrightPassValue; + float m_Intensity; + float m_Attenuation; + EGaussianBlurPixelRadius m_GaussianBlur; + int m_RenderPassCount; +}; + +//---------------------------------------------------------------------------- + +struct SPostFXToneMappingDesc +{ + bool m_Enable; + + float m_Saturation; + float m_Exposure; +}; + +//---------------------------------------------------------------------------- + +struct SPostFXAADesc +{ + bool m_Enable; +}; + +//---------------------------------------------------------------------------- + +struct SRenderingDesc +{ + ERenderType m_Type; + bool m_ReceiveLight; + + SPostFXDistortionDesc m_Distortion; + SPostFXBloomDesc m_Bloom; + SPostFXToneMappingDesc m_ToneMapping; + SPostFXAADesc m_FXAA; +}; + +//---------------------------------------------------------------------------- + +struct SLightDesc +{ + bool m_Internal = true; + ELightCategory m_Category; + + A_FloatPoint3 m_Direction; + A_FloatPoint3 m_Position; + A_FloatPoint3 m_Color; + A_FloatPoint3 m_Ambient; + float m_Intensity; + float m_Angle; + float m_Feather; + + AEGP_LightType m_Type; +}; + +//---------------------------------------------------------------------------- + +struct SCameraDesc +{ + bool m_Internal = false; + bool m_AECameraPresent = false; + + A_FloatPoint3 m_Position; + A_FloatPoint3 m_Rotation; + + float m_FOV; + float m_Near = 0.1f; + float m_Far = 1000; + +}; + +//---------------------------------------------------------------------------- + +struct SBackdropMesh +{ + std::string m_Path; + + bool m_EnableRendering; + bool m_EnableCollisions; + bool m_EnableAnimations; + + A_FloatPoint3 m_Position; + A_FloatPoint3 m_Rotation; + A_FloatPoint3 m_Scale; + + float m_Roughness; + float m_Metalness; +}; + +//---------------------------------------------------------------------------- + +struct SBackdropEnvironmentMap +{ + std::string m_Path; + + bool m_EnableRendering = false; + + float m_Intensity; + A_FloatPoint3 m_Color; + +}; + +//---------------------------------------------------------------------------- + +enum EEmitterEffectGenericCall : int +{ + EmitterDesc = 0, + GetEmitterInfos +}; + + +//---------------------------------------------------------------------------- + +struct SGetEmitterInfos +{ + const EEmitterEffectGenericCall m_Type = EEmitterEffectGenericCall::GetEmitterInfos; + char m_Name[1024]; + char m_PathSource[1024]; +}; + +//---------------------------------------------------------------------------- + +struct SEmitterDesc +{ + const EEmitterEffectGenericCall m_Type = EEmitterEffectGenericCall::EmitterDesc; + static int s_ID; +public: + std::string m_Name; + std::string m_PathSource; + std::string m_UUID; + + ETransformType m_TransformType; + A_FloatPoint3 m_Position; + A_FloatPoint3 m_Rotation; + + bool m_IsAlphaBGOverride; + float m_AlphaBGOverride; + + int m_Seed = 0; + + SCameraDesc m_Camera; + SRenderingDesc m_Rendering; + + SBackdropMesh m_BackdropMesh; + SBackdropEnvironmentMap m_BackdropEnvironmentMap; + + SLightDesc m_Light; + + float m_ScaleFactor = 1; + + bool m_Update; + bool m_UpdateBackdrop = true; + bool m_LoadBackdrop = false; + int m_DebugID; + + A_long m_LayerID; + bool m_IsDeleted = false; + bool m_ReloadEffect = false; + + bool m_SimStatePrev = true; + bool m_SimState = true; + + SEmitterDesc() + { + SEmitterDesc::s_ID++; + m_DebugID = SEmitterDesc::s_ID; + m_Position.x = 0; + m_Position.y = 0; + m_Position.z = 0; + + m_Rotation.x = 0; + m_Rotation.y = 0; + m_Rotation.z = 0; + + m_IsAlphaBGOverride = false; + m_AlphaBGOverride = 1.0f; + m_LayerID = 0; + } +}; + +//---------------------------------------------------------------------------- + +#pragma region AttributeSampler + +enum ESamplerShapeType : int +{ + SamplerShapeType_Box = 0, + SamplerShapeType_Sphere, + SamplerShapeType_Ellipsoid, + SamplerShapeType_Cylinder, + SamplerShapeType_Capsule, + SamplerShapeType_Cone, + SamplerShapeType_Mesh, + + SamplerShapeType_None, + __SamplerShapeType_Count = SamplerShapeType_Mesh +}; + +//---------------------------------------------------------------------------- + +struct SBaseSamplerDescriptor +{ + uint32_t m_UsageFlags = 0; +}; + +//---------------------------------------------------------------------------- + +struct SShapeSamplerDescriptor : public SBaseSamplerDescriptor +{ + ESamplerShapeType m_Type; + + float m_Dimension[3]; + + std::string m_Path; + + //Skinned Backdrop + bool m_BindToBackdrop; + bool m_WeightedSampling; + unsigned int m_ColorStreamID; + unsigned int m_WeightStreamID; + + SShapeSamplerDescriptor() + : m_Type(SamplerShapeType_None) + , m_BindToBackdrop(false) + , m_WeightedSampling(false) + , m_ColorStreamID(0) + , m_WeightStreamID(0) + + { + m_Dimension[0] = 1.0f; + m_Dimension[1] = 1.0f; + m_Dimension[2] = 1.0f; + } +}; + +//---------------------------------------------------------------------------- + +struct STextSamplerDescriptor : public SBaseSamplerDescriptor +{ + AEGP_LayerIDVal m_LayerID = AEGP_LayerIDVal_NONE; + std::string m_Data; +}; + +//---------------------------------------------------------------------------- + +struct SAudioSamplerDescriptor : public SBaseSamplerDescriptor +{ + AEGP_LayerIDVal m_LayerID = AEGP_LayerIDVal_NONE; + + std::string m_ChannelGroup = ""; +}; + +//---------------------------------------------------------------------------- + +struct SImageSamplerDescriptor : public SBaseSamplerDescriptor +{ + AEGP_LayerIDVal m_LayerID = AEGP_LayerIDVal_NONE; +}; + +//---------------------------------------------------------------------------- + +struct SVectorFieldSamplerDescriptor : public SBaseSamplerDescriptor +{ + std::string m_Path; + + EInterpolationType m_Interpolation; + float m_Strength; + A_FloatPoint3 m_Position; + + bool m_ResourceUpdate; +}; + +//---------------------------------------------------------------------------- + +enum EAttributeSamplerType : int +{ + AttributeSamplerType_None = 0, + AttributeSamplerType_Animtrack, + AttributeSamplerType_Audio, + AttributeSamplerType_Curve, + AttributeSamplerType_EventStream, + AttributeSamplerType_Geometry, + AttributeSamplerType_Image, + AttributeSamplerType_ImageAtlas, + AttributeSamplerType_Grid, + AttributeSamplerType_Text, + AttributeSamplerType_VectorField, + __AttributeSamplerType_Count, +}; + +//---------------------------------------------------------------------------- + +enum EAttributeSamplerParameterType : int +{ + AttributeSamplerType_Parameters_Infernal_Uuid = 1, + AttributeSamplerType_Parameters_Infernal_Name, + AttributeSamplerType_Parameters_Shapes, + + AttributeSamplerType_Topic_Shape_Start, + + AttributeSamplerType_Topic_Shape_Box_Start, + AttributeSamplerType_Parameters_Box_Size_X, + AttributeSamplerType_Parameters_Box_Size_Y, + AttributeSamplerType_Parameters_Box_Size_Z, + AttributeSamplerType_Topic_Shape_Box_End, + + AttributeSamplerType_Topic_Shape_Sphere_Start, + AttributeSamplerType_Parameters_Sphere_Radius, + AttributeSamplerType_Parameters_Sphere_InnerRadius, + AttributeSamplerType_Topic_Shape_Sphere_End, + + AttributeSamplerType_Topic_Shape_Ellipsoid_Start, + AttributeSamplerType_Parameters_Ellipsoid_Radius, + AttributeSamplerType_Parameters_Ellipsoid_InnerRadius, + AttributeSamplerType_Topic_Shape_Ellipsoid_End, + + AttributeSamplerType_Topic_Shape_Cylinder_Start, + AttributeSamplerType_Parameters_Cylinder_Radius, + AttributeSamplerType_Parameters_Cylinder_Height, + AttributeSamplerType_Parameters_Cylinder_InnerRadius, + AttributeSamplerType_Topic_Shape_Cylinder_End, + + AttributeSamplerType_Topic_Shape_Capsule_Start, + AttributeSamplerType_Parameters_Capsule_Radius, + AttributeSamplerType_Parameters_Capsule_Height, + AttributeSamplerType_Parameters_Capsule_InnerRadius, + AttributeSamplerType_Topic_Shape_Capsule_End, + + AttributeSamplerType_Topic_Shape_Cone_Start, + AttributeSamplerType_Parameters_Cone_Radius, + AttributeSamplerType_Parameters_Cone_Height, + AttributeSamplerType_Topic_Shape_Cone_End, + + AttributeSamplerType_Topic_Shape_Mesh_Start, + AttributeSamplerType_Parameters_Mesh_Scale, + AttributeSamplerType_Parameters_Mesh_Path, + AttributeSamplerType_Parameters_Mesh_Bind_Backdrop, + AttributeSamplerType_Parameters_Mesh_Bind_Backdrop_Weighted_Enabled, + AttributeSamplerType_Parameters_Mesh_Bind_Backdrop_ColorStreamID, + AttributeSamplerType_Parameters_Mesh_Bind_Backdrop_WeightStreamID, + AttributeSamplerType_Topic_Shape_Mesh_End, + + AttributeSamplerType_Topic_Shape_End, + + AttributeSamplerType_Layer_Pick, + + AttributeSamplerType_Layer_Sample_Once, + AttributeSamplerType_Layer_Sample_Seeking, + + AttributeSamplerType_Parameters_VectorField_Path, + AttributeSamplerType_Parameters_VectorField_Strength, + AttributeSamplerType_Parameters_VectorField_Position, + AttributeSamplerType_Parameters_VectorField_Interpolation, + + AttributeSamplerType_Layer_Sample_Downsampling_X, + AttributeSamplerType_Layer_Sample_Downsampling_Y, + + __AttributeSamplerType_Parameters_Count +}; + +//---------------------------------------------------------------------------- + +struct SAttributeBaseDesc +{ + unsigned int m_Order; + bool m_IsAttribute; + + std::string m_Name; + std::string m_CategoryName; + + bool m_IsDeleted = false; + + SAttributeBaseDesc() + : m_Order(0) + , m_IsAttribute(false) + , m_Name("") + , m_CategoryName("") + { + + } + + SAttributeBaseDesc(const SAttributeBaseDesc &other) + : m_Order(other.m_Order) + , m_Name(other.m_Name) + , m_CategoryName(other.m_CategoryName) + , m_IsDeleted(other.m_IsDeleted) + { + } + + SAttributeBaseDesc &operator=(const SAttributeBaseDesc &other) + { + m_Name = other.m_Name; + m_CategoryName = other.m_CategoryName; + + return *this; + } + + std::string GetAttributePKKey() + { + std::string key = ""; + if (m_CategoryName.length() != 0) + { + key += m_CategoryName; + key += ":"; + } + key += m_Name; + return key; + } +}; + +//---------------------------------------------------------------------------- + +struct SAttributeSamplerDesc : public SAttributeBaseDesc +{ +public: + EAttributeSamplerType m_Type; + SBaseSamplerDescriptor *m_Descriptor = nullptr; + std::string m_ResourcePath = ""; + bool m_IsDefaultValue = true; + + SAttributeSamplerDesc(const char* name = nullptr, const char* category = nullptr, EAttributeSamplerType type = AttributeSamplerType_None) + : m_Type(type) + { + m_Name = name == nullptr ? "" : name; + m_CategoryName = category == nullptr ? "" : category; + } + + SAttributeSamplerDesc(const SAttributeSamplerDesc &other) + : SAttributeBaseDesc(other) + , m_Type(other.m_Type) + , m_Descriptor(other.m_Descriptor) + , m_IsDefaultValue(other.m_IsDefaultValue) + { + if(m_ResourcePath.length() == 0) + m_ResourcePath = (other.m_ResourcePath); + } + + SAttributeSamplerDesc &operator=(const SAttributeSamplerDesc &other) + { + m_Name = other.m_Name; + m_CategoryName = other.m_CategoryName; + m_Type = other.m_Type; + m_Descriptor = other.m_Descriptor; + m_IsDeleted = other.m_IsDeleted; + m_IsDefaultValue = other.m_IsDefaultValue; + + if (m_ResourcePath.length() == 0) + m_ResourcePath = (other.m_ResourcePath); + + return *this; + } +}; + +#pragma endregion + +//---------------------------------------------------------------------------- +#pragma region Attribute + +enum EAttributeType : int +{ + AttributeType_None = 0, + AttributeType_Bool1, + AttributeType_Bool2, + AttributeType_Bool3, + AttributeType_Bool4, + AttributeType_Int1, + AttributeType_Int2, + AttributeType_Int3, + AttributeType_Int4, + AttributeType_Float1, + AttributeType_Float2, + AttributeType_Float3, + AttributeType_Float4, + __AttributeType_Count, +}; + +//---------------------------------------------------------------------------- + +enum EAttributeParameterType : int +{ + Attribute_Parameters_Bool1 = 1, + Attribute_Parameters_Bool2, + Attribute_Parameters_Bool3, + Attribute_Parameters_Bool4, + Attribute_Parameters_Int1, + Attribute_Parameters_Int2, + Attribute_Parameters_Int3, + Attribute_Parameters_Int4, + Attribute_Parameters_Float1, + Attribute_Parameters_Float2, + Attribute_Parameters_Float3, + Attribute_Parameters_Float4, + Attribute_Parameters_Infernal_Uuid, + Attribute_Parameters_AffectedByScale, + Attribute_Parameters_Infernal_Name, + Attribute_Parameters_Color_RGB, + Attribute_Parameters_Color_A, + Attribute_Parameters_Reset, + __Attribute_Parameters_Count +}; + +//---------------------------------------------------------------------------- + +enum EAttributeSemantic : int +{ + AttributeSemantic_None = 0, + AttributeSemantic_Coordinate, + AttributeSemantic_Scale, + AttributeSemantic_Color, + __AttributeSemantic_Count +}; + +//---------------------------------------------------------------------------- + +union UAttributeValue +{ + void *m_Invalid; + bool m_Bool4[4]; + int m_Int4[4]; + float m_Float4[4]; + float m_Angles[3]; +}; + +//---------------------------------------------------------------------------- + +struct SAttributeDesc : public SAttributeBaseDesc +{ +public: + EAttributeType m_Type; + EAttributeSemantic m_AttributeSemantic; + + UAttributeValue m_DefaultValue; + + UAttributeValue m_MinValue; + UAttributeValue m_MaxValue; + + bool m_HasMax = false; + bool m_HasMin = false; + + UAttributeValue m_Value; + bool m_IsValid; + bool m_IsDirty; + + std::mutex m_Lock; +public: + bool m_IsDefaultValue = true; + bool m_IsAffectedByScale = false; + + SAttributeDesc(const char* name = nullptr, const char* category = nullptr, EAttributeType type = AttributeType_None, EAttributeSemantic semantic = EAttributeSemantic::AttributeSemantic_None) + : m_Type(type) + , m_AttributeSemantic(semantic) + , m_DefaultValue() + , m_MinValue() + , m_MaxValue() + , m_Value() + , m_IsValid(true) + , m_IsDirty(true) + { + m_IsAttribute = true; + m_Name = name == nullptr ? "" : name; + m_CategoryName = category == nullptr ? "" : category; + } + + SAttributeDesc(const SAttributeDesc &other) + : SAttributeBaseDesc(other) + , m_Type(other.m_Type) + , m_AttributeSemantic(other.m_AttributeSemantic) + , m_DefaultValue(other.m_DefaultValue) + , m_MinValue(other.m_MinValue) + , m_MaxValue(other.m_MaxValue) + , m_HasMax(other.m_HasMax) + , m_HasMin(other.m_HasMin) + , m_Value(other.m_Value) + , m_IsValid(other.m_IsValid) + , m_IsDirty(true) + , m_IsDefaultValue(other.m_IsDefaultValue) + { + + } + + ~SAttributeDesc() + { + + } + + SAttributeDesc& operator=(const SAttributeDesc &other) + { + m_Name = other.m_Name; + m_CategoryName = other.m_CategoryName; + m_Type = other.m_Type; + m_AttributeSemantic = other.m_AttributeSemantic; + + m_HasMin = other.m_HasMin; + m_HasMax = other.m_HasMax; + + m_MinValue = other.m_MinValue; + m_MaxValue = other.m_MaxValue; + + if (m_IsDefaultValue == true) + { + m_Value = other.m_Value; + m_IsDefaultValue = other.m_IsDefaultValue; + } + m_DefaultValue = other.m_DefaultValue; + m_IsDirty = true; + m_IsValid = other.m_IsValid; + m_IsDeleted = other.m_IsDeleted; + return *this; + } + + void Invalidate() + { + m_IsValid = false; + } + + bool isValid() + { + return m_IsValid; + } + + bool ResetValues() + { + m_Lock.lock(); + memcpy(&m_Value, &m_DefaultValue, sizeof(UAttributeValue)); + m_IsDirty = true; + m_IsDefaultValue = true; + m_Lock.unlock(); + + return true; + } + + template + void SetDefaultValue(T *value) + { + return _SetValueImpl(value, m_DefaultValue, true); + } + + template + void GetDefaultValue(T *value) + { + return _GetValueImpl(value, m_DefaultValue); + } + + template + void GetDefaultValueByType(EAttributeType type, T *value) + { + _GetValueByTypeImpl(type, value, m_DefaultValue); + } + + template + void SetValue(T *value) + { + return _SetValueImpl(value, m_Value); + } + + template + void GetValue(T *value) + { + return _GetValueImpl(value, m_Value); + } + + template + void GetValueByType(EAttributeType type, T *value) + { + _GetValueByTypeImpl(type, value, m_Value); + } + + void *GetRawValue() + { + return _GetRawValueImpl(m_Value); + } + + void GetValueAsStreamValue(EAttributeType type, AEGP_StreamValue *value) + { + _GetValueAsStreamValueImpl(type, value, m_Value); + } + + template + void SetMinValue(T *value) + { + return _SetValueImpl(value, m_MinValue); + } + + template + void GetMinValueByType(EAttributeType type, T *value) + { + _GetValueByTypeImpl(type, value, m_MinValue); + } + + template + void SetMaxValue(T *value) + { + return _SetValueImpl(value, m_MaxValue); + } + + template + void GetMaxValueByType(EAttributeType type, T *value) + { + _GetValueByTypeImpl(type, value, m_MaxValue); + } + + void Reset() + { + m_IsDirty = true; + m_IsValid = false; + m_Value = {}; + m_Name = ""; + m_CategoryName = ""; + m_Type = AttributeType_None; + m_AttributeSemantic = EAttributeSemantic::AttributeSemantic_None; + } +private: + template + void _SetValueImpl(T *value, UAttributeValue &field, bool isDefault = false) + { + m_Lock.lock(); + switch (m_Type) + { + case AttributeType_Bool4: + case AttributeType_Bool3: + case AttributeType_Bool2: + case AttributeType_Bool1: + memcpy(field.m_Bool4, value, sizeof(bool) * 4); + break; + case AttributeType_Int4: + case AttributeType_Int3: + case AttributeType_Int2: + case AttributeType_Int1: + memcpy(field.m_Int4, value, sizeof(int) * 4); + break; + case AttributeType_Float4: + case AttributeType_Float3: + case AttributeType_Float2: + case AttributeType_Float1: + memcpy(field.m_Float4, value, sizeof(float) * 4); + break; + default: + m_IsValid = false; + AE_VERIFY(false); + break; + } + m_IsDirty = true; + m_IsDefaultValue = isDefault; + m_Lock.unlock(); + } + + template + void _GetValueByTypeImpl(EAttributeType type, T *value, UAttributeValue &field) + { + m_Lock.lock(); + switch (type) + { + case AttributeType_Bool4: + *value = (T)field.m_Bool4[3]; + break; + case AttributeType_Bool3: + *value = (T)field.m_Bool4[2]; + break; + case AttributeType_Bool2: + *value = (T)field.m_Bool4[1]; + break; + case AttributeType_Bool1: + *value = (T)field.m_Bool4[0]; + break; + case AttributeType_Int4: + *value = (T)field.m_Int4[3]; + break; + case AttributeType_Int3: + *value = (T)field.m_Int4[2]; + break; + case AttributeType_Int2: + *value = (T)field.m_Int4[1]; + break; + case AttributeType_Int1: + *value = (T)field.m_Int4[0]; + break; + case AttributeType_Float4: + *value = (T)field.m_Float4[3]; + break; + case AttributeType_Float3: + *value = (T)field.m_Float4[2]; + break; + case AttributeType_Float2: + *value = (T)field.m_Float4[1]; + break; + case AttributeType_Float1: + *value= (T)field.m_Float4[0]; + break; + default: + m_IsValid = false; + AE_VERIFY(false); + break; + } + m_Lock.unlock(); + } + + void _GetValueAsStreamValueImpl(EAttributeType type, AEGP_StreamValue *value, UAttributeValue &field) + { + m_Lock.lock(); + switch (type) + { + case AttributeType_Bool4: + value->val.one_d = field.m_Bool4[3]; + break; + case AttributeType_Bool3: + value->val.one_d = field.m_Bool4[2]; + break; + case AttributeType_Bool2: + value->val.one_d = field.m_Bool4[1]; + break; + case AttributeType_Bool1: + value->val.one_d = field.m_Bool4[0]; + break; + case AttributeType_Int4: + value->val.one_d = field.m_Int4[3]; + break; + case AttributeType_Int3: + value->val.one_d = field.m_Int4[2]; + break; + case AttributeType_Int2: + value->val.one_d = field.m_Int4[1]; + break; + case AttributeType_Int1: + value->val.one_d = field.m_Int4[0]; + break; + case AttributeType_Float4: + value->val.one_d = field.m_Float4[3]; + break; + case AttributeType_Float3: + value->val.one_d = field.m_Float4[2]; + break; + case AttributeType_Float2: + value->val.one_d = field.m_Float4[1]; + break; + case AttributeType_Float1: + value->val.one_d = field.m_Float4[0]; + break; + default: + m_IsValid = false; + AE_VERIFY(false); + break; + } + m_Lock.unlock(); + } + + template + void _GetValueImpl(T *value, UAttributeValue &field) + { + m_Lock.lock(); + switch (m_Type) + { + case AttributeType_Bool4: + value[3] = field.m_Bool4[3]; + case AttributeType_Bool3: + value[2] = field.m_Bool4[2]; + case AttributeType_Bool2: + value[1] = field.m_Bool4[1]; + case AttributeType_Bool1: + value[0] = field.m_Bool4[0]; + break; + case AttributeType_Int4: + value[3] = (T)field.m_Int4[3]; + case AttributeType_Int3: + value[2] = (T)field.m_Int4[2]; + case AttributeType_Int2: + value[1] = (T)field.m_Int4[1]; + case AttributeType_Int1: + value[0] = (T)field.m_Int4[0]; + break; + case AttributeType_Float4: + value[3] = field.m_Float4[3]; + case AttributeType_Float3: + value[2] = field.m_Float4[2]; + case AttributeType_Float2: + value[1] = field.m_Float4[1]; + case AttributeType_Float1: + value[0] = field.m_Float4[0]; + break; + default: + m_IsValid = false; + AE_VERIFY(false); + break; + } + m_Lock.unlock(); + } + + void *_GetRawValueImpl(UAttributeValue &field) + { + m_Lock.lock(); + + void* result = nullptr; + switch (m_Type) + { + case AttributeType_Bool4: + case AttributeType_Bool3: + case AttributeType_Bool2: + case AttributeType_Bool1: + result = (void*)&field.m_Bool4; + break; + case AttributeType_Int4: + case AttributeType_Int3: + case AttributeType_Int2: + case AttributeType_Int1: + result = (void*)&field.m_Int4; + break; + case AttributeType_Float4: + case AttributeType_Float3: + case AttributeType_Float2: + case AttributeType_Float1: + result = (void*)&field.m_Float4; + break; + default: + AE_VERIFY(false); + break; + } + m_Lock.unlock(); + return result; + } +}; + +#pragma endregion + +//---------------------------------------------------------------------------- + +union SAAEExtraData +{ + SAAEExtraData(PF_Cmd Cmd, void *data) + { + switch (Cmd) + { + case PF_Cmd_SMART_PRE_RENDER: + m_PreRenderData = reinterpret_cast(data); + break; + case PF_Cmd_SMART_RENDER: + m_SmartRenderData = reinterpret_cast(data); + break; + case PF_Cmd_USER_CHANGED_PARAM: + m_ChangeParamData = reinterpret_cast(data); + break; + default: + m_UndefinedData = data; + break; + } + } + PF_SmartRenderExtra *m_SmartRenderData; + PF_PreRenderExtra *m_PreRenderData; + PF_UserChangedParamExtra *m_ChangeParamData; + void *m_UndefinedData; +}; + +//---------------------------------------------------------------------------- + +struct SAAEIOData +{ + SAAEIOData(PF_Cmd Cmd, PF_InData *InData, PF_OutData *OutData, void *data, const int *paramIndexes) + : m_Cmd(Cmd) + , m_InData(InData) + , m_OutData(OutData) + , m_ExtraData(Cmd, data) + , m_WorldSuite(nullptr) + , m_ReturnCode(PF_Err_NONE) + , m_ParametersIndexes(paramIndexes) + { + if (m_InData && m_OutData) + { + AEFX_AcquireSuite( m_InData, + m_OutData, + kPFWorldSuite, + kPFWorldSuiteVersion2, + "Couldn't load suite.", + (void**)&m_WorldSuite); + } + }; + ~SAAEIOData() + { + if (m_InData && m_OutData) + { + AEFX_ReleaseSuite( m_InData, + m_OutData, + kPFWorldSuite, + kPFWorldSuiteVersion2, + "Couldn't release suite."); + } + m_WorldSuite = nullptr; + }; + + PF_Cmd m_Cmd; + + PF_InData *m_InData; + PF_OutData *m_OutData; + + SAAEExtraData m_ExtraData; + + PF_WorldSuite2 *m_WorldSuite; + + PF_Err m_ReturnCode; + + const int *m_ParametersIndexes; +}; + +//---------------------------------------------------------------------------- + +struct SAAEScopedParams +{ + PF_ParamDef m_ParamData; + PF_InData *m_InData; + + SAAEScopedParams(SAAEIOData& AAEData, A_u_long type) : + m_InData(AAEData.m_InData) + { + AEFX_CLR_STRUCT(m_ParamData); + int idx = (AAEData.m_ParametersIndexes != nullptr) ? AAEData.m_ParametersIndexes[type] : type; + PF_CHECKOUT_PARAM( m_InData, + idx, + m_InData->current_time, + m_InData->time_step, + m_InData->time_scale, + &m_ParamData); + } + ~SAAEScopedParams() + { + PF_CHECKIN_PARAM(m_InData, &m_ParamData); + m_InData = nullptr; + } + + PF_ParamDef &GetRawParam() { return m_ParamData; } + float GetAngle() const { return (float)m_ParamData.u.ad.value / 65536.0f; } + float GetFloat() const { return (float)m_ParamData.u.fs_d.value; } + float GetPercent() const { return (float)m_ParamData.u.fd.value / (float)m_ParamData.u.fd.valid_max; } + int GetInt() const { return (int)m_ParamData.u.fs_d.value; } + int GetComboBoxValue() const { return (int)m_ParamData.u.pd.value; } + bool GetCheckBoxValue() const { return (bool)m_ParamData.u.bd.value; } + PF_LayerDef GetLayer() const { return (PF_LayerDef)m_ParamData.u.ld; } + A_FloatPoint3 GetPoint3D() const + { + A_FloatPoint3 position = {(float)m_ParamData.u.point3d_d.x_value * m_InData->downsample_x.den, + (float)m_ParamData.u.point3d_d.y_value * m_InData->downsample_y.den, + (float)m_ParamData.u.point3d_d.z_value * ::sqrt(m_InData->downsample_x.den * m_InData->downsample_y.den)}; + return position; + } + A_FloatPoint GetPoint2D() const + { + A_FloatPoint position = { (float)m_ParamData.u.td.x_value * m_InData->downsample_x.den, + (float)m_ParamData.u.td.y_value * m_InData->downsample_y.den }; + return position; + } + A_FloatPoint3 GetColor() const + { + const PF_UnionablePixel &color = m_ParamData.u.cd.value; + return A_FloatPoint3{ color.red / 255.0f, color.green / 255.0f, color.blue / 255.0f }; + } +}; + +//---------------------------------------------------------------------------- + +struct SAAECamera +{ + float m_YFov; +}; + +//---------------------------------------------------------------------------- + +inline void CopyCharToUTF16(const char *input, + A_UTF16Char *destination) +{ + std::string basicStr(input); + std::u16string ws; + + ws.append(basicStr.begin(), basicStr.end()); + memcpy(destination, ws.data(), (ws.length() + 1) * sizeof(char16_t)); +} + +//---------------------------------------------------------------------------- + +inline void WCharToString(aechar_t *input, std::string *destination) +{ + std::u16string ws(input); + destination->append(ws.begin(), ws.end()); +} + +//---------------------------------------------------------------------------- + +inline unsigned int hashString(const char *str) +{ + unsigned int hash = 5381; + int c; + + while ((c = *str++)) + hash = ((hash << 5) + hash) + c; /* hash * 33 + c */ + + return hash; +} + +//---------------------------------------------------------------------------- + +inline float RadToDeg(const float angle) +{ + return angle * 180.f / 3.141592f; +} + +//---------------------------------------------------------------------------- + +inline float DegToRad(const float angle) +{ + return angle * 3.141592f / 180.f; +} + +//---------------------------------------------------------------------------- + +__AAEPK_END + +//---------------------------------------------------------------------------- + +struct PopcornFXSuite1 +{ + SPAPI A_Err (*InitializePopcornFXIFN) (AAePk::SAAEIOData& AAEData); + + SPAPI A_Err (*HandleNewEmitterEvent) (AAePk::SAAEIOData& AAEData, AAePk::SEmitterDesc *descriptor); + + SPAPI A_Err (*HandleDeleteEmitterEvent) (AAePk::SAAEIOData& AAEData, AAePk::SEmitterDesc *descriptor); + + SPAPI bool (*CheckEmitterValidity) (AAePk::SAAEIOData& AAEData, AAePk::SEmitterDesc *descriptor); + + SPAPI A_Err (*UpdateScene) (AAePk::SAAEIOData& AAEData, AAePk::SEmitterDesc* descriptor); + + SPAPI A_Err (*UpdateEmitter) (AAePk::SAAEIOData& AAEData, AAePk::SEmitterDesc* descriptor); + + SPAPI A_Err (*DisplayMarketplacePanel) (AAePk::SAAEIOData& AAEData, AAePk::SEmitterDesc* descriptor); + + SPAPI A_Err (*DisplayBrowseEffectPanel) (AAePk::SAAEIOData& AAEData, AAePk::SEmitterDesc* descriptor); + + SPAPI A_Err (*DisplayBrowseMeshDialog) (AAePk::SAAEIOData& AAEData, AAePk::SEmitterDesc* descriptor); + + SPAPI A_Err (*DisplayBrowseEnvironmentMapDialog) (AAePk::SAAEIOData& AAEData, AAePk::SEmitterDesc* descriptor); + + SPAPI A_Err (*ReimportEffect) (AAePk::SAAEIOData& AAEData, AAePk::SEmitterDesc* descriptor); + + SPAPI A_Err (*Display_AttributeSampler_BrowseMeshDialog) (AAePk::SAAEIOData& AAEData, AAePk::SAttributeSamplerDesc* descriptor); + + SPAPI A_Err (*ShutdownPopcornFXIFN) (AAePk::SAAEIOData& AAEData); + + SPAPI A_Err (*SetParametersIndexes) (const int *indexes, AAePk::EPKChildPlugins plugin); + + SPAPI A_Err (*SetDefaultLayerPosition) (AAePk::SAAEIOData& AAEData, AEGP_LayerH layer); + + SPAPI A_Err (*MoveEffectIntoCurrentView) (AAePk::SAAEIOData& AAEData, AAePk::SEmitterDesc* descriptor); + +}; + +//---------------------------------------------------------------------------- + +#endif // !__POPCORNFX_SUITE_H__ + + diff --git a/AE_Suites/PopcornFX_UID.h b/AE_Suites/PopcornFX_UID.h new file mode 100644 index 00000000..e7ac9d64 --- /dev/null +++ b/AE_Suites/PopcornFX_UID.h @@ -0,0 +1,67 @@ +//---------------------------------------------------------------------------- +// Copyright Persistant Studios, SARL. All Rights Reserved. https://www.popcornfx.com/terms-and-conditions/ +//---------------------------------------------------------------------------- +#pragma once + +#ifndef __POPCORNFX_UID_H__ +#define __POPCORNFX_UID_H__ + +#include "PopcornFX_Define.h" + +#include +#include +#include +#include +#include +#include +#include +#include + +__AAEPK_BEGIN + +//---------------------------------------------------------------------------- + +class CUUIDGenerator +{ +private: + CUUIDGenerator() {} + + static unsigned char _RandomChar() + { + std::random_device rd; + std::mt19937 gen(rd()); + std::uniform_int_distribution<> dis(0, 255); + return static_cast(dis(gen)); + } + + static std::string _GenerateHex(const unsigned int len) + { + std::stringstream ss; + + for (unsigned int i = 0; i < len; i++) + { + unsigned char rc = _RandomChar(); + std::stringstream hexstream; + + hexstream << std::hex << int(rc); + + std::string hex = hexstream.str(); + + ss << (hex.length() < 2 ? '0' + hex : hex); + } + return ss.str(); + } +public: + ~CUUIDGenerator() {}; + + static std::string Get32() { return _GenerateHex(32); } + static std::string Get16() { return _GenerateHex(16); } + static std::string Get8() { return _GenerateHex(8); } + +}; + +//---------------------------------------------------------------------------- + +__AAEPK_END + +#endif diff --git a/CopyQTDllsForAE.py b/CopyQTDllsForAE.py new file mode 100644 index 00000000..d86ade92 --- /dev/null +++ b/CopyQTDllsForAE.py @@ -0,0 +1,105 @@ +import os +import shutil +import sys +import subprocess +import pathlib + +# Check if file's relative location is as expected +script_dir = pathlib.Path(os.path.abspath(__file__)).parent +assert script_dir.match("*/source_tree/Integrations/AfterEffects") + +sys.path.append(str(script_dir / "../../SDK/Python")) +from Libs.pk_tools_locate import get_qt_bin_path + +#SETUP +#============ +QT_BIN_PATH_OVERRIDE="" # e.g. "E:\\SDK\\Qt\\Qt5.15.2\\5.15.2\\msvc2019_64\\bin" + +assembly_folder = "External/popcornfx.qt" +debug_dlls = False #Set this to True to add debug dlls in the private assembly +qt_dll_override_manifest = "qtoverride.dll.manifest" +win_kit_bin_path = "C:\\Program Files (x86)\\Windows Kits\\10\\bin" + +# [0] path: str +# [1] addInAssembly: bool +# [2] patchWithManifest: bool +dlls_to_copy = [ + ("Qt5Core.dll", True, False), #The first one must be Qt5Core + ("Qt5Gui.dll", True, True), + ("Qt5Widgets.dll", True, True), + ("../plugins/platforms/qwindows.dll", False, True), + ] +#============ + +def FindMtExe(): + versions_list = [name for name in os.listdir(win_kit_bin_path) if os.path.isdir(os.path.join(win_kit_bin_path, name)) and name.startswith("10.")] + versions_list.sort(reverse=True) + for version in versions_list: + mt_exe_path = os.path.join(win_kit_bin_path, version + "\\x64\\mt.exe") + if (os.path.exists(mt_exe_path)): + return mt_exe_path + return "" + +def CopyDll(dll, debug, path_qt_folder, mt_exe_path, f): + dll_path = dll[0] #path + if debug: + split_path = os.path.splitext(dll_path) + dll_path = split_path[0] + "d" + split_path[1] + src_fpath = os.path.join(path_qt_folder, dll_path) + file = os.path.basename(dll_path) + dest_fpath = os.path.join(assembly_folder, file) + print("Copying: " + file) + shutil.copy(src_fpath, dest_fpath) + if dll[1]: #addInAssembly + f.write(" \n") + if dll[2]: #patchWithManifest + cmd = [mt_exe_path, "-manifest", "qtoverride.dll.manifest", "-outputresource:" + assembly_folder + "/" + file + ";#2"] + process = subprocess.run(cmd, check=True, stdout=subprocess.DEVNULL) + process.check_returncode() + +def main(): + mt_exe_path = FindMtExe() + if not mt_exe_path: + print("Error: Could not found mt.exe") + sys.exit(1) + + if not os.path.exists(qt_dll_override_manifest): + print("Error: Could not found:" + qt_dll_override_manifest) + sys.exit(1) + + path_qt_folder = QT_BIN_PATH_OVERRIDE if QT_BIN_PATH_OVERRIDE else str(get_qt_bin_path(True)) + if not os.path.exists(path_qt_folder): + print("Error: Could not found Qt folder: " + path_qt_folder) + sys.exit(1) + print("Found Qt directory at: " + path_qt_folder) + + if not path_qt_folder: + print("Error: Could not found Qt directory in PATH") + sys.exit(1) + + if os.path.isdir(assembly_folder): + shutil.rmtree(assembly_folder) + os.mkdir(assembly_folder) + f = open(assembly_folder + "/popcornfx.qt.manifest", "w") + if not f: + print("Error: Could not open to write:" + assembly_folder + "/popcornfx.qt.manifest") + sys.exit(1) + + f.write("\n") + f.write("\"\n") + f.write("\n") + f.write(" \n") + + for dll in dlls_to_copy: + CopyDll(dll, False, path_qt_folder, mt_exe_path, f) + if debug_dlls: + CopyDll(dll, True, path_qt_folder, mt_exe_path, f) + + f.write("\n") + f.write("") + f.close() + + sys.exit(0) + +if __name__ == "__main__": + main() \ No newline at end of file diff --git a/External/AE SDK/Headers/A.h b/External/AE SDK/Headers/A.h new file mode 100644 index 00000000..b0ba6616 --- /dev/null +++ b/External/AE SDK/Headers/A.h @@ -0,0 +1,196 @@ +/*******************************************************************/ +/* */ +/* ADOBE CONFIDENTIAL */ +/* _ _ _ _ _ _ _ _ _ _ _ _ _ */ +/* */ +/* Copyright 2007 Adobe Systems Incorporated */ +/* All Rights Reserved. */ +/* */ +/* NOTICE: All information contained herein is, and remains the */ +/* property of Adobe Systems Incorporated and its suppliers, if */ +/* any. The intellectual and technical concepts contained */ +/* herein are proprietary to Adobe Systems Incorporated and its */ +/* suppliers and may be covered by U.S. and Foreign Patents, */ +/* patents in process, and are protected by trade secret or */ +/* copyright law. Dissemination of this information or */ +/* reproduction of this material is strictly forbidden unless */ +/* prior written permission is obtained from Adobe Systems */ +/* Incorporated. */ +/* */ +/*******************************************************************/ + +/** A.h + + Adobe-standard (hopefully one day) types to promote plug-in sharing. + +**/ +#ifndef _H_A +#define _H_A + +#ifdef A_INTERNAL + + #include + +#else + #include "stdint.h" + + typedef int32_t A_long; + typedef uint32_t A_u_long; + typedef char A_char; + typedef double A_FpLong; + typedef float A_FpShort; + typedef A_long A_Err; + typedef void * A_Handle; + typedef A_long A_Fixed; + typedef A_u_long A_UFixed; + + #if defined( __MWERKS__) || defined (__GNUC__) // metrowerks codewarrior and XCode/GCC + typedef int16_t A_short; + typedef uint16_t A_u_short; + typedef uint8_t A_u_char; + typedef uint8_t A_Boolean; + typedef intptr_t A_intptr_t; + #else // windows + typedef short A_short; + typedef unsigned short A_u_short; + typedef unsigned char A_u_char; + typedef unsigned char A_Boolean; + #ifdef _WIN64 + typedef __int64 A_intptr_t; + #else + typedef int32_t A_intptr_t; + #endif + #endif + +#ifdef _MSC_VER // visual c++ + typedef unsigned __int64 A_u_longlong; +#endif + +#if defined( __MWERKS__) || defined (__GNUC__) // metrowerks codewarrior and XCode/GCC + typedef uint64_t A_u_longlong; +#endif + + +#include + + + typedef struct { + A_long value; + A_u_long scale; + } A_Time; + + typedef struct { + A_long num; /* numerator */ + A_u_long den; /* denominator */ + } A_Ratio; + + typedef struct { + A_FpLong x, y; + } A_FloatPoint; + + typedef struct { + A_FpLong x, y, z; + } A_FloatPoint3; + + typedef struct { + A_FpLong left, top, right, bottom; + } A_FloatRect; + + typedef struct { + A_FpLong mat[3][3]; + } A_Matrix3; + + typedef struct { + A_FpLong mat[4][4]; + } A_Matrix4; + + typedef struct { + A_short top, left, bottom, right; + } A_LegacyRect; + + typedef struct { + A_long left, top, right, bottom; + } A_LRect; + + typedef A_LRect A_Rect; + + typedef struct { + A_long x, y; + } A_LPoint; + + typedef struct { + A_FpLong radius, angle; + } A_FloatPolar; + + typedef A_u_longlong A_HandleSize; + +#include + + + + +#endif + + +#include + +typedef struct { + A_FpLong alpha; + A_FpLong red; + A_FpLong green; + A_FpLong blue; + +} A_Color; + +#include + + + + + +#define A_THROW(ERR) throw ((A_long) ERR) + +enum { + A_Err_NONE = 0, + A_Err_GENERIC, + A_Err_STRUCT, + A_Err_PARAMETER, + A_Err_ALLOC, + A_Err_WRONG_THREAD, // Some calls can only be used on UI (Main) or Render threads. Also, calls back to AE can only be made from the same thread AE called you on + A_Err_CONST_PROJECT_MODIFICATION, // An attempt was made to write to a read only copy of an AE project. Project changes must originate in the UI/Main thread. + A_Err_RESERVED_7, + A_Err_RESERVED_8, + A_Err_RESERVED_9, + A_Err_RESERVED_10, + A_Err_RESERVED_11, + A_Err_RESERVED_12, + A_Err_MISSING_SUITE = 13, // acquire suite failed on a required suite + A_Err_RESERVED_14, + A_Err_RESERVED_15, + A_Err_RESERVED_16, + A_Err_RESERVED_17, + A_Err_RESERVED_18, + A_Err_RESERVED_19, + A_Err_RESERVED_20, + A_Err_RESERVED_21, + A_Err_NOT_IN_CACHE_OR_COMPUTE_PENDING, + + A_Err_LAST +}; + +typedef struct { + A_short majorS; + A_short minorS; +} A_Version; + +typedef struct _Up_OpaqueMem **AEGP_MemHandle; + +typedef A_u_short A_UTF16Char; + +#if defined( __MWERKS__) || defined (__GNUC__) // metrowerks codewarrior and XCode/GCC + typedef A_char A_LegacyEnumType; +#else // windows + typedef A_long A_LegacyEnumType; +#endif + +#endif diff --git a/External/AE SDK/Headers/AEConfig.h b/External/AE SDK/Headers/AEConfig.h new file mode 100644 index 00000000..c1b36982 --- /dev/null +++ b/External/AE SDK/Headers/AEConfig.h @@ -0,0 +1,102 @@ +#ifndef AECONFIG_H +#define AECONFIG_H + +/* +Usage guidelines for these defines. 4/12/2006 + +Always use the most specific kind for your problem. Try and use +the form + +#ifdef AE_XXXXX (i.e. AE_OS_MAC) + +#elif defined(AE_NOT_XXXX) (i.e. AE_OS_WIN) + +#else + #error "unknown" +#endif + +when creating conditionally compiled blocks. + +AE_OS_MAC | AE_OS_WIN + +are used to select between the most popular version of the operating +system API's. As of this writing AE_OS_MAC implies 10.4.4u SDK, and +AE_OS_WIN implies the platform SDK shipped with VS8 and _WIN32. + + +AE_PROC_PPC | AE_PROC_INTEL + +are used for code that will only execute on one processor family or +the other. Essentially should only be used for asm, or asm based +intrinsics. Note: we do not currently have a define for things +like SSE or SSE3 as we don't build the whole code base targetted +for different instances of processors. You'll need to do runtime checks for SSE3 +(though our minimum requirement is Pentium4 so SSE2 can be assumed). + + +AE_BIG_ENDIAN | AE_LITTLE_ENDIAN + +PowerPC on Mac was BIG endian (as is network byte order). +x86 is a little endian architecture. + +Try and avoid writing new code that uses this. Use XML or dva::filesupport +for writing things to disk. + +These defines should be seldom used, instead use the byte swapping macro's +already defined in U which will be a no-op on platforms that don't need it. + +For the record, our file format is stored big endian. + + +*/ +//Define our OS defines +#if defined(_WIN32) + #define AE_OS_WIN +#elif defined(__GNUC__) && defined(__MACH__) + #include "TargetConditionals.h" // defines the nesting of TARGET_OS_* + #if TARGET_OS_MAC + #if TARGET_OS_IPHONE + // Older SDKs ( before TV, WATCH ) do not have TARGET_OS_IOS defined. + #if TARGET_OS_IOS || !defined(TARGET_OS_IOS) + #define AE_OS_IOS + #endif + #else + #define AE_OS_MAC + #endif // TARGET_OS_IPHONE + + #if TARGET_OS_SIMULATOR + #define AE_OS_APPLE_SIM + #endif + #endif // TARGET_OS_MAC +#elif Rez + #define AE_OS_MAC +#elif defined(__ANDROID__) + #define AE_OS_ANDROID +#else + #error "unrecognized AE platform" +#endif + +//Define our Processor defines +#if defined(__i386__) || defined(_M_IX86) + #define AE_PROC_INTEL +#elif defined(_M_X64) || defined(__amd64__) || defined(__x86_64__) + #define AE_PROC_INTELx64 +#elif defined(__arm64__) || defined(__aarch64__) + #define AE_PROC_ARM64 +#else + #error "unrecognized AE processor" +#endif + +#if defined(AE_OS_MAC) && defined(AE_PROC_ARM64) +// This is used to enable/disable features that are still being +// ported/tested to run on Mac arm64based M1 processors, aka Apple Silicon. +// It is intended for Adobe internal use, and will be going away once the mac +// arm64 work is completed. +#define AE_MAC_ARM64_PROTOTYPE_TODO +#endif + +//Define our Byte order +#define AE_LITTLE_ENDIAN + + +#endif diff --git a/External/AE SDK/Headers/AEFX_ArbParseHelper.c b/External/AE SDK/Headers/AEFX_ArbParseHelper.c new file mode 100644 index 00000000..789f269b --- /dev/null +++ b/External/AE SDK/Headers/AEFX_ArbParseHelper.c @@ -0,0 +1,171 @@ +// AEFX_ArbParseHelper.c +// + + + +#include "AEFX_ArbParseHelper.h" + +#include +#include +#include +#include +#include + +PF_Err +AEFX_AppendText( A_char *srcAC, /* >> */ + const A_u_long dest_sizeL, /* >> */ + A_char *destAC, /* <> */ + A_u_long *current_indexPLu) /* <> */ +{ + PF_Err err = PF_Err_NONE; + + A_u_long new_strlenLu = (A_u_long) strlen(srcAC) + *current_indexPLu; + + + if (new_strlenLu <= dest_sizeL) { + destAC[*current_indexPLu] = 0x00; + + strcat(destAC, srcAC); + *current_indexPLu = new_strlenLu; + } else { + err = AEFX_ParseError_APPEND_ERROR; + } + + return err; +} + + + + +PF_Err +AEFX_ParseCell( PF_InData *in_data, /* >> */ + PF_OutData *out_data, /* >> */ + const A_char *startPC, /* >> */ + A_u_long *current_indexPL, /* << */ + A_char *bufAC) /* << AEFX_CELL_SIZE */ +{ + PF_Err err = PF_Err_NONE; + A_char c; + A_char buf[AEFX_CELL_SIZE]; + A_char *scan; + A_short count; + + if (startPC[*current_indexPL] == AEFX_Char_EOL) { + err = AEFX_ParseError_EXPECTING_MORE_DATA; + } else if (startPC[*current_indexPL] == 0) { + err = AEFX_ParseError_EXPECTING_MORE_DATA; + } else { + count = 0; + scan = buf; + while ((c = startPC[(*current_indexPL)++]) != 0) { + if (c == AEFX_Char_TAB) + break; + if (c == AEFX_Char_EOL) { + (*current_indexPL)--; + break; + } + + *scan++ = c; + + if (++count >= AEFX_CELL_SIZE) + break; + } + *scan = 0; + + // trim spaces from head + scan = buf; + while (isspace(*scan)) + scan++; + + strcpy(bufAC, scan); + + // trim spaces from end (guaranteed not to scan past start of string, because + // if the string were all spaces, it would be trimmed down to nothing in the + // head-trim step above + if (*bufAC) { + scan = bufAC + strlen(bufAC) - 1; + while (*scan == AEFX_Char_SPACE) { + *scan-- = 0; + } + } + } + + return err; + +} + + +/** AEFX_ParseFpLong + + Reads in the next cell in the input stream and converts it to a double. + The first non-space character must be numeric. + +**/ +PF_Err +AEFX_ParseFpLong( PF_InData *in_data, /* >> */ + PF_OutData *out_data, /* >> */ + const A_char *startPC, /* >> */ + A_u_long *current_indexPL, /* << */ + PF_FpLong *dPF) /* << */ +{ + PF_Err err = PF_Err_NONE; + A_char c; + A_char *end_ptr; + A_char buf[AEFX_CELL_SIZE]; + + err = AEFX_ParseCell(in_data, out_data, startPC, current_indexPL, buf); + + if (!err) { + c = buf[0]; + + if (!isdigit(c) && c != '.' && c != '-') { + err = AEFX_ParseError_EXPECTING_A_NUMBER; + } else { + errno = 0; + *dPF = strtod(buf, &end_ptr); + } + } + + return err; +} + + + +PF_Err +AEFX_MatchCell( PF_InData *in_data, /* >> */ + PF_OutData *out_data, /* >> */ + const A_char *strPC, /* >> */ + const A_char *startPC, /* >> */ + A_u_long *current_indexPL, /* << */ + PF_Boolean *matchPB0) /* << */ +{ + PF_Err err = PF_Err_NONE; + A_char buf[AEFX_CELL_SIZE]; + A_u_long origLu = *current_indexPL; + PF_Boolean found = 0; + + if (startPC[*current_indexPL] == AEFX_Char_EOL) { + found = 0; + err = AEFX_ParseError_EXPECTING_MORE_DATA; + } else { + err = AEFX_ParseCell(in_data, out_data, startPC, current_indexPL, buf); + + if (!err) { + found = STR_EQUAL(buf, strPC); + + if (!found) + *current_indexPL = origLu; + } + } + + if (!err && !found && matchPB0 == NULL) { + err = AEFX_ParseError_MATCH_ERROR; + } + + if (matchPB0) + *matchPB0 = found; + + return err; +} + + diff --git a/External/AE SDK/Headers/AEFX_ArbParseHelper.h b/External/AE SDK/Headers/AEFX_ArbParseHelper.h new file mode 100644 index 00000000..fa79fa3e --- /dev/null +++ b/External/AE SDK/Headers/AEFX_ArbParseHelper.h @@ -0,0 +1,75 @@ +// AEFX_ArbParseHelper.h +// + +// This file has no header, and is designed to by #included as necessary. -jja 9/30/98 + + +#ifndef _H_AEFX_ArbParseHelper +#define _H_AEFX_ArbParseHelper + +#include + +#define AEFX_Char_TAB '\t' +#define AEFX_Char_EOL '\r' +#define AEFX_Char_SPACE ' ' + +#ifndef AEFX_CELL_SIZE +#define AEFX_CELL_SIZE 256 +#endif + +#ifdef __cplusplus +extern "C" { +#endif + + +enum { + AEFX_ParseError_EXPECTING_MORE_DATA = 0x00FEBE00, + AEFX_ParseError_APPEND_ERROR, + AEFX_ParseError_EXPECTING_A_NUMBER, + AEFX_ParseError_MATCH_ERROR +}; +typedef A_long AEFX_ParseErrors; + + + +#ifndef STR_EQUAL + #define STR_EQUAL(A, B) (strcmp((A),(B)) == 0) +#endif + + +PF_Err +AEFX_AppendText( A_char *srcAC, /* >> */ + const A_u_long dest_sizeL, /* >> */ + A_char *destAC, /* <> */ + A_u_long *current_indexPLu); /* <> */ + + +PF_Err +AEFX_ParseFpLong( PF_InData *in_data, /* >> */ + PF_OutData *out_data, /* >> */ + const A_char *startPC, /* >> */ + A_u_long *current_indexPL, /* << */ + PF_FpLong *dPF); /* << */ + + +PF_Err +AEFX_MatchCell( PF_InData *in_data, /* >> */ + PF_OutData *out_data, /* >> */ + const A_char *strPC, /* >> */ + const A_char *startPC, /* >> */ + A_u_long *current_indexPL, /* << */ + PF_Boolean *matchPB0); /* << */ + +PF_Err +AEFX_ParseCell( PF_InData *in_data, /* >> */ + PF_OutData *out_data, /* >> */ + const A_char *startPC, /* >> */ + A_u_long *current_indexPL, /* << */ + A_char *bufAC); /* << AEFX_CELL_SIZE */ + + +#ifdef __cplusplus +} // extern "C" +#endif + +#endif diff --git a/External/AE SDK/Headers/AEFX_ChannelDepthTpl.h b/External/AE SDK/Headers/AEFX_ChannelDepthTpl.h new file mode 100644 index 00000000..55c0546d --- /dev/null +++ b/External/AE SDK/Headers/AEFX_ChannelDepthTpl.h @@ -0,0 +1,59 @@ +#ifndef _H_AEFX_CHANNELDEPTHTPL +#define _H_AEFX_CHANNELDEPTHTPL + +/** AEFX_ChannelDepthTpl.h + + (c) 2005 Adobe Systems Incorporated + +**/ + +// Basic pixel traits structure. This structure is never used per se, merely overidden -- see below. +template +struct PixelTraits { + typedef int PixType; + typedef int DataType; + static DataType + LutFunc(DataType input, const DataType *map); + + enum {max_value = 0 }; +}; + + +// 8 bit pixel types, constants, and functions +template <> +struct PixelTraits{ + typedef PF_Pixel8 PixType; + typedef u_char DataType; + static DataType + LutFunc(DataType input, const DataType *map){return map[input];} + enum {max_value = PF_MAX_CHAN8}; +}; + +// 16 bit pixel types, constants, and functions +template <> +struct PixelTraits{ + typedef PF_Pixel16 PixType; + typedef u_short DataType; + static u_short + LutFunc(u_short input, const u_short *map); + enum {max_value = PF_MAX_CHAN16}; +}; + + +inline u_short +PixelTraits::LutFunc(u_short input, + const u_short *map) +{ + u_short index = input >> (15 - PF_TABLE_BITS); + uint32_t fract = input & ((1 << (15 - PF_TABLE_BITS)) - 1); + A_long result = map [index]; + + if (fract) { + result += ((((A_long) map [index + 1] - result) * fract) + + (1 << (14 - PF_TABLE_BITS))) >> (15 - PF_TABLE_BITS); + } + return (u_short) result; + +} + +#endif //_H_AEFX_CHANNELDEPTHTPL \ No newline at end of file diff --git a/External/AE SDK/Headers/AEFX_SuiteHandlerTemplate.h b/External/AE SDK/Headers/AEFX_SuiteHandlerTemplate.h new file mode 100644 index 00000000..b51cf18e --- /dev/null +++ b/External/AE SDK/Headers/AEFX_SuiteHandlerTemplate.h @@ -0,0 +1,63 @@ +#ifndef _H_AEFX_SUITE_HELPER_TEMPLATE +#define _H_AEFX_SUITE_HELPER_TEMPLATE + +#include +#include +#include +#include + + +#ifdef __cplusplus + +// Throws A_Err_MISSING_SUITE if acquisition fails and the second template argument, ALLOW_NO_SUITE, is set to false +template +class AEFX_SuiteScoper +{ +public: + AEFX_SuiteScoper(const PF_InData *in_data, const char *suite_name, int32_t suite_versionL, PF_OutData *out_dataP0 = 0, const char *err_stringZ0 = 0) + { + i_suite_name = suite_name; + i_suite_versionL = suite_versionL; + i_basic_suiteP = in_data->pica_basicP; + + const void *suiteP; + SPErr err = i_basic_suiteP->AcquireSuite(i_suite_name, i_suite_versionL, &suiteP); + + if (err != kSPNoError) { + if (ALLOW_NO_SUITE) { + suiteP = NULL; + } + else { + if (out_dataP0) { + const char *error_stringPC = err_stringZ0 ? err_stringZ0 : "Not able to acquire AEFX Suite."; + out_dataP0->out_flags |= PF_OutFlag_DISPLAY_ERROR_MESSAGE; + (*in_data->utils->ansi.sprintf)(out_dataP0->return_msg, error_stringPC); + } + A_THROW(A_Err_MISSING_SUITE); + } + } + + i_suiteP = reinterpret_cast(suiteP); + } + + ~AEFX_SuiteScoper() + { + if (i_suiteP) { + i_basic_suiteP->ReleaseSuite(i_suite_name, i_suite_versionL); // ignore error, nothing we can do in dtor + } + } + + const SUITETYPE* operator->() const { return i_suiteP; } + const SUITETYPE* get() const { return i_suiteP; } + +private: + mutable const SUITETYPE *i_suiteP; + SPBasicSuite *i_basic_suiteP; + const char *i_suite_name; + int32_t i_suite_versionL; +}; + + +#endif // __cplusplus + +#endif // _H diff --git a/External/AE SDK/Headers/AEFX_SuiteHelper.c b/External/AE SDK/Headers/AEFX_SuiteHelper.c new file mode 100644 index 00000000..9ddd9b2a --- /dev/null +++ b/External/AE SDK/Headers/AEFX_SuiteHelper.c @@ -0,0 +1,139 @@ +/************************************************************************** +* +* ADOBE CONFIDENTIAL +* ___________________ +* +* Copyright 2009 Adobe Systems Incorporated +* All Rights Reserved. +* +* NOTICE: All information contained herein is, and remains the property of +* Adobe Systems Incorporated and its suppliers, if any. The intellectual +* and technical concepts contained herein are proprietary to Adobe Systems +* Incorporated and its suppliers and may be covered by U.S. and Foreign +* Patents,patents in process,and are protected by trade secret or copyright +* law. Dissemination of this information or reproduction of this material +* is strictly forbidden unless prior written permission is obtained from +* Adobe Systems Incorporated. +**************************************************************************/ + + +/** AEFX_SuiteHelper.c + + Contains helper routines for acquiring/releasing suites. + +**/ + +#include "AEFX_SuiteHelper.h" +#include + +PF_Err AEFX_AcquireSuite( PF_InData *in_data, /* >> */ + PF_OutData *out_data, /* >> */ + const char *name, /* >> */ + int32_t version, /* >> */ + const char *error_stringPC0, /* >> */ + void **suite) /* << */ +{ + PF_Err err = PF_Err_NONE; + SPBasicSuite *bsuite; + + bsuite = in_data->pica_basicP; + + if (bsuite) { + (*bsuite->AcquireSuite)((char*)name, version, (const void**)suite); + + if (!*suite) { + err = PF_Err_BAD_CALLBACK_PARAM; + } + } else { + err = PF_Err_BAD_CALLBACK_PARAM; + } + + if (err) { + const char *error_stringPC = error_stringPC0 ? error_stringPC0 : "Not able to acquire AEFX Suite."; + + out_data->out_flags |= PF_OutFlag_DISPLAY_ERROR_MESSAGE; + + PF_SPRINTF(out_data->return_msg, error_stringPC); + } + + return err; +} + + + +PF_Err AEFX_ReleaseSuite( PF_InData *in_data, /* >> */ + PF_OutData *out_data, /* >> */ + const char *name, /* >> */ + int32_t version, /* >> */ + const char *error_stringPC0) /* >> */ +{ + PF_Err err = PF_Err_NONE; + SPBasicSuite *bsuite; + + bsuite = in_data->pica_basicP; + + if (bsuite) { + (*bsuite->ReleaseSuite)((char*)name, version); + } else { + err = PF_Err_BAD_CALLBACK_PARAM; + } + + if (err) { + const char *error_stringPC = error_stringPC0 ? error_stringPC0 : "Not able to release AEFX Suite."; + + out_data->out_flags |= PF_OutFlag_DISPLAY_ERROR_MESSAGE; + + PF_SPRINTF(out_data->return_msg, error_stringPC); + } + + return err; +} + + +PF_Err AEFX_AcquireDrawbotSuites( PF_InData *in_data, /* >> */ + PF_OutData *out_data, /* >> */ + DRAWBOT_Suites *suitesP) /* << */ +{ + PF_Err err = PF_Err_NONE; + + if (suitesP == NULL) { + out_data->out_flags |= PF_OutFlag_DISPLAY_ERROR_MESSAGE; + + PF_SPRINTF(out_data->return_msg, "NULL suite pointer passed to AEFX_AcquireDrawbotSuites"); + + err = PF_Err_UNRECOGNIZED_PARAM_TYPE; + } + + if (!err) { + err = AEFX_AcquireSuite(in_data, out_data, kDRAWBOT_DrawSuite, kDRAWBOT_DrawSuite_VersionCurrent, NULL, (void **)&suitesP->drawbot_suiteP); + } + if (!err) { + err = AEFX_AcquireSuite(in_data, out_data, kDRAWBOT_SupplierSuite, kDRAWBOT_SupplierSuite_VersionCurrent, NULL, (void **)&suitesP->supplier_suiteP); + } + if (!err) { + err = AEFX_AcquireSuite(in_data, out_data, kDRAWBOT_SurfaceSuite, kDRAWBOT_SurfaceSuite_VersionCurrent, NULL, (void **)&suitesP->surface_suiteP); + } + if (!err) { + err = AEFX_AcquireSuite(in_data, out_data, kDRAWBOT_PathSuite, kDRAWBOT_PathSuite_VersionCurrent, NULL, (void **)&suitesP->path_suiteP); + } + + return err; +} + + +PF_Err AEFX_ReleaseDrawbotSuites( PF_InData *in_data, /* >> */ + PF_OutData *out_data) /* >> */ +{ + PF_Err err = PF_Err_NONE; + + AEFX_ReleaseSuite(in_data, out_data, kDRAWBOT_DrawSuite, kDRAWBOT_DrawSuite_VersionCurrent, NULL); + AEFX_ReleaseSuite(in_data, out_data, kDRAWBOT_SupplierSuite, kDRAWBOT_SupplierSuite_VersionCurrent, NULL); + AEFX_ReleaseSuite(in_data, out_data, kDRAWBOT_SurfaceSuite, kDRAWBOT_SurfaceSuite_VersionCurrent, NULL); + AEFX_ReleaseSuite(in_data, out_data, kDRAWBOT_PathSuite, kDRAWBOT_PathSuite_VersionCurrent, NULL); + + return err; +} + + + + diff --git a/External/AE SDK/Headers/AEFX_SuiteHelper.h b/External/AE SDK/Headers/AEFX_SuiteHelper.h new file mode 100644 index 00000000..2ede44c8 --- /dev/null +++ b/External/AE SDK/Headers/AEFX_SuiteHelper.h @@ -0,0 +1,157 @@ +/************************************************************************** +* +* ADOBE CONFIDENTIAL +* ___________________ +* +* Copyright 2009 Adobe Systems Incorporated +* All Rights Reserved. +* +* NOTICE: All information contained herein is, and remains the property of +* Adobe Systems Incorporated and its suppliers, if any. The intellectual +* and technical concepts contained herein are proprietary to Adobe Systems +* Incorporated and its suppliers and may be covered by U.S. and Foreign +* Patents,patents in process,and are protected by trade secret or copyright +* law. Dissemination of this information or reproduction of this material +* is strictly forbidden unless prior written permission is obtained from +* Adobe Systems Incorporated. +**************************************************************************/ + +#ifndef AEFX_SUITE_HELPER_H +#define AEFX_SUITE_HELPER_H + + +/** AEFX_SuiteHelper.h + + Contains helper routines for acquiring/releasing suites. + + NOTE: If you're writing C++ plug-ins that support exceptions, use the AEGP_SuiteHandler class or AEFX_SuiteScoper. + +**/ + +#include +#include +#include +#include + + + +#ifdef __cplusplus + extern "C" { +#endif + +PF_Err AEFX_AcquireSuite( PF_InData *in_data, /* >> */ + PF_OutData *out_data, /* >> */ + const char *name, /* >> */ + int32_t version, /* >> */ + const char *error_stringPC0, /* >> */ + void **suite); /* << */ + + +PF_Err AEFX_ReleaseSuite( PF_InData *in_data, /* >> */ + PF_OutData *out_data, /* >> */ + const char *name, /* >> */ + int32_t version, /* >> */ + const char *error_stringPC0); /* >> */ + + +PF_Err AEFX_AcquireDrawbotSuites( PF_InData *in_data, /* >> */ + PF_OutData *out_data, /* >> */ + DRAWBOT_Suites *suiteP); /* << */ + + +PF_Err AEFX_ReleaseDrawbotSuites( PF_InData *in_data, /* >> */ + PF_OutData *out_data); /* >> */ + + +#ifdef __cplusplus + } +#endif + + +#ifdef __cplusplus + + template + class AEFX_SuiteHelperT + { + public: + AEFX_SuiteHelperT( PF_InData *in_data, /* >> */ + PF_OutData *out_data, /* >> */ + const char *name, /* >> */ + int32_t version) : /* >> */ + mInDataP(in_data), mOutDataP(out_data), mSuiteName(name), mSuiteVersion(version), mSuiteP(NULL) + { + void *suiteP(NULL); + + PF_Err err = AEFX_AcquireSuite(mInDataP, mOutDataP, mSuiteName, mSuiteVersion, NULL, &suiteP); + + if (err) { + A_THROW(err); + } + + mSuiteP = reinterpret_cast(suiteP); + } + + ~AEFX_SuiteHelperT() + { + (void)AEFX_ReleaseSuite(mInDataP, mOutDataP, mSuiteName, mSuiteVersion, NULL); + } + + const SuiteType* operator->() const + { + return mSuiteP; + } + + SuiteType* get() const + { + return mSuiteP; + } + + private: + + PF_InData *mInDataP; + PF_OutData *mOutDataP; + const char *mSuiteName; + int32_t mSuiteVersion; + SuiteType *mSuiteP; + }; + + + +// clients of this class probably should just be using the regular template +// instead + +class AEFX_DrawbotSuitesScoper +{ +public: + AEFX_DrawbotSuitesScoper(PF_InData *in_data, PF_OutData *out_data) + : + i_in_data(in_data), + i_out_data(out_data) + { + PF_Err err = AEFX_AcquireDrawbotSuites(in_data, out_data, &i_suites); + + if (err) { + A_THROW(err); + } + } + + inline DRAWBOT_Suites* Get() + { + return &i_suites; + } + + ~AEFX_DrawbotSuitesScoper() + { + AEFX_ReleaseDrawbotSuites(i_in_data, i_out_data); + } + +private: + DRAWBOT_Suites i_suites; + PF_InData *i_in_data; + PF_OutData *i_out_data; +}; + +#endif + + +#endif // AEFX_SUITE_HELPER_H diff --git a/External/AE SDK/Headers/AEGP_SuiteHandler.cpp b/External/AE SDK/Headers/AEGP_SuiteHandler.cpp new file mode 100644 index 00000000..146a5f5e --- /dev/null +++ b/External/AE SDK/Headers/AEGP_SuiteHandler.cpp @@ -0,0 +1,66 @@ +/*******************************************************************/ +/* */ +/* ADOBE CONFIDENTIAL */ +/* _ _ _ _ _ _ _ _ _ _ _ _ _ */ +/* */ +/* Copyright 2007 Adobe Systems Incorporated */ +/* All Rights Reserved. */ +/* */ +/* NOTICE: All information contained herein is, and remains the */ +/* property of Adobe Systems Incorporated and its suppliers, if */ +/* any. The intellectual and technical concepts contained */ +/* herein are proprietary to Adobe Systems Incorporated and its */ +/* suppliers and may be covered by U.S. and Foreign Patents, */ +/* patents in process, and are protected by trade secret or */ +/* copyright law. Dissemination of this information or */ +/* reproduction of this material is strictly forbidden unless */ +/* prior written permission is obtained from Adobe Systems */ +/* Incorporated. */ +/* */ +/*******************************************************************/ + +/** AEGP_SuiteHandler.cpp + + Implementation of AEGP_SuiteHandler non-inlines. See AEGP_SuiteHandler.h for usage. + + created 9/11/2000 jms +**/ + + +#include +#include + +AEGP_SuiteHandler::AEGP_SuiteHandler(const SPBasicSuite *pica_basicP) : + i_pica_basicP(pica_basicP) +{ + AEFX_CLR_STRUCT(i_suites); + + if (!i_pica_basicP) { //can't construct w/out basic suite, everything else is demand loaded + MissingSuiteError(); + } +} + +AEGP_SuiteHandler::~AEGP_SuiteHandler() +{ + ReleaseAllSuites(); +} + +// Had to go to the header file to be inlined to please CW mach-o target +/*void *AEGP_SuiteHandler::pLoadSuite(A_char *nameZ, A_long versionL) const +{ + const void *suiteP; + A_long err = i_pica_basicP->AcquireSuite(nameZ, versionL, &suiteP); + + if (err || !suiteP) { + MissingSuiteError(); + } + + return (void*)suiteP; +}*/ + +// Free a particular suite. Ignore errors, because, what is there to be done if release fails? +void AEGP_SuiteHandler::ReleaseSuite(const A_char *nameZ, A_long versionL) +{ + i_pica_basicP->ReleaseSuite(nameZ, versionL); +} + diff --git a/External/AE SDK/Headers/AEGP_SuiteHandler.h b/External/AE SDK/Headers/AEGP_SuiteHandler.h new file mode 100644 index 00000000..59bc043b --- /dev/null +++ b/External/AE SDK/Headers/AEGP_SuiteHandler.h @@ -0,0 +1,601 @@ +/*******************************************************************/ +/* */ +/* ADOBE CONFIDENTIAL */ +/* _ _ _ _ _ _ _ _ _ _ _ _ _ */ +/* */ +/* Copyright 2007 Adobe Systems Incorporated */ +/* All Rights Reserved. */ +/* */ +/* NOTICE: All information contained herein is, and remains the */ +/* property of Adobe Systems Incorporated and its suppliers, if */ +/* any. The intellectual and technical concepts contained */ +/* herein are proprietary to Adobe Systems Incorporated and its */ +/* suppliers and may be covered by U.S. and Foreign Patents, */ +/* patents in process, and are protected by trade secret or */ +/* copyright law. Dissemination of this information or */ +/* reproduction of this material is strictly forbidden unless */ +/* prior written permission is obtained from Adobe Systems */ +/* Incorporated. */ +/* */ +/*******************************************************************/ + + + +/** AEGP_SuiteHandler.h + + DEPRECATED: + This way of doing things is out of date. See AEFX_SuiteHandlerTemplate.h for the + new way of doing things. + + -kjw 2/28/2014 + + A very helpful class that manages demand loading and automatic, exception-safe freeing + of AEGP suites. + + USAGE INSTRUCTIONS: + + The accompanying file, AEGP_SuiteHandler.cpp, is designed to be compiled right into + the client application or plug-in. + + You'll get a link error. + + This is because AEGP_SuiteHandler.cpp lacks a definition for the MissingSuiteError() + method. You must provide one to define the error handling behaviour of the class. + This function may or may not display an error message etc. but it must end + by throwing an exception. It cannot return. + + Other than that, usage is pretty trivial. Construct with a pointer to the PICA + basic suite, and then call the public method to obtain lazily loaded pointers + to other AEGP suites. Upon desctruction, all loaded suites are freed (so this class + is really handy for writing exception-safe AEGP code.) + + NOTE!!! If you need to upgrade a suite, DO NOT SIMPLY UPDATE THE VERSION NUMBER. + You should: + 1. Add a new member to the Suites structure for that suite. + 2. Add the boiler plate macro to release the suite in ReleaseAllSuites (AEGP_SUITE_RELEASE_BOILERPLATE). + 3. Add the boiler plate macro to define the suite. (AEGP_SUITE_ACCESS_BOILERPLATE) + + If you have any questions, ask me. -jja 5/7/2004 + + If you'll be using ADM suites, #define I_NEED_ADM_SUPPORT before #including AEGP_SuiteHandler.h. + + -bbb 9/16/2004 +**/ + +#ifndef _H_AEGP_SUITEHANDLER +#define _H_AEGP_SUITEHANDLER + +#include +#include +#include +#include +#include +#include +#include + +#ifdef I_NEED_ADM_SUPPORT +#include +#include +#include +#include +#include +#include +#include +#endif + +// Suite registration and handling object +class AEGP_SuiteHandler { + +private: + // forbid copy construct + AEGP_SuiteHandler(const AEGP_SuiteHandler&) {} + AEGP_SuiteHandler& operator=(const AEGP_SuiteHandler&) { return *this; } + + // basic suite pointer + const SPBasicSuite *i_pica_basicP; + + // Suites we can register. These are mutable because they are demand loaded using a const object. + + struct Suites { + AEGP_KeyframeSuite4 *keyframe_suite4P; + AEGP_StreamSuite3 *stream_suite3P; + AEGP_StreamSuite4 *stream_suite4P; + AEGP_StreamSuite5 *stream_suite5P; + AEGP_MarkerSuite1 *marker_suite1P; + AEGP_MarkerSuite2 *marker_suite2P; + AEGP_MarkerSuite3 *marker_suite3P; + AEGP_CompSuite4 *comp_suite4P; + AEGP_CompSuite5 *comp_suite5P; + AEGP_CompSuite6 *comp_suite6P; + AEGP_CompSuite7 *comp_suite7P; + AEGP_CompSuite8 *comp_suite8P; + AEGP_CompSuite9 *comp_suite9P; + AEGP_CompSuite10 *comp_suite10P; + AEGP_CompSuite11 *comp_suite11P; + AEGP_LayerSuite3 *layer_suite3P; + AEGP_LayerSuite4 *layer_suite4P; + AEGP_StreamSuite2 *stream_suite2P; + AEGP_DynamicStreamSuite2 *dynamic_stream_suite2P; + AEGP_DynamicStreamSuite3 *dynamic_stream_suite3P; + AEGP_DynamicStreamSuite4 *dynamic_stream_suite4P; + AEGP_KeyframeSuite3 *keyframe_suite3P; + AEGP_CanvasSuite5 *canvas_suite5P; + AEGP_CanvasSuite6 *canvas_suite6P; + AEGP_CanvasSuite7 *canvas_suite7P; + AEGP_CanvasSuite8 *canvas_suite8P; + AEGP_CameraSuite2 *camera_suite2P; + AEGP_RegisterSuite5 *register_suite5P; + AEGP_MemorySuite1 *memory_suite1P; + AEGP_ItemViewSuite1 *item_view_suite1P; + AEGP_ItemSuite9 *item_suite9P; + AEGP_ItemSuite8 *item_suite8P; + AEGP_ItemSuite7 *item_suite7P; + AEGP_ItemSuite6 *item_suite6P; + AEGP_ItemSuite5 *item_suite5P; + AEGP_ItemSuite1 *item_suite1P; + AEGP_LightSuite1 *light_suite1P; + AEGP_LightSuite2 *light_suite2P; + AEGP_EffectSuite1 *effect_suite1P; + AEGP_EffectSuite2 *effect_suite2P; + AEGP_EffectSuite3 *effect_suite3P; + AEGP_EffectSuite4 *effect_suite4P; + AEGP_MaskSuite4 *mask_suite4P; + AEGP_MaskOutlineSuite1 *mask_outline_suite1P; + AEGP_MaskOutlineSuite2 *mask_outline_suite2P; + AEGP_MaskOutlineSuite3 *mask_outline_suite3P; + AEGP_CommandSuite1 *command_suite1P; + AEGP_UtilitySuite3 *utility_suite3P; + AEGP_RenderSuite1 *render_suite1P; + AEGP_RenderSuite2 *render_suite2P; + AEGP_RenderSuite3 *render_suite3P; + AEGP_RenderSuite4 *render_suite4P; + AEGP_RenderSuite5 *render_suite5P; + PF_ANSICallbacksSuite1 *ansi_callbacks_suite1P; + PF_HandleSuite1 *handle_suite1P; + PF_FillMatteSuite2 *fill_matte_suite2P; + PF_WorldTransformSuite1 *world_transform_suite1P; + AEGP_QueryXformSuite2 *query_xform_suite2P; + AEGP_CompositeSuite2 *composite_suite2P; + PF_WorldSuite1 *world_suite1P; + AEGP_PFInterfaceSuite1 *pf_interface_suite1P; + AEGP_MathSuite1 *math_suite1P; + PF_AdvTimeSuite4 *adv_time_suite4P; + PF_PathQuerySuite1 *path_query_suite1P; + PF_PathDataSuite1 *path_data_suite1P; + PF_ParamUtilsSuite3 *param_utils_suite3P; + PFAppSuite4 *app_suite4P; + PFAppSuite5 *app_suite5P; + PFAppSuite6 *app_suite6P; + PF_AdvAppSuite2 *adv_app_suite2P; + AEGP_IOInSuite4 *io_in_suite4P; + AEGP_IOOutSuite4 *io_out_suite4P; + AEGP_PersistentDataSuite3 *persistent_data_suite3P; + AEGP_PersistentDataSuite4 *persistent_data_suite4P; + AEGP_RenderQueueSuite1 *render_queue_suite1P; + AEGP_RQItemSuite2 *rq_item_suite2P; + AEGP_OutputModuleSuite4 *output_module_suite4P; + AEGP_FIMSuite3 *fim_suite3P; + PF_Sampling8Suite1 *sampling_8_suite1P; + PF_Sampling16Suite1 *sampling_16_suite1P; + PF_Iterate8Suite1 *iterate_8_suite1P; + PF_iterate16Suite1 *iterate_16_suite1P; + PF_iterateFloatSuite1 *iterate_float_suite1P; + PF_Iterate8Suite2 *iterate_8_suite2P; + PF_iterate16Suite2 *iterate_16_suite2P; + PF_iterateFloatSuite2 *iterate_float_suite2P; + AEGP_CollectionSuite2 *collection_suite2P; + AEGP_TextDocumentSuite1 *text_document_suite1P; + AEGP_SoundDataSuite1 *sound_data_suite1P; + AEGP_IterateSuite1 *aegp_iterate_suite1P; + AEGP_IterateSuite2 *aegp_iterate_suite2P; + AEGP_TextLayerSuite1 *text_layer_suite1P; + AEGP_ArtisanUtilSuite1 *artisan_util_suite1P; + AEGP_WorldSuite2 *aegp_world_suite_2P; + AEGP_WorldSuite3 *aegp_world_suite_3P; + AEGP_RenderOptionsSuite1 *render_options_suite_1P; + AEGP_LayerRenderOptionsSuite1 *layer_render_options_suite_1P; + AEGP_LayerRenderOptionsSuite2 *layer_render_options_suite_2P; + AEGP_RenderAsyncManagerSuite1 *async_manager_suite_1P; + AEGP_TrackerSuite1 *tracker_suite_1P; + AEGP_TrackerUtilitySuite1 *tracker_utility_suite_1P; + PF_HelperSuite2 *helper_suite_2P; + AEGP_LayerSuite5 *layer_suite_5P; + AEGP_LayerSuite6 *layer_suite_6P; + AEGP_LayerSuite7 *layer_suite_7P; + AEGP_LayerSuite8 *layer_suite_8P; + +#ifdef I_NEED_ADM_SUPPORT + ADMBasicSuite8 *adm_basic_suite_8P; + ADMDialogSuite8 *adm_dialog_suite_8P; + ADMDialogGroupSuite3 *adm_dialog_group_suite_3P; + ADMItemSuite8 *adm_item_suite_8P; + ADMListSuite3 *adm_list_suite_3P; + ADMEntrySuite5 *adm_entry_suite_5P; + ADMNotifierSuite2 *adm_notifier_suite_2P; +#endif + AEGP_LayerSuite1 *layer_suite_1P; + AEGP_MaskSuite1 *mask_suite_1P; + AEGP_MaskSuite5 *mask_suite_5P; + AEGP_MaskSuite6 *mask_suite_6P; + AEGP_StreamSuite1 *stream_suite_1P; + AEGP_CompSuite1 *comp_suite_1P; + AEGP_CollectionSuite1 *collection_suite_1P; + AEGP_KeyframeSuite1 *keyframe_suite_1P; + PF_AdvAppSuite1 *adv_app_suite_1P; + AEGP_UtilitySuite1 *utility_suite_1P; + AEGP_RenderOptionsSuite2 *render_options_suite_2P; + AEGP_ProjSuite5 *proj_suite_5P; + AEGP_ProjSuite6 *proj_suite_6P; + AEGP_FootageSuite5 *footage_suite_5P; + AEGP_RQItemSuite3 *rq_item_suite_3P; + AEGP_UtilitySuite4 *utility_suite_4P; + AEGP_ColorSettingsSuite3 *color_settings_suite_3P; + AEGP_ColorSettingsSuite2 *color_settings_suite_2P; + AEGP_ColorSettingsSuite1 *color_settings_suite_1P; + PF_AdvItemSuite1 *adv_item_suite_1P; + AEGP_RenderOptionsSuite3 *render_options_suite_3P; + PF_ColorParamSuite1 *color_param_suite_1P; + PF_SamplingFloatSuite1 *sampling_float_suite_1P; + AEGP_UtilitySuite5 *utility_suite_5P; + AEGP_UtilitySuite6 *utility_suite_6P; + PF_EffectCustomUISuite1 *custom_ui_suite1P; + PF_EffectCustomUISuite2 *custom_ui_suite2P; + PF_EffectCustomUIOverlayThemeSuite1 *custom_ui_theme_suite1P; + + //Drawbot Suites + DRAWBOT_DrawbotSuiteCurrent *drawing_suite_currentP; + DRAWBOT_SupplierSuiteCurrent *drawbot_supplier_suite_currentP; + DRAWBOT_SurfaceSuiteCurrent *drawbot_surface_suite_currentP; + DRAWBOT_PathSuiteCurrent *drawbot_path_suite_currentP; + + SPSuitesSuite *suites_suite_2P; + }; + + mutable Suites i_suites; + + // private methods + // I had to make this inline by moving the definition from the .cpp file + // CW mach-o target was freaking otherwise when seeing the call to this + // function in inlined public suite accessors below + + void *LoadSuite(const A_char *nameZ, A_long versionL) const + { + const void *suiteP; + A_long err = i_pica_basicP->AcquireSuite(nameZ, versionL, &suiteP); + + if (err || !suiteP) { + MissingSuiteError(); + } + + return (void*)suiteP; + } + + void ReleaseSuite(const A_char *nameZ, A_long versionL); + void ReleaseAllSuites() + { + #define AEGP_SUITE_RELEASE_BOILERPLATE(MEMBER_NAME, kSUITE_NAME, kVERSION_NAME) \ + if (i_suites.MEMBER_NAME) { \ + ReleaseSuite(kSUITE_NAME, kVERSION_NAME); \ + } + + AEGP_SUITE_RELEASE_BOILERPLATE(marker_suite1P, kAEGPMarkerSuite, kAEGPMarkerSuiteVersion1); + AEGP_SUITE_RELEASE_BOILERPLATE(marker_suite2P, kAEGPMarkerSuite, kAEGPMarkerSuiteVersion2); + AEGP_SUITE_RELEASE_BOILERPLATE(marker_suite3P, kAEGPMarkerSuite, kAEGPMarkerSuiteVersion3); + AEGP_SUITE_RELEASE_BOILERPLATE(layer_suite3P, kAEGPLayerSuite, kAEGPLayerSuiteVersion3); + AEGP_SUITE_RELEASE_BOILERPLATE(layer_suite4P, kAEGPLayerSuite, kAEGPLayerSuiteVersion4); + AEGP_SUITE_RELEASE_BOILERPLATE(stream_suite5P, kAEGPStreamSuite, kAEGPStreamSuiteVersion5); + AEGP_SUITE_RELEASE_BOILERPLATE(stream_suite4P, kAEGPStreamSuite, kAEGPStreamSuiteVersion4); + AEGP_SUITE_RELEASE_BOILERPLATE(stream_suite3P, kAEGPStreamSuite, kAEGPStreamSuiteVersion3); + AEGP_SUITE_RELEASE_BOILERPLATE(stream_suite2P, kAEGPStreamSuite, kAEGPStreamSuiteVersion2); + AEGP_SUITE_RELEASE_BOILERPLATE(stream_suite_1P, kAEGPStreamSuite, kAEGPStreamSuiteVersion1); + AEGP_SUITE_RELEASE_BOILERPLATE(dynamic_stream_suite2P, kAEGPDynamicStreamSuite, kAEGPDynamicStreamSuiteVersion2); + AEGP_SUITE_RELEASE_BOILERPLATE(dynamic_stream_suite3P, kAEGPDynamicStreamSuite, kAEGPDynamicStreamSuiteVersion3); + AEGP_SUITE_RELEASE_BOILERPLATE(dynamic_stream_suite4P, kAEGPDynamicStreamSuite, kAEGPDynamicStreamSuiteVersion4); + AEGP_SUITE_RELEASE_BOILERPLATE(keyframe_suite4P, kAEGPKeyframeSuite, kAEGPKeyframeSuiteVersion4); + AEGP_SUITE_RELEASE_BOILERPLATE(keyframe_suite3P, kAEGPKeyframeSuite, kAEGPKeyframeSuiteVersion3); + AEGP_SUITE_RELEASE_BOILERPLATE(keyframe_suite_1P, kAEGPKeyframeSuite, kAEGPKeyframeSuiteVersion1); + AEGP_SUITE_RELEASE_BOILERPLATE(comp_suite4P, kAEGPCompSuite, kAEGPCompSuiteVersion4); + AEGP_SUITE_RELEASE_BOILERPLATE(comp_suite5P, kAEGPCompSuite, kAEGPCompSuiteVersion5); + AEGP_SUITE_RELEASE_BOILERPLATE(comp_suite6P, kAEGPCompSuite, kAEGPCompSuiteVersion6); + AEGP_SUITE_RELEASE_BOILERPLATE(comp_suite7P, kAEGPCompSuite, kAEGPCompSuiteVersion7); + AEGP_SUITE_RELEASE_BOILERPLATE(comp_suite8P, kAEGPCompSuite, kAEGPCompSuiteVersion8); + AEGP_SUITE_RELEASE_BOILERPLATE(comp_suite9P, kAEGPCompSuite, kAEGPCompSuiteVersion9); + AEGP_SUITE_RELEASE_BOILERPLATE(comp_suite10P, kAEGPCompSuite, kAEGPCompSuiteVersion10); + AEGP_SUITE_RELEASE_BOILERPLATE(comp_suite11P, kAEGPCompSuite, kAEGPCompSuiteVersion11); + AEGP_SUITE_RELEASE_BOILERPLATE(canvas_suite5P, kAEGPCanvasSuite, kAEGPCanvasSuiteVersion5); + AEGP_SUITE_RELEASE_BOILERPLATE(canvas_suite6P, kAEGPCanvasSuite, kAEGPCanvasSuiteVersion6); + AEGP_SUITE_RELEASE_BOILERPLATE(canvas_suite7P, kAEGPCanvasSuite, kAEGPCanvasSuiteVersion7); + AEGP_SUITE_RELEASE_BOILERPLATE(canvas_suite8P, kAEGPCanvasSuite, kAEGPCanvasSuiteVersion8); + AEGP_SUITE_RELEASE_BOILERPLATE(camera_suite2P, kAEGPCameraSuite, kAEGPCameraSuiteVersion2); + AEGP_SUITE_RELEASE_BOILERPLATE(register_suite5P, kAEGPRegisterSuite, kAEGPRegisterSuiteVersion5); + AEGP_SUITE_RELEASE_BOILERPLATE(item_view_suite1P, kAEGPItemViewSuite, kAEGPItemViewSuiteVersion1); + AEGP_SUITE_RELEASE_BOILERPLATE(item_suite8P, kAEGPItemSuite, kAEGPItemSuiteVersion8); + AEGP_SUITE_RELEASE_BOILERPLATE(item_suite7P, kAEGPItemSuite, kAEGPItemSuiteVersion7); + AEGP_SUITE_RELEASE_BOILERPLATE(item_suite6P, kAEGPItemSuite, kAEGPItemSuiteVersion6); + AEGP_SUITE_RELEASE_BOILERPLATE(item_suite5P, kAEGPItemSuite, kAEGPItemSuiteVersion5); + AEGP_SUITE_RELEASE_BOILERPLATE(item_suite1P, kAEGPItemSuite, kAEGPItemSuiteVersion1); + AEGP_SUITE_RELEASE_BOILERPLATE(pf_interface_suite1P, kAEGPPFInterfaceSuite, kAEGPPFInterfaceSuiteVersion1); + AEGP_SUITE_RELEASE_BOILERPLATE(math_suite1P, kAEGPMathSuite, kAEGPMathSuiteVersion1); + AEGP_SUITE_RELEASE_BOILERPLATE(adv_time_suite4P, kPFAdvTimeSuite, kPFAdvTimeSuiteVersion4); + AEGP_SUITE_RELEASE_BOILERPLATE(path_query_suite1P, kPFPathQuerySuite, kPFPathQuerySuiteVersion1); + AEGP_SUITE_RELEASE_BOILERPLATE(memory_suite1P, kAEGPMemorySuite, kAEGPMemorySuiteVersion1); + AEGP_SUITE_RELEASE_BOILERPLATE(path_data_suite1P, kPFPathDataSuite, kPFPathDataSuiteVersion1); + AEGP_SUITE_RELEASE_BOILERPLATE(param_utils_suite3P, kPFParamUtilsSuite, kPFParamUtilsSuiteVersion3); + AEGP_SUITE_RELEASE_BOILERPLATE(app_suite4P, kPFAppSuite, kPFAppSuiteVersion4); + AEGP_SUITE_RELEASE_BOILERPLATE(app_suite5P, kPFAppSuite, kPFAppSuiteVersion5); + AEGP_SUITE_RELEASE_BOILERPLATE(app_suite6P, kPFAppSuite, kPFAppSuiteVersion6); + AEGP_SUITE_RELEASE_BOILERPLATE(adv_app_suite2P, kPFAdvAppSuite, kPFAdvAppSuiteVersion2); + AEGP_SUITE_RELEASE_BOILERPLATE(light_suite1P, kAEGPLightSuite, kAEGPLightSuiteVersion1); + AEGP_SUITE_RELEASE_BOILERPLATE(light_suite2P, kAEGPLightSuite, kAEGPLightSuiteVersion2); + AEGP_SUITE_RELEASE_BOILERPLATE(effect_suite1P, kAEGPEffectSuite, kAEGPEffectSuiteVersion1); + AEGP_SUITE_RELEASE_BOILERPLATE(effect_suite2P, kAEGPEffectSuite, kAEGPEffectSuiteVersion2); + AEGP_SUITE_RELEASE_BOILERPLATE(effect_suite3P, kAEGPEffectSuite, kAEGPEffectSuiteVersion3); + AEGP_SUITE_RELEASE_BOILERPLATE(effect_suite4P, kAEGPEffectSuite, kAEGPEffectSuiteVersion4); + AEGP_SUITE_RELEASE_BOILERPLATE(mask_suite4P, kAEGPMaskSuite, kAEGPMaskSuiteVersion4); + AEGP_SUITE_RELEASE_BOILERPLATE(mask_outline_suite1P, kAEGPMaskOutlineSuite, kAEGPMaskOutlineSuiteVersion1); + AEGP_SUITE_RELEASE_BOILERPLATE(mask_outline_suite2P, kAEGPMaskOutlineSuite, kAEGPMaskOutlineSuiteVersion2); + AEGP_SUITE_RELEASE_BOILERPLATE(mask_outline_suite3P, kAEGPMaskOutlineSuite, kAEGPMaskOutlineSuiteVersion3); + AEGP_SUITE_RELEASE_BOILERPLATE(command_suite1P, kAEGPCommandSuite, kAEGPCommandSuiteVersion1); + AEGP_SUITE_RELEASE_BOILERPLATE(utility_suite3P, kAEGPUtilitySuite, kAEGPUtilitySuiteVersion3); + AEGP_SUITE_RELEASE_BOILERPLATE(render_suite1P, kAEGPRenderSuite, kAEGPRenderSuiteVersion1); + AEGP_SUITE_RELEASE_BOILERPLATE(render_suite2P, kAEGPRenderSuite, kAEGPRenderSuiteVersion2); + AEGP_SUITE_RELEASE_BOILERPLATE(render_suite3P, kAEGPRenderSuite, kAEGPRenderSuiteVersion3); + AEGP_SUITE_RELEASE_BOILERPLATE(render_suite4P, kAEGPRenderSuite, kAEGPRenderSuiteVersion4); + AEGP_SUITE_RELEASE_BOILERPLATE(render_suite5P, kAEGPRenderSuite, kAEGPRenderSuiteVersion5); + AEGP_SUITE_RELEASE_BOILERPLATE(ansi_callbacks_suite1P, kPFANSISuite, kPFANSISuiteVersion1); + AEGP_SUITE_RELEASE_BOILERPLATE(handle_suite1P, kPFHandleSuite, kPFHandleSuiteVersion1); + AEGP_SUITE_RELEASE_BOILERPLATE(fill_matte_suite2P, kPFFillMatteSuite, kPFFillMatteSuiteVersion2); + AEGP_SUITE_RELEASE_BOILERPLATE(world_transform_suite1P, kPFWorldTransformSuite, kPFWorldTransformSuiteVersion1); + AEGP_SUITE_RELEASE_BOILERPLATE(query_xform_suite2P, kAEGPQueryXformSuite, kAEGPQueryXformSuiteVersion2); + AEGP_SUITE_RELEASE_BOILERPLATE(composite_suite2P, kAEGPCompositeSuite, kAEGPCompositeSuiteVersion2); + AEGP_SUITE_RELEASE_BOILERPLATE(world_suite1P, kPFWorldSuite, kPFWorldSuiteVersion1); + AEGP_SUITE_RELEASE_BOILERPLATE(io_in_suite4P, kAEGPIOInSuite, kAEGPIOInSuiteVersion4); + AEGP_SUITE_RELEASE_BOILERPLATE(io_out_suite4P, kAEGPIOOutSuite, kAEGPIOOutSuiteVersion4); + AEGP_SUITE_RELEASE_BOILERPLATE(render_queue_suite1P, kAEGPRenderQueueSuite, kAEGPRenderQueueSuiteVersion1); + AEGP_SUITE_RELEASE_BOILERPLATE(rq_item_suite2P, kAEGPRQItemSuite, kAEGPRQItemSuiteVersion2); + AEGP_SUITE_RELEASE_BOILERPLATE(output_module_suite4P, kAEGPOutputModuleSuite, kAEGPOutputModuleSuiteVersion4); + AEGP_SUITE_RELEASE_BOILERPLATE(fim_suite3P, kAEGPFIMSuite, kAEGPFIMSuiteVersion3); + AEGP_SUITE_RELEASE_BOILERPLATE(math_suite1P, kAEGPMathSuite, kAEGPMathSuiteVersion1); + AEGP_SUITE_RELEASE_BOILERPLATE(adv_time_suite4P, kPFAdvTimeSuite, kPFAdvTimeSuiteVersion4); + AEGP_SUITE_RELEASE_BOILERPLATE(sampling_8_suite1P, kPFSampling8Suite, kPFSampling8SuiteVersion1); + AEGP_SUITE_RELEASE_BOILERPLATE(sampling_16_suite1P, kPFSampling16Suite, kPFSampling16SuiteVersion1); + AEGP_SUITE_RELEASE_BOILERPLATE(iterate_8_suite1P, kPFIterate8Suite, kPFIterate8SuiteVersion1); + AEGP_SUITE_RELEASE_BOILERPLATE(iterate_16_suite1P, kPFIterate16Suite, kPFIterate16SuiteVersion1); + AEGP_SUITE_RELEASE_BOILERPLATE(iterate_float_suite1P, kPFIterateFloatSuite, kPFIterateFloatSuiteVersion1); + AEGP_SUITE_RELEASE_BOILERPLATE(iterate_8_suite2P, kPFIterate8Suite, kPFIterate8SuiteVersion2); + AEGP_SUITE_RELEASE_BOILERPLATE(iterate_16_suite2P, kPFIterate16Suite, kPFIterate16SuiteVersion2); + AEGP_SUITE_RELEASE_BOILERPLATE(iterate_float_suite2P, kPFIterateFloatSuite, kPFIterateFloatSuiteVersion2); + AEGP_SUITE_RELEASE_BOILERPLATE(collection_suite2P, kAEGPCollectionSuite, kAEGPCollectionSuiteVersion2); + AEGP_SUITE_RELEASE_BOILERPLATE(text_document_suite1P, kAEGPTextDocumentSuite, kAEGPTextDocumentSuiteVersion1); + AEGP_SUITE_RELEASE_BOILERPLATE(sound_data_suite1P, kAEGPSoundDataSuite, kAEGPSoundDataVersion1); + AEGP_SUITE_RELEASE_BOILERPLATE(text_layer_suite1P, kAEGPTextLayerSuite, kAEGPTextLayerSuiteVersion1); + AEGP_SUITE_RELEASE_BOILERPLATE(artisan_util_suite1P, kAEGPArtisanUtilSuite, kAEGPArtisanUtilSuiteVersion1); + AEGP_SUITE_RELEASE_BOILERPLATE(aegp_world_suite_2P, kAEGPWorldSuite, kAEGPWorldSuiteVersion2); + AEGP_SUITE_RELEASE_BOILERPLATE(aegp_world_suite_3P, kAEGPWorldSuite, kAEGPWorldSuiteVersion3); + AEGP_SUITE_RELEASE_BOILERPLATE(render_options_suite_1P, kAEGPRenderOptionsSuite, kAEGPRenderOptionsSuiteVersion1); + AEGP_SUITE_RELEASE_BOILERPLATE(tracker_suite_1P, kAEGPTrackerSuite, kAEGPTrackerSuiteVersion1); + AEGP_SUITE_RELEASE_BOILERPLATE(tracker_utility_suite_1P, kAEGPTrackerUtilitySuite, kAEGPTrackerUtilitySuiteVersion1); + AEGP_SUITE_RELEASE_BOILERPLATE(helper_suite_2P, kPFHelperSuite2, kPFHelperSuite2Version2); + AEGP_SUITE_RELEASE_BOILERPLATE(layer_suite_5P, kAEGPLayerSuite, kAEGPLayerSuiteVersion5); + AEGP_SUITE_RELEASE_BOILERPLATE(layer_suite_6P, kAEGPLayerSuite, kAEGPLayerSuiteVersion6); + AEGP_SUITE_RELEASE_BOILERPLATE(layer_suite_7P, kAEGPLayerSuite, kAEGPLayerSuiteVersion7); + AEGP_SUITE_RELEASE_BOILERPLATE(layer_suite_8P, kAEGPLayerSuite, kAEGPLayerSuiteVersion8); + AEGP_SUITE_RELEASE_BOILERPLATE(adv_item_suite_1P, kPFAdvItemSuite, kPFAdvItemSuiteVersion1); +#ifdef I_NEED_ADM_SUPPORT + AEGP_SUITE_RELEASE_BOILERPLATE(adm_basic_suite_8P, kADMBasicSuite, kADMBasicSuiteVersion8); + AEGP_SUITE_RELEASE_BOILERPLATE(adm_dialog_suite_8P, kADMDialogSuite, kADMDialogSuiteVersion8); + AEGP_SUITE_RELEASE_BOILERPLATE(adm_dialog_group_suite_3P, kADMDialogGroupSuite, kADMDialogGroupSuiteVersion3); + AEGP_SUITE_RELEASE_BOILERPLATE(adm_item_suite_8P, kADMItemSuite, kADMItemSuiteVersion8); + AEGP_SUITE_RELEASE_BOILERPLATE(adm_list_suite_3P, kADMListSuite, kADMListSuiteVersion3); + AEGP_SUITE_RELEASE_BOILERPLATE(adm_entry_suite_5P, kADMEntrySuite, kADMEntrySuiteVersion5); + AEGP_SUITE_RELEASE_BOILERPLATE(adm_notifier_suite_2P, kADMNotifierSuite, kADMNotifierSuiteVersion2); +#endif + AEGP_SUITE_RELEASE_BOILERPLATE(layer_suite_1P, kAEGPLayerSuite, kAEGPLayerSuiteVersion1); + AEGP_SUITE_RELEASE_BOILERPLATE(mask_suite_1P, kAEGPMaskSuite, kAEGPMaskSuiteVersion1); + AEGP_SUITE_RELEASE_BOILERPLATE(mask_suite_5P, kAEGPMaskSuite, kAEGPMaskSuiteVersion5); + AEGP_SUITE_RELEASE_BOILERPLATE(mask_suite_6P, kAEGPMaskSuite, kAEGPMaskSuiteVersion6); + AEGP_SUITE_RELEASE_BOILERPLATE(comp_suite_1P, kAEGPCompSuite, kAEGPCompSuiteVersion1); + AEGP_SUITE_RELEASE_BOILERPLATE(collection_suite_1P, kAEGPCollectionSuite, kAEGPCollectionSuiteVersion1); + AEGP_SUITE_RELEASE_BOILERPLATE(adv_app_suite_1P, kPFAdvAppSuite, kPFAdvAppSuiteVersion1); + AEGP_SUITE_RELEASE_BOILERPLATE(utility_suite_1P, kAEGPUtilitySuite, kAEGPUtilitySuiteVersion1); + AEGP_SUITE_RELEASE_BOILERPLATE(render_options_suite_2P, kAEGPRenderOptionsSuite, kAEGPRenderOptionsSuiteVersion2); + AEGP_SUITE_RELEASE_BOILERPLATE(layer_render_options_suite_1P, kAEGPLayerRenderOptionsSuite, kAEGPLayerRenderOptionsSuiteVersion1); + AEGP_SUITE_RELEASE_BOILERPLATE(layer_render_options_suite_2P, kAEGPLayerRenderOptionsSuite, kAEGPLayerRenderOptionsSuiteVersion2); + AEGP_SUITE_RELEASE_BOILERPLATE(async_manager_suite_1P, kAEGPRenderAsyncManagerSuite, kAEGPRenderAsyncManagerSuiteVersion1); + AEGP_SUITE_RELEASE_BOILERPLATE(proj_suite_5P, kAEGPProjSuite, kAEGPProjSuiteVersion5); + AEGP_SUITE_RELEASE_BOILERPLATE(proj_suite_6P, kAEGPProjSuite, kAEGPProjSuiteVersion6); + AEGP_SUITE_RELEASE_BOILERPLATE(footage_suite_5P, kAEGPFootageSuite, kAEGPFootageSuiteVersion5); + AEGP_SUITE_RELEASE_BOILERPLATE(rq_item_suite_3P, kAEGPRQItemSuite, kAEGPRQItemSuiteVersion3); + AEGP_SUITE_RELEASE_BOILERPLATE(utility_suite_4P, kAEGPUtilitySuite, kAEGPUtilitySuiteVersion4); + AEGP_SUITE_RELEASE_BOILERPLATE(persistent_data_suite4P, kAEGPPersistentDataSuite, kAEGPPersistentDataSuiteVersion4); + AEGP_SUITE_RELEASE_BOILERPLATE(persistent_data_suite3P, kAEGPPersistentDataSuite, kAEGPPersistentDataSuiteVersion3); + AEGP_SUITE_RELEASE_BOILERPLATE(color_settings_suite_3P, kAEGPColorSettingsSuite, kAEGPColorSettingsSuiteVersion3); + AEGP_SUITE_RELEASE_BOILERPLATE(color_settings_suite_2P, kAEGPColorSettingsSuite, kAEGPColorSettingsSuiteVersion2); + AEGP_SUITE_RELEASE_BOILERPLATE(color_settings_suite_1P, kAEGPColorSettingsSuite, kAEGPColorSettingsSuiteVersion1); + AEGP_SUITE_RELEASE_BOILERPLATE(color_param_suite_1P, kPFColorParamSuite, kPFColorParamSuiteVersion1); + AEGP_SUITE_RELEASE_BOILERPLATE(sampling_float_suite_1P, kPFSamplingFloatSuite, kPFSamplingFloatSuiteVersion1); + AEGP_SUITE_RELEASE_BOILERPLATE(utility_suite_5P, kAEGPUtilitySuite, kAEGPUtilitySuiteVersion5); + AEGP_SUITE_RELEASE_BOILERPLATE(utility_suite_6P, kAEGPUtilitySuite, kAEGPUtilitySuiteVersion6); + AEGP_SUITE_RELEASE_BOILERPLATE(custom_ui_suite1P, kPFEffectCustomUISuite, kPFEffectCustomUISuiteVersion1); + AEGP_SUITE_RELEASE_BOILERPLATE(custom_ui_suite2P, kPFEffectCustomUISuite, kPFEffectCustomUISuiteVersion2); + AEGP_SUITE_RELEASE_BOILERPLATE(custom_ui_theme_suite1P, kPFEffectCustomUIOverlayThemeSuite, kPFEffectCustomUIOverlayThemeSuiteVersion1); + AEGP_SUITE_RELEASE_BOILERPLATE(drawing_suite_currentP, kDRAWBOT_DrawSuite, kDRAWBOT_DrawSuite_VersionCurrent); + AEGP_SUITE_RELEASE_BOILERPLATE(drawbot_supplier_suite_currentP, kDRAWBOT_SupplierSuite, kDRAWBOT_SupplierSuite_VersionCurrent); + AEGP_SUITE_RELEASE_BOILERPLATE(drawbot_surface_suite_currentP, kDRAWBOT_SurfaceSuite, kDRAWBOT_SurfaceSuite_VersionCurrent); + AEGP_SUITE_RELEASE_BOILERPLATE(drawbot_path_suite_currentP, kDRAWBOT_PathSuite, kDRAWBOT_PathSuite_VersionCurrent); + AEGP_SUITE_RELEASE_BOILERPLATE(suites_suite_2P, kSPSuitesSuite, kSPSuitesSuiteVersion); +} + + // Here is the error handling function which must be defined. + // It must exit by throwing an exception, it cannot return. + void MissingSuiteError() const; + +public: + // To construct, pass pica_basicP + AEGP_SuiteHandler(const SPBasicSuite *pica_basicP); + ~AEGP_SuiteHandler(); + + const SPBasicSuite *Pica() const { return i_pica_basicP; } + + #define AEGP_SUITE_ACCESS_BOILERPLATE(SUITE_NAME, VERSION_NUMBER, SUITE_PREFIX, MEMBER_NAME, kSUITE_NAME, kVERSION_NAME) \ + SUITE_PREFIX##SUITE_NAME##VERSION_NUMBER *SUITE_NAME##VERSION_NUMBER() const \ + { \ + if (i_suites.MEMBER_NAME == NULL) { \ + i_suites.MEMBER_NAME = (SUITE_PREFIX##SUITE_NAME##VERSION_NUMBER*) \ + LoadSuite(kSUITE_NAME, kVERSION_NAME); \ + } \ + return i_suites.MEMBER_NAME; \ + } + + AEGP_SUITE_ACCESS_BOILERPLATE(MarkerSuite, 1, AEGP_, marker_suite1P, kAEGPMarkerSuite, kAEGPMarkerSuiteVersion1); + AEGP_SUITE_ACCESS_BOILERPLATE(MarkerSuite, 2, AEGP_, marker_suite2P, kAEGPMarkerSuite, kAEGPMarkerSuiteVersion2); + AEGP_SUITE_ACCESS_BOILERPLATE(MarkerSuite, 3, AEGP_, marker_suite3P, kAEGPMarkerSuite, kAEGPMarkerSuiteVersion3); + AEGP_SUITE_ACCESS_BOILERPLATE(LayerSuite, 3, AEGP_, layer_suite3P, kAEGPLayerSuite, kAEGPLayerSuiteVersion3); + AEGP_SUITE_ACCESS_BOILERPLATE(LayerSuite, 4, AEGP_, layer_suite4P, kAEGPLayerSuite, kAEGPLayerSuiteVersion4); + AEGP_SUITE_ACCESS_BOILERPLATE(StreamSuite, 5, AEGP_, stream_suite5P, kAEGPStreamSuite, kAEGPStreamSuiteVersion5); + AEGP_SUITE_ACCESS_BOILERPLATE(StreamSuite, 4, AEGP_, stream_suite4P, kAEGPStreamSuite, kAEGPStreamSuiteVersion4); + AEGP_SUITE_ACCESS_BOILERPLATE(StreamSuite, 3, AEGP_, stream_suite3P, kAEGPStreamSuite, kAEGPStreamSuiteVersion3); + AEGP_SUITE_ACCESS_BOILERPLATE(StreamSuite, 2, AEGP_, stream_suite2P, kAEGPStreamSuite, kAEGPStreamSuiteVersion2); + AEGP_SUITE_ACCESS_BOILERPLATE(StreamSuite, 1, AEGP_, stream_suite_1P, kAEGPStreamSuite, kAEGPStreamSuiteVersion1); + AEGP_SUITE_ACCESS_BOILERPLATE(DynamicStreamSuite, 2, AEGP_, dynamic_stream_suite2P, kAEGPDynamicStreamSuite, kAEGPDynamicStreamSuiteVersion2); + AEGP_SUITE_ACCESS_BOILERPLATE(DynamicStreamSuite, 3, AEGP_, dynamic_stream_suite3P, kAEGPDynamicStreamSuite, kAEGPDynamicStreamSuiteVersion3); + AEGP_SUITE_ACCESS_BOILERPLATE(DynamicStreamSuite, 4, AEGP_, dynamic_stream_suite4P, kAEGPDynamicStreamSuite, kAEGPDynamicStreamSuiteVersion4); + AEGP_SUITE_ACCESS_BOILERPLATE(KeyframeSuite, 4, AEGP_, keyframe_suite4P, kAEGPKeyframeSuite, kAEGPKeyframeSuiteVersion4); + AEGP_SUITE_ACCESS_BOILERPLATE(KeyframeSuite, 3, AEGP_, keyframe_suite3P, kAEGPKeyframeSuite, kAEGPKeyframeSuiteVersion3); + AEGP_SUITE_ACCESS_BOILERPLATE(KeyframeSuite, 1, AEGP_, keyframe_suite_1P, kAEGPKeyframeSuite, kAEGPKeyframeSuiteVersion1); + AEGP_SUITE_ACCESS_BOILERPLATE(CompSuite, 4, AEGP_, comp_suite4P, kAEGPCompSuite, kAEGPCompSuiteVersion4); + AEGP_SUITE_ACCESS_BOILERPLATE(CompSuite, 5, AEGP_, comp_suite5P, kAEGPCompSuite, kAEGPCompSuiteVersion5); + AEGP_SUITE_ACCESS_BOILERPLATE(CompSuite, 6, AEGP_, comp_suite6P, kAEGPCompSuite, kAEGPCompSuiteVersion6); + AEGP_SUITE_ACCESS_BOILERPLATE(CompSuite, 7, AEGP_, comp_suite7P, kAEGPCompSuite, kAEGPCompSuiteVersion7); + AEGP_SUITE_ACCESS_BOILERPLATE(CompSuite, 8, AEGP_, comp_suite8P, kAEGPCompSuite, kAEGPCompSuiteVersion8); + AEGP_SUITE_ACCESS_BOILERPLATE(CompSuite, 9, AEGP_, comp_suite9P, kAEGPCompSuite, kAEGPCompSuiteVersion9); + AEGP_SUITE_ACCESS_BOILERPLATE(CompSuite, 10, AEGP_, comp_suite10P, kAEGPCompSuite, kAEGPCompSuiteVersion10); + AEGP_SUITE_ACCESS_BOILERPLATE(CompSuite, 11, AEGP_, comp_suite11P, kAEGPCompSuite, kAEGPCompSuiteVersion11); + AEGP_SUITE_ACCESS_BOILERPLATE(CanvasSuite, 5, AEGP_, canvas_suite5P, kAEGPCanvasSuite, kAEGPCanvasSuiteVersion5); + AEGP_SUITE_ACCESS_BOILERPLATE(CanvasSuite, 6, AEGP_, canvas_suite6P, kAEGPCanvasSuite, kAEGPCanvasSuiteVersion6); + AEGP_SUITE_ACCESS_BOILERPLATE(CanvasSuite, 7, AEGP_, canvas_suite7P, kAEGPCanvasSuite, kAEGPCanvasSuiteVersion7); + AEGP_SUITE_ACCESS_BOILERPLATE(CanvasSuite, 8, AEGP_, canvas_suite8P, kAEGPCanvasSuite, kAEGPCanvasSuiteVersion8); + AEGP_SUITE_ACCESS_BOILERPLATE(CameraSuite, 2, AEGP_, camera_suite2P, kAEGPCameraSuite, kAEGPCameraSuiteVersion2); + AEGP_SUITE_ACCESS_BOILERPLATE(RegisterSuite, 5, AEGP_, register_suite5P, kAEGPRegisterSuite, kAEGPRegisterSuiteVersion5); + AEGP_SUITE_ACCESS_BOILERPLATE(MemorySuite, 1, AEGP_, memory_suite1P, kAEGPMemorySuite, kAEGPMemorySuiteVersion1); + AEGP_SUITE_ACCESS_BOILERPLATE(ItemViewSuite, 1, AEGP_, item_view_suite1P, kAEGPItemViewSuite, kAEGPItemViewSuiteVersion1); + AEGP_SUITE_ACCESS_BOILERPLATE(ItemSuite, 9, AEGP_, item_suite9P, kAEGPItemSuite, kAEGPItemSuiteVersion9); + AEGP_SUITE_ACCESS_BOILERPLATE(ItemSuite, 8, AEGP_, item_suite8P, kAEGPItemSuite, kAEGPItemSuiteVersion8); + AEGP_SUITE_ACCESS_BOILERPLATE(ItemSuite, 7, AEGP_, item_suite7P, kAEGPItemSuite, kAEGPItemSuiteVersion7); + AEGP_SUITE_ACCESS_BOILERPLATE(ItemSuite, 6, AEGP_, item_suite6P, kAEGPItemSuite, kAEGPItemSuiteVersion6); + AEGP_SUITE_ACCESS_BOILERPLATE(ItemSuite, 5, AEGP_, item_suite5P, kAEGPItemSuite, kAEGPItemSuiteVersion5); + AEGP_SUITE_ACCESS_BOILERPLATE(ItemSuite, 1, AEGP_, item_suite1P, kAEGPItemSuite, kAEGPItemSuiteVersion1); + AEGP_SUITE_ACCESS_BOILERPLATE(PFInterfaceSuite, 1, AEGP_, pf_interface_suite1P, kAEGPPFInterfaceSuite, kAEGPPFInterfaceSuiteVersion1); + AEGP_SUITE_ACCESS_BOILERPLATE(MathSuite, 1, AEGP_, math_suite1P, kAEGPMathSuite, kAEGPMathSuiteVersion1); + AEGP_SUITE_ACCESS_BOILERPLATE(AdvTimeSuite, 4, PF_, adv_time_suite4P, kPFAdvTimeSuite, kPFAdvTimeSuiteVersion4); + AEGP_SUITE_ACCESS_BOILERPLATE(PathQuerySuite, 1, PF_, path_query_suite1P, kPFPathQuerySuite, kPFPathQuerySuiteVersion1); + AEGP_SUITE_ACCESS_BOILERPLATE(PathDataSuite, 1, PF_, path_data_suite1P, kPFPathDataSuite, kPFPathDataSuiteVersion1); + AEGP_SUITE_ACCESS_BOILERPLATE(ParamUtilsSuite, 3, PF_, param_utils_suite3P, kPFParamUtilsSuite, kPFParamUtilsSuiteVersion3); + AEGP_SUITE_ACCESS_BOILERPLATE(AppSuite, 4, PF, app_suite4P, kPFAppSuite, kPFAppSuiteVersion4); + AEGP_SUITE_ACCESS_BOILERPLATE(AppSuite, 5, PF, app_suite5P, kPFAppSuite, kPFAppSuiteVersion5); + AEGP_SUITE_ACCESS_BOILERPLATE(AppSuite, 6, PF, app_suite6P, kPFAppSuite, kPFAppSuiteVersion6); + AEGP_SUITE_ACCESS_BOILERPLATE(AdvAppSuite, 2, PF_, adv_app_suite2P, kPFAdvAppSuite, kPFAdvAppSuiteVersion2); + AEGP_SUITE_ACCESS_BOILERPLATE(LightSuite, 1, AEGP_, light_suite1P, kAEGPLightSuite, kAEGPLightSuiteVersion1); + AEGP_SUITE_ACCESS_BOILERPLATE(LightSuite, 2, AEGP_, light_suite2P, kAEGPLightSuite, kAEGPLightSuiteVersion2); + AEGP_SUITE_ACCESS_BOILERPLATE(EffectSuite, 1, AEGP_, effect_suite1P, kAEGPEffectSuite, kAEGPEffectSuiteVersion1); + AEGP_SUITE_ACCESS_BOILERPLATE(EffectSuite, 2, AEGP_, effect_suite2P, kAEGPEffectSuite, kAEGPEffectSuiteVersion2); + AEGP_SUITE_ACCESS_BOILERPLATE(EffectSuite, 3, AEGP_, effect_suite3P, kAEGPEffectSuite, kAEGPEffectSuiteVersion3); + AEGP_SUITE_ACCESS_BOILERPLATE(EffectSuite, 4, AEGP_, effect_suite4P, kAEGPEffectSuite, kAEGPEffectSuiteVersion4); + AEGP_SUITE_ACCESS_BOILERPLATE(MaskSuite, 4, AEGP_, mask_suite4P, kAEGPMaskSuite, kAEGPMaskSuiteVersion4); + AEGP_SUITE_ACCESS_BOILERPLATE(MaskOutlineSuite, 1, AEGP_, mask_outline_suite1P, kAEGPMaskOutlineSuite, kAEGPMaskOutlineSuiteVersion1); + AEGP_SUITE_ACCESS_BOILERPLATE(MaskOutlineSuite, 2, AEGP_, mask_outline_suite2P, kAEGPMaskOutlineSuite, kAEGPMaskOutlineSuiteVersion2); + AEGP_SUITE_ACCESS_BOILERPLATE(MaskOutlineSuite, 3, AEGP_, mask_outline_suite3P, kAEGPMaskOutlineSuite, kAEGPMaskOutlineSuiteVersion3); + AEGP_SUITE_ACCESS_BOILERPLATE(CommandSuite, 1, AEGP_, command_suite1P, kAEGPCommandSuite, kAEGPCommandSuiteVersion1); + AEGP_SUITE_ACCESS_BOILERPLATE(UtilitySuite, 3, AEGP_, utility_suite3P, kAEGPUtilitySuite, kAEGPUtilitySuiteVersion3); + AEGP_SUITE_ACCESS_BOILERPLATE(RenderSuite, 1, AEGP_, render_suite1P, kAEGPRenderSuite, kAEGPRenderSuiteVersion1); + AEGP_SUITE_ACCESS_BOILERPLATE(RenderSuite, 2, AEGP_, render_suite2P, kAEGPRenderSuite, kAEGPRenderSuiteVersion2); + AEGP_SUITE_ACCESS_BOILERPLATE(RenderSuite, 3, AEGP_, render_suite3P, kAEGPRenderSuite, kAEGPRenderSuiteVersion3); + AEGP_SUITE_ACCESS_BOILERPLATE(RenderSuite, 4, AEGP_, render_suite4P, kAEGPRenderSuite, kAEGPRenderSuiteVersion4); + AEGP_SUITE_ACCESS_BOILERPLATE(RenderSuite, 5, AEGP_, render_suite5P, kAEGPRenderSuite, kAEGPRenderSuiteVersion5); + AEGP_SUITE_ACCESS_BOILERPLATE(ANSICallbacksSuite, 1, PF_, ansi_callbacks_suite1P, kPFANSISuite, kPFANSISuiteVersion1); + AEGP_SUITE_ACCESS_BOILERPLATE(HandleSuite, 1, PF_, handle_suite1P, kPFHandleSuite, kPFHandleSuiteVersion1); + AEGP_SUITE_ACCESS_BOILERPLATE(FillMatteSuite, 2, PF_, fill_matte_suite2P, kPFFillMatteSuite, kPFFillMatteSuiteVersion2); + AEGP_SUITE_ACCESS_BOILERPLATE(WorldTransformSuite, 1, PF_, world_transform_suite1P, kPFWorldTransformSuite, kPFWorldTransformSuiteVersion1); + AEGP_SUITE_ACCESS_BOILERPLATE(QueryXformSuite, 2, AEGP_, query_xform_suite2P, kAEGPQueryXformSuite, kAEGPQueryXformSuiteVersion2); + AEGP_SUITE_ACCESS_BOILERPLATE(CompositeSuite, 2, AEGP_, composite_suite2P, kAEGPCompositeSuite, kAEGPCompositeSuiteVersion2); + AEGP_SUITE_ACCESS_BOILERPLATE(WorldSuite, 1, PF_, world_suite1P, kPFWorldSuite, kPFWorldSuiteVersion1); + AEGP_SUITE_ACCESS_BOILERPLATE(IOInSuite, 4, AEGP_, io_in_suite4P, kAEGPIOInSuite, kAEGPIOInSuiteVersion4); + AEGP_SUITE_ACCESS_BOILERPLATE(IOOutSuite, 4, AEGP_, io_out_suite4P, kAEGPIOOutSuite, kAEGPIOOutSuiteVersion4); + AEGP_SUITE_ACCESS_BOILERPLATE(RenderQueueSuite, 1, AEGP_, render_queue_suite1P, kAEGPRenderQueueSuite, kAEGPRenderQueueSuiteVersion1); + AEGP_SUITE_ACCESS_BOILERPLATE(RQItemSuite, 2, AEGP_, rq_item_suite2P, kAEGPRQItemSuite, kAEGPRQItemSuiteVersion2); + AEGP_SUITE_ACCESS_BOILERPLATE(OutputModuleSuite, 4, AEGP_, output_module_suite4P, kAEGPOutputModuleSuite, kAEGPOutputModuleSuiteVersion4); + AEGP_SUITE_ACCESS_BOILERPLATE(FIMSuite, 3, AEGP_, fim_suite3P, kAEGPFIMSuite, kAEGPFIMSuiteVersion3); + AEGP_SUITE_ACCESS_BOILERPLATE(Sampling8Suite, 1, PF_, sampling_8_suite1P, kPFSampling8Suite, kPFSampling8SuiteVersion1); + AEGP_SUITE_ACCESS_BOILERPLATE(Sampling16Suite, 1, PF_, sampling_16_suite1P, kPFSampling16Suite, kPFSampling16SuiteVersion1); + AEGP_SUITE_ACCESS_BOILERPLATE(Iterate8Suite, 1, PF_, iterate_8_suite1P, kPFIterate8Suite, kPFIterate8SuiteVersion1); + AEGP_SUITE_ACCESS_BOILERPLATE(Iterate16Suite, 1, PF_, iterate_16_suite1P, kPFIterate16Suite, kPFIterate16SuiteVersion1); + AEGP_SUITE_ACCESS_BOILERPLATE(IterateFloatSuite, 1, PF_, iterate_float_suite1P, kPFIterateFloatSuite, kPFIterateFloatSuiteVersion1); + AEGP_SUITE_ACCESS_BOILERPLATE(Iterate8Suite, 2, PF_, iterate_8_suite2P, kPFIterate8Suite, kPFIterate8SuiteVersion2); + AEGP_SUITE_ACCESS_BOILERPLATE(Iterate16Suite, 2, PF_, iterate_16_suite2P, kPFIterate16Suite, kPFIterate16SuiteVersion2); + AEGP_SUITE_ACCESS_BOILERPLATE(IterateFloatSuite, 2, PF_, iterate_float_suite2P, kPFIterateFloatSuite, kPFIterateFloatSuiteVersion2); + AEGP_SUITE_ACCESS_BOILERPLATE(CollectionSuite, 2, AEGP_, collection_suite2P, kAEGPCollectionSuite, kAEGPCollectionSuiteVersion2); + AEGP_SUITE_ACCESS_BOILERPLATE(TextDocumentSuite, 1, AEGP_, text_document_suite1P, kAEGPTextDocumentSuite, kAEGPTextDocumentSuiteVersion1); + AEGP_SUITE_ACCESS_BOILERPLATE(SoundDataSuite, 1, AEGP_, sound_data_suite1P, kAEGPSoundDataSuite, kAEGPSoundDataVersion1); + AEGP_SUITE_ACCESS_BOILERPLATE(IterateSuite, 1, AEGP_, aegp_iterate_suite1P, kAEGPIterateSuite, kAEGPIterateSuiteVersion1); + AEGP_SUITE_ACCESS_BOILERPLATE(IterateSuite, 2, AEGP_, aegp_iterate_suite2P, kAEGPIterateSuite, kAEGPIterateSuiteVersion2); + AEGP_SUITE_ACCESS_BOILERPLATE(TextLayerSuite, 1, AEGP_, text_layer_suite1P, kAEGPTextLayerSuite, kAEGPTextLayerSuiteVersion1); + AEGP_SUITE_ACCESS_BOILERPLATE(ArtisanUtilSuite, 1, AEGP_, artisan_util_suite1P, kAEGPArtisanUtilSuite, kAEGPArtisanUtilSuiteVersion1); + AEGP_SUITE_ACCESS_BOILERPLATE(WorldSuite, 2, AEGP_, aegp_world_suite_2P, kAEGPWorldSuite, kAEGPWorldSuiteVersion2); + AEGP_SUITE_ACCESS_BOILERPLATE(WorldSuite, 3, AEGP_, aegp_world_suite_3P, kAEGPWorldSuite, kAEGPWorldSuiteVersion3); + AEGP_SUITE_ACCESS_BOILERPLATE(RenderOptionsSuite, 1, AEGP_, render_options_suite_1P, kAEGPRenderOptionsSuite, kAEGPRenderOptionsSuiteVersion1); + AEGP_SUITE_ACCESS_BOILERPLATE(TrackerSuite, 1, AEGP_, tracker_suite_1P, kAEGPTrackerSuite, kAEGPTrackerSuiteVersion1); + AEGP_SUITE_ACCESS_BOILERPLATE(TrackerUtilitySuite, 1, AEGP_, tracker_utility_suite_1P, kAEGPTrackerUtilitySuite, kAEGPTrackerUtilitySuiteVersion1); + AEGP_SUITE_ACCESS_BOILERPLATE(HelperSuite, 2, PF_, helper_suite_2P, kPFHelperSuite2, kPFHelperSuite2Version2); + AEGP_SUITE_ACCESS_BOILERPLATE(LayerSuite, 5, AEGP_, layer_suite_5P, kAEGPLayerSuite, kAEGPLayerSuiteVersion5); + AEGP_SUITE_ACCESS_BOILERPLATE(LayerSuite, 6, AEGP_, layer_suite_6P, kAEGPLayerSuite, kAEGPLayerSuiteVersion6); + AEGP_SUITE_ACCESS_BOILERPLATE(LayerSuite, 7, AEGP_, layer_suite_7P, kAEGPLayerSuite, kAEGPLayerSuiteVersion7); + AEGP_SUITE_ACCESS_BOILERPLATE(LayerSuite, 8, AEGP_, layer_suite_8P, kAEGPLayerSuite, kAEGPLayerSuiteVersion8); +#ifdef I_NEED_ADM_SUPPORT + AEGP_SUITE_ACCESS_BOILERPLATE(BasicSuite, 8, ADM, adm_basic_suite_8P, kADMBasicSuite, kADMBasicSuiteVersion8); + AEGP_SUITE_ACCESS_BOILERPLATE(DialogSuite, 8, ADM, adm_dialog_suite_8P, kADMDialogSuite, kADMDialogSuiteVersion8); + AEGP_SUITE_ACCESS_BOILERPLATE(DialogGroupSuite, 3, ADM, adm_dialog_group_suite_3P, kADMDialogGroupSuite, kADMDialogGroupSuiteVersion3); + AEGP_SUITE_ACCESS_BOILERPLATE(ItemSuite, 8, ADM, adm_item_suite_8P, kADMItemSuite, kADMItemSuiteVersion8); + AEGP_SUITE_ACCESS_BOILERPLATE(ListSuite, 3, ADM, adm_list_suite_3P, kADMListSuite, kADMListSuiteVersion3); + AEGP_SUITE_ACCESS_BOILERPLATE(EntrySuite, 5, ADM, adm_entry_suite_5P, kADMEntrySuite, kADMEntrySuiteVersion5); + AEGP_SUITE_ACCESS_BOILERPLATE(NotifierSuite, 2, ADM, adm_notifier_suite_2P, kADMNotifierSuite, kADMNotifierSuiteVersion2); +#endif + AEGP_SUITE_ACCESS_BOILERPLATE(LayerSuite, 1, AEGP_, layer_suite_1P, kAEGPLayerSuite, kAEGPLayerSuiteVersion1); + AEGP_SUITE_ACCESS_BOILERPLATE(AdvItemSuite, 1, PF_, adv_item_suite_1P, kPFAdvItemSuite, kPFAdvItemSuiteVersion1); + AEGP_SUITE_ACCESS_BOILERPLATE(MaskSuite, 1, AEGP_, mask_suite_1P, kAEGPMaskSuite, kAEGPMaskSuiteVersion1); + AEGP_SUITE_ACCESS_BOILERPLATE(MaskSuite, 5, AEGP_, mask_suite_5P, kAEGPMaskSuite, kAEGPMaskSuiteVersion5); + AEGP_SUITE_ACCESS_BOILERPLATE(MaskSuite, 6, AEGP_, mask_suite_6P, kAEGPMaskSuite, kAEGPMaskSuiteVersion6); + AEGP_SUITE_ACCESS_BOILERPLATE(CompSuite, 1, AEGP_, comp_suite_1P, kAEGPCompSuite, kAEGPCompSuiteVersion1); + AEGP_SUITE_ACCESS_BOILERPLATE(CollectionSuite, 1, AEGP_, collection_suite_1P, kAEGPCollectionSuite, kAEGPCollectionSuiteVersion1); + AEGP_SUITE_ACCESS_BOILERPLATE(AdvAppSuite, 1, PF_, adv_app_suite_1P, kPFAdvAppSuite, kPFAdvAppSuiteVersion1); + AEGP_SUITE_ACCESS_BOILERPLATE(UtilitySuite, 1, AEGP_, utility_suite_1P, kAEGPUtilitySuite, kAEGPUtilitySuiteVersion1); + AEGP_SUITE_ACCESS_BOILERPLATE(RenderOptionsSuite, 2, AEGP_, render_options_suite_2P, kAEGPRenderOptionsSuite, kAEGPRenderOptionsSuiteVersion2); + AEGP_SUITE_ACCESS_BOILERPLATE(RenderOptionsSuite, 3, AEGP_, render_options_suite_3P, kAEGPRenderOptionsSuite, kAEGPRenderOptionsSuiteVersion3); + AEGP_SUITE_ACCESS_BOILERPLATE(LayerRenderOptionsSuite, 1, AEGP_, layer_render_options_suite_1P, kAEGPLayerRenderOptionsSuite, kAEGPLayerRenderOptionsSuiteVersion1); + AEGP_SUITE_ACCESS_BOILERPLATE(LayerRenderOptionsSuite, 2, AEGP_, layer_render_options_suite_2P, kAEGPLayerRenderOptionsSuite, kAEGPLayerRenderOptionsSuiteVersion2); + AEGP_SUITE_ACCESS_BOILERPLATE(RenderAsyncManagerSuite, 1, AEGP_, async_manager_suite_1P, kAEGPRenderAsyncManagerSuite, kAEGPRenderAsyncManagerSuiteVersion1); + AEGP_SUITE_ACCESS_BOILERPLATE(ProjSuite, 5, AEGP_, proj_suite_5P, kAEGPProjSuite, kAEGPProjSuiteVersion5); + AEGP_SUITE_ACCESS_BOILERPLATE(ProjSuite, 6, AEGP_, proj_suite_6P, kAEGPProjSuite, kAEGPProjSuiteVersion6); + AEGP_SUITE_ACCESS_BOILERPLATE(FootageSuite, 5, AEGP_, footage_suite_5P, kAEGPFootageSuite, kAEGPFootageSuiteVersion5); + AEGP_SUITE_ACCESS_BOILERPLATE(RQItemSuite, 3, AEGP_, rq_item_suite_3P, kAEGPRQItemSuite, kAEGPRQItemSuiteVersion3); + AEGP_SUITE_ACCESS_BOILERPLATE(UtilitySuite, 4, AEGP_, utility_suite_4P, kAEGPUtilitySuite, kAEGPUtilitySuiteVersion4); + AEGP_SUITE_ACCESS_BOILERPLATE(ColorSettingsSuite, 3, AEGP_, color_settings_suite_3P, kAEGPColorSettingsSuite, kAEGPColorSettingsSuiteVersion3); + AEGP_SUITE_ACCESS_BOILERPLATE(ColorSettingsSuite, 2, AEGP_, color_settings_suite_2P, kAEGPColorSettingsSuite, kAEGPColorSettingsSuiteVersion2); + AEGP_SUITE_ACCESS_BOILERPLATE(ColorSettingsSuite, 1, AEGP_, color_settings_suite_1P, kAEGPColorSettingsSuite, kAEGPColorSettingsSuiteVersion1); + AEGP_SUITE_ACCESS_BOILERPLATE(ColorParamSuite, 1, PF_, color_param_suite_1P, kPFColorParamSuite, kPFColorParamSuiteVersion1); + AEGP_SUITE_ACCESS_BOILERPLATE(PersistentDataSuite, 4, AEGP_, persistent_data_suite4P, kAEGPPersistentDataSuite, kAEGPPersistentDataSuiteVersion4); + AEGP_SUITE_ACCESS_BOILERPLATE(PersistentDataSuite, 3, AEGP_, persistent_data_suite3P, kAEGPPersistentDataSuite, kAEGPPersistentDataSuiteVersion3); + AEGP_SUITE_ACCESS_BOILERPLATE(SamplingFloatSuite, 1, PF_, sampling_float_suite_1P, kPFSamplingFloatSuite, kPFSamplingFloatSuiteVersion1); + AEGP_SUITE_ACCESS_BOILERPLATE(UtilitySuite, 5, AEGP_, utility_suite_5P, kAEGPUtilitySuite, kAEGPUtilitySuiteVersion5); + AEGP_SUITE_ACCESS_BOILERPLATE(UtilitySuite, 6, AEGP_, utility_suite_6P, kAEGPUtilitySuite, kAEGPUtilitySuiteVersion6); + AEGP_SUITE_ACCESS_BOILERPLATE(EffectCustomUISuite, 1, PF_, custom_ui_suite1P, kPFEffectCustomUISuite, kPFEffectCustomUISuiteVersion1); + AEGP_SUITE_ACCESS_BOILERPLATE(EffectCustomUISuite, 2, PF_, custom_ui_suite2P, kPFEffectCustomUISuite, kPFEffectCustomUISuiteVersion2); + AEGP_SUITE_ACCESS_BOILERPLATE(EffectCustomUIOverlayThemeSuite, 1, PF_, custom_ui_theme_suite1P, kPFEffectCustomUIOverlayThemeSuite, kPFEffectCustomUIOverlayThemeSuiteVersion1); + AEGP_SUITE_ACCESS_BOILERPLATE(DrawbotSuite, Current, DRAWBOT_, drawing_suite_currentP, kDRAWBOT_DrawSuite, kDRAWBOT_DrawSuite_VersionCurrent); + AEGP_SUITE_ACCESS_BOILERPLATE(SupplierSuite, Current, DRAWBOT_, drawbot_supplier_suite_currentP, kDRAWBOT_SupplierSuite, kDRAWBOT_SupplierSuite_VersionCurrent); + AEGP_SUITE_ACCESS_BOILERPLATE(SurfaceSuite, Current, DRAWBOT_, drawbot_surface_suite_currentP, kDRAWBOT_SurfaceSuite, kDRAWBOT_SurfaceSuite_VersionCurrent); + AEGP_SUITE_ACCESS_BOILERPLATE(PathSuite, Current, DRAWBOT_, drawbot_path_suite_currentP, kDRAWBOT_PathSuite, kDRAWBOT_PathSuite_VersionCurrent); + + AEGP_SUITE_ACCESS_BOILERPLATE(SuitesSuite, , SP, suites_suite_2P, kSPSuitesSuite, kSPSuitesSuiteVersion); +}; + +#endif diff --git a/External/AE SDK/Headers/AEGP_Utils.cpp b/External/AE SDK/Headers/AEGP_Utils.cpp new file mode 100644 index 00000000..8b598074 --- /dev/null +++ b/External/AE SDK/Headers/AEGP_Utils.cpp @@ -0,0 +1,37 @@ +#include "AEGP_Utils.h" + + +A_Err GetNewFirstLayerInFirstComp( + SPBasicSuite *sP, + AEGP_LayerH *first_layerPH) +{ + A_Err err = A_Err_NONE; + + AEGP_ItemH itemH = NULL; + AEGP_ItemType type = AEGP_ItemType_NONE; + AEGP_CompH compH = NULL; + AEGP_ProjectH projH = NULL; + A_long num_projectsL = 0, + num_layersL = 0; + + AEGP_SuiteHandler suites(sP); + + ERR(suites.ProjSuite5()->AEGP_GetProjectByIndex(0, &projH)); + ERR(suites.ItemSuite8()->AEGP_GetFirstProjItem(projH, &itemH)); + ERR(suites.ItemSuite6()->AEGP_GetItemType(itemH, &type)); + + while ((itemH != NULL) && (type != AEGP_ItemType_COMP)){ + ERR(suites.ItemSuite6()->AEGP_GetNextProjItem(projH, itemH, &itemH)); + ERR(suites.ItemSuite6()->AEGP_GetItemType(itemH, &type)); + } + if (!err && (type == AEGP_ItemType_COMP)){ + err = suites.CompSuite4()->AEGP_GetCompFromItem(itemH, &compH); + } + if (!err && compH) { + err = suites.LayerSuite5()->AEGP_GetCompNumLayers(compH, &num_layersL); + } + if (!err && num_layersL){ + err = suites.LayerSuite5()->AEGP_GetCompLayerByIndex(compH, 0, first_layerPH); + } + return err; +} \ No newline at end of file diff --git a/External/AE SDK/Headers/AEGP_Utils.h b/External/AE SDK/Headers/AEGP_Utils.h new file mode 100644 index 00000000..a2f2b06f --- /dev/null +++ b/External/AE SDK/Headers/AEGP_Utils.h @@ -0,0 +1,9 @@ +#include "A.h" +#include "AE_GeneralPlug.h" +#include "AEGP_SuiteHandler.h" +#include "AE_Macros.h" + +A_Err GetNewFirstLayerInFirstComp( + SPBasicSuite *sP, + AEGP_LayerH *first_layerPH); + diff --git a/External/AE SDK/Headers/AE_AdvEffectSuites.h b/External/AE SDK/Headers/AE_AdvEffectSuites.h new file mode 100644 index 00000000..5ea6901d --- /dev/null +++ b/External/AE SDK/Headers/AE_AdvEffectSuites.h @@ -0,0 +1,343 @@ +/*******************************************************************/ +/* */ +/* ADOBE CONFIDENTIAL */ +/* _ _ _ _ _ _ _ _ _ _ _ _ _ */ +/* */ +/* Copyright 2007 Adobe Systems Incorporated */ +/* All Rights Reserved. */ +/* */ +/* NOTICE: All information contained herein is, and remains the */ +/* property of Adobe Systems Incorporated and its suppliers, if */ +/* any. The intellectual and technical concepts contained */ +/* herein are proprietary to Adobe Systems Incorporated and its */ +/* suppliers and may be covered by U.S. and Foreign Patents, */ +/* patents in process, and are protected by trade secret or */ +/* copyright law. Dissemination of this information or */ +/* reproduction of this material is strictly forbidden unless */ +/* prior written permission is obtained from Adobe Systems */ +/* Incorporated. */ +/* */ +/*******************************************************************/ + +#ifndef _H_AE_AdvEffectSuites +#define _H_AE_AdvEffectSuites + +#include +#include +#include + +#include + +#ifdef __cplusplus + extern "C" { +#endif + + +#define kPFAdvAppSuite "PF AE Adv App Suite" +#define kPFAdvAppSuiteVersion1 1 /* frozen in AE 5.0 */ + + +typedef struct PF_AdvAppSuite1 { + + SPAPI PF_Err (*PF_SetProjectDirty)(void); + + SPAPI PF_Err (*PF_SaveProject)(void); + + SPAPI PF_Err (*PF_SaveBackgroundState)(void); + + SPAPI PF_Err (*PF_ForceForeground)(void); + + SPAPI PF_Err (*PF_RestoreBackgroundState)(void); + + SPAPI PF_Err (*PF_RefreshAllWindows)(void); + + // 2 lines of text, same as calling PF_InfoDrawText3( line1Z0, line2Z0, NULL) + SPAPI PF_Err (*PF_InfoDrawText)( + const A_char *line1Z0, + const A_char *line2Z0); + + SPAPI PF_Err (*PF_InfoDrawColor)( + PF_Pixel color); + + // 3 lines of text + SPAPI PF_Err (*PF_InfoDrawText3)( + const A_char *line1Z0, + const A_char *line2Z0, + const A_char *line3Z0); + + // 3 lines, with two lines including formatting for right and left justification + SPAPI PF_Err (*PF_InfoDrawText3Plus)( + const A_char *line1Z0, + const A_char *line2_jrZ0, + const A_char *line2_jlZ0, + const A_char *line3_jrZ0, + const A_char *line3_jlZ0); + +} PF_AdvAppSuite1; + + + + + +#define kPFAdvAppSuiteVersion2 2/* to be frozen in AE 6.0 */ + +typedef struct PF_AdvAppSuite2 { + + SPAPI PF_Err (*PF_SetProjectDirty)(void); + + SPAPI PF_Err (*PF_SaveProject)(void); + + SPAPI PF_Err (*PF_SaveBackgroundState)(void); + + SPAPI PF_Err (*PF_ForceForeground)(void); + + SPAPI PF_Err (*PF_RestoreBackgroundState)(void); + + SPAPI PF_Err (*PF_RefreshAllWindows)(void); + + // 2 lines of text, same as calling PF_InfoDrawText3( line1Z0, line2Z0, NULL) + SPAPI PF_Err (*PF_InfoDrawText)( + const A_char *line1Z0, + const A_char *line2Z0); + + SPAPI PF_Err (*PF_InfoDrawColor)( + PF_Pixel color); + + // 3 lines of text + SPAPI PF_Err (*PF_InfoDrawText3)( + const A_char *line1Z0, + const A_char *line2Z0, + const A_char *line3Z0); + + // 3 lines, with two lines including formatting for right and left justification + SPAPI PF_Err (*PF_InfoDrawText3Plus)( + const A_char *line1Z0, + const A_char *line2_jrZ0, + const A_char *line2_jlZ0, + const A_char *line3_jrZ0, + const A_char *line3_jlZ0); + + // append a line of text to top line for so many ticks + SPAPI PF_Err (*PF_AppendInfoText)( + const A_char *appendZ0); + + +} PF_AdvAppSuite2; + + + +#define PF_MAX_TIME_LEN 31 + +enum { + PF_Step_FORWARD, + PF_Step_BACKWARD +}; +typedef A_LegacyEnumType PF_Step; + +enum { + PF_TimeDisplayFormatTimecode, + PF_TimeDisplayFormatFrames, + PF_TimeDisplayFormatFeetFrames // OBSOLETE: returned only by kPFAdvTimeSuiteVersion1 +}; + +typedef struct { + A_char display_mode; + A_long framemax; + A_long frames_per_foot; + A_char frames_start; + A_Boolean nondrop30B; + A_Boolean honor_source_timecodeB; + A_Boolean use_feet_framesB; +} PF_TimeDisplayPrefVersion3; + + + +#define kPFAdvTimeSuite "PF AE Adv Time Suite" +#define kPFAdvTimeSuiteVersion4 4 //frozen for ae15.0 + +typedef struct PF_AdvTimeSuite4 { + + SPAPI PF_Err (*PF_FormatTimeActiveItem)( A_long time_valueUL, // time is value/scale in seconds + A_u_long time_scaleL, + PF_Boolean durationB, // is the time value a duration or time? + A_char *time_buf); // allocate as PF_MAX_TIME_LEN + 1 + + SPAPI PF_Err (*PF_FormatTime)( PF_InData *in_data, + PF_EffectWorld *world, + A_long time_valueUL, + A_u_long time_scaleL, + PF_Boolean durationB, + A_char *time_buf); + + SPAPI PF_Err (*PF_FormatTimePlus)( PF_InData *in_data, + PF_EffectWorld *world, + A_long time_valueUL, + A_u_long time_scaleL, + PF_Boolean comp_timeB, + PF_Boolean durationB, + A_char *time_buf); + + SPAPI PF_Err (*PF_GetTimeDisplayPref)( PF_TimeDisplayPrefVersion3 *tdp, + A_long *starting_frame_num); + + SPAPI PF_Err (*PF_TimeCountFrames)( const A_Time* start_timeTP, + const A_Time* time_stepTP, + A_Boolean include_partial_frameB, + A_long* frame_countL); + +} PF_AdvTimeSuite4; + + +#define kPFAdvTimeSuite "PF AE Adv Time Suite" +#define kPFAdvTimeSuiteVersion3 3 //frozen for ae14.2 + +typedef struct PF_AdvTimeSuite3 { + + SPAPI PF_Err (*PF_FormatTimeActiveItem)( A_long time_valueUL, // time is value/scale in seconds + A_u_long time_scaleL, + PF_Boolean durationB, // is the time value a duration or time? + A_char *time_buf); // allocate as PF_MAX_TIME_LEN + 1 + + SPAPI PF_Err (*PF_FormatTime)( PF_InData *in_data, + PF_EffectWorld *world, + A_long time_valueUL, + A_u_long time_scaleL, + PF_Boolean durationB, + A_char *time_buf); + + SPAPI PF_Err (*PF_FormatTimePlus)( PF_InData *in_data, + PF_EffectWorld *world, + A_long time_valueUL, + A_u_long time_scaleL, + PF_Boolean comp_timeB, + PF_Boolean durationB, + A_char *time_buf); + + SPAPI PF_Err (*PF_GetTimeDisplayPref)( PF_TimeDisplayPrefVersion3 *tdp, + A_long *starting_frame_num); + +} PF_AdvTimeSuite3; + + +#define kPFAdvTimeSuiteVersion2 2 + +typedef struct { + A_char display_mode; + A_char framemax; + A_char frames_per_foot; + A_char frames_start; + A_Boolean nondrop30B; + A_Boolean honor_source_timecodeB; + A_Boolean use_feet_framesB; +} PF_TimeDisplayPrefVersion2; + +typedef struct PF_AdvTimeSuite2 { + + SPAPI PF_Err (*PF_FormatTimeActiveItem)( A_long time_valueUL, // time is value/scale in seconds + A_u_long time_scaleL, + PF_Boolean durationB, // is the time value a duration or time? + A_char *time_buf); // allocate as PF_MAX_TIME_LEN + 1 + + SPAPI PF_Err (*PF_FormatTime)( PF_InData *in_data, + PF_EffectWorld *world, + A_long time_valueUL, + A_u_long time_scaleL, + PF_Boolean durationB, + A_char *time_buf); + + SPAPI PF_Err (*PF_FormatTimePlus)( PF_InData *in_data, + PF_EffectWorld *world, + A_long time_valueUL, + A_u_long time_scaleL, + PF_Boolean comp_timeB, + PF_Boolean durationB, + A_char *time_buf); + + + SPAPI PF_Err (*PF_GetTimeDisplayPref)( PF_TimeDisplayPrefVersion2 *tdp, + A_long *starting_frame_num); + + + +} PF_AdvTimeSuite2; + + + +#define kPFAdvTimeSuiteVersion1 1 /* frozen in AE 5.0 */ + +typedef struct { + A_char time_display_format; + A_char framemax; + A_char nondrop30; + A_char frames_per_foot; +} PF_TimeDisplayPref; + +typedef struct PF_AdvTimeSuite1 { + + SPAPI PF_Err (*PF_FormatTimeActiveItem)( A_long time_valueUL, // time is value/scale in seconds + A_u_long time_scaleL, + PF_Boolean durationB, // is the time value a duration or time? + A_char *time_buf); // allocate as PF_MAX_TIME_LEN + 1 + + SPAPI PF_Err (*PF_FormatTime)( PF_InData *in_data, + PF_EffectWorld *world, + A_long time_valueUL, + A_u_long time_scaleL, + PF_Boolean durationB, + A_char *time_buf); + + SPAPI PF_Err (*PF_FormatTimePlus)( PF_InData *in_data, + PF_EffectWorld *world, + A_long time_valueUL, + A_u_long time_scaleL, + PF_Boolean comp_timeB, + PF_Boolean durationB, + A_char *time_buf); + + + SPAPI PF_Err (*PF_GetTimeDisplayPref)( PF_TimeDisplayPref *tdp, + A_long *starting_frame_num); + +} PF_AdvTimeSuite1; + + + +#define kPFAdvItemSuite "PF AE Adv Item Suite" +#define kPFAdvItemSuiteVersion1 1 /* frozen in AE 5.0 */ + + + +typedef struct PF_AdvItemSuite1 { + + SPAPI PF_Err (*PF_MoveTimeStep)( PF_InData *in_data, + PF_EffectWorld *world, + PF_Step time_dir, + A_long num_stepsL); + + SPAPI PF_Err (*PF_MoveTimeStepActiveItem) ( PF_Step time_dir, + A_long num_stepsL); + + + SPAPI PF_Err (*PF_TouchActiveItem) (void); + + + SPAPI PF_Err (*PF_ForceRerender)( PF_InData *in_data, + PF_EffectWorld *world); + + + SPAPI PF_Err (*PF_EffectIsActiveOrEnabled)( PF_ContextH contextH, + PF_Boolean *enabledPB); + + +} PF_AdvItemSuite1; + + + +#ifdef __cplusplus +} +#endif + +#include + + +#endif diff --git a/External/AE SDK/Headers/AE_CacheOnLoadSuite.h b/External/AE SDK/Headers/AE_CacheOnLoadSuite.h new file mode 100644 index 00000000..3572ce71 --- /dev/null +++ b/External/AE SDK/Headers/AE_CacheOnLoadSuite.h @@ -0,0 +1,39 @@ +/*******************************************************************/ +/* */ +/* ADOBE CONFIDENTIAL */ +/* _ _ _ _ _ _ _ _ _ _ _ _ _ */ +/* */ +/* Copyright 2003 Adobe Systems Incorporated */ +/* All Rights Reserved. */ +/* */ +/* NOTICE: All information contained herein is, and remains the */ +/* property of Adobe Systems Incorporated and its suppliers, if */ +/* any. The intellectual and technical concepts contained */ +/* herein are proprietary to Adobe Systems Incorporated and its */ +/* suppliers and may be covered by U.S. and Foreign Patents, */ +/* patents in process, and are protected by trade secret or */ +/* copyright law. Dissemination of this information or */ +/* reproduction of this material is strictly forbidden unless */ +/* prior written permission is obtained from Adobe Systems */ +/* Incorporated. */ +/* */ +/*******************************************************************/ + +#ifndef AECACHEONLOADSUITE +#define AECACHEONLOADSUITE + +/** +** CacheOnLoadSuite, used to signal whether or not the plugin needs to load from +** disk every time on startup. +*/ +#define kPFCacheOnLoadSuite "PF Cache On Load Suite" +#define kPFCacheOnLoadSuiteVersion1 1 + +typedef struct PF_CacheOnLoadSuite1 { + + SPAPI PF_Err (*PF_SetNoCacheOnLoad)( PF_ProgPtr effect_ref, + long effectAvailable); + +} PF_CacheOnLoadSuite1; + +#endif // AECACHEONLOADSUITE \ No newline at end of file diff --git a/External/AE SDK/Headers/AE_ChannelSuites.h b/External/AE SDK/Headers/AE_ChannelSuites.h new file mode 100644 index 00000000..3ce87f56 --- /dev/null +++ b/External/AE SDK/Headers/AE_ChannelSuites.h @@ -0,0 +1,509 @@ +/*******************************************************************/ +/* */ +/* ADOBE CONFIDENTIAL */ +/* _ _ _ _ _ _ _ _ _ _ _ _ _ */ +/* */ +/* Copyright 2007 Adobe Systems Incorporated */ +/* All Rights Reserved. */ +/* */ +/* NOTICE: All information contained herein is, and remains the */ +/* property of Adobe Systems Incorporated and its suppliers, if */ +/* any. The intellectual and technical concepts contained */ +/* herein are proprietary to Adobe Systems Incorporated and its */ +/* suppliers and may be covered by U.S. and Foreign Patents, */ +/* patents in process, and are protected by trade secret or */ +/* copyright law. Dissemination of this information or */ +/* reproduction of this material is strictly forbidden unless */ +/* prior written permission is obtained from Adobe Systems */ +/* Incorporated. */ +/* */ +/*******************************************************************/ + + +#ifndef _H_AE_ChannelSuites +#define _H_AE_ChannelSuites + +#include +#include + +#include + + +#ifdef __cplusplus + extern "C" { +#endif + + +/** PF_ChannelSuite + + PF_GetLayerChannelCount + use this to find the number of channels associated with a given source layer + Most likely use is to get number of channels for iteration purposes. + + -param_index is the parameter index of the layer whose source you wish to interrogate + -num_paramsL is the number of "auxillary" channels + + + PF_GetLayerIndexedChannelRefAndDesc + Given a channel index return the opaque channelRef and a channel description + channel index must lie between 0 and num_channels-1 + you will use the channelRef in all subsequent calls + + PF_GetLayerTypedChannelRefAndDesc + Given a type retrieve the channelRef and ChannelDescription + + PF_CheckoutLayerChannel + given the time parameters and a channel reference, get the data + The data chunk is allocated is of the type requested. + The data is in chunky format. + + + + PF_ProgPtr effect_ref, >> + PF_ChannelRefPtr channel_refP, >> + A_long what_time, >> + A_long duration, >> + A_u_long time_scale, >> + PF_DataType data_type, >> + PF_ChannelData *channel_chunkP) <<------ + + PF_CheckinLayerChannel + The checked out channel must be checked in to avoid memory leaks. + PF_ProgPtr effect_ref, + PF_ChannelRefPtr channel_refP, + PF_ChannelDataPtr channel_data_chunkP + +**/ + +#define PF_CHANNEL_DEPTH_INFINITY 1e7 + +#define kPFChannelSuite1 "PF AE Channel Suite" +#define kPFChannelSuiteVersion1 1 /* frozen in AE 5.0 */ + + + + +/** + ** channel data access macros with a check for the type + **/ + +#define PF_GET_CHANNEL_FLOAT_DATA( CHUNK, FLOAT_PTR) \ + do { \ + if ( (CHUNK).data_type == PF_DataType_FLOAT) { \ + FLOAT_PTR = (A_FpShort *) (CHUNK).dataPV; \ + } else { \ + FLOAT_PTR = NULL; \ + } \ + } while(0) + + +#define PF_GET_CHANNEL_DOUBLE_DATA( CHUNK, DOUBLE_PTR) \ + do { \ + if ((CHUNK).data_type == PF_DataType_DOUBLE) { \ + DOUBLE_PTR = (A_FpLong *) (CHUNK).dataPV; \ + } else { \ + DOUBLE_PTR = NULL; \ + } \ + } while(0) + + +#define PF_GET_CHANNEL_LONG_DATA( CHUNK, LONG_PTR) \ + do { \ + if ((CHUNK).data_type == PF_DataType_LONG) { \ + LONG_PTR = (A_long *) (CHUNK).dataPV; \ + } else { \ + LONG_PTR = NULL; \ + } \ + } while(0) + + + +#define PF_GET_CHANNEL_SHORT_DATA( CHUNK, SHORT_PTR) \ + do { \ + if ((CHUNK).data_type == PF_DataType_SHORT) { \ + SHORT_PTR = (A_short *) (CHUNK).dataPV; \ + } else { \ + SHORT_PTR = NULL; \ + } \ + } while(0) + + +#define PF_GET_CHANNEL_FIXED_DATA( CHUNK, FIXED_PTR) \ + do { \ + if ((CHUNK).data_type == PF_DataType_FIXED_16_16) { \ + FIXED_PTR = (A_long *) (CHUNK).dataPV; \ + } else { \ + FIXED_PTR = NULL; \ + } \ + } while(0) + + + + +#define PF_GET_CHANNEL_CHAR_DATA( CHUNK, CHAR_PTR) \ + do { \ + if ((CHUNK).data_type == PF_DataType_CHAR) { \ + CHAR_PTR = (A_char *) (CHUNK).dataPV; \ + } else { \ + CHAR_PTR = NULL; \ + } \ + } while(0) + + + + +#define PF_GET_CHANNEL_U_BYTE_DATA( CHUNK, BYTE_PTR) \ + do { \ + if ((CHUNK).data_type == PF_DataType_U_BYTE) { \ + BYTE_PTR = (A_u_char *) (CHUNK).dataPV; \ + } else { \ + BYTE_PTR = NULL; \ + } \ + } while(0) + + + + + +#define PF_GET_CHANNEL_U_SHORT_DATA( CHUNK, U_SHORT_PTR) \ + do { \ + if ((CHUNK).data_type == PF_DataType_U_SHORT) { \ + U_SHORT_PTR = (A_u_short *) (CHUNK).dataPV;\ + } else { \ + U_SHORT_PTR = NULL; \ + } \ + } while(0) + + + + +#define PF_GET_CHANNEL_U_FIXED_DATA( CHUNK, U_FIXED_PTR) \ + do { \ + if ((CHUNK).data_type == PF_DataType_U_FIXED_16_16) { \ + U_FIXED_PTR = (A_u_long) (CHUNK).dataPV; \ + } else { \ + U_FIXED_PTR = NULL; \ + } \ + } while(0) + + + + +/** + ** get a row of the chunk data + **/ +#define PF_GET_CHANNEL_ROW_FLOAT_DATA( CHUNK, ROW, FLOAT_PTR) \ + do { \ + if (((CHUNK).data_type == PF_DataType_FLOAT) && ((ROW) < (CHUNK).heightL)) { \ + FLOAT_PTR = (A_FpShort *) ((A_char *)(CHUNK).dataPV + (ROW) * (CHUNK).row_bytesL); \ + } else { \ + FLOAT_PTR = NULL; \ + } \ + } while(0) + + +#define PF_GET_CHANNEL_ROW_DOUBLE_DATA( CHUNK, ROW, DOUBLE_PTR) \ + do { \ + if (((CHUNK).data_type == PF_DataType_DOUBLE) && ((ROW) < (CHUNK).heightL)) { \ + DOUBLE_PTR = (A_FpLong *) ((A_char *)(CHUNK).dataPV + (ROW) * (CHUNK).row_bytesL); \ + } else { \ + DOUBLE_PTR = NULL; \ + } \ + } while(0) + + +#define PF_GET_CHANNEL_ROW_LONG_DATA( CHUNK, ROW, LONG_PTR) \ + do { \ + if (((CHUNK).data_type == PF_DataType_LONG) && ((ROW) < (CHUNK).heightL)) { \ + LONG_PTR = (A_long *) ((A_char *)(CHUNK).dataPV + (ROW) * (CHUNK).row_bytesL); \ + } else { \ + LONG_PTR = NULL; \ + } \ + } while(0) + + + +#define PF_GET_CHANNEL_ROW_SHORT_DATA( CHUNK, ROW, SHORT_PTR) \ + do { \ + if (((CHUNK).data_type == PF_DataType_SHORT) && ((ROW) < (CHUNK).heightL)) { \ + SHORT_PTR = (A_short *) ((A_char *)(CHUNK).dataPV + (ROW) * (CHUNK).row_bytesL); \ + } else { \ + SHORT_PTR = NULL; \ + } \ + } while(0) + + +#define PF_GET_CHANNEL_ROW_FIXED_DATA( CHUNK, ROW, FIXED_PTR) \ + do { \ + if (((CHUNK).data_type == PF_DataType_FIXED_16_16) && ((ROW) < (CHUNK).heightL)) { \ + FIXED_PTR = (A_long *) ((A_char *)(CHUNK).dataPV + (ROW) * (CHUNK).row_bytesL); \ + } else { \ + FIXED_PTR = NULL; \ + } \ + } while(0) + + + + +#define PF_GET_CHANNEL_ROW_CHAR_DATA( CHUNK, ROW, CHAR_PTR) \ + do { \ + if (((CHUNK).data_type == PF_DataType_CHAR) && ((ROW) < (CHUNK).heightL)) { \ + CHAR_PTR = (A_char *) ((A_char *)(CHUNK).dataPV + (ROW) * (CHUNK).row_bytesL); \ + } else { \ + CHAR_PTR = NULL; \ + } \ + } while(0) + + + + +#define PF_GET_CHANNEL_ROW_U_BYTE_DATA( CHUNK, ROW, BYTE_PTR) \ + do { \ + if (((CHUNK).data_type == PF_DataType_U_BYTE) && ((ROW) < (CHUNK).heightL)) { \ + BYTE_PTR = (A_u_char *) ((A_char *)(CHUNK).dataPV + (ROW) * (CHUNK).row_bytesL); \ + } else { \ + BYTE_PTR = NULL; \ + } \ + } while(0) + + + + + +#define PF_GET_CHANNEL_ROW_U_SHORT_DATA( CHUNK, ROW, U_SHORT_PTR) \ + do { \ + if (((CHUNK).data_type == PF_DataType_U_SHORT) && ((ROW) < (CHUNK).heightL)) { \ + U_SHORT_PTR = (A_u_short *) ((A_char *)(CHUNK).dataPV + (ROW) * (CHUNK).row_bytesL); \ + } else { \ + U_SHORT_PTR = NULL; \ + } \ + } while(0) + + + + +#define PF_GET_CHANNEL_ROW_U_FIXED_DATA( CHUNK, ROW, U_FIXED_PTR) \ + do { \ + if (((CHUNK).data_type == PF_DataType_U_FIXED_16_16) && ((ROW) < (CHUNK).heightL)) { \ + U_FIXED_PTR = (A_u_long) ((A_char *)(CHUNK).dataPV + (ROW) * (CHUNK).row_bytesL); \ + } else { \ + U_FIXED_PTR = NULL; \ + } \ + } while(0) + + + + + + +/** + ** get a item from the chunk data + **/ +#define PF_GET_CHANNEL_ROW_COL_FLOAT_DATA( CHUNK, ROW, COL, FLOAT_PTR) \ + do { \ + if (((CHUNK).data_type == PF_DataType_FLOAT) && \ + ((ROW) >= 0) && \ + ((COL) >= 0) && \ + ((ROW) < (CHUNK).heightL) && \ + ((COL) < (CHUNK).widthL)) { \ + FLOAT_PTR = (A_FpShort *) ((A_char *)(CHUNK).dataPV + (ROW) * (CHUNK).row_bytesL); \ + FLOAT_PTR = (A_FpShort *)FLOAT_PTR + (COL) * (CHUNK).dimensionL; \ + } else { \ + FLOAT_PTR = NULL; \ + } \ + } while(0) + + +#define PF_GET_CHANNEL_ROW_COL_DOUBLE_DATA( CHUNK, ROW, COL, DOUBLE_PTR) \ + do { \ + if (((CHUNK).data_type == PF_DataType_DOUBLE) && \ + ((ROW) >= 0) && \ + ((COL) >= 0) && \ + ((ROW) < (CHUNK).heightL) && \ + ((COL) < (CHUNK).widthL)) { \ + DOUBLE_PTR = (A_FpLong *) ((A_char *)(CHUNK).dataPV + (ROW) * (CHUNK).row_bytesL); \ + DOUBLE_PTR = (A_FpLong *)DOUBLE_PTR + (COL) * (CHUNK).dimensionL; \ + } else { \ + DOUBLE_PTR = NULL; \ + } \ + } while(0) + + +#define PF_GET_CHANNEL_ROW_COL_LONG_DATA( CHUNK, ROW, COL, LONG_PTR) \ + do { \ + if (((CHUNK).data_type == PF_DataType_LONG) && \ + ((ROW) >= 0) && \ + ((COL) >= 0) && \ + ((ROW) < (CHUNK).heightL) && \ + ((COL) < (CHUNK).widthL)) { \ + LONG_PTR = (A_long *) ((A_char *)(CHUNK).dataPV + (ROW) * (CHUNK).row_bytesL); \ + LONG_PTR = (A_long *) LONG_PTR + (COL) * (CHUNK).dimensionL; \ + } else { \ + LONG_PTR = NULL; \ + } \ + } while(0) + + + +#define PF_GET_CHANNEL_ROW_COL_SHORT_DATA( CHUNK, ROW, COL, SHORT_PTR) \ + do { \ + if (((CHUNK).data_type == PF_DataType_SHORT) && \ + ((ROW) >= 0) && \ + ((COL) >= 0) && \ + ((ROW) < (CHUNK).heightL) && \ + ((COL) < (CHUNK).widthL)) { \ + SHORT_PTR = (A_short *) ((A_char *)(CHUNK).dataPV + (ROW) * (CHUNK).row_bytesL); \ + SHORT_PTR = (A_short *) SHORT_PTR + (COL) * (CHUNK).dimensionL;\ + } else { \ + SHORT_PTR = NULL; \ + } \ + } while(0) + + +#define PF_GET_CHANNEL_ROW_COL_FIXED_DATA( CHUNK, ROW, COL, FIXED_PTR) \ + do { \ + if (((CHUNK).data_type == PF_DataType_FIXED_16_16) && \ + ((ROW) >= 0) && \ + ((COL) >= 0) && \ + ((ROW) < (CHUNK).heightL) && \ + ((COL) < (CHUNK).widthL)) { \ + FIXED_PTR = (A_long *) ((A_char *)(CHUNK).dataPV + (ROW) * (CHUNK).row_bytesL); \ + FIXED_PTR = (A_long *) FIXED_PTR + (COL) * (CHUNK).dimensionL; \ + } else { \ + FIXED_PTR = NULL; \ + } \ + } while(0) + + + + +#define PF_GET_CHANNEL_ROW_COL_CHAR_DATA( CHUNK, ROW, COL, CHAR_PTR) \ + do { \ + if (((CHUNK).data_type == PF_DataType_CHAR) && \ + ((ROW) >= 0) && \ + ((COL) >= 0) && \ + ((ROW) < (CHUNK).heightL) && \ + ((COL) < (CHUNK).widthL)) { \ + CHAR_PTR = (A_char *) ((A_char *)(CHUNK).dataPV + (ROW) * (CHUNK).row_bytesL); \ + CHAR_PTR = (A_char *) CHAR_PTR + (COL) * (CHUNK).dimensionL; \ + } else { \ + CHAR_PTR = NULL; \ + } \ + } while(0) + + + + +#define PF_GET_CHANNEL_ROW_COL_U_BYTE_DATA( CHUNK, ROW, COL, BYTE_PTR) \ + do { \ + if (((CHUNK).data_type == PF_DataType_U_BYTE) && \ + ((ROW) >= 0) && \ + ((COL) >= 0) && \ + ((ROW) < (CHUNK).heightL) && \ + ((COL) < (CHUNK).widthL)) { \ + BYTE_PTR = (A_u_char *) ((A_char *)(CHUNK).dataPV + (ROW) * (CHUNK).row_bytesL); \ + BYTE_PTR = (A_u_char *) BYTE_PTR + (COL) * (CHUNK).dimensionL; \ + } else { \ + BYTE_PTR = NULL; \ + } \ + } while(0) + + + + + +#define PF_GET_CHANNEL_ROW_COL_U_SHORT_DATA( CHUNK, ROW, COL, U_SHORT_PTR) \ + do { \ + if (((CHUNK).data_type == PF_DataType_U_SHORT) && \ + ((ROW) >= 0) && \ + ((COL) >= 0) && \ + ((ROW) < (CHUNK).heightL) && \ + ((COL) < (CHUNK).widthL)) { \ + U_SHORT_PTR = (A_u_short *) ((A_char *)(CHUNK).dataPV + (ROW) * (CHUNK).row_bytesL); \ + U_SHORT_PTR = (A_u_short *) U_SHORT_PTR + (COL) * (CHUNK).dimensionL; \ + } else { \ + U_SHORT_PTR = NULL; \ + } \ + } while(0) + + + + +#define PF_GET_CHANNEL_ROW_COL_U_FIXED_DATA( CHUNK, ROW, COL, U_FIXED_PTR) \ + do { \ + if (((CHUNK).data_type == PF_DataType_U_FIXED_16_16) && \ + ((ROW) >= 0) && \ + ((COL) >= 0) && \ + ((ROW) < (CHUNK).heightL) && \ + ((COL) < (CHUNK).widthL)) { \ + U_FIXED_PTR = (A_u_long) ((A_char *)(CHUNK).dataPV + (ROW) * (CHUNK).row_bytesL); \ + U_FIXED_PTR = (A_u_long) U_FIXED_PTR + (COL) * (CHUNK).dimensionL; \ + } else { \ + U_FIXED_PTR = NULL; \ + } \ + } while(0) + + + + + + +/** + ** the suite functions + **/ + +typedef struct PF_ChannelSuite1 { /* frozen in AE 5.0 */ + + SPAPI PF_Err (*PF_GetLayerChannelCount)( + PF_ProgPtr effect_ref, /* >> */ + PF_ParamIndex param_index, /* >> */ + A_long *num_channelsPL); /* << */ + + SPAPI PF_Err (*PF_GetLayerChannelIndexedRefAndDesc)( + PF_ProgPtr effect_ref, /* >> */ + PF_ParamIndex param_index, /* >> */ + PF_ChannelIndex channel_index, /* >> */ + PF_Boolean *foundPB, /* << */ + PF_ChannelRef *channel_refP, /* << */ + PF_ChannelDesc *channel_descP); /* << */ + + + SPAPI PF_Err (*PF_GetLayerChannelTypedRefAndDesc)( + PF_ProgPtr effect_ref, /* >> */ + PF_ParamIndex param_index, /* >> */ + PF_ChannelType channel_type, /* >> */ + PF_Boolean *foundPB, /* << */ + PF_ChannelRef *channel_refP, /* << */ + PF_ChannelDesc *channel_descP); /* << */ + + SPAPI PF_Err (*PF_CheckoutLayerChannel)( + PF_ProgPtr effect_ref, /* >> */ + PF_ChannelRefPtr channel_refP, /* >> */ + A_long what_time, /* >> */ + A_long duration, /* >> */ + A_u_long time_scale, /* >> */ + PF_DataType data_type, /* << */ + PF_ChannelChunk *channel_chunkP); /* << */ + + + SPAPI PF_Err (*PF_CheckinLayerChannel)( + PF_ProgPtr effect_ref, /* >> */ + PF_ChannelRefPtr channel_refP, /* >> */ + PF_ChannelChunk *channel_chunkP); /* << */ + + +} PF_ChannelSuite1; + + + + + +#ifdef __cplusplus + } // end extern "C" +#endif + + +#include + + +#endif diff --git a/External/AE SDK/Headers/AE_ComputeCacheSuite.h b/External/AE SDK/Headers/AE_ComputeCacheSuite.h new file mode 100644 index 00000000..e11481d5 --- /dev/null +++ b/External/AE SDK/Headers/AE_ComputeCacheSuite.h @@ -0,0 +1,175 @@ +/******************************************************************** +* ADOBE CONFIDENTIAL +* __________________ +* +* Copyright 2020 Adobe Inc. +* All Rights Reserved. +* +* NOTICE: All information contained herein is, and remains +* the property of Adobe and its suppliers, if any. The intellectual +* and technical concepts contained herein are proprietary to Adobe +* and its suppliers and are protected by all applicable intellectual +* property laws, including trade secret and copyright laws. +* Dissemination of this information or reproduction of this material +* is strictly forbidden unless prior written permission is obtained +* from Adobe. +********************************************************************/ + +#ifndef _H_AE_ComputeCacheSuite +#define _H_AE_ComputeCacheSuite + +#include +#include + +#ifdef AEGP_INTERNAL + #include +#endif + +#ifdef __cplusplus + extern "C" { +#endif + +///////////////////////////////////// MC Compute -- plugin registration of cached computations + +// Globally unique identifier for the compute class, such as "adobe.ae.effect.test_effect.cache_v_1" +typedef const char *AEGP_CCComputeClassIdP; + +typedef void *AEGP_CCComputeOptionsRefconP; // opaque content provided by plugin for generating key and value. Input to the compute. +typedef void *AEGP_CCComputeValueRefconP; // opaque compute result from the plugin + + +// GUID used as the cache key. +typedef struct AEGP_GUID { + A_long bytes[4]; +} AEGP_GUID; + +typedef AEGP_GUID AEGP_CCComputeKey; +typedef AEGP_CCComputeKey *AEGP_CCComputeKeyP; + +typedef void *AEGP_CCCheckoutReceiptP; + +// +// The effect supplies implementations of these callbacks. +// +typedef struct AEGP_ComputeCacheCallbacks { + // Cache key. Called when creating a cache entry and when doing a cache lookup. Should be fast to compute. All of the inputs + // needed to uniquely address the cache entry must be hashed into the key. If a layer checkout is needed to calculate the cache + // value, such as with a histogram, then the hash of that input must be included. See PF_ParamUtilsSuite::PF_GetCurrentState + // to get the hash for a layer param. Note this is the hash of the inputs needed to generate the frame, not a hash the pixels + // in the frame, thus a render is not triggered when making this call. + A_Err (*generate_key)( + AEGP_CCComputeOptionsRefconP optionsP, + AEGP_CCComputeKeyP out_keyP); + + // The expensive call. Generate the cache data from the input parameters. + A_Err (*compute)( + AEGP_CCComputeOptionsRefconP optionsP, + AEGP_CCComputeValueRefconP *out_valuePP); + + // The computed value may not be a flat data structure. This should return the total memory footprint. The size is an input + // to the cache purging heuristic. + size_t (*approx_size_value)( + AEGP_CCComputeValueRefconP valueP); + + // The computed value lives in the cache. This is called to free the value when the cached is to be purged. All resources + // owned by the cache value must be freed here. + void (*delete_compute_value)( + AEGP_CCComputeValueRefconP valueP); +} AEGP_ComputeCacheCallbacks; + + + +#define kAEGPComputeCacheSuite "AEGP Compute Cache" +#define kAEGPComputeCacheSuiteVersion1 1 /* frozen in AE 18.2 */ + +typedef struct AEGP_ComputeCacheSuite1 { + + // Register a cache type. + SPAPI A_Err (*AEGP_ClassRegister)( + AEGP_CCComputeClassIdP compute_classP, + const AEGP_ComputeCacheCallbacks *callbacksP); + + // Unregister a cache type. Note that all cached values will be purged at this time since the delete_compute_value callback + // is how cache entries are deleted, and delete_compute_value is not available after unregister. + SPAPI A_Err (*AEGP_ClassUnregister)( + AEGP_CCComputeClassIdP compute_classP); + + + // This is the main checkout call. + // + // When adding cache support one of the first questions to answer is if a single render call needs to checkout more than one + // cache value. If more than one cache value is needed then the multi-checkout pattern, below, can be applied to concurrently + // calculate the caches across multiple render calls and thus avoid serialization of the compute. + // + // SINGLE CACHE VALUE + // If a render call only needs one cache value then set wait_for_other_threadB to true. The checkout call will return a receipt, + // possibly calling the compute callback to populate the cache; or waiting on another thread that had already started the + // needed computation. + // + // MULTI-CHECKOUT + // If a render call needs multiple cache values then this pattern can be used to keep the render threads utilized and thus + // avoid serializing the compute. + // Render() + // { + // bool first_err = AEGP_ComputeIfNeededAndCheckout(first_options, do_not_wait); + // bool second_err = AEGP_ComputeIfNeededAndCheckout(second_options, do_not_wait); + // // Add as many additional do_not_wait checkout calls here as needed. + // + // if(first_err == A_Err_NOT_IN_CACHE_OR_COMPUTE_PENDING) { + // AEGP_ComputeIfNeededAndCheckout(wait); + // } + // if(second_err == A_Err_NOT_IN_CACHE_OR_COMPUTE_PENDING) { + // AEGP_ComputeIfNeededAndCheckout(wait); + // } + // // Add as many additional waiting checkout calls here as needed + // } + // + // wait_for_other_threadB + // CACHE STATE || FALSE TRUE | + // ================++========================+========================+ + // No cache || Compute and checkout | Compute and checkout | + // ----------------++------------------------+------------------------+ + // Being computed || Return error, see | Wait for the other | + // by another thread || below. | thread and checkout | + // ----------------++------------------------+------------------------+ + // Cached || Checkout | Checkout | + // ----------------++------------------------+------------------------+ + // + // Returns A_Err_NOT_IN_CACHE_OR_COMPUTE_PENDING if wait_for_other_threadB is false and another thread is currently computing + // the cache value. Note that the host will not notify the user of this error; it will be silent to the user. + // + // Must call AEGP_CheckinComputeReceipt on success. Check-in must be done before returning to the host. + SPAPI A_Err (*AEGP_ComputeIfNeededAndCheckout)( + AEGP_CCComputeClassIdP compute_classP, + AEGP_CCComputeOptionsRefconP opaque_optionsP, + bool wait_for_other_threadB, + AEGP_CCCheckoutReceiptP *compute_receiptPP); + + // This call does a cache check, and thus should return always quickly. It does not do compute nor does it wait for another + // thread that is populating the cache. + // This call could be used to implement a polling pattern where another piece of code is expected to populate the cache. For + // example, a UI thread could poll the cache regularly for a histogram that is generated on a render thread. + // + // Either returns cache value or A_Err_NOT_IN_CACHE_OR_COMPUTE_PENDING if cache miss. + // Must call AEGP_CheckinComputeReceipt on success. Check-in must be done before returning to the host. + SPAPI A_Err (*AEGP_CheckoutCached)( + AEGP_CCComputeClassIdP compute_classP, + AEGP_CCComputeOptionsRefconP opaque_optionsP, + AEGP_CCCheckoutReceiptP *compute_receiptPP); + + // Get the cache value from a checkout receipt. + SPAPI A_Err (*AEGP_GetReceiptComputeValue)( + const AEGP_CCCheckoutReceiptP compute_receiptP, + AEGP_CCComputeValueRefconP *compute_valuePP); + + // Check-in a receipt. + SPAPI A_Err (*AEGP_CheckinComputeReceipt)( + AEGP_CCCheckoutReceiptP compute_receiptP ); + +} AEGP_ComputeCacheSuite1; + +#ifdef __cplusplus + } // end extern "C" +#endif + +#endif diff --git a/External/AE SDK/Headers/AE_CreatorInfo.h b/External/AE SDK/Headers/AE_CreatorInfo.h new file mode 100644 index 00000000..2867c1a0 --- /dev/null +++ b/External/AE SDK/Headers/AE_CreatorInfo.h @@ -0,0 +1 @@ +/*******************************************************************/ /* */ /* ADOBE CONFIDENTIAL */ /* _ _ _ _ _ _ _ _ _ _ _ _ _ */ /* */ /* Copyright 2007 Adobe Systems Incorporated */ /* All Rights Reserved. */ /* */ /* NOTICE: All information contained herein is, and remains the */ /* property of Adobe Systems Incorporated and its suppliers, if */ /* any. The intellectual and technical concepts contained */ /* herein are proprietary to Adobe Systems Incorporated and its */ /* suppliers and may be covered by U.S. and Foreign Patents, */ /* patents in process, and are protected by trade secret or */ /* copyright law. Dissemination of this information or */ /* reproduction of this material is strictly forbidden unless */ /* prior written permission is obtained from Adobe Systems */ /* Incorporated. */ /* */ /*******************************************************************/ /* If you'd like After Effects to open files created by your application IN your application, embed this structure in that file. Data must be in Motorola byte order. Your application must then respond to the appleEvent (mac) or the command line flags (win) that are specified in the structure. */ #define ADBE_CREATOR_ATOM_TYPE 'Cr8r' #define CR8R_MAGIC 0xBEEFCAFE #define ADBE_CREATOR_ATOM_VERS_MAJOR 1 #define ADBE_CREATOR_ATOM_VERS_MINOR 0 typedef struct adbe_creator_atom { unsigned long magicLu; // set to CR8R_MAGIC long atom_sizeL; // size of this structure (sizeof(CR8R_CreatorAtom)) short atom_vers_majorS; // set to ADBE_CREATOR_ATOM_VERS_MAJOR short atom_vers_minorS; // set to ADBE_CREATOR_ATOM_VERS_MINOR // mac unsigned long creator_codeLu; // application code on MacOS unsigned long creator_eventLu; // invocation appleEvent // windows char creator_extAC[16]; // extension allowing registry search to app char creator_flagAC[16]; // flag passed to app at invocation time char creator_nameAC[32]; // name of the creator application } CR8R_CreatorAtom, **CR8R_CreatorAtomHandle; \ No newline at end of file diff --git a/External/AE SDK/Headers/AE_Effect.h b/External/AE SDK/Headers/AE_Effect.h new file mode 100644 index 00000000..bb1107b2 --- /dev/null +++ b/External/AE SDK/Headers/AE_Effect.h @@ -0,0 +1,3049 @@ +/*******************************************************************/ +/* */ +/* ADOBE CONFIDENTIAL */ +/* _ _ _ _ _ _ _ _ _ _ _ _ _ */ +/* */ +/* Copyright 2007 Adobe Systems Incorporated */ +/* All Rights Reserved. */ +/* */ +/* NOTICE: All information contained herein is, and remains the */ +/* property of Adobe Systems Incorporated and its suppliers, if */ +/* any. The intellectual and technical concepts contained */ +/* herein are proprietary to Adobe Systems Incorporated and its */ +/* suppliers and may be covered by U.S. and Foreign Patents, */ +/* patents in process, and are protected by trade secret or */ +/* copyright law. Dissemination of this information or */ +/* reproduction of this material is strictly forbidden unless */ +/* prior written permission is obtained from Adobe Systems */ +/* Incorporated. */ +/* */ +/*******************************************************************/ + + +/** AE_Effect.h + + Part of the After Effects SDK + + CONTENTS + Version Information + Constants And Enumerations + Output Flags + Input Flags + Command Selectors + Simple Types + Pixel Access Macros + Effect Parameter Description Structures + Interaction Callbacks + Effect Parameter Blocks + Effect Prototype + + NOTES + It may be easiest to start reading this file at the bottom + and work your way, section by section, to the top. Of course, + the best thing to do is start with the sample filter and the + work your way from that back through the goodies in this file. + + All strings in this spec are NULL-terminated (C strings). + +**/ + +// This stuff is a test to make sure that no code is including +// this file with contradictory settings of A_INTERNAL. It must +// come *before* the _H_AE_Effect "include once" test. +// You can define A_SUPPRESS_A_INTERNAL_WARNING if you have a plugin +// that breaks this rule innocently. +#ifdef A_INTERNAL + #define A_INTERNAL_TEST_ONE 1 +#else + #define A_INTERNAL_TEST_TWO 1 +#endif + +#if (A_INTERNAL_TEST_ONE && A_INTERNAL_TEST_TWO) + #ifndef A_SUPPRESS_A_INTERNAL_WARNING + #pragma message("Warning: You have included AE_Effect.h once with A_INTERNAL set and once without.") + #endif +#endif + +// End of A_INTERNAL consistency check. + + +#ifndef _H_AE_Effect +#define _H_AE_Effect + +#ifdef A_INTERNAL + #include "PF_Private.h" +#endif + +#include "A.h" +#if defined(__APPLE__) +#include +#endif +#include + + +#ifdef __cplusplus + extern "C" { +#endif + +#ifndef __cplusplus + #if defined(__ANDROID__) + #include + #endif +#endif + +/** -------------------- Version Information ---------------------------------- + ** + ** Please use these macros for designating the version information + ** of your plug-ins. Should After Effects encounter more than one version + ** of a specific plug-in when it starts up, it will use this information + ** to decide which plug-in to honor. The plug-in version information + ** (field 'my_version' in the PF_OutData) should be set at GLOBAL_SETUP + ** time. + ** + ** This version information is meant for your version control, and should + ** not be confused with the min_version and desired_version fields in the + ** PF_OutData structure, which refer to the version of the PF specification. + ** + **/ + +#define PF_Vers_BUILD_BITS 0x1ffL +#define PF_Vers_BUILD_SHIFT 0 +#define PF_Vers_STAGE_BITS 0x3L +#define PF_Vers_STAGE_SHIFT 9 +#define PF_Vers_BUGFIX_BITS 0xfL +#define PF_Vers_BUGFIX_SHIFT 11 +#define PF_Vers_SUBVERS_BITS 0xfL +#define PF_Vers_SUBVERS_SHIFT 15 +#define PF_Vers_VERS_BITS 0x7L // incomplete without high bits, below +#define PF_Vers_VERS_SHIFT 19 +// skipping these bits for similarity to Up_Vers_ARCH_*, currently unused in PF +#define PF_Vers_VERS_HIGH_BITS 0xfL // expand version max from 7 to 127 +#define PF_Vers_VERS_HIGH_SHIFT 26 + +// b/c we are stripping the stand alone vers value for two fields +#define PF_Vers_VERS_LOW_SHIFT 3 +#define PF_Vers_VERS_HIGH(vers) ((vers)>>PF_Vers_VERS_LOW_SHIFT) + +#define PF_VERSION(vers, subvers, bugvers, stage, build) \ + (A_u_long)( \ + ((((A_u_long)PF_Vers_VERS_HIGH(vers)) & PF_Vers_VERS_HIGH_BITS) << PF_Vers_VERS_HIGH_SHIFT) | \ + ((((A_u_long)(vers)) & PF_Vers_VERS_BITS) << PF_Vers_VERS_SHIFT) | \ + ((((A_u_long)(subvers)) & PF_Vers_SUBVERS_BITS)<> PF_Vers_VERS_SHIFT) & PF_Vers_VERS_BITS) + (((vers >> PF_Vers_VERS_HIGH_SHIFT) & PF_Vers_VERS_HIGH_BITS) << PF_Vers_VERS_LOW_SHIFT)) + +#define PF_Version_SUBVERS(vers) \ + ((((A_u_long) vers) >> PF_Vers_SUBVERS_SHIFT) & PF_Vers_SUBVERS_BITS) + +#define PF_Version_BUGFIX(vers) \ + ((((A_u_long) vers) >> PF_Vers_BUGFIX_SHIFT) & PF_Vers_BUGFIX_BITS) + +#define PF_Version_STAGE(vers) \ + ((((A_u_long) vers) >> PF_Vers_STAGE_SHIFT) & PF_Vers_STAGE_BITS) + +#define PF_Version_BUILD(vers) \ + ((((A_u_long) vers) >> PF_Vers_BUILD_SHIFT) & PF_Vers_BUILD_BITS) + + +enum { + PF_Stage_DEVELOP, + PF_Stage_ALPHA, + PF_Stage_BETA, + PF_Stage_RELEASE +}; +typedef A_long PF_Stage; + + + + + + +/** -------------------- Constants And Enumerations -------------------- + + These version numbers refer to the PF_AE_PLUG_IN_VERSION & SUBVERSION of all releases of AE, and, correspondingly, + the API used by each plug-in (i.e. the SDK that the plug-in is compiled against). The plug-in can check this number + (PF_SpecVersion version field in in_data) to see which API the host supports, and the host can check to see what API + the plug-in is expecting (as listed in the plug-in's PiPL). + +**/ + +//CC +#define PF_AE220_PLUG_IN_VERSION 13 // manually set for SDK changes to allow more than 32 max threads for PF_Iterate +#define PF_AE220_PLUG_IN_SUBVERS 27 // manually set for SDK changes to allow more than 32 max threads for PF_Iterate + +#define PF_AE184_PLUG_IN_VERSION 13 // manually set for mid-cycle SDK drop +#define PF_AE184_PLUG_IN_SUBVERS 26 // manually set for mid-cycle SDK drop + +#define PF_AE182_PLUG_IN_VERSION 13 // manually set for mid-cycle SDK drop +#define PF_AE182_PLUG_IN_SUBVERS 25 // manually set for mid-cycle SDK drop + +#define PF_AE180_PLUG_IN_VERSION 13 // auto-set by prep_codeline_for_release.py, adjust comment if manually edit is okay +#define PF_AE180_PLUG_IN_SUBVERS 24 // auto-set by prep_codeline_for_release.py, adjust comment if manually edit is okay + +#define PF_AE177_PLUG_IN_VERSION 13 // auto-set by prep_codeline_for_release.py, adjust comment if manually edit is okay +#define PF_AE177_PLUG_IN_SUBVERS 23 // auto-set by prep_codeline_for_release.py, adjust comment if manually edit is okay + +#define PF_AE176_PLUG_IN_VERSION 13 // auto-set by prep_codeline_for_release.py, adjust comment if manually edit is okay +#define PF_AE176_PLUG_IN_SUBVERS 22 // auto-set by prep_codeline_for_release.py, adjust comment if manually edit is okay + +#define PF_AE175_PLUG_IN_VERSION 13 // auto-set by prep_codeline_for_release.py, adjust comment if manually edit is okay +#define PF_AE175_PLUG_IN_SUBVERS 21 // auto-set by prep_codeline_for_release.py, adjust comment if manually edit is okay + +#define PF_AE171_PLUG_IN_VERSION 13 // auto-set by prep_codeline_for_release.py, adjust comment if manually edit is okay +#define PF_AE171_PLUG_IN_SUBVERS 20 // auto-set by prep_codeline_for_release.py, adjust comment if manually edit is okay + +#define PF_AE170_PLUG_IN_VERSION 13 // auto-set by prep_codeline_for_release.py, adjust comment if manually edit is okay +#define PF_AE170_PLUG_IN_SUBVERS 18 // auto-set by prep_codeline_for_release.py, adjust comment if manually edit is okay + +#define PF_AE161_PLUG_IN_VERSION 13 // auto-set by prep_codeline_for_release.py, adjust comment if manually edit is okay +#define PF_AE161_PLUG_IN_SUBVERS 17 // auto-set by prep_codeline_for_release.py, adjust comment if manually edit is okay + +#define PF_AE160_PLUG_IN_VERSION 13 // auto-set by prep_codeline_for_release.py, adjust comment if manually edit is okay +#define PF_AE160_PLUG_IN_SUBVERS 16 // auto-set by prep_codeline_for_release.py, adjust comment if manually edit is okay + +#define PF_AE151_PLUG_IN_VERSION 13 // auto-set by prep_codeline_for_release.py, adjust comment if manually edit is okay +#define PF_AE151_PLUG_IN_SUBVERS 15 // auto-set by prep_codeline_for_release.py, adjust comment if manually edit is okay + +#define PF_AE150_PLUG_IN_VERSION 13 // auto-set by prep_codeline_for_release.py, adjust comment if manually edit is okay +#define PF_AE150_PLUG_IN_SUBVERS 15 // auto-set by prep_codeline_for_release.py, adjust comment if manually edit is okay + +#define PF_AE142_PLUG_IN_VERSION 13 // auto-set by prep_codeline_for_release.py, adjust comment if manually edit is okay +#define PF_AE142_PLUG_IN_SUBVERS 14 // auto-set by prep_codeline_for_release.py, adjust comment if manually edit is okay + +#define PF_AE140_PLUG_IN_VERSION 13 // auto-set by prep_codeline_for_release.py, adjust comment if manually edit is okay +#define PF_AE140_PLUG_IN_SUBVERS 13 // auto-set by prep_codeline_for_release.py, adjust comment if manually edit is okay + +#define PF_AE138_PLUG_IN_VERSION 13 // auto-set by prep_codeline_for_release.py, adjust comment if manually edit is okay +#define PF_AE138_PLUG_IN_SUBVERS 11 // auto-set by prep_codeline_for_release.py, adjust comment if manually edit is okay + +// AE137 is same plugin version as AE136, below + +#define PF_AE136_PLUG_IN_VERSION 13 // auto-set by prep_codeline_for_release.py, adjust comment if manually edit is okay +#define PF_AE136_PLUG_IN_SUBVERS 10 // auto-set by prep_codeline_for_release.py, adjust comment if manually edit is okay + +#define PF_AE135_PLUG_IN_VERSION 13 // auto-set by prep_codeline_for_release.py, adjust comment if manually edit is okay +#define PF_AE135_PLUG_IN_SUBVERS 9 // auto-set by prep_codeline_for_release.py, adjust comment if manually edit is okay + +// AE131 and AE132 are the same plugin version as AE130, below + +#define PF_AE130_PLUG_IN_VERSION 13 // auto-set by prep_codeline_for_release.py, adjust comment if manually edit okay +#define PF_AE130_PLUG_IN_SUBVERS 7 // auto-set by prep_codeline_for_release.py, adjust comment if manually edit okay + +#define PF_AE122_PLUG_IN_VERSION 13 // auto-set by prep_codeline_for_release.py, adjust comment if manually edit okay +#define PF_AE122_PLUG_IN_SUBVERS 6 // auto-set by prep_codeline_for_release.py, adjust comment if manually edit okay + +#define PF_AE121_PLUG_IN_VERSION 13 // auto-set by prep_codeline_for_release.py, adjust comment if manually edit okay +#define PF_AE121_PLUG_IN_SUBVERS 5 // auto-set by prep_codeline_for_release.py, adjust comment if manually edit okay + +#define PF_AE120_PLUG_IN_VERSION 13 +#define PF_AE120_PLUG_IN_SUBVERS 4 + +//CS6.0.1 +//Plugins have to make dummy checkout (hack) to fix W3163764 in CS6. The bug has been fixed in CS6.0.1 so increase SDK minor version +//so that plugins can constrain the hack only for CS6. +#define PF_AE1101_PLUG_IN_VERSION 13 +#define PF_AE1101_PLUG_IN_SUBVERS 3 + +#define PF_AE110_PLUG_IN_VERSION 13 +#define PF_AE110_PLUG_IN_SUBVERS 2 + +#define PF_AE105_PLUG_IN_VERSION 13 +#define PF_AE105_PLUG_IN_SUBVERS 1 + +#define PF_AE100_PLUG_IN_VERSION 13 +#define PF_AE100_PLUG_IN_SUBVERS 0 + +#define PF_AE90_PLUG_IN_VERSION 12 +#define PF_AE90_PLUG_IN_SUBVERS 14 + +#define PF_AE80_PLUG_IN_VERSION 12 +#define PF_AE80_PLUG_IN_SUBVERS 13 + +#define PF_AE70_PLUG_IN_VERSION 12 +#define PF_AE70_PLUG_IN_SUBVERS 12 + +#define PF_AE65_PLUG_IN_VERSION 12 +#define PF_AE65_PLUG_IN_SUBVERS 11 + +#define PF_AE41_PLUG_IN_VERSION 12 +#define PF_AE41_PLUG_IN_SUBVERS 2 + +#define PF_AE40_PLUG_IN_VERSION 12 +#define PF_AE40_PLUG_IN_SUBVERS 1 + +#define PF_AE31_PLUG_IN_VERSION 11 +#define PF_AE31_PLUG_IN_SUBVERS 6 +#define PF_AE31_PLUG_IN_SUBVERS_STRICTIFY 8 + +#define PF_AE_PLUG_IN_VERSION PF_AE220_PLUG_IN_VERSION // manually set for SDK changes to allow more than 32 max threads for PF_Iterate +#define PF_AE_PLUG_IN_SUBVERS PF_AE220_PLUG_IN_SUBVERS // manually set for SDK changes to allow more than 32 max threads for PF_Iterate + +/* Note: AE3.1 will drive any v11.x plugin + AE4.0 will drive any v11.x or v12.x plugin + AE4.1 will drive any v11.x or v12.x plugin, changed current version from 12.1 -> 12.2 + + If you use PF_AE31_PLUG_IN_VERSION, PF_AE31_PLUG_IN_SUBVERS_STRICTIFY + or later (e.g. 11.8 or 12.0) AE4.0 will enforce new stricter rules and + report more plug-in errors. +*/ + + +#define PF_MAX_EFFECT_NAME_LEN 31 +#define PF_MAX_EFFECT_CATEGORY_NAME_LEN 31 +#define PF_MAX_EFFECT_PARAM_NAME_LEN 31 +#define PF_MAX_PARAM_DESCRIPTION_LEN 31 +#define PF_MAX_PARAM_VALUE_LEN 31 +#define PF_MAX_EFFECT_MSG_LEN 255 + +// Through AE6.5, effects could only have this many parameters. Now the number is unlimited. +#define PF_AE65_AND_EARLIER_MAX_NUM_EFFECT_PARAMS 127 + +#define PF_MAX_WORLD_WIDTH 30000 +#define PF_MAX_WORLD_HEIGHT 30000 + +#define PF_FIRST_ERR 512 + + +/* Standard effect categories for After Effects effects modules. + * These need to be set in the PiPL. + */ +#define PF_Category_BLUR_AND_SHARPEN "Blur & Sharpen" +#define PF_Category_CHANNEL "Channel" +#define PF_Category_DISTORT "Distort" +#define PF_Category_IMAGE_CONTROL "Image Control" +#define PF_Category_KEYING "Keying" +#define PF_Category_PERSPECTIVE "Perspective" +#define PF_Category_STYLIZE "Stylize" +#define PF_Category_TEXT "Text" +#define PF_Category_VIDEO "Video" +#define PF_Category_TRANSITION "Transition" +#define PF_Category_AUDIO "Audio" +#define PF_Category_OTHER "Other" + +enum { + PF_Quality_DRAWING_AUDIO = -1, // only used to inform audio plugins that the output + // will be used to draw the waveform; the plugin should + // not perform any filtering operations that may weaken + // the amplitude when rendering at low sampling rates + + PF_Quality_LO = 0, // LO & HI are sent to both audio & visual effects + PF_Quality_HI +}; +typedef A_long PF_Quality; + +enum { + PF_MF_Alpha_PREMUL = 0, + PF_MF_Alpha_STRAIGHT = (1L << 0) +}; +typedef A_long PF_ModeFlags; + +#define PF_ALPHA_PREMUL(F) (((F) & 0x00000001) == 0) +#define PF_ALPHA_STRAIGHT(F) (((F) & 0x00000001)) + +enum { + PF_Field_FRAME = 0L, + PF_Field_UPPER = 1L, + PF_Field_LOWER = 2L +}; +typedef A_long PF_Field; + + + +/* PF_ParamType + */ +enum { + PF_Param_RESERVED = -1, + PF_Param_LAYER = 0, + PF_Param_SLIDER, /* obsolete, use PF_Param_FLOAT_SLIDER */ + PF_Param_FIX_SLIDER,/* obsolete, use PF_Param_FLOAT_SLIDER */ + PF_Param_ANGLE, + PF_Param_CHECKBOX, + PF_Param_COLOR, + PF_Param_POINT, + PF_Param_POPUP, + PF_Param_CUSTOM, /* obsolete */ + PF_Param_NO_DATA, /* used for CustomUI in Effect window controls, with NO data stream */ + PF_Param_FLOAT_SLIDER, + PF_Param_ARBITRARY_DATA, // in AE: must combine with either PF_PUI_TOPIC/PF_PUI_CONTROL or PF_PUI_NO_ECW + // in PPro starting with 8.0: it's OK to set none of those flags, which allows you to + // see the parameter's keyframe track on the right side of Effect Controls + // without creating a custom control + PF_Param_PATH, + PF_Param_GROUP_START, + PF_Param_GROUP_END, + PF_Param_BUTTON, // must combine with PF_ParamFlag_SUPERVISE + PF_Param_RESERVED2, + PF_Param_RESERVED3, + PF_Param_POINT_3D // only supported by AE, not PPro +}; +typedef A_long PF_ParamType; + + +/* PF_ParamFlags + + These flags are passed when adding a param (using PF_ADD_PARAM) to specify + some details about how the param can be used. The flags + are: + + PF_ParamFlag_CANNOT_TIME_VARY + If this is passed, the parameter will not be allowed to vary + over time -- no keyframe controller will appear at the right. + + PF_ParamFlag_CANNOT_INTERP + If this is passed, parameter values are not interpolated + between. You can still use no interp and discontinuous interp. + + PF_ParamFlag_COLLAPSE_TWIRLY / PF_ParamFlag_START_COLLAPSED + Set this flag if you want the parameter's twirly arrow in the + Effect Control Window to be twirled up by default when the + effect is first applied. New in AE 4.0: you can now set & + clear this bit when handling PF_Cmd_UPDATE_PARAMS_UI and + PF_Cmd_USER_CHANGED_PARAM messages, so as to twirl your + parameters and groups up and down at will. + + PF_ParamFlag_SUPERVISE + If this is passed, PF_Cmd_USER_CHANGED_PARAM will be sent when + this parameter changes. + + PF_ParamFlag_USE_VALUE_FOR_OLD_PROJECTS + This only affects the loading of projects saved with an older version + of the effect which lacks parameters added later. When set, the PF_ParamDef + "value" field set in PF_ADD_PARAM will be used to initialize the missing parameter, + but the "dephault" field will still be used for initial value of the parameter when + the effect is newly applied or reset. This is useful for when you want a + parameter to default to one value but need it set to something else to + preserve rendering behaviour for older projects. + + This flag is valid for all PF_Param types except PF_Param_LAYER + + PF_ParamFlag_LAYER_PARAM_IS_TRACKMATTE + For PF_Param_LAYER, this flag indicates that the layer parameter is to be presented + as a track matte. Supported by Premiere, ignored in AE. + + PF_ParamFlag_EXCLUDE_FROM_HAVE_INPUTS_CHANGED + See doc for PF_HaveInputsChangedOverTimeSpan. + + PF_ParamFlag_SKIP_REVEAL_WHEN_UNHIDDEN + when this param is "un hidden" (cuz it may hide and show), then the GUI is NOT to cause + the parameter to be "revealed", ie: it won't twirl down it's parents and scroll it into view + +**/ +enum { + PF_ParamFlag_RESERVED1 = 1 << 0, + PF_ParamFlag_CANNOT_TIME_VARY = 1 << 1, /* can't vary over time */ + PF_ParamFlag_CANNOT_INTERP = 1 << 2, /* can only vary discontinuously */ + PF_ParamFlag_RESERVED2 = 1 << 3, /* was _old_ PF_ParamFlag_WANTS_UPDATE value, never used */ + PF_ParamFlag_RESERVED3 = 1 << 4, /* was _old_ PF_ParamFlag_SEPARATE, now use PF_PUI_ECW_SEPARATOR */ + PF_ParamFlag_COLLAPSE_TWIRLY = 1 << 5, /* controls the twirl-state of the twirly-arrow in the ECW (dynamic) */ + PF_ParamFlag_SUPERVISE = 1 << 6, /* call me with PF_Cmd_USER_CHANGED_PARAM (new in AE 4.0) */ + PF_ParamFlag_START_COLLAPSED = PF_ParamFlag_COLLAPSE_TWIRLY, /* when first applied, param comes up collapsed */ + PF_ParamFlag_USE_VALUE_FOR_OLD_PROJECTS = 1 << 7, /* see extensive comment above */ + PF_ParamFlag_LAYER_PARAM_IS_TRACKMATTE = 1 << 7, /* only valid for layer parameters. indicates that a layer param is used as a track-matte with applied filters (used in Premiere, ignored in AE) */ + PF_ParamFlag_EXCLUDE_FROM_HAVE_INPUTS_CHANGED = 1 << 8, /* only relevant if you call PF_HaveInputsChangedOverTimeSpan() */ + PF_ParamFlag_SKIP_REVEAL_WHEN_UNHIDDEN = 1 << 9 /* dont reveal this stream when un-hidden (use only during param setup) */ +}; +typedef A_long PF_ParamFlags; + +enum { + PF_Err_NONE = 0, + PF_Err_OUT_OF_MEMORY = 4, + PF_Err_INTERNAL_STRUCT_DAMAGED = PF_FIRST_ERR, + PF_Err_INVALID_INDEX, /* out of range, or action not allowed on this index */ + PF_Err_UNRECOGNIZED_PARAM_TYPE, + PF_Err_INVALID_CALLBACK, + PF_Err_BAD_CALLBACK_PARAM, + PF_Interrupt_CANCEL, /* Returned when user interrupts rendering */ + PF_Err_CANNOT_PARSE_KEYFRAME_TEXT /* Returned from PF_Arbitrary_SCAN_FUNC when effect + cannot parse arbitrary data from text */ +}; +typedef A_long PF_Err; + + +enum { + PF_WorldFlag_DEEP = 1L << 0, + PF_WorldFlag_WRITEABLE = 1L << 1, + + + PF_WorldFlag_RESERVED0 = 1L << 24, + PF_WorldFlag_RESERVED1 = 1L << 25, + PF_WorldFlag_RESERVED2 = 1L << 26, + PF_WorldFlag_RESERVED3 = 1L << 27, + PF_WorldFlag_RESERVED4 = 1L << 28, + PF_WorldFlag_RESERVED5 = 1L << 29, + PF_WorldFlag_RESERVED6 = 1L << 30, + PF_WorldFlag_RESERVED = 1L << 31 +}; + +typedef A_long PF_WorldFlags; + +#define PF_WORLD_IS_DEEP(W) ( ((W)->world_flags & PF_WorldFlag_DEEP) != 0 ) + +#define PF_MAX_CHAN8 255 +#define PF_HALF_CHAN8 128 +#define PF_MAX_CHAN16 32768 +#define PF_HALF_CHAN16 16384 + + + +/** -------------------- Output Flags -------------------- + + The out_flags field of the OutData can be set to an OR-ed + combination of these flags to communicate various things to + the driver program. The flags are described here: + + PF_OutFlag_NONE + This is the "empty" setting -- no outflags. + + PF_OutFlag_WIDE_TIME_INPUT + Set this flag if the effect calls get_param to inquire a + parameter at a time besides the current one (e.g. to get + the previous video frame). This should be sent, if it is + going to be sent, at PF_Cmd_GLOBAL_SETUP. Can be over-ridden + dynamically during PF_Cmd_QUERY_DYNAMIC_FLAGS. + + As of AE10, this flag is no longer recommended. It still works the + same way and is safe to set, but there's a more efficient option. + See PF_OutFlag2_AUTOMATIC_WIDE_TIME_INPUT. + + PF_OutFlag_NON_PARAM_VARY + Set this if the effect uses information other than the parameters + in the param list to generate its output at the current time. + For instance, if the effect uses the current time of the frame + or some random value to decide the output, set this flag. This + flag should be sent at PF_Cmd_GLOBAL_SETUP. If the effect + produces changing frames when applied to a still image and + all parameters are constant, that's a sure sign that this bit + should be set (e.g. Wave Warp). Can be over-ridden dynamically + during PF_Cmd_QUERY_DYNAMIC_FLAGS. + + PF_OutFlag_SEQUENCE_DATA_NEEDS_FLATTENING + When you allocate a sequence data handle, the app + may write the handle out to disk and reuse it + later. Pass this flag if the handle is not "flat" + (i.e. has pointers or handles hanging off of it). + Basically, this gives you a chance to alter the + handle contents before it is written out to disk, + so you won't get invalid handles or pointers. Once + you have flattened a handle, you will get an + opportunity to un-flatten it before the effect + needs to continue. For sequence data, you will be + invoked with a PF_Cmd_SEQUENCE_RESETUP call. You + should store a boolean at a common offset in your + unflattened and flattened data that says whether + the data is flat or not. If you get a + PF_Cmd_SEQUENCE_RESETUP and the boolean indicated + the data is flattened, you should unflatten the + data, free the flattened data handle, and set the + sequence_data handle in the PF_OutData. If you + ever set the data to NULL when you flatten it, you + will NOT get the sequence resetup call to + unflatten it. Instead, you may just get a RENDER + call with NULL data. Forewarned is forearmed. This + flag, indicating if the data will need to be + flattened, should be set at PF_Cmd_GLOBAL_SETUP time. + + PF_OutFlag_I_DO_DIALOG + Set this is the effect responds to a PF_Cmd_DO_DIALOG, i.e. Does this + effect bring up an options dialog box. PF_Cmd_DO_DIALOG is generated + when the user presses the Options button on the Effect floater. + This flag should be set at PF_Cmd_GLOBAL_SETUP time. + + PF_OutFlag_USE_OUTPUT_EXTENT + The output layer is passed with an "extent rect" indicating + the area of the layer that actually contains visible image data. If + the effect changes its behavior based on the extent rect (for instance, + by not iterating over the entire image), set this flag, so the + application will know whether having the extent change should cause + the frame to re-render. Specify this flag at PF_Cmd_GLOBAL_SETUP. + + PF_OutFlag_SEND_DO_DIALOG + Some filters need their options dialog box to be brought up at least + once to be valid. You can set this flag, and the driver app will + automatically send a PF_Cmd_DO_DIALOG to the effect when it is applied. + The DO_DIALOG will be sent after PF_Cmd_SEQUENCE_SETUP. This flag + should be set in PF_Cmd_SEQUENCE_SETUP if it is going to be set. + + PF_OutFlag_DISPLAY_ERROR_MESSAGE + Whenever the return_msg field in the PF_OutData is set to a string, + After Effects will bring up a simple dialog box containing that + string. If you set this flag, the dialog box will be made to look + like an error message dialog box. If you don't set this flag, it + will be an undecorated dialog box. Using this flag, an effects module + can have and display its own error messages and not worry about the + code for dialog boxes -- the program will do it for you. + This flag can be sent after any command. + + PF_OutFlag_I_EXPAND_BUFFER + Starting with After Effects 2.0, effects will be able to expand their buffers + beyond the current layer's dimensions. This has always been part of the + PF specification, but as an extra precaution (and hint to the AE rendering + engine) set this flag at PF_Cmd_GLOBAL_SETUP if you plan to expand your + buffer. + + PF_OutFlag_I_SHRINK_BUFFER + Set this flag if you can shrink your buffer based on the extent-rects passed + to you in order to be more memory efficient. + + PF_OutFlag_PIX_INDEPENDENT + Set this flag if the output at a given pixel is not dependent on the values + of the pixels around it. If this is set, the pixels After Effects does not + care about (because of field rendering, for example) could be filled with garbage + colors. Please set this flag at PF_Cmd_GLOBAL_SETUP. Can be over-ridden + dynamically during PF_Cmd_QUERY_DYNAMIC_FLAGS. + + PF_OutFlag_I_WRITE_INPUT_BUFFER + Set this flag if your effect would like to write into the input buffer. This + can be useful if you need an scratch buffer, but it also invalidates some speedups + in the AE rendering pipeline, so use it with some discretion. Please set this + flag at PF_Cmd_GLOBAL_SETUP. + + PF_OutFlag_KEEP_RESOURCE_OPEN + + Obsoleted in AE 2015 (does nothing when set). + + Set this flag if your effect expects its Macintosh resource fork to be open + at any time other than global setup. Note that this does not mean that + the resource fork will be kept open at all times, just whenever the + effect is being executed. + + PF_OutFlag_NOP_RENDER + + Set this flag in PF_Cmd_GLOBAL_SETUP if the render would never result in changes + to the source image (or audio?). For example, an expression control would set this. + + PF_OutFlag_CUSTOM_UI + + This flag must be set if your effect has a custom UI in the Effect Controls + Window, Layer Window or Comp Window. + + PF_OutFlag2_CUSTOM_UI_ASYNC_MANAGER (new in 13.5) + + This flags enables use of AEGP_CheckoutOrRender_*_AsyncManager() calls + which avoid the need for plugin management of the lifetime of async custom UI renders from the UI thread. + The plugin asks for what frames it needs and the manager calls PF_Event_DRAW again when they are available + (or cancels them as needed automatically). The plugin responds in PF_Event_DRAW by asking for what it needs + and drawing what it can from what is available. + + Due to separation of Render thread and UI thread in 13.5, frames for custom UI should no longer be + rendered synchronously (see RenderSuite5 for more details). The manager simplifies this, especially when + there are multiple requests needed for DRAW. + + When enabled, this flag associates a "PF_AsyncManager" with the NEW_CONTEXT/CLOSE_CONTEXT and PF_Event_DRAW + that will automatically track completion of 1 or more asynch render requests made for drawing custom UI. + As requests complete, PF_Event_DRAW will be called again and the current state of the CUSTOM_UI can be drawn. + Such requests may be canceled automatically as the user scrubs the time needle or project changes are made and + become invalid. + + This flag is used in addition to the CUSTOM_UI flag during PF_Cmd_GLOBAL_SETUP + + PF_OutFlag_REFRESH_UI + + Can be returned from PF_Cmd_EVENT, PF_Cmd_RENDER, and PF_Cmd_DO_DIALOG. + Causes the effects control window, layer window, and comp window to be re-drawn. + + PF_OutFlag_I_USE_SHUTTER_ANGLE + + Must be set at PF_Cmd_GLOBAL_SETUP time if the effect uses + the shutter_angle or the shutter_phase. Can be over-ridden dynamically during + PF_Cmd_QUERY_DYNAMIC_FLAGS. + + PF_OutFlag_I_USE_AUDIO + + Must be set at PF_Cmd_GLOBAL_SETUP time for a visual effect + that calls the audio checkout calls. + + PF_OutFlag_I_AM_OBSOLETE + + Set at PF_Cmd_GLOBAL_SETUP time for effects that don't + want to appear in the AE Effects menu (but will still be invoked + if you load a project that has an old copy of the effect applied). + + PF_OutFlag_FORCE_RERENDER + + Set at PF_Cmd_EVENT if the effect modified sequence data, + or did anything else that requires the effect needs to re-render. + Note that setting PF_ChangeFlag_CHANGED_VALUE automatically + causes a re-render, so don't worry about setting PF_OutFlag_FORCE_RERENDER + in that case. Also, I_MIX_GUID_DEPENDENCIES can be used to trigger a rerender on + dependant changes if sequence_data has not been changed. + + IMPORTANT: FORCE_RERENDER should be used as a last resort. Long term we should be eliminating the need for this + because it causes forced cache invalidation that doesn't work well with undo. + Once we have the full set of APIs in place needed to manage render state, we will be able to deprecate this. + Prefer using ARB data + CHANGED_VALUE or I_MIX_GUID_DEPENDENCIES when possible instead. + + In 13.5 the split between a UI and render threads means that FORCE_RERENDER will now also have the needed + side effect of copying sequence_data state to the render project. This can be expensive if the sequence_data is large. + Support GET_FLATTENED_SEQUENCE_DATA to prevent deallocation of your sequence_data, which can help. + GET_FLATTENED_SEQUENCE_DATA support is required for FORCE_RERENDER use in custom mouse/key events. + + PF_OutFlag_PiPL_OVERRIDES_OUTDATA_OUTFLAGS + + Valid only for setting in your PiPL. When set out_flags will be + ignored at PF_Cmd_GLOBAL_SETUP time (& thus don't need to match). + + PF_OutFlag_I_HAVE_EXTERNAL_DEPENDENCIES + + Set this flag at PF_Cmd_GLOBAL_SETUP time if the effect has dependencies + that the user should know about before transporting their project to a + different machine. For example, dependencies on an installed font, + or on an external file. If set, the effect will receive a + PF_Cmd_GET_EXTERNAL_DEPENDENCIES request, where the extra + param will be a PF_ExtDependenciesExtra, and the effect should + report its information based on the given sequence_data. + + PF_OutFlag_SEND_UPDATE_PARAMS_UI + + Set this flag at PF_Cmd_GLOBAL_SETUP time if you want to receive + PF_Cmd_UPDATE_PARAMS_UI messages. + + PF_OutFlag_AUDIO_FLOAT_ONLY + + Set this flag if you only want to receive PF_SIGNED_FLOAT data + when processing audio data. Requires PF_OutFlag_AUDIO_EFFECT_TOO + or PF_OutFlag_AUDIO_EFFECT_ONLY. + + PF_OutFlag_AUDIO_IIR + + Set this flag at PF_Cmd_GLOBAL_SETUP time if you are an + Infinite-Impulse-Response audio filter (i.e. your output at a given + time depends on your output from previous times). + + PF_OutFlag_I_SYNTHESIZE_AUDIO + + Set this flag at PF_Cmd_GLOBAL_SETUP time if you generate + audio even when handed silence. Requires PF_OutFlag_AUDIO_EFFECT_TOO + or PF_OutFlag_AUDIO_EFFECT_ONLY. + + PF_OutFlag_AUDIO_EFFECT_TOO + + Must be set at PF_Cmd_GLOBAL_SETUP time for an effect that + wants to filter the audio too (as opposed to just reading the audio). + + PF_OutFlag_AUDIO_EFFECT_ONLY + + Must be set at PF_Cmd_GLOBAL_SETUP time for an effect + that only filters audio (no video). + + PF_OutFlag2_SUPPORTS_QUERY_DYNAMIC_FLAGS + + Set this during PF_Cmd_GLOBAL_SETUP if the effect handles PF_Cmd_QUERY_DYNAMIC_FLAGS. + Supporting this command can dramatically improve performance for certain + effects, because it provides dynamic information to the host about what + can be cached (as opposed to PIPL bits which cannot be changed at run-time) + + PF_OutFlag2_I_USE_3D_CAMERA + + This bit must be set if the effect ever uses the AEGP PF_Interface suite to + access camera layers. Can be over-ridden dynamically during PF_Cmd_QUERY_DYNAMIC_FLAGS. + + PF_OutFlag2_I_USE_3D_LIGHTS + + This bit must be set if the effect ever uses the AEGP PF_Interface suite to + access camera layers. Can be over-ridden dynamically during PF_Cmd_QUERY_DYNAMIC_FLAGS. + + PF_OutFlag2_PARAM_GROUP_START_COLLAPSED_FLAG + + If you want a parameter group to honor the PF_ParamFlag_COLLAPSE_TWIRLY or + PF_ParamFlag_START_COLLAPSED flag, set this bit. Otherwise, all parameter + groups will be collapsed by default. + + PF_OutFlag2_DOESNT_NEED_EMPTY_PIXELS + + Added for render optimizations; shrinks the input buffer passed to the effect to + exclude any empty pixels (where empty means "zero alpha" unless + PF_OutFlag2_REVEALS_ZERO_ALPHA is set, in which case RGB must be zero as well.) + The origin of the trimmed buffer can be found in in_data->pre_effect_source_origin. + Effects with both this flag and PF_OutFlag_I_EXPAND_BUFFER set may get called with + a null input buffer if their input is completely empty, and must be able to handle + this case without crashing. This flag can be cleared dynamically during + PF_Cmd_QUERY_DYNAMIC_FLAGS. + + PF_OutFlag2_REVEALS_ZERO_ALPHA + + The effect can take pixels with zero alpha and reveal the RGB data in them (like + our Set Channels effect). This tells After Effects not to trim such pixels when + determining the input for the effect. This flag can be cleared dynamically during + PF_Cmd_QUERY_DYNAMIC_FLAGS. + + PF_OutFlag2_I_AM_DEPRECATED + this effect is still available, and shows up under user-visible "Obsolete" category + in the UI. Setting this flag means "there's a better way to do this, but this effect + may still be useful in some situations". distinct from PF_OutFlag_I_AM_OBSOLETE in + that these will still show up in the GUI and the user can still apply them to new + projects. The category that is set by the effect is pretty much ignored, as it will + instead always go into the "Obsolete" category + + PF_OutFlag2_I_USE_TIMECODE + New in AE 9.0. The effect depends on the Composition's timecode or a layer's + source footage timecode. If the underlying timecode changes the effects will + be asked to rerender. + + PF_OutFlag2_AUTOMATIC_WIDE_TIME_INPUT + New in AE 10. Requires setting of PF_OutFlag_WIDE_TIME_INPUT (which allows you + to support old hosts), but effectively overrides that flag. When set, all + parameter checkouts are tracked so over-time dependencies are known by AE. Note + that if you use this new flag, and you cache any time-dependent data in your + sequence data (or anywhere else), you must validate that cache using the + new PF_HaveInputsChangedOverTimeSpan() before using it. + + This only works for smart effects (those that set PF_OutFlag2_SUPPORTS_SMART_RENDER). If you haven't + set that, After Effects will silently treat this as PF_OutFlag_WIDE_TIME_INPUT instead. + + To test that it's working, apply your effect with one parameter keyframed on every frame. + RAM Preview to fill the cache, then change one of the keyframes. The related frame and + all dependent frames (e.g. later frames, in the case of a simulation) should lose their + cache marks and require re-rendering. Simlarly, upstream changes to sources of layer + parameters should cause time-selective invalidation of the cache. + + PF_OutFlag2_DEPENDS_ON_UNREFERENCED_MASKS + Set this if you are going to look at paths that aren't directly referenced by a path + param, e.g. if you are going to draw a stroke on all masks. + + PF_OutFlag2_OUTPUT_IS_WATERMARKED + Set this if your output is going to be watermarked in some way that makes it unsuitable for + final use, probably because the user is using an unlicensed demo version. It is ok to change + this state during the course of app session, if e.g. a floating license status changes. + Plugin authors that actually do have this state changing asynchronously must be careful to + have the next render match the last state returned from QUERY_DYNAMIC_FLAGS otherwise race conditions + could cause incorrect frames to be cached. (This is a non-issue if you only change this in response + to DO_DIALOG.) + + PF_OutFlag2_I_MIX_GUID_DEPENDENCIES (new in 13.5) + Smart effects only. With this option, FORCE_RERENDER becomes a cache-savvy more efficient MAYBE rerender. + If custom UI or DO_DIALOG change sequence data, returning FORCE_RERENDER requests AE to check whether + rerender needs to occur. During PreRender, the effect uses the GuidMixInPtr callback to mix + any additional state that affects the render into our internal GUID for the cached frame. + AE can then tell whether the frame already exists and if so, no longer needs to render. + This also means that DO_DIALOG no longer always blows the cache and that undo works across DO_DIALOG. + Cancelation of DO_DIALOG no longer blows the cache either. + This also means that I_USE_* flags are now basically redundant since any dependency could be mixed in. + Just be sure to mix in everything that can uniquely affect resulting rendered pixels (that is not already + an AE stream parameter). But don't mixin things that are disabled and have no render effect (this + results in less cache efficiency). + + PF_OutFlag2_SUPPORTS_THREADED_RENDERING + Indicates the effect supports rendering on multiple threads at the same time. Single or multiple + applications of this effect on a layer can be called to render at the same time on multiple threads. + + UI selectors are still sent on the main thread, however Sequence Setup, Sequence Resetup, Sequence SetDown, + PreRender, and Render may be sent on multiple threads at the same time as the UI selectors are being handled + so all of these selectors must be thread safe. + + Global Setup and Global Setdown selectors are unaffected by this flag. Regardless whether this flag is set + or not, they will only be sent on the main thread, and will not be sent at the same time as any other selectors. + + If the effect sets PF_OutFlag_SEQUENCE_DATA_NEEDS_FLATTENING indicating the sequence data needs flattening + then it must also set PF_OutFlag2_SUPPORTS_GET_FLATTENED_SEQUENCE_DATA. + + sequence_data is read-only at render time and must be accessed with PF_EffectSequenceDataSuite. + in_data->sequence_data will be NULL during render. AEGP_ComputeCacheSuite is suggested if writing to + sequence_data at render time is needed for caching. This suite unifies cache entries so multiple threads do + not recompute the same cache value. If neither of these solutions work, see the next flag, + PF_OutFlag2_MUTABLE_RENDER_SEQUENCE_DATA_SLOWER. + + PF_OutFlag2_MUTABLE_RENDER_SEQUENCE_DATA_SLOWER + Indicates the effect needs sequence_data replicated for each render thread, thus allowing each render to have + sequence_data which can be written to. Note that changes to sequence_data will be discarded regularly, currently + after each span of frames is rendered such as single RAM Preview or Render Queue export. + +**/ + +enum { + PF_OutFlag_NONE = 0L, + + // which PF_Cmds each flag is relevant for: + PF_OutFlag_KEEP_RESOURCE_OPEN = 1L << 0, // PF_Cmd_GLOBAL_SETUP + PF_OutFlag_WIDE_TIME_INPUT = 1L << 1, // PF_Cmd_GLOBAL_SETUP, PF_Cmd_QUERY_DYNAMIC_FLAGS + PF_OutFlag_NON_PARAM_VARY = 1L << 2, // PF_Cmd_GLOBAL_SETUP, PF_Cmd_QUERY_DYNAMIC_FLAGS + PF_OutFlag_RESERVED6 = 1L << 3, + PF_OutFlag_SEQUENCE_DATA_NEEDS_FLATTENING = 1L << 4, // PF_Cmd_GLOBAL_SETUP + PF_OutFlag_I_DO_DIALOG = 1L << 5, // PF_Cmd_GLOBAL_SETUP + PF_OutFlag_USE_OUTPUT_EXTENT = 1L << 6, // PF_Cmd_GLOBAL_SETUP + PF_OutFlag_SEND_DO_DIALOG = 1L << 7, // PF_Cmd_SEQUENCE_SETUP + PF_OutFlag_DISPLAY_ERROR_MESSAGE = 1L << 8, // all PF_Cmds + PF_OutFlag_I_EXPAND_BUFFER = 1L << 9, // PF_Cmd_GLOBAL_SETUP + PF_OutFlag_PIX_INDEPENDENT = 1L << 10, // PF_Cmd_GLOBAL_SETUP, PF_Cmd_QUERY_DYNAMIC_FLAGS + PF_OutFlag_I_WRITE_INPUT_BUFFER = 1L << 11, // PF_Cmd_GLOBAL_SETUP + PF_OutFlag_I_SHRINK_BUFFER = 1L << 12, // PF_Cmd_GLOBAL_SETUP + PF_OutFlag_WORKS_IN_PLACE = 1L << 13, // PF_Cmd_GLOBAL_SETUP + PF_OutFlag_RESERVED8 = 1L << 14, + PF_OutFlag_CUSTOM_UI = 1L << 15, // PF_Cmd_GLOBAL_SETUP + PF_OutFlag_RESERVED7 = 1L << 16, + PF_OutFlag_REFRESH_UI = 1L << 17, // PF_Cmd_EVENT, PF_Cmd_RENDER, PF_Cmd_DO_DIALOG + PF_OutFlag_NOP_RENDER = 1L << 18, // PF_Cmd_GLOBAL_SETUP + PF_OutFlag_I_USE_SHUTTER_ANGLE = 1L << 19, // PF_Cmd_GLOBAL_SETUP, PF_Cmd_QUERY_DYNAMIC_FLAGS + PF_OutFlag_I_USE_AUDIO = 1L << 20, // PF_Cmd_GLOBAL_SETUP + PF_OutFlag_I_AM_OBSOLETE = 1L << 21, // PF_Cmd_GLOBAL_SETUP + PF_OutFlag_FORCE_RERENDER = 1L << 22, // PF_Cmd_EVENT, PF_Cmd_USER_CHANGED_PARAM, PF_Cmd_UPDATE_PARAMS_UI + PF_OutFlag_PiPL_OVERRIDES_OUTDATA_OUTFLAGS = 1L << 23, // PiPL-only-flag + PF_OutFlag_I_HAVE_EXTERNAL_DEPENDENCIES = 1L << 24, // PF_Cmd_GLOBAL_SETUP + PF_OutFlag_DEEP_COLOR_AWARE = 1L << 25, // PF_Cmd_GLOBAL_SETUP + PF_OutFlag_SEND_UPDATE_PARAMS_UI = 1L << 26, // PF_Cmd_GLOBAL_SETUP + + // audio flags (PF_OutFlag_AUDIO_EFFECT_TOO or PF_OutFlag_AUDIO_EFFECT_ONLY required for audio effects) + PF_OutFlag_AUDIO_FLOAT_ONLY = 1L << 27, // PF_Cmd_GLOBAL_SETUP + PF_OutFlag_AUDIO_IIR = 1L << 28, // PF_Cmd_GLOBAL_SETUP + PF_OutFlag_I_SYNTHESIZE_AUDIO = 1L << 29, // PF_Cmd_GLOBAL_SETUP + PF_OutFlag_AUDIO_EFFECT_TOO = 1L << 30, // PF_Cmd_GLOBAL_SETUP + PF_OutFlag_AUDIO_EFFECT_ONLY = 1L << 31 // PF_Cmd_GLOBAL_SETUP +}; +typedef A_long PF_OutFlags; + +enum { + PF_OutFlag2_NONE = 0L, + // which PF_Cmds each flag is relevant for: + PF_OutFlag2_SUPPORTS_QUERY_DYNAMIC_FLAGS = 1L << 0, // PF_Cmd_GLOBAL_SETUP + PF_OutFlag2_I_USE_3D_CAMERA = 1L << 1, // PF_Cmd_GLOBAL_SETUP, PF_Cmd_QUERY_DYNAMIC_FLAGS + PF_OutFlag2_I_USE_3D_LIGHTS = 1L << 2, // PF_Cmd_GLOBAL_SETUP, PF_Cmd_QUERY_DYNAMIC_FLAGS + PF_OutFlag2_PARAM_GROUP_START_COLLAPSED_FLAG= 1L << 3, // PF_Cmd_GLOBAL_SETUP + PF_OutFlag2_I_AM_THREADSAFE = 1L << 4, // PF_Cmd_GLOBAL_SETUP (unused) + PF_OutFlag2_CAN_COMBINE_WITH_DESTINATION = 1L << 5, // Premiere only (as of AE 6.0) + PF_OutFlag2_DOESNT_NEED_EMPTY_PIXELS = 1L << 6, // PF_Cmd_GLOBAL_SETUP, PF_Cmd_QUERY_DYNAMIC_FLAGS + PF_OutFlag2_REVEALS_ZERO_ALPHA = 1L << 7, // PF_Cmd_GLOBAL_SETUP, PF_Cmd_QUERY_DYNAMIC_FLAGS + PF_OutFlag2_PRESERVES_FULLY_OPAQUE_PIXELS = 1L << 8, // Premiere only (as of AE 6.0) + PF_OutFlag2_SUPPORTS_SMART_RENDER = 1L << 10, // PF_Cmd_GLOBAL_SETUP + PF_OutFlag2_RESERVED9 = 1L << 11, // PF_Cmd_GLOBAL_SETUP + PF_OutFlag2_FLOAT_COLOR_AWARE = 1L << 12, // PF_Cmd_GLOBAL_SETUP, may require PF_OutFlag2_SUPPORTS_SMART_RENDER + PF_OutFlag2_I_USE_COLORSPACE_ENUMERATION = 1L << 13, // PF_Cmd_GLOBAL_SETUP, not implemented in AE7 (may be impl in Premiere Pro) + PF_OutFlag2_I_AM_DEPRECATED = 1L << 14, // PF_Cmd_GLOBAL_SETUP + PF_OutFlag2_PPRO_DO_NOT_CLONE_SEQUENCE_DATA_FOR_RENDER = 1L << 15, // PF_Cmd_GLOBAL_SETUP, Premiere only, CS4.1 and later + PF_OutFlag2_RESERVED10 = 1L << 16, // PF_Cmd_GLOBAL_SETUP + PF_OutFlag2_AUTOMATIC_WIDE_TIME_INPUT = 1L << 17, // PF_Cmd_GLOBAL_SETUP, falls back to PF_OutFlag_WIDE_TIME_INPUT if not PF_OutFlag2_SUPPORTS_SMART_RENDER + PF_OutFlag2_I_USE_TIMECODE = 1L << 18, // PF_Cmd_GLOBAL_SETUP + PF_OutFlag2_DEPENDS_ON_UNREFERENCED_MASKS = 1L << 19, // PF_Cmd_GLOBAL_SETUP, PF_Cmd_QUERY_DYNAMIC_FLAGS + PF_OutFlag2_OUTPUT_IS_WATERMARKED = 1L << 20, // PF_Cmd_GLOBAL_SETUP, PF_Cmd_QUERY_DYNAMIC_FLAGS + PF_OutFlag2_I_MIX_GUID_DEPENDENCIES = 1L << 21, // PF_Cmd_GLOBAL_SETUP + PF_OutFlag2_AE13_5_THREADSAFE = 1L << 22, // PF_Cmd_GLOBAL_SETUP (unused) + PF_OutFlag2_SUPPORTS_GET_FLATTENED_SEQUENCE_DATA = 1L << 23, // PF_Cmd_GLOBAL_SETUP, support required if both PF_OutFlag_SEQUENCE_DATA_NEEDS_FLATTENING and PF_OutFlag2_SUPPORTS_THREADED_RENDERING is set + PF_OutFlag2_CUSTOM_UI_ASYNC_MANAGER = 1L << 24, // PF_Cmd_GLOBAL_SETUP + PF_OutFlag2_SUPPORTS_GPU_RENDER_F32 = 1L << 25, // PF_Cmd_GLOBAL_SETUP, PF_Cmd_GPU_DEVICE_SETUP. Must also set PF_RenderOutputFlag_GPU_RENDER_POSSIBLE at pre-render to enable GPU rendering. + PF_OutFlag2_RESERVED12 = 1L << 26, // PF_Cmd_GLOBAL_SETUP + PF_OutFlag2_SUPPORTS_THREADED_RENDERING = 1L << 27, // PF_Cmd_GLOBAL_SETUP + PF_OutFlag2_MUTABLE_RENDER_SEQUENCE_DATA_SLOWER = 1L << 28 // PF_Cmd_GLOBAL_SETUP +}; +typedef A_long PF_OutFlags2; + + +/** -------------------- Input Flags -------------------- + + The in_flags field of the InData can be set to an OR-ed + combination of these flags to communicate various things from AE to an effect plugin + The flags are described here: + + PF_InFlag_NONE + This is the "empty" setting -- no inflags. + + PF_InFlag_PROJECT_IS_RENDER_ONLY (since 13.5) + + For efficiency, if a plugin sets up UI that is not used in render, this flag + can be tested to skip that step when an effect is being RESETUP for render only. + Effect instances with this flag on in RESETUP are in read-only AE projects and will not receive UI related selectors. + + This is an optimization hint. If you don't make such optimizations in render your plugin should still work. + + This flag should generally not be used to suppress errors in render. Errors should still be reported as usual via AE standard mechanisms, + and AE will then handle the differences in context reporting. + + If this is off, UI should be set up normally (and the effect could also be running in an earlier version of + AE that assumed render and UI on the same effect instance.) + +**/ + +enum { + PF_InFlag_NONE = 0L, + PF_InFlag_PROJECT_IS_RENDER_ONLY = 1L << 0 // since 13.5 and only in PF_Cmd_SEQUENCE_RESETUP +}; +typedef A_long PF_InFlags; + + + + + +/** -------------------- Command Selectors -------------------- + + The first parameter to the effect routine is one of t hese command + selectors. The commands are described here. + + PF_Cmd_ABOUT + This command should display an information dialog box about the + effect module. The easiest thing to do is PF_SPRINTF the info + into the out_data->return_msg field. After Effects will bring + up a simple undecorated modal dialog with your text proudly displayed. + This command can be sent at _any_ time, so don't count on having + any global data or anything else set. (Except, as always, the + current resource file will be set to your effects module.) + + PF_Cmd_GLOBAL_SETUP + When you get this command, you should check the version of the + effect protocol with which you are being invoked, and set any of + the necessary out flags (described above) or out data fields + (described below). If your global data was flattened, the flat + data will be passed here and you should unflatten it, free the + flat global data, and set the OutData global_data to the new un-flat + data. Alternatively, the global data may come in NULL and you can + allocate new global data at this time. + + PF_Cmd_GLOBAL_SETDOWN + You should free any global data you have allocated when you get + this command. + + PF_Cmd_PARAMS_SETUP + Here you should add any params your effect wants using the + PF_ADD_PARAM callback described below. This is called after global + setup -- see the add_param callback described below. + + PF_Cmd_SEQUENCE_SETUP + This is called when the effect is first applied to a layer. + A sequence is a series of images that will usually be all be of the same + size and in the same context. You can allocate sequence data + at this time -- many more input fields are defined at this time. + See the PF_InData description below. + + As of 13.5 this only happens on the UI thread. + Except for legacy (no GET_FLATTENED_SEQUENCE_DATA) effects that do I_DO_DIALOG which can still hit this in render. + + PF_Cmd_SEQUENCE_RESETUP + This call is made to unflatten flattened sequence data. + There are at least three cases when this can happen: + 1) after the sequence data is written to disk, 2) after the + sequence data is read in from disk, 3) after a duplicate + is made (called on both original and the new sequence). + + This can happen in UI or Render thread (13.5), the effect must handle + initialization of a NULL sequence_data input if needed. See also PF_InFlag_PROJECT_IS_RENDER_ONLY. + + PF_Cmd_SEQUENCE_FLATTEN + This call is made to flatten unflat sequence data so it can be + cached to disk. After the data is flattened, free the un-flat data + and set the out_data->sequence_data to the new flat data. + If you don't want your sequence handle written to disk, you + can set it to NULL (after disposing it) at this time. Presumably + you would then reallocate it at another time. + + This command will be sent when saving and when duplicating + the sequence. + + PF_Cmd_GET_FLATTENED_SEQUENCE_DATA (new in 13.5) + Returns an independent allocation of the sequence data which can be written + to disk or used to initialise or update other instances of the effect plug-in. + + The host calls this command to serialize the sequence data without + having to flatten and resetup the UI plug-in as was legacy practice. (However, at present effects + still may need flattening in render if the sequence_data is about to be assigned.) + + An effect that implements GET_FLATTENED_SEQUENCE_DATA will only receive SEQUENCE_SETUP on the UI thread. + SEQUENCE_RESETUP can happen on either thread. Make sure you handle a NULL sequence_data in RESETUP. + (Without GET_FLATTENED, a legacy effect may still get SEQUENCE_SETUP in render but DO_DIALOG will not be called.) + + Also when enabled, this means that the effect is guaranteed to get a + SEQUENCE_SETDOWN cmd to dispose the effect's sequence_data (previously + it was possible for AE to bypass this if the sequence_data was flat, + but that lead to SEQUENCE_SETUP/SETDOWN imbalances for some plugins. + The imbalance should not happen when using this flag, but the plugin must + handle being called on SETDOWN with possibly flat data. For example, + try copy and pasting an effect onto itself. + + Support for this command is indicated by setting + PF_OutFlag2_SUPPORTS_GET_FLATTENED_SEQUENCE_DATA + + The ownership of the returned handle is transferred to the host. + + PF_Cmd_SEQUENCE_SETDOWN + You should free any sequence data you have allocated when you + get this command. + + PF_Cmd_DO_DIALOG + This command indicated that the Options button or command has + been selected and the effect should bring up its options dialog. + This command will only be sent it the effect has indicated that + it has an options dialog with PF_OutFlag_I_DO_DIALOG. This + command will automatically be sent once upon applying the filter + if PF_OutFlag_SEND_DO_DIALOG is set in SEQUENCE_SETUP. + + PF_Cmd_FRAME_SETUP + This is called immediately before each frame is invoked. You + can allocate frame data at this time, if you wish, or you can + just wait for the RENDER which will immediately follow. + + PF_Cmd_RENDER + This is the call to render the frame. All fields in the in_data + will be valid at this time and you can inquire parameters or + what-have-you. This should set the output frame with the new + image data. This is the main action command. + + PF_Cmd_FRAME_SETDOWN + If you allocated data in PF_Cmd_FRAME_SETUP, this is the time + to free it and clean up after rendering the frame. + + PF_Cmd_USER_CHANGED_PARAM + This command will be sent if you set the PF_ParamFlag_SUPERVISE + flag for a param. This allows you to modify the params array contents to + control values or make one control affect others, including arbitrary + data. This command will be sent whenever the user interacts with a + standard param controller that has PF_ParamFlag_SUPERVISE + set. + + The "extra" field will be a pointer to a PF_UserChangedParamExtra structure + which contains the param_index of the changed parameter. + + You can return PF_ChangeFlag_CHANGED_VALUE and/or call PF_UpdateParamUI() + for any param. + + PF_Cmd_UPDATE_PARAMS_UI + This command will be sent when the Effect Controls Window (ECW) + needs to updated (e.g. after opening the ECW or moving the comp to + a new time) if you have set PF_OutFlag_SEND_UPDATE_PARAMS_UI at + global setup time. + + This gives you a chance to call PF_UpdateParamUI() to modify certain + ui fields for the params. See the doc for PF_UpdateParamUI() + to see which fields can be modified. + + WARNING: When handling PF_Cmd_UPDATE_PARAMS_UI, you can call + PF_UpdateParamUI() for any param(s), but not PF_ChangeFlag_CHANGED_VALUE -- + only cosmetic changes can be made in response to this command. + + PF_Cmd_QUERY_DYNAMIC_FLAGS + This command will be sent at arbitrary times if PF_OutFlag2_SUPPORTS_QUERY_DYNAMIC_FLAGS + is set during global setup. During this call the effect may examine the values + of its parameters at the current time (except layer parameters) by checking them out, + and decide whether any of the flags that support PF_Cmd_QUERY_DYNAMIC_FLAGS should be set. + + The appropriate flags must be set in out_data->out_flags and out_data->out_flags2 before + returning. The effect must decide what information is necessary to render a frame at + the current time, given only the values of parameters at that time. Clearing the + appropriate bits when possible can result in great performance improvements, but + incorrectly clearing bits will result in caching bugs, and you won't like that. Nope. + +**/ +enum { /* The order of this enumeration must not be altered! */ + PF_Cmd_ABOUT = 0, /* about can be called at any time */ + PF_Cmd_GLOBAL_SETUP, /* check versions, cpu, serial #, etc. always */ + PF_Cmd_UNUSED_0, + PF_Cmd_GLOBAL_SETDOWN, + PF_Cmd_PARAMS_SETUP, /* add parameters here */ + PF_Cmd_SEQUENCE_SETUP, + PF_Cmd_SEQUENCE_RESETUP, /* if part of in_data changed */ + PF_Cmd_SEQUENCE_FLATTEN, /* prepare handle to be written to disk */ + PF_Cmd_SEQUENCE_SETDOWN, + PF_Cmd_DO_DIALOG, /* called after SEQUENCE_SETUP only if effect requests */ + PF_Cmd_FRAME_SETUP, + PF_Cmd_RENDER, + PF_Cmd_FRAME_SETDOWN, + +/* most of these command types make use of the 'extra' field */ + + PF_Cmd_USER_CHANGED_PARAM, /* user just changed a param value, extra contains ptr to PF_UserChangedParamExtra */ + PF_Cmd_UPDATE_PARAMS_UI, /* UI fields in paramdefs need to be refreshed according to new values, no extra info */ + PF_Cmd_EVENT, /* handle some event. extra contains a ptr to a relevant structure */ + PF_Cmd_GET_EXTERNAL_DEPENDENCIES, /* new in AE4.1: return text description of things like fonts, etc. in PF_ExtDependenciesExtra */ + PF_Cmd_COMPLETELY_GENERAL, /* new in AE4.1: Used for completely general effect calls via AEGP */ + + PF_Cmd_QUERY_DYNAMIC_FLAGS, /* new in AE5.0: allows effect to control certain flags based on parameter values */ + + PF_Cmd_AUDIO_RENDER, /* For Audio Effects */ + PF_Cmd_AUDIO_SETUP, + PF_Cmd_AUDIO_SETDOWN, + + PF_Cmd_ARBITRARY_CALLBACK, /* used for arbitrary data, passes PF_ArbParamsExtra * in extra */ + + PF_Cmd_SMART_PRE_RENDER, /* used with Smart Render effect interface */ + PF_Cmd_SMART_RENDER, + + PF_Cmd_RESERVED1, /* private command */ + PF_Cmd_RESERVED2, /* private command */ + PF_Cmd_RESERVED3, /* private command */ + + PF_Cmd_GET_FLATTENED_SEQUENCE_DATA, + PF_Cmd_TRANSLATE_PARAMS_TO_PREFS, + + PF_Cmd_RESERVED4, /* private command */ + PF_Cmd_SMART_RENDER_GPU, /* used when rendering on the GPU */ + PF_Cmd_GPU_DEVICE_SETUP, + PF_Cmd_GPU_DEVICE_SETDOWN, + + PF_Cmd_NUM_CMDS +}; +typedef A_long PF_Cmd; + + +/** -------------------- Simple Types -------------------- +**/ + +typedef struct _PF_LayerAudio *PF_LayerAudio; + +typedef void *PF_SndSamplePtr; + +/* The following is an opaque type you pass to callback routines */ +struct PF_ProgressInfo; +typedef struct PF_ProgressInfo *PF_ProgPtr; + +typedef A_long PF_ParamValue; + +typedef struct { + A_short major; + A_short minor; +} PF_SpecVersion; + +typedef A_long PF_ParamIndex; + +typedef A_u_long PF_UFixed; + +#ifndef A_INTERNAL + + #if defined(_WINDOWS) || defined(__ANDROID__) + + typedef A_long PF_Fixed; + typedef A_char PF_Boolean; + typedef void **PF_Handle; + + typedef struct { + A_short v; + A_short h; + } PF_LegacyPoint; + + typedef struct { + A_short top, left, bottom, right; + } PF_LegacyRect; + + #else + + typedef Fixed PF_Fixed; + typedef Boolean PF_Boolean; + typedef Handle PF_Handle; + + #endif + + typedef struct { + #ifdef LPOINT_RENAME_COMPONENTS + A_long x; + A_long y; + #else + A_long h; + A_long v; + #endif + } PF_Point; + + typedef struct { + A_long left, top, right, bottom; + } PF_LRect; + + typedef PF_LRect PF_Rect; + + typedef PF_Rect PF_UnionableRect; + + typedef struct { + A_long num; /* numerator */ + A_u_long den; /* denominator */ + } PF_RationalScale; + +#endif + +#define PF_Fixed_MINVAL ((PF_Fixed)0x80000000) // Maximally negative value +#define PF_Fixed_MAXVAL ((PF_Fixed)0x7fffffff) // Maximally positive value + + +typedef struct { + PF_Fixed x, y; +} PF_FixedPoint; + +typedef struct { + PF_Fixed left, top, right, bottom; +} PF_FixedRect; + +typedef struct { + PF_Fixed mat[3][3]; +} PF_Matrix; + + +#ifndef A_INTERNAL + + // Basic pixel defn's + typedef struct { + A_u_char alpha, red, green, blue; + } PF_Pixel; + + typedef PF_Pixel PF_Pixel8; + typedef PF_Pixel PF_UnionablePixel; + + typedef struct { + #ifdef PF_PIXEL16_RENAME_COMPONENTS + // this style is useful for debugging code converted from 8 bit + A_u_short alphaSu, redSu, greenSu, blueSu; + #else + A_u_short alpha, red, green, blue; + #endif + } PF_Pixel16; + + typedef A_FpShort PF_FpShort; + typedef A_FpLong PF_FpLong; + + typedef struct { + PF_FpShort alpha, red, green, blue; + } PF_PixelFloat, PF_Pixel32; + + typedef struct { + PF_FpLong mat[3][3]; + } PF_FloatMatrix; + +#endif + + +typedef A_u_long PF_PixLong; + +typedef struct _PF_PixelOpaque *PF_PixelOpaquePtr; + +#ifdef PF_DEEP_COLOR_AWARE + typedef PF_PixelOpaquePtr PF_PixelPtr; +#else + typedef PF_Pixel *PF_PixelPtr; +#endif + + + +#define PF_HUE_UNDEFINED 0x80000000 + +typedef PF_Fixed PF_RGB_Pixel[3]; +typedef PF_Fixed PF_YIQ_Pixel[3]; +typedef PF_Fixed PF_HLS_Pixel[3]; + + + + +/** -------------------- Pixel Access Macros -------------------- + + If you're using the PF_PixLong struct for pixel representation, + you can use these macros to guarantee correct channel access + for a given pixel. + +**/ + +#define PF_PixLong_ALPHA(pl) ((A_u_char)(0xff & ((pl) >> 24))) +#define PF_PixLong_RED(pl) ((A_u_char)(0xff & ((pl) >> 16))) +#define PF_PixLong_GREEN(pl) ((A_u_char)(0xff & ((pl) >> 8))) +#define PF_PixLong_BLUE(pl) ((A_u_char)(0xff & (pl))) + +#define PF_SET_PixLong_ALPHA(pl, v) (pl)&=0x00ffffff, (pl)|=((A_long)(v)<<24) +#define PF_SET_PixLong_RED(pl, v) (pl)&=0xff00ffff, (pl)|=((A_long)(v)<<16) +#define PF_SET_PixLong_GREEN(pl, v) (pl)&=0xffff00ff, (pl)|=((A_long)(v)<<8) +#define PF_SET_PixLong_BLUE(pl, v) (pl)&=0xffffff00, (pl)|=(0xff & (v)) +#define PF_MAKE_PixLong(a, r, g, b) \ + ((PF_PixLong)(((A_long)(a)<<24) | ((A_long)(r)<<16) | ((A_long)(g)<<8) | (b))) + + + +/*********************** multi-channel data *********************/ + +/** + ** the kinds of multichannels we understand + **/ +#define PF_ChannelType_DEPTH 'DPTH' +#define PF_ChannelType_DEPTHAA 'DPAA' // since 16.0 for 3D Precomp in some Artisans +#define PF_ChannelType_NORMALS 'NRML' +#define PF_ChannelType_OBJECTID 'OBID' +#define PF_ChannelType_MOTIONVECTOR 'MTVR' +#define PF_ChannelType_BK_COLOR 'BKCR' +#define PF_ChannelType_TEXTURE 'TEXR' +#define PF_ChannelType_COVERAGE 'COVR' +#define PF_ChannelType_NODE 'NODE' +#define PF_ChannelType_MATERIAL 'MATR' +#define PF_ChannelType_UNCLAMPED 'UNCP' +#define PF_ChannelType_UNKNOWN 'UNKN' + +typedef A_long PF_ChannelType; + + +/** + ** These are the elementary data types we understand. + ** By convention we reserve the last characters of the type + ** to designate the size in bytes of a plane of data. This together + ** with the dimension tells us the size of each pixel. + ** For example, data of PF_ChannelType_COLOR with PF_DataType_DOUBLE would + ** consist of 32 bytes per pixel. + **/ +#define PF_DataType_FLOAT 'FLT4' /* 4 byte */ +#define PF_DataType_DOUBLE 'DBL8' /* 8 byte */ +#define PF_DataType_LONG 'LON4' /* 4 bytes */ +#define PF_DataType_SHORT 'SHT2' /* 2 bytes */ +#define PF_DataType_FIXED_16_16 'FIX4' /* 4 bytes */ +#define PF_DataType_CHAR 'CHR1' /* 1 byte */ +#define PF_DataType_U_BYTE 'UBT1' /* 1 byte */ +#define PF_DataType_U_SHORT 'UST2' /* 2 bytes */ +#define PF_DataType_U_FIXED_16_16 'UFX4' /* 4 bytes */ +#define PF_DataType_RGB 'RBG ' /* 3 bytes */ + +typedef A_long PF_DataType; + + + + + +/** + ** for enumerating over all the channels + **/ +typedef A_long PF_ChannelIndex; + + + + + +/** + ** a description of the channel + ** use this when iterating through channels to determine + ** the characteristics of the channel + ** + **/ +#define PF_CHANNEL_NAME_LEN 63 + +typedef struct { + PF_ChannelType channel_type; + A_char name[PF_CHANNEL_NAME_LEN+1]; + PF_DataType data_type; + A_long dimension; // the number of data per pixel +} PF_ChannelDesc; // eg 3 for normals + + + + + +/** + ** the opaque type representing the channel data + **/ +typedef struct { + A_intptr_t opaque[8]; +} PF_ChannelRef, *PF_ChannelRefPtr; + + + + + + +/** + ** the channel data parallels the image data in size and shape. + ** the width is the number of pixels, the height is the number of scanlines + ** the height is image_height + ** the dimension is the number of planes in a pixel + ** the row_bytes is the length of a scanline in bytes + ** the data type is the type of data in a plane + ** Note : a pixel consists of dimensionL * sizeof(data_type) bytes + ** dataH is a handle to the data. + ** dataPV is a pointer to the dereferenced locked handle + ** effects should always have dataPV non null. + **/ +typedef struct { + PF_ChannelRef channel_ref; + A_long widthL; + A_long heightL; + A_long dimensionL; + A_long row_bytesL; + PF_DataType data_type; + PF_Handle dataH; + void *dataPV; +} PF_ChannelChunk; + + + +/** -------------------- Effect Parameter Description Structures -------------------- + + In general each structure is divided into two parts: + a) description of the parameter + b) setting of parameter at the current invocation time + + A number of these structures end in A_char*, A_char[] unions. These + structures are "flattened" between the add_param callback (in which + the A_char * should be used) and the read-only values accessible when + the effect is later invoked (at which time the A_char [] is used and + the string data is concatenated right at the end of the struct). + +**/ + + +enum { + PF_LayerDefault_MYSELF = -1, /* default to this layer */ + PF_LayerDefault_NONE = 0 /* default to no layer */ +}; + +/** Layer -- PF_Param_LAYER + + Layer parameters represent movie or image layers in the composition. + All effects automatically have 1 layer param, param[0], which is the + layer to which they have been applied. Some effects may have additional + layer parameters to do compound effects or multi-channel effects. If + your effects module has a layer parameter other than the param[0] default, + you will have to call the checkout_param callback to access the contents + of that layer. There is a special case for all layer params (except the + param[0] automatic layer) which is that the user can set them to , + indicating that no layer is selected. The effect can detect this, because + the checkout_param callback will not return an error, but the "data" pointer + in the returned LayerDef struct will be NULL. For the NULL-layers, the + effect should attempt some logical interpretation, like pretending there + is an all alpha-zero layer or perhaps just using param[0]. + +**/ + +#ifndef A_INTERNAL + + + +typedef struct PF_LayerDef { + /* PARAMETER VALUE */ + + void *reserved0; + void *reserved1; + + PF_WorldFlags world_flags; + + PF_PixelPtr data; + + A_long rowbytes; + A_long width; + A_long height; + PF_UnionableRect extent_hint; + /* For source, extent_hint is the smallest rect encompassing all opaque + * (non-zero alpha) areas of the layer. For output, this encompasses + * the area that needs to be rendered (i.e. not covered by other layers, + * needs refreshing, etc.). if your plug-in varies based on extent (like + * a diffusion dither, for example) you should ignore this param and + * render the full frame each time. + */ + void *platform_ref; /* unused since CS5 */ + + A_long reserved_long1; + + void *reserved_long4; + + PF_RationalScale pix_aspect_ratio; /* pixel aspect ratio of checked out layer */ + + void *reserved_long2; + + A_long origin_x; /* origin of buffer in layer coords; smart effect checkouts only */ + A_long origin_y; + + A_long reserved_long3; + + /* PARAMETER DESCRIPTION */ + A_long dephault; /* use a PF_LayerDefault constant defined above */ + +} PF_LayerDef; + + + +typedef PF_LayerDef PF_EffectWorld; + +#endif + +#ifdef PF_USE_OLD_WORLD /* set this for source code compatibility with older effects */ + typedef PF_EffectWorld PF_World; +#endif + +enum { + PF_UNSIGNED_PCM = 0, + PF_SIGNED_PCM = 1, + PF_SIGNED_FLOAT = 2 +}; +typedef A_short PF_SoundFormat; + + +// Sound encoding is always SIGNED +enum { + PF_SSS_1 = 1, + PF_SSS_2 = 2, + PF_SSS_4 = 4 +}; +typedef A_short PF_SoundSampleSize; // in bytes + +enum { + PF_Channels_MONO = 1, + PF_Channels_STEREO = 2 +}; +typedef A_short PF_SoundChannels; + + +typedef struct { + PF_FpLong rateF; + PF_SoundChannels num_channels; + PF_SoundFormat format; + PF_SoundSampleSize sample_size; +} PF_SoundFormatInfo; + +typedef struct { + PF_SoundFormatInfo fi; + A_long num_samples; + void *dataP; +} PF_SoundWorld; + + + +enum { + PF_ValueDisplayFlag_NONE = 0, + PF_ValueDisplayFlag_PERCENT = 1 << 0, // append % to value display for A_FpShort sliders (for fixed-point sliders, also maps range into 0-100%) + PF_ValueDisplayFlag_PIXEL = 1 << 1, // assume 0..1 is a pixel value, either 0..255, 0..32768, or 0..1.0 in UI (value will always be 0..1), + PF_ValueDisplayFlag_RESERVED1 = 1 << 2, // reserved for After Effects + PF_ValueDisplayFlag_REVERSE = 1 << 3 // presentation negates values. eg: a true -5 would be presented as "5", and typing in "22" would store in the model as -22 +}; + +#define PF_VALUEFLAG_IS_PERCENT(A) (((A) & PF_ValueDisplayFlag_PERCENT) != 0) +#define PF_VALUEFLAG_IS_PIXEL(A) (((A) & PF_ValueDisplayFlag_PIXEL) != 0) +#define PF_VALUEFLAG_IS_REVERSED(A) (((A) & PF_ValueDisplayFlag_REVERSE) != 0) + +typedef A_short PF_ValueDisplayFlags; + + +/** Slider -- PF_Param_SLIDER +**/ +typedef struct { + /* PARAMETER VALUE */ + PF_ParamValue value; + A_char value_str[PF_MAX_PARAM_VALUE_LEN + 1]; /* string for value */ + A_char value_desc[PF_MAX_PARAM_DESCRIPTION_LEN + 1]; /* qualitative descr */ + + /* PARAMETER DESCRIPTION */ + PF_ParamValue valid_min, valid_max; /* acceptable input range */ + PF_ParamValue slider_min, slider_max; /* range represented by width of slider */ + PF_ParamValue dephault; +} PF_SliderDef; + + +/** Fixed Point Slider -- PF_Param_FIX_SLIDER +**/ +typedef struct { + /* PARAMETER VALUE */ + PF_Fixed value; + A_char value_str[PF_MAX_PARAM_VALUE_LEN + 1]; /* string for value */ + A_char value_desc[PF_MAX_PARAM_DESCRIPTION_LEN + 1]; /* qualitative descr */ + + /* PARAMETER DESCRIPTION */ + PF_Fixed valid_min, valid_max; /* acceptable input range */ + PF_Fixed slider_min, slider_max; /* range represented by width of slider */ + PF_Fixed dephault; + A_short precision; /* decimal places to display */ + PF_ValueDisplayFlags display_flags; /* set bit to 1 to enable special display: + * --> bit 0 == append percent sign + */ +} PF_FixedSliderDef; + + +#define AEFX_AUDIO_DEFAULT_CURVE_TOLERANCE 0.05f + + +enum { + PF_FSliderFlag_NONE = 0, + PF_FSliderFlag_WANT_PHASE = 1L << 0 /* works for audio effects only */ +}; +typedef A_u_long PF_FSliderFlags; + +/** Floating Point Slider -- PF_Param_FLOAT_SLIDER +**/ +typedef struct { + /* PARAMETER VALUE */ + PF_FpLong value; + PF_FpLong phase; /* used for PF_FSliderFlag_WANT_PHASE */ + A_char value_desc[PF_MAX_PARAM_DESCRIPTION_LEN + 1]; /* qualitative descr */ + + /* PARAMETER DESCRIPTION */ + PF_FpShort valid_min, valid_max; /* acceptable input range */ + PF_FpShort slider_min, slider_max; /* range represented by width of slider */ + PF_FpShort dephault; + A_short precision; /* decimal places to display */ + PF_ValueDisplayFlags display_flags; /* set bit to 1 to enable special display: + * --> bit 0 == append percent sign + */ + PF_FSliderFlags fs_flags; + PF_FpShort curve_tolerance; /* used for subdividing audio effects + set to zero for default, or non-audio */ + + /* next 2 fields are used in Premiere Pro and ignored in AE */ + PF_Boolean useExponent; /* use exponential value display */ + PF_FpShort exponent; /* typical values from 0.01 to 100 */ +} PF_FloatSliderDef; + + +/** Angle -- PF_Param_ANGLE +**/ +typedef struct { + /* PARAMETER VALUE */ + PF_Fixed value; /* degrees with fixed point accuracy; + * this is NOT limited in range to 0 to 360. + */ + + /* PARAMETER DESCRIPTION */ + PF_Fixed dephault; + + /* Min and max values. Note!! Not supported for effect plugins. + ** Angle properties in effects are always unlimited in range. + */ + PF_Fixed valid_min, valid_max; +} PF_AngleDef; + + +/** CheckBox -- PF_Param_CHECKBOX +**/ +typedef struct { + /* PARAMETER VALUE */ + PF_ParamValue value; + + /* PARAMETER DESCRIPTION */ + PF_Boolean dephault; + A_char reserved; /* padding */ + A_short reserved1; + union { + const A_char *nameptr; + } u; +} PF_CheckBoxDef; + + +/** Color -- PF_Param_COLOR +**/ +typedef struct { + /* PARAMETER VALUE */ + PF_UnionablePixel value; + + /* PARAMETER DESCRIPTION */ + PF_UnionablePixel dephault; +} PF_ColorDef; + + +/** Point -- PF_Param_POINT + + The values for the point use the source's coordinate system, with the + origin at the top left. The values are expressed in fixed point, with + 16 bits of fractional precision (out of a total of 32 bits). + + The dephaults (sorry) are expressed as percentages (with 16 bits of + fraction) with the origin at the top left. The percent can be negative, + but should not be smaller than -600%. It should not be greater than 600%. + + If restrict_bounds is TRUE, the user will not be allowed to specify + points outside the bounds of the layer to which they are applying the + effect. If this is TRUE, the dephaults should be between 0.0 and 100.0. + +**/ +typedef struct { + /* PARAMETER VALUE */ + PF_Fixed x_value; + PF_Fixed y_value; + + /* PARAMETER DESCRIPTION */ + A_char reserved[3]; + PF_Boolean restrict_bounds; /* restrict bounds to size of src */ + PF_Fixed x_dephault; /* percentage */ + PF_Fixed y_dephault; /* percentage */ +} PF_PointDef; + + +/** 3D Point -- PF_Param_POINT_3D + + Just like POINT, with an extra dimension. Supported in AE starting with version 10.5 (CS 5.5). + +**/ +typedef struct { + /* PARAMETER VALUE */ + PF_FpLong x_value; + PF_FpLong y_value; + PF_FpLong z_value; + + /* PARAMETER DESCRIPTION */ + PF_FpLong x_dephault; /* percentage of layer width; note: use 50 for halfway, not 0.5; this matches the old PF_PointDef behavior */ + PF_FpLong y_dephault; /* percentage of layer height */ + PF_FpLong z_dephault; /* percentage of layer _height_ (since typical layers are zero depth) */ + + char reserved[16]; /* set to zeros */ +} PF_Point3DDef; + +/** Popup Menu -- PF_Param_POPUP + ** + ** can also be used as a radio-button group in some hosts + ** when PF_PUI_RADIO_BUTTON is set + ** + **/ +typedef struct { + /* PARAMETER VALUE */ + PF_ParamValue value; + + /* PARAMETER DESCRIPTION */ + A_short num_choices; + A_short dephault; + union { + const A_char *namesptr; /* menu manager standard, '|' separator */ + } u; +} PF_PopupDef; + + +/** Momentary Buttons -- PF_Param_BUTTON + ** + ** supported by AE starting with CS 5.5 (AE 10.5); may be supported in other hosts + ** + **/ +typedef struct { + /* PARAMETER VALUE */ + PF_ParamValue value; // not used at this time + + union { + const A_char *namesptr; /* button name */ + } u; +} PF_ButtonDef; + + + + +enum { + PF_PathID_NONE = 0 +}; +typedef A_u_long PF_PathID; + + +enum { + PF_MaskMode_NONE = 0, // mask shape does nothing + PF_MaskMode_ADD, // shape is added into mask (normal behavior (really screen!)) + PF_MaskMode_SUBTRACT, + PF_MaskMode_INTERSECT, + PF_MaskMode_LIGHTEN, + PF_MaskMode_DARKEN, + PF_MaskMode_DIFFERENCE, + PF_MaskMode_ACCUM, // real add, not screen (not exposed in UI!) + + PF_NUM_MASKMODES +}; +#define PF_NUM_USER_MASKMODES (PF_NUM_MASKMODES - 1) +typedef A_long PF_MaskMode; + + + +/** Path -- PF_Param_PATH + + Path parameters give access to the mask/path/shapes of the layer on which + the effect is applied. For more information + on how to use these paths, see the PF_PathQuerySuite, and the PF_PathDataSuite + in AE_EffectSuites.h + +**/ +typedef struct PF_PathDef { + + /* PARAMETER VALUE */ + PF_PathID path_id; /* to be used with PF_CheckoutPath() + note that path_id != PF_PathID_NONE does not + guarantee that PF_CheckoutPath will return a + valid path (it may have been deleted) */ + + /* PARAMETER DESCRIPTION */ + A_long reserved0; /* not currently used, set to zero */ + + A_long dephault; /* 0 means that the default is NONE, + other numbers are the 1-based index of the + path, if the path doesn't exist, the + path_idLu value will be PF_PathID_NONE. + */ +} PF_PathDef; + + +/* --------------------- ARBITRARY DATA ----------------------------------- + * new arbitrary data type - you supply functions for various activities + * needed by After Effects to manipulate your arbitrary data. + */ + +typedef PF_Handle PF_ArbitraryH; + + +typedef struct { + A_short id; /* for effect use: lets effect distinguish between */ + /* different arbitrary data param types in the same effect */ + A_short pad; /* padding, set to zero */ + PF_ArbitraryH dephault; /* becomes owned by host at ADD_PARAM time */ + PF_ArbitraryH value; /* pass NULL at ADD_PARAM time; owned by host at render time */ + void *refconPV; /* passed into all callbacks, for effect use */ +} PF_ArbitraryDef; + + + +enum { + PF_Arbitrary_NEW_FUNC = 0, + PF_Arbitrary_DISPOSE_FUNC, + PF_Arbitrary_COPY_FUNC, + PF_Arbitrary_FLAT_SIZE_FUNC, + PF_Arbitrary_FLATTEN_FUNC, + PF_Arbitrary_UNFLATTEN_FUNC, + PF_Arbitrary_INTERP_FUNC, + PF_Arbitrary_COMPARE_FUNC, + PF_Arbitrary_PRINT_SIZE_FUNC, + PF_Arbitrary_PRINT_FUNC, + PF_Arbitrary_SCAN_FUNC +}; +typedef A_long PF_FunctionSelector; + + + +enum { + PF_ArbCompare_EQUAL = 0, + PF_ArbCompare_LESS, + PF_ArbCompare_MORE, + PF_ArbCompare_NOT_EQUAL +}; +typedef A_long PF_ArbCompareResult; + + +enum { + PF_ArbPrint_NONE = 0, + PF_ArbPrint_ABBREVIATED = 1 << 0 +}; +typedef A_long PF_ArbPrintFlags; + + + +/* this is what gets passed in the extra parameter with + * PF_Cmd_ARBITRARY_CALLBACKS + */ +typedef struct { + + PF_FunctionSelector which_function; + + A_short id; + A_short padding; + + union { + + /* PF_Arbitrary_NEW_FUNC + * + * allocate and initialize the data + * the passed in parameter,v, will already have its non data fields filled in + * you just allocate and optionally fill out the data. + */ + struct { + void *refconPV; /* >> */ + PF_ArbitraryH *arbPH; /* << */ + } new_func_params; + + + + /* PF_Arbitrary_DISPOSE_FUNC + * + * dispose of any allocated data + */ + struct { + void *refconPV; + PF_ArbitraryH arbH; + } dispose_func_params; + + + + /* PF_Arbitrary_COPY_FUNC + * + * make a copy of src_dataP into dst_dataP. refconPV was assigned from parameter def. + */ + struct { + void *refconPV; + PF_ArbitraryH src_arbH; + PF_ArbitraryH *dst_arbPH; /* << allocated by copy func, owned by caller */ + } copy_func_params; + + + + /* PF_Arbitrary_FLAT_SIZE_FUNC + * + * return in flat_data_sizePLu the number of bytes that are needed to flatten the object. + */ + struct { + void *refconPV; + PF_ArbitraryH arbH; + A_u_long *flat_data_sizePLu; /* << */ + } flat_size_func_params; + + + + /* PF_Arbitrary_FLATTEN_FUNC + * + * Flatten the arbH and place it into the supplied buffer, honoring its size. + */ + struct { + void *refconPV; + PF_ArbitraryH arbH; + A_u_long buf_sizeLu; // size of buffer + void *flat_dataPV; // buffer already allocated + } flatten_func_params; + + + + /* PF_Arbitrary_UNFLATTEN_FUNC + * + * opposite of FlattenFunc, unpack the buffer into a PF_ArbitraryH. + */ + struct { + void *refconPV; + A_u_long buf_sizeLu; /* size of buffer */ + const void *flat_dataPV; /* >> */ + PF_ArbitraryH *arbPH; /* << */ // owned by caller + } unflatten_func_params; + + + + /* PF_Arbitrary_INTERP_FUNC + * + * The interpolation function takes a left and a right keyframe and a value between + * 0 and 1, 0 being the left keyframe, 1 represents the right keyframe. + * allocate PF_ArbitraryH and fill it with interpolated data. + * The velocity curves have already been accounted for when the normalized time value was + * calculated. + */ + struct { + void *refconPV; + PF_ArbitraryH left_arbH; /* >> */ // left keyframe + PF_ArbitraryH right_arbH; /* >> */ // right keyframe + PF_FpLong tF; /* >> */ // range [0,1] + PF_ArbitraryH *interpPH; /* << */ // becomes owned by caller + } interp_func_params; + + + /* PF_Arbitrary_COMPARE_FUNC + * + * compare two arbitrary data types for equality + * return 0 if equal, otherwise return 1 in comparePL + */ + struct { + void *refconPV; + PF_ArbitraryH a_arbH; /* >> */ // value 1 + PF_ArbitraryH b_arbH; /* >> */ // value 2 + PF_ArbCompareResult *compareP; /* << */ // result of compare use enumeration above + } compare_func_params; + + + + /* PF_Arbitrary_PRINT_SIZE_FUNC + * + * return in print_sizePLu the number of bytes that are needed to print the object. + */ + struct { + void *refconPV; + PF_ArbitraryH arbH; /* >> */ // the data + A_u_long *print_sizePLu; /* << */ // size of buffer needed to print + } print_size_func_params; + + + /* PF_Arbitrary_PRINT_FUNC + * + * return in buff a user-readable description of your arb data + */ + struct { + void *refconPV; /* >> */ + PF_ArbPrintFlags print_flags; /* >> */ // PF_ArbPrint_NONE means print the complete description + PF_ArbitraryH arbH; /* >> */ + A_u_long print_sizeLu; /* >> */ // size of buffer + A_char *print_bufferPC; /* << */ + } print_func_params; + + + + /* PF_Arbitrary_SCAN_FUNC + * + * return a PF_ArbitraryH from the text description of your arb data + */ + struct { + void *refconPV; /* >> */ + const A_char *bufPC; /* >> */ + A_u_long bytes_to_scanLu; /* >> */ + PF_ArbitraryH *arbPH; /* << */ + } scan_func_params; + + } u; + +} PF_ArbParamsExtra; + + +typedef struct { + PF_ParamIndex param_index; +} PF_UserChangedParamExtra; // passed as extra for PF_Cmd_USER_CHANGED_PARAM + + +/* The following is an opaque type you pass to PF_Cmd_TRANSLATE_PARAMS_TO_PREFS */ +typedef struct PF_ImporterPrefsData *PF_ImporterPrefsDataPtr; + +/* prefsPC is a pointer to an importer opaque data (prefs) that coincides + * with its matching importer. It's an in/out param. The host owns it, + * but the filter will modify it. + * prefs_sizeLU is the size of the prefs object pointed to. + * This is part of a Premiere Pro feature that requires a matching Importer/Source Settings effect + * and will only be used in that particular case. + */ +typedef struct { + PF_ImporterPrefsDataPtr prefsPC; + A_u_long prefs_sizeLu; +} PF_TranslateParamsToPrefsExtra; // passed as extra for PF_Cmd_TRANSLATE_PARAMS_TO_PREFS + + +enum { + PF_DepCheckType_NONE = 0, + PF_DepCheckType_ALL_DEPENDENCIES, + PF_DepCheckType_MISSING_DEPENDENCIES +}; +typedef A_long PF_DepCheckType; + +typedef struct { + PF_DepCheckType check_type; /* >> */ // effect should ignore any unknown type + PF_Handle dependencies_strH; /* << */ // NULL terminated string. Flat and disposed of by the host +} PF_ExtDependenciesExtra; + + +#ifdef PREMIERE_INTERNAL + #include "PF_Private_Premiere.h" +#else + + +typedef union { + PF_LayerDef ld; + PF_SliderDef sd; + PF_FixedSliderDef fd; + PF_AngleDef ad; + PF_CheckBoxDef bd; + PF_ColorDef cd; + PF_PointDef td; + PF_PopupDef pd; + PF_FloatSliderDef fs_d; + PF_ArbitraryDef arb_d; + PF_PathDef path_d; + PF_ButtonDef button_d; + PF_Point3DDef point3d_d; +} PF_ParamDefUnion; + +#endif + +/** Param UI Flags + + PF_PUI_TOPIC + + Set this flag if you handle PF_Cmd_EVENTs for the "topic" of + the parameter. The "topic" is the portion of the param UI + in the Effect Controls Window (ECW) that is still visible + when the twirly-arrow is twirled up for that param. + + If you set this flag, you must also set PF_OutFlag_CUSTOM_UI + at PF_Cmd_GLOBAL_SETUP time. + + PF_PUI_CONTROL + + Set this flag if you handle PF_Cmd_EVENTs for the control + area in the ECW. This is the area that becomes invisible + when you twirl up a parameter's twirly arrow (and is the + usual place to have your custom UI). + + If you set this flag, you must also set PF_OutFlag_CUSTOM_UI + at PF_Cmd_GLOBAL_SETUP time. + + PF_PUI_STD_CONTROL_ONLY + + Set this flag if you want the standard control only -- no + data stream will be associated with this parameter, and + thus no keyframes (nothing appears in the Time Layout window + for this type of param). + + You might want to do this to control something in your + sequence data with a standard control. Or in your arb + data, or custom UI in the comp window, or to group-set multiple + other controls. + + + This flag can be used with these param types: + PF_Param_SLIDER, PF_Param_FIX_SLIDER, PF_Param_ANGLE, + PF_Param_CHECKBOX, PF_Param_COLOR, PF_Param_POINT, + PF_Param_POPUP, PF_Param_FLOAT_SLIDER, PF_Param_POINT_3D + + but NOT: + + PF_Param_CUSTOM, PF_Param_NO_DATA, + PF_Param_LAYER, PF_Param_ARBITRARY_DATA, PF_Param_PATH + + If you set this flag, you must also set PF_ParamFlag_SUPERVISE + (otherwise you would never find out about value changes, and + the setting would never be used for anything). This flag + does not require the setting of PF_OutFlag_CUSTOM_UI. + + If you want a standard control for PF_Param_ARBITRARY_DATA, + just add one (or more) using PF_PUI_STD_CONTROL_ONLY with + the supported param types, and then when handling + PF_Cmd_USER_CHANGED_PARAM you can modify your arb data. + + + PF_PUI_NO_ECW_UI + + Set this flag if you want no UI to appear in the Effect Controls + Window. Presumably, you are setting the value of the parameter + through some other method (e.g. custom UI in the comp window, + or while handling PF_Cmd_USER_CHANGED_PARAM for a different param with + PF_ParamFlag_SUPERVISE set). In AE, this doesn't affect keyframe + visibility in the timeline. In PPro it does remove the entire row, + so you won't see keyframes. + + PF_PUI_ECW_SEPARATOR + + Set this flag if you'd like a thick line above this parameter + in the effect control window. This is provided so that parameters + can be grouped visually, if needed (without adding groups). + This flag can be changed at runtime through the PF_UpdateParamUI() + method. Not used by AE. + + PF_PUI_INVISIBLE + + Set this flag if you'd like the parameter to be initially invisible. This is useful + if your effect needs hidden data parameters that affect rendering. + + Premiere only: The parameter can later be made visible by clearing the flag + during the PF_UpdateParamUI() callback. + +**/ + +enum { + PF_PUI_NONE = 0, + PF_PUI_TOPIC = 1L << 0, // effect has custom UI and wants events for this params' title (portion visible when twirled up) + PF_PUI_CONTROL = 1L << 1, // effect has custom UI and wants events for this params' control (portion invisible when twirled up) + // use the width and height below + + // following flags are new in AE 4.0 + + PF_PUI_STD_CONTROL_ONLY = 1L << 2, // param will be used as UI only, no data (new in AE 4.0) */ + PF_PUI_NO_ECW_UI = 1L << 3, // stop param from appearing in Effect Controls (which in PPro also means you won't see a keyframe track there) + PF_PUI_ECW_SEPARATOR = 1L << 4, // draw a thick separating line above this param; not used by AE + PF_PUI_DISABLED = 1L << 5, // disable (gray-out) UI for this param + + // following flags are new in AE 4.1 + + // AE will not erase the ECW topic, it's up to the FX to erase/draw every pixel. + // Handy if FX author implements an offscreen, prevents flashing. + PF_PUI_DONT_ERASE_TOPIC = 1L << 6, + PF_PUI_DONT_ERASE_CONTROL = 1L << 7, + + PF_PUI_RADIO_BUTTON = 1L << 8, // display as a radio-button group; only valid for PF_Param_POPUP; ignored by AE + + PF_PUI_INVISIBLE = 1L << 9 // in AE as of CS6, this hides the parameter UI in both the Effect Controls and Timeline. + // in Premiere since earlier than that, this hides the parameter UI in the Effect Controls, + // which includes the keyframe track; for PPro only, the flag is dynamic and can be cleared + // to make the parameter visible again. +}; +typedef A_long PF_ParamUIFlags; + +/** PF_ChangeFlags + + New in AE 4.0 (although PF_ChangeFlag_CHANGED_VALUE was implemented + by setting low bit of old changed field). + + PF_ChangeFlag_CHANGED_VALUE + + Set this flag for each param whose value you change when handling + a PF_Cmd_USER_CHANGED_PARAM or specific PF_Cmd_EVENT events + (PF_Event_DO_CLICK, PF_Event_DRAG, & PF_Event_KEYDOWN). If set during + PF_Cmd_EVENT, but sure to also set PF_EO_HANDLED_EVENT before returning. + You can change as many params as you want at once. These changes are undoable and + re-doable by the user. Exception: do not set PF_PUI_STD_CONTROL_ONLY + param values with this flag, use PF_UpdateParamUI() instead. + + PF_ChangeFlag_SET_TO_VARY + + Not yet implemented. Same restrictions as PF_ChangeFlag_CHANGED_VALUE. + + PF_ChangeFlag_SET_TO_CONSTANT + + Not yet implemented. Same restrictions as PF_ChangeFlag_CHANGED_VALUE. + +**/ + +enum { + PF_ChangeFlag_NONE = 0, + PF_ChangeFlag_CHANGED_VALUE = 1L << 0, + PF_ChangeFlag_RESERVED = 1L << 1, + PF_ChangeFlag_SET_TO_VARY = 1L << 2, + PF_ChangeFlag_SET_TO_CONSTANT = 1L << 3 +}; +typedef A_long PF_ChangeFlags; + + +/** ParamDef +**/ +typedef struct { + /* PARAMETER VALUE */ + union { + A_long id; // used by PF_ADD_PARAM callback, see doc + PF_ChangeFlags change_flags; // set when handling PF_Cmd_USER_CHANGED_PARAM & PF_Cmd_UPDATE_PARAMS_UI + } uu; + + PF_ParamUIFlags ui_flags; + A_short ui_width; /* ignored if !PF_PUI_CONTROL */ + A_short ui_height; /* ignored if !PF_PUI_CONTROL */ + + /* PARAMETER DESCRIPTION */ + PF_ParamType param_type; + A_char name[PF_MAX_EFFECT_PARAM_NAME_LEN + 1]; + PF_ParamFlags flags; + + A_long unused; // Once upon a time was reserved_tdb + PF_ParamDefUnion u; + +} PF_ParamDef, *PF_ParamDefPtr, **PF_ParamDefH; + +typedef PF_ParamDef** PF_ParamList; + +#define PF_ParamDef_IS_PUI_FLAG_SET(_defP, _puiFlag) \ + (((_defP)->ui_flags & _puiFlag) != 0) + +#define PF_ParamDef_IS_PARAM_FLAG_SET(_defP, _paramFlag) \ + (((_defP)->flags & _paramFlag) != 0) + + + + /** -------------------- Smart Render Interface Constants and Structures -------------------- + + PF_Cmd_SMART_PRE_RENDER gets a PF_PreRenderExtra struct in the extra pointer, and must + fill out the "output" field before returning. + + PF_Cmd_SMART_RENDER gets a PF_SmartRenderExtra struct in the extra pointer, if pre-render was invoked. + + */ + + enum { + PF_ChannelMask_ALPHA = 0x1, + PF_ChannelMask_RED = 0x2, + PF_ChannelMask_GREEN = 0x4, + PF_ChannelMask_BLUE = 0x8, + PF_ChannelMask_ARGB = 0xF + }; + typedef A_long PF_ChannelMask; + + enum { + PF_GPU_Framework_NONE = 0, + PF_GPU_Framework_OPENCL, + PF_GPU_Framework_METAL, + PF_GPU_Framework_CUDA, + }; + typedef A_long PF_GPU_Framework; + + typedef struct { + PF_LRect rect; + PF_Field field; + PF_ChannelMask channel_mask; + PF_Boolean preserve_rgb_of_zero_alpha; // whether the effect should attempt to preserve RGB when A=0 + char unused[3]; // keep this zeroed! + A_long reserved[4]; // this too + } PF_RenderRequest; + + typedef struct { + PF_RenderRequest output_request; // what the effect is being asked to render + short bitdepth; // bitdepth the effect is being driven in (in bpc) + const void *gpu_data; + PF_GPU_Framework what_gpu; + A_u_long device_index; + } PF_PreRenderInput; + + typedef void (*PF_DeletePreRenderDataFunc)(void *pre_render_data); + + + enum { + PF_RenderOutputFlag_RETURNS_EXTRA_PIXELS = 0x1, // if it's just as cheap to compute more pixels at once, set this to allow result > request rect + PF_RenderOutputFlag_GPU_RENDER_POSSIBLE = 0x2 // if the GPU render is possible given the params and frame render context + }; + typedef short PF_RenderOutputFlags; + + typedef struct { + PF_LRect result_rect; // the rectangle actually available from this request (can be empty) + PF_LRect max_result_rect; // the maximum size the output could possibly be, if AE asked for all of it + // (this must not vary depending on requested output size!) + + PF_Boolean solid; // optimization hint; set this if there is full alpha at every pixel in the result rect + PF_Boolean reserved; + PF_RenderOutputFlags flags; // RETURNS_EXTRA_PIXELS, other things later + + void* pre_render_data; // will be passed back to render + PF_DeletePreRenderDataFunc delete_pre_render_data_func; // and eventually passed to this function for deletion, if set + + } PF_PreRenderOutput; + +typedef struct { + PF_LRect result_rect; // the rectangle actually available from this request (can be empty) + PF_LRect max_result_rect; // the maximum size the output could possibly be, if AE asked for all of it + PF_RationalScale par; // aspect ratio of pixels + PF_Boolean solid; // boolean; true if result has full alpha throughout result rect + PF_Boolean reservedB[3]; + A_long ref_width; // original size of layer, pre-effects (without DSF, comp size for collapsed layers) + A_long ref_height; + A_long reserved[6]; + } PF_CheckoutResult; + + + typedef struct { + + PF_Err (*checkout_layer)( + PF_ProgPtr effect_ref, // reference from in_data + PF_ParamIndex index, // 0 = input, 1..n = param + A_long checkout_idL, // chosen by effect, must be >=0 and unique + const PF_RenderRequest *req, + A_long what_time, + A_long time_step, + A_u_long time_scale, + PF_CheckoutResult *checkout_result); // out + + PF_Err (*GuidMixInPtr)( + PF_ProgPtr effect_ref, // reference from in_data + //const PF_RenderRequest *req, + A_u_long buf_sizeLu, /* >> size of buffer to mix into guid */ + const void *buf ); + + } PF_PreRenderCallbacks; + + // This is passed as the extra parameter to PF_Cmd_PRE_RENDER when an effect is using the pre-render interface. + // Effect must fill out output. + typedef struct { + PF_PreRenderInput *input; + PF_PreRenderOutput *output; + PF_PreRenderCallbacks *cb; + } PF_PreRenderExtra; + + typedef struct { + PF_RenderRequest output_request; // what the effect is being asked to render + short bitdepth; // bitdepth the effect is being driven in (in bpc) + void *pre_render_data;// passed back from value placed in extra->output->pre_render_data during PF_Cmd_PRE_RENDER + const void *gpu_data; + PF_GPU_Framework what_gpu; + A_u_long device_index; // For use in conjunction with PrSDKGPUDeviceSuite + } PF_SmartRenderInput; + + typedef struct { + + PF_Err (*checkout_layer_pixels)( + PF_ProgPtr effect_ref, // reference from in_data + A_long checkout_idL, // passed during checkout_layer + PF_EffectWorld **pixels); // out, valid for duration of current command or until checked in + + PF_Err (*checkin_layer_pixels)( // not strictly necessary to call, but useful to free up memory early + PF_ProgPtr effect_ref, + A_long checkout_idL); + + PF_Err (*checkout_output)( + PF_ProgPtr effect_ref, // reference from in_data + PF_EffectWorld **output); // out + + } PF_SmartRenderCallbacks; + + // Passed as extra param during PF_Cmd_SMART_RENDER + typedef struct { + PF_SmartRenderInput *input; + PF_SmartRenderCallbacks *cb; + } PF_SmartRenderExtra; + + + /** -------------------- GPU Setup/Setdown Constants and Structures -------------------- + + PF_Cmd_GPU_DEVICE_SETUP gets a PF_GPUDeviceSetupExtra struct in the extra pointer. + + PF_Cmd_GPU_DEVICE_SETDOWN gets a PF_GPUDeviceSetdownExtra struct in the extra pointer. + + */ + + + typedef struct { + PF_GPU_Framework what_gpu; + A_u_long device_index; // For use in conjunction with PrSDKGPUDeviceSuite + } PF_GPUDeviceSetupInput; + + typedef struct { + void *gpu_data; // effect owned pointer. + } PF_GPUDeviceSetupOutput; + + typedef struct { + PF_GPUDeviceSetupInput *input; + PF_GPUDeviceSetupOutput *output; + } PF_GPUDeviceSetupExtra; + + + + typedef struct { + void *gpu_data; // effect must dispose. + PF_GPU_Framework what_gpu; + A_u_long device_index; // For use in conjunction with PrSDKGPUDeviceSuite + } PF_GPUDeviceSetdownInput; + + typedef struct { + PF_GPUDeviceSetdownInput *input; + } PF_GPUDeviceSetdownExtra; + + + +/** -------------------- Interaction Callbacks -------------------- + + Effects modules use callbacks to define their parameters. When invoked, + they will be given the parameters values at the particular invocation + moment, but some effects may need to ask for the parameter values at + other times (notably of layer parameters for, say, a visual echo). + + While running, effects modules are responsible for checking for user + interrupts. This checking can be done with either the abort callback, + which will return a value indicating if the user has taken any action, + or with the progress callback, which performs user interrupt checking + just like the abort callback, and also displays a progress display. + + At the bottom of this section are macros for accessing these callback + routines. The first parameter to each macro is a pointer to a PF_InData + structure, defined below. This pointer will be passed to your effect. + + checkout_param + The checkout_param callback allows you to inquire param values at times + other than the current one, and allows you to access layer params other + than the default input layer and the output layer. See the notes on the + "params" structure at the end of this file. The PF_ParamDef you must + specify cannot point into the "params" array; the memory must exist else- + where, such as on the stack. + + If you checkout a layer parameter and the layer popup is currently set + to , the return value will be filled with zeros. You can check + the "data" pointer. If it is NULL, then the layer param is set to + and you should do something like faking an all alpha zero layer or some + such nonsense. IMPORTANT: Due to 13.5 threading changes, checking out + a layer param that is not inside of UPDATE_PARAMS_UI will return + a frame with black pixels to avoid render requests and possible deadlock. + In other selectors the actual render will be triggered as it did before. + + checkin_param + When you have called checkout_param, you must call checkin_param when you + are done, so After Effects can clean up after itself and you. This is + very important for smooth functioning and also to save memory where possible. + Once checked in, the fields in the PF_ParamDef will no longer be valid. + + add_param + When given the PARAMS_SETUP message, the effect will generally make a + series of calls to the add_param routine to define the interface that + the After Effects user will see. See the PF_ParamDefs defined above. + Currently you can only add params at the end, and only at PARAMS_SETUP + time. + + abort + Periodically, you should check if the user wants to interrupt the + current processing. The abort proc here will return non-zero if + the effects module should suspend its current processing. If you + call this routine and it returns a value other than zero, you should + return that value when your effect returns. That will let us know + if the effect completed rendering or not. + + progress + Alternatively, you may wish to display a progress bar while you are + processing the image. This routine combines the abort proc user + interrupt checking with code that will display a progress bar for + you. The current and total params represent a fraction (current/total) + that describes how far you are along in your processing. Current + should equal total when done. Additionally, this routine will return + non-zero if you should suspend/abort your current processing. You + should probably try not to call this too frequently (e.g. at every pixel). + It is better to call it, say, once per scanline, unless your filter is + really really slow. + +**/ + +typedef struct _PF_CustomUIInfo PF_CustomUIInfo; + + +typedef struct { + // IMPORTANT: This structure is FROZEN. Changing this would break binary compatibility with PF_InData + + PF_Err (*checkout_param)( + PF_ProgPtr effect_ref, /* reference from in_data */ + PF_ParamIndex index, /* 0 = input, 1..n = param */ + A_long what_time, + A_long time_step, /* duration between frames in time_scale units */ + A_u_long time_scale, + PF_ParamDef *param); /* the param you've been waiting for... */ + + PF_Err (*checkin_param)( + PF_ProgPtr effect_ref, /* reference from in_data */ + PF_ParamDef *param); + + PF_Err (*add_param)( + PF_ProgPtr effect_ref, /* reference from in_data */ + PF_ParamIndex index, /* -1 = add to end */ + PF_ParamDefPtr def); + + PF_Err (*abort)( + PF_ProgPtr effect_ref); /* reference from in_data */ + + PF_Err (*progress)( + PF_ProgPtr effect_ref, /* reference from in_data */ + A_long current, + A_long total); + + PF_Err (*register_ui)( + PF_ProgPtr effect_ref, /* reference from in_data */ + PF_CustomUIInfo *cust_info); + + PF_Err (*checkout_layer_audio)( + PF_ProgPtr effect_ref, /* reference from in_data */ + PF_ParamIndex index, /* 0 = input, 1..n = param */ + A_long start_time, /* in time_scale units */ + A_long duration, /* in time_scale units */ + A_u_long time_scale, /* units/sec */ + PF_UFixed rate, /* unsigned! */ + A_long bytes_per_sample, + A_long num_channels, + A_long fmt_signed, /* non-zero for signed, zero for unsigned */ + PF_LayerAudio *audio); /* the LayerAudio you've been waiting for... */ + + PF_Err (*checkin_layer_audio)( + PF_ProgPtr effect_ref, /* reference from in_data */ + PF_LayerAudio audio); + + PF_Err (*get_audio_data)( + PF_ProgPtr effect_ref, /* reference from in_data */ + PF_LayerAudio audio, + PF_SndSamplePtr *data0, /* optional - packed array of samples, if stereo, left/right */ + A_long *num_samples0, /* optional */ + PF_UFixed *rate0, /* optional - unsigned! */ + A_long *bytes_per_sample0, /* optional */ + A_long *num_channels0, /* optional */ + A_long *fmt_signed0); /* optional - non-zero for signed, zero for unsigned */ + + void *reserved_str[3]; + + void *reserved[10]; + +} PF_InteractCallbacks; + + +#define PF_CHECKOUT_PARAM(IN_DATA, INDEX, TIME, STEP, SCALE, PARAM) \ + (*(IN_DATA)->inter.checkout_param)((IN_DATA)->effect_ref, \ + (INDEX), (TIME), (STEP), (SCALE), (PARAM)) + +#define PF_CHECKIN_PARAM(IN_DATA, PARAM) \ + (*(IN_DATA)->inter.checkin_param)((IN_DATA)->effect_ref, (PARAM)) + +#define PF_ADD_PARAM(IN_DATA, INDEX, DEF) \ + (*(IN_DATA)->inter.add_param)((IN_DATA)->effect_ref, (INDEX), (DEF)) + +#define PF_ABORT(IN_DATA) \ + (*(IN_DATA)->inter.abort)((IN_DATA)->effect_ref) + +#define PF_PROGRESS(IN_DATA, CURRENT, TOTAL) \ + (*(IN_DATA)->inter.progress)((IN_DATA)->effect_ref, (CURRENT), (TOTAL)) + +#define PF_REGISTER_UI(IN_DATA, CUST_INFO) \ + (*(IN_DATA)->inter.register_ui)((IN_DATA)->effect_ref, (CUST_INFO)) + +#define PF_CHECKOUT_LAYER_AUDIO(IN_DATA, INDEX, START_TIME, DURATION, SCALE, RATE, \ + BYTES_PER_SAMPLE, NUM_CHANNELS, FMT_SIGNED, AUDIO) \ + (*(IN_DATA)->inter.checkout_layer_audio)((IN_DATA)->effect_ref, \ + (INDEX), (START_TIME), (DURATION), (SCALE), (RATE), (BYTES_PER_SAMPLE), \ + (NUM_CHANNELS), (FMT_SIGNED), (AUDIO)) + +#define PF_CHECKIN_LAYER_AUDIO(IN_DATA, AUDIO) \ + (*(IN_DATA)->inter.checkin_layer_audio)((IN_DATA)->effect_ref, (AUDIO)) + +#define PF_GET_AUDIO_DATA(IN_DATA, AUDIO, DATA_0, NUM_SAMPLES_0, RATE_0, \ + BYTES_PER_SAMPLE_0, NUM_CHANNELS_0, FMT_SIGNED_0) \ + (*(IN_DATA)->inter.get_audio_data)((IN_DATA)->effect_ref, \ + (AUDIO), (DATA_0), (NUM_SAMPLES_0), (RATE_0), (BYTES_PER_SAMPLE_0), \ + (NUM_CHANNELS_0), (FMT_SIGNED_0)) + + +/** -------------------- Effect Parameter Blocks -------------------- + + The effects module itself is invoked with input and output blocks + of parameters for various messages that it needs to handle. The + output block (values returned from the effect to the program) and + the input block (values provided by the program for the edification + of the effect) are defined here. Discussion follows. + + The Output Block + + Most fields of the output block are only examined for changes after + certain commands have been sent to the effect module. Each field + below describes when it will be checked. + + my_version + This is the version number of your plug-in effect, not to be confused + with the version of the plug-in specification. Please set this + at PF_Cmd_GLOBAL_SETUP. + + name + This lets you override the name of the effect in the Time Layout and + in the Effect Controls windows when the effect is applied. The name from + the PiPL resource is always used in the Effect menu. This field is + checked after PF_Cmd_SEQUENCE_SETUP. You will almost always leave + this field empty. + + global_data + This is a Handle that you can allocate at PF_Cmd_GLOBAL_SETUP + time. It will be passed back to you verbatim in the input + parameter block for use later on. In PF_Cmd_GLOBAL_SETUP, + the global_data field in the Input Block may be set to a + flattened version of your global data, in which case you should + unflatten it, free the flat version, and set this field to the + unflattened new global data. + + It will be locked & unlocked for you automatically like sequence_data. + + num_params + The calling application will sanity check the num_params field + vs the times add_param is called. The implicit main + layer parameter MUST be included in the parameter count. Use the + num_params value in the in_data as a starting value (it will + include the implicit layer parameter). + Set this field when you get PF_Cmd_PARAMS_SETUP. + + sequence_data + This is a Handle that you can allocate (using PF_NEW_HANDLE) + at PF_Cmd_SEQUENCE_SETUP time. + It will be passed back to you in the input parameter block + for later use. + + WARNING: this handle is always locked for you before your plugin + is called, and the lock-state is restored on the way out. If you + have arbitrary data, your plugin can be called re-entrantly, so + if you have a lock/unlock inside your plugin, the handle will + become unlocked prematurely -- instead simply depend on the host + to lock & unlock your sequence data for you. Of course during + PF_Cmd_SEQUENCE_SETUP the handle you allocate will not be + locked unless you explicitly lock it at that time. + + The contents of this handle will be written out to + disk. If other handles hang off this block, you must specify the + PF_OutFlag_SEQUENCE_DATA_NEEDS_FLATTENING out flag when you get + the PF_Cmd_GLOBAL_SETUP command. You will then receive the + PF_Cmd_SEQUENCE_FLATTEN before your handle is written out. At that + time, you should create a flat version of the handle contents, + free the old unflat handle, and set this field to the flattened + version of the handle. Or after disposing, simply set to NULL + and nothing will be written to disk. + + You will receive a PF_Cmd_SEQUENCE_RESETUP + call to unflatten this handle (as well as to adjust the sequence + data to altered frame rates, etc). If your + sequence data can be flat or unflat, you should store its current + state along with the other data, and check that value in Resetup. + If the handle is flat, Resetup should unflatten it, free the flat + handle, and set this field to the new unflat usable handle. + + flat_sdata_size + OBSOLETE. Turns out, it was never used. Since the handle + set in sequence_data must be allocated using PF_NEW_HANDLE, + the host can find out the size of the handle without asking. + + frame_data + This is a Handle that you can allocated at PF_Cmd_FRAME_SETUP + time. It will be passed to you in the input parameters, as + with the global_data and the sequence_data. This will not + be written out to disk. There is no particular use for this. + Set this field in PF_Cmd_FRAME_SETUP, if you must. + + It will be locked & unlocked for you like sequence_data. + + width + height + origin + You set these fields at PF_Cmd_FRAME_SETUP time to indicate + that the output image will be larger than the input image. + You should set width and height to the size that you want the + output buffer to be. Set origin to the place that the + point (0,0) in the input should map to in the new larger + output. Thus, if you created a 5 pixel drop shadow up and left, + you would set origin to (5, 5). + + out_flags + out_flags2 + This field can be set to an OR-ed combination of the PF_OutFlag + and PF_OutFlag2 constants (don't mix them up!) to communicate + things to After Effects. This will be checked after every + command, but only certain flags are relevant at given times. + Check the PF_OutFlag constants above. + + return_msg + This is a message string (in C string format) that will be + interpreted as either an error message or a useful display + message (for instance, for handling PF_Cmd_ABOUT). Fill + this string with a message you want After Effects to report + to the user for you. It will come up in a simple dialog + with an OK button. Set the first byte of this string to '\0' + to indicate no string -- it is set that way upon entry. This + field is examined after every PF_Cmd. + + The Input Block + + Many parts of the input block are actually structures defined elsewhere + in this file, or in the companion file AE_EffectCB.h. See the documentation + where those structures are defined to understand their contents. + With any given PF_Cmd, only certain fields in the Input Block will + have valid values. Each field described below tells when it is valid. + + in_flags + in_flags2 + These are various flags indicating some boolean value to + the effect module. This is a combination of PF_InFlag values + OR-ed together. This is set for all commands, though most + flags make sense only at certain times. Usually this is + just a copy of the PiPL global flags. See PF_OutFlags and + PF_OutFlags2 above. + + inter + This is a structure defined above containing callbacks + related to user interaction. This has callbacks to add parameters, + to check if the user has interrupted the effect, to display + a progress bar, and to inquire parameter values outside of the + current moment. See the doc above. When each callback can + validly be executed is defined above. + + utils + This is a pointer to a block of useful graphical and mathematical + callbacks provided for the effects module. The documentation + for this block is in the AE_EffectCB.h file. This is a void *, + which can be confusing. See AE_EffectCB.h for macros to use these + functions. This pointer will be defined at all times. + + effect_ref + This is a opaque piece of data that needs to be passed to + most of the various callback routines. Don't worry about it. + + quality + This is set to one of the PF_Quality constants above to + describe the Quality currently chosen by the user. Ideally, + your effect should do a faster version with LO quality, and + a better, "broadcast"-able version with HI quality. Also, + some of the utility callbacks perform differently between + LO and HI quality. This is defined for all PF_Cmds related + to SEQUENCE and FRAME (obviously, including RENDER). + + version + This is the version of the effects spec with which you are + being invoked. This will not be defined until after GLOBAL_SETUP. + + serial_num + This is the serial number of the invoking application. + + appl_id + This is the identifier of the invoking application. It will + be the creator A_long of the app. + + freq + This is an estimate of the frequency with which you should + call the abort check callback. You can ignore this. + + num_params + This is set to the number of input parameters you are receiving. + + what_cpu + This is set to the return value from Gestalt asking what sort + of CPU your machine has. If your effect requires a certain + type of CPU it should check this value and return an error + indicating that it cannot run. After Effects only runs on + 68020s and higher, so don't sweat it if you require that. + + what_fpu + This is set to the return value from Gestalt asking what sort + of FPU your machine has. If you require a floating point unit, + you should return the OutFlag indicating that in GLOBAL_SETUP, + and then do not execute your floating point code if this value + is set to 0 -- just do a PF_COPY of the input to the output when + you get the PF_Cmd_RENDER. See OutFlag description above. + + current_time + This is the time of the current frame. It will be set in RENDER. + The number of the current frame is current_time / time_step. + All effects sequences start at time 0. + + time_step + This is the time difference to the next or last frame. This value + and current_time and total_time are in units given by time_scale. + The time between frames is time_step, not 1. This value will be 0 + at SEQUENCE_SETUP if it is not constant for all frames. It will + be set correctly in the FRAME calls, even if it's not constant. + + total_time + This is the amount of time from the start to the end of the + image sequence on which this effect is being invoked. The total + number of frames is total_time / time_step. + + time_scale + These are the units that current_time, time_step, and total_time + are in. See QuickTime for an explanation of how these time values work. + + width + height + These are the size of the input image. As Stoney Ballard points out, + these are certainly NOT the same as the width and height fields in param[0], + but rather reflect the full-resolution dimensions of the input layer. + + field + Will be set to PF_Field_UPPER or PF_Field_LOWER during field-rendering + if certain conditions are met -- for example: effect must have + PF_OutFlag_PIX_INDEPENDENT set, and the layer to which the effect is + applied must not be rotated, scaled nor positioned on a subpixel. + You can safely ignore the setting of this field, but might be able to + optimize things by only processing the specified field. + + extent_hint + This is a rectangle that indicates the intersection of the visible + portions of the input and output layers. For an effect that does + not do a geometric distortion of the image, copying just this rectangle + from the source image to the destination image is sufficient to copy + all the image data that the user will see. This can speed up effects + very much. Just iterate over only this rectangle of pixels. + + output_origin_x + output_origin_y + These fields correspond to the origin returned in the out_data at + PF_Cmd_FRAME_SETUP time. They indicate the position of the top left + corner of the input buffer in the output buffer. + + downsample_x + downsample_y + For speed, the user may have asked for only every Nth vertical or + horizontal pixel to be actually rendered by After Effects. The width + and height of all effect parameters (including layers) will be + automatically adjusted to compensate, but the effect needs to know + the downsampling factors to correctly interpret scalar parameters + (ie. sliders) that represent pixel distances in the image. + Downsample factors will be in the range 1 to 999+. This is set in + SEQUENCE_SETUP or RESETUP as the case may be. As of PF_PLUG_IN_VERSION 2, + this factor is a rational quantity. + + global_data + sequence_data + frame_data + These fields are copied from the out data on previous invocations + and set here for you to access as you need them. They will only + be set if they have been allocated during previous commands. + + pre_effect_source_origin_x + pre_effect_source_origin_y + These fields are the origin of the source image in the input buffer. They are set + only during frame calls (PF_Cmd_FRAME_SETUP, PF_Cmd_RENDER, PF_Cmd_FRAME_SETDOWN). + They will be non-zero only if one or more effects that preceded this effect + on the same layer resized the output buffer (i.e. specified that the output + image will be larger or smaller than the input image). + +**/ + + +typedef struct { + A_u_long my_version; /* version # for plug-in code */ + A_char name[PF_MAX_EFFECT_NAME_LEN + 1]; /* only used at seq setup to change */ + PF_Handle global_data; + A_long num_params; + PF_Handle sequence_data; + A_long flat_sdata_size;/* obsolete */ + PF_Handle frame_data; + A_long width; /* change if you want resized output */ + A_long height; + PF_Point origin; + PF_OutFlags out_flags; /* ORed combo of PF_OutFlag values */ + A_char return_msg[PF_MAX_EFFECT_MSG_LEN + 1]; + A_long start_sampL; /* used only for audio commands */ + A_long dur_sampL; /* used only for audio commands */ + PF_SoundWorld dest_snd; /* used only for audio commands */ + PF_OutFlags2 out_flags2; /* ORed combo of PF_OutFlag2 values */ +} PF_OutData; + + +typedef struct { + PF_InteractCallbacks inter; /* effect interaction related callbacks */ + struct _PF_UtilCallbacks *utils; /* utility callbacks -- see AE_EffectCB.h */ + PF_ProgPtr effect_ref; /* opaque value for callbacks */ + PF_Quality quality; /* quality user has selected */ + PF_SpecVersion version; + A_long serial_num; + A_long appl_id; + A_long num_params; + A_long reserved; + A_long what_cpu; /* return value from Gestalt asking CPU */ + A_long what_fpu; /* as above for FPU */ + A_long current_time; + A_long time_step; /* time diff between calls or to next call */ + A_long total_time; + A_long local_time_step;/* time step in local comp */ + A_u_long time_scale; /* units per second of time system */ + PF_Field field; /* if field is specified, other field may be garbage */ + PF_Fixed shutter_angle; /* motion blur shutter angle (range is 0 to 1) */ + A_long width; /* full resolution width of source layer */ + A_long height; /* full resolution height of source layer */ + PF_Rect extent_hint; /* intersection of input and output extents */ + A_long output_origin_x; /* origin of input buffer in output buffer */ + A_long output_origin_y; /* non-zero only when effect changes buffer size */ + PF_RationalScale downsample_x; + PF_RationalScale downsample_y; + PF_RationalScale pixel_aspect_ratio; /* h/v of pixel aspect ratio (NTSC D-1 -> 0.9) */ + PF_InFlags in_flags; + PF_Handle global_data; /* the data created by global_setup */ + PF_Handle sequence_data; /* data from sequence_setup */ + PF_Handle frame_data; /* data from frame_data -- state for this render */ + A_long start_sampL; /* used only for audio commands */ + A_long dur_sampL; /* used only for audio commands */ + A_long total_sampL; /* used only for audio commands */ + PF_SoundWorld src_snd; /* used only for audio commands */ + struct SPBasicSuite *pica_basicP; /* pointer to PICA basic suite. Enjoy! */ + A_long pre_effect_source_origin_x; /* origin of original source in input buffer */ + A_long pre_effect_source_origin_y; /* non-zero only during frame calls (setup, render, setdown) + when effect follows an effect that resizes its output buffer */ + PF_Fixed shutter_phase; /* offset from frame time to shutter open time as a percentage of a frame */ +} PF_InData; + + +/** -------------------- Effect Prototype -------------------- + + The effects module provides a single entry point corresponding to the + below prototype through which all messages are dispatched to the + appropriate code. + + The cmd parameter is one of the PF_Cmd enumeration defined above. + All commands are discussed at that enumeration. There are a lot. + + The in_data and out_data parameters are respectively, PF_InData and + PF_OutData blocks defined and described above. The in_data contains + read only information that the effect can use. The out_data contains + write only information through which the effect communicates back to + the calling program. The descriptions above give a lot more detail. + + The params list is an array of pointers to variably sized PF_ParamDef + structs. This is in typical Unix-like argv format, where the last item + points to NULL. The entries in this array describe the current settings + of the parameters to the effect. Params[0] is the layer to which the + effect has been applied and is a PF_LayerDef param. Other parameters + are defined by the effect. + + The output param is also a PF_LayerDef param, like params[0], and is + an output buffer into which your effect should write the new contents + of the layer. + + A brief explanation about parameter passing to effects: + + When you are invoked to Render, all "params" array entries will be filled + with their value at the current time, except for layer params other than + the default input layer parameter (ie. param[0]). To get other layer param + values, you must call the checkout_param callback. (See callbacks above.) + + In other words, on PF_Cmd_RENDER, params[0] will be a valid ready-to-use + PF_EffectWorld and output will be a valid ready-to-use PF_EffectWorld. Other params that + are not layer params (i.e. sliders, popups, etc.) will be ready-to-use, filled + with their value at the current time; you do not need to call checkout_param for + them. However, other params (besides [0]) that are layer params will NOT be + filled in correctly -- you must make a checkout_param callback to get them. + + ANY param which you call checkout_param on, you must also call checkin_param + before you exit. If not, After Effects will automatically erase your effect + module code resource from the users hard disk, along with any files that contain + your name or any nicknames you have. Sorry. Calling checkin_param is important! + +**/ + +typedef PF_Err (*PF_FilterProc)( + PF_Cmd cmd, + PF_InData *in_data, + PF_OutData *out_data, + PF_ParamList params, + PF_LayerDef *output, + void *extra); + + +#ifdef __cplusplus +} // end extern "C" +#endif + + + +#include + + +#endif /* _H_AE_Effect */ + diff --git a/External/AE SDK/Headers/AE_EffectCB.h b/External/AE SDK/Headers/AE_EffectCB.h new file mode 100644 index 00000000..c5c0360f --- /dev/null +++ b/External/AE SDK/Headers/AE_EffectCB.h @@ -0,0 +1,1223 @@ +/*******************************************************************/ +/* */ +/* ADOBE CONFIDENTIAL */ +/* _ _ _ _ _ _ _ _ _ _ _ _ _ */ +/* */ +/* Copyright 2007 Adobe Systems Incorporated */ +/* All Rights Reserved. */ +/* */ +/* NOTICE: All information contained herein is, and remains the */ +/* property of Adobe Systems Incorporated and its suppliers, if */ +/* any. The intellectual and technical concepts contained */ +/* herein are proprietary to Adobe Systems Incorporated and its */ +/* suppliers and may be covered by U.S. and Foreign Patents, */ +/* patents in process, and are protected by trade secret or */ +/* copyright law. Dissemination of this information or */ +/* reproduction of this material is strictly forbidden unless */ +/* prior written permission is obtained from Adobe Systems */ +/* Incorporated. */ +/* */ +/*******************************************************************/ + + +/** AE_EffectCB.h + + Part of the After Effects SDK + + NOTES + This file describes utility functions and macros for accessing + those utilities that are provided to every filter. These functions + provide graphical tools, mathematical utilities, and other basic + library functions. + + An effect will want to use these callbacks for three primary reasons: + + 1) The mathematical and graphics callbacks will be efficiently + implemented, and will adaptively take advantage of any hardware + acceleration transparent to the effects module. + 2) The callbacks will maximize portability of the effect code + and consistency of results from platform to platform and from + effect to effect. + 3) The callbacks will simplify construction of complex filters, + both making filters easier to write and resulting in smaller + code for each filter. + + The After Effects standard for routine parameters is to list input + parameters first, then list parameters whose contents will be modified, + and then pass output parameters whose old value will be completely + replaced. Large or significant params tend to be listed earlier within + their segment. Most callbacks we provide follow this standard, so with a + convolution callback, we generally would order parameters: + convolve(src_world, convolution_details, dst_world) + However, not all Mac routines follow this, so to be easily + brain-compatible with Mac programmers, we structure some routines + (actually just CopyBits) that we provide to be as much like the + corresponding Mac routine as possible. + +**/ + +#ifndef _H_AE_EffectCB +#define _H_AE_EffectCB + + +#include + +#include + +#ifdef __cplusplus + extern "C" { +#endif + + +/** ---------- Useful Constants ---------- **/ + +#define PF_PI 3.14159265358979323846 +#define PF_2PI 6.28318530717958647692 +#define PF_HALF_PI 1.57079632679489661923 +#define PF_E 2.7182818284590452354 +#define PF_SQRT2 1.41421356237309504880 +#define PF_RAD_PER_DEGREE 0.01745329251994329576 + + + +/** ---------- PF_KernelFlags ---------- + + Many functions work with "kernels" or matrices of values. These matrices + can be of different types, of different arrangements, and can be generated + or treated in different ways. The KernelFlags are used in a variety of + functions to determine how the matrices should be created and used. You + should OR together any flags you need. Which flags are relevant for a + given routine are documented along with the prototype for the routine below. + + The most important information to consider is the type of data. + You will have to choose whether to use Fixeds, Chars, or Longs. + See the information on the USE_... flags below. + + Note, the default for each flag is listed first and passing zero for + the flags parameter will automatically get you the defaults. + + ??? Some of the non-default parameters may not be implemented. Where + a flag is not implemented it will be commented with ??? beside it. + +**/ + +/* pass bottom flag for 1 dimensional kernel, or top for 2D kernel */ +#define PF_KernelFlag_2D 0 +#define PF_KernelFlag_1D (1L << 0) + +/* pass bottom flag to equalize kernel, forcing the volume under the + * kernel surface to be the same as the volume under the covered area + * of pixels. Otherwise, it will be unnormalized. + */ +#define PF_KernelFlag_UNNORMALIZED 0 +#define PF_KernelFlag_NORMALIZED (1L << 1) + +/* use the first flag to force values to be clamped into their valid + * range (that is determined by the type of item (A_char, fixed, A_long). + */ +#define PF_KernelFlag_CLAMP 0 +#define PF_KernelFlag_NO_CLAMP (1L << 2) + +/* pass the first flag to treat kernel as an array of longs valued from 0 to 255. + * pass the second to treat kernel as an array of unsigned chars from 0 to 255, + * pass the third to treat kernel as an array of Fixeds from 0 to 1. + * ??? NOTE! For now, only USE_LONG is implemented! ??? + */ +#define PF_KernelFlag_USE_LONG 0 +#define PF_KernelFlag_USE_CHAR (1L << 3) +#define PF_KernelFlag_USE_FIXED (1L << 4) +#define PF_KernelFlag_USE_UNDEFINED ((1L << 4) | (1L << 3)) + +/* pass the top flag to apply a 1D convolution horizontally, + * the second to apply it vertically. + */ +#define PF_KernelFlag_HORIZONTAL 0 +#define PF_KernelFlag_VERTICAL (1L << 5) + +/* pass the second flag to replicate border pixels when sampling + * off the edge; pass the first flag to treat pixels off the + * edge as alpha zero (black). ??? NOTE! The replicate borders + * flag is unimplemented and this will be ignored. ??? + */ +#define PF_KernelFlag_TRANSPARENT_BORDERS 0 +#define PF_KernelFlag_REPLICATE_BORDERS (1L << 6) + +/* top flag indicates straight convolution, second tells the + * convolution code to alpha-weight the contributions of pixels + * to the resulting convolved output. ??? NOTE! The alpha weighted + * convolve is not implemented and this will be ignored. ??? + */ +#define PF_KernelFlag_STRAIGHT_CONVOLVE 0 +#define PF_KernelFlag_ALPHA_WEIGHT_CONVOLVE (1L << 7) + +typedef A_u_long PF_KernelFlags; + + + +/** ---------- PF_SampleEdgeBehav ---------- + + The sampling routines always deal with 32 bit images, and thus + need to compute properly alpha-weighted samples. An issue arises + when an attempt is made to sample outside of the image content area. + + Before PF_PLUG_IN_VERSION 2, After Effects always treated pixels + outside of the image content area as having alpha = 0, which is desirable + in many cases. Distortions and other effects may want different sampling + behaviors, however, hence the PF_SampleEdgeBehav. + + +**/ + +enum { + PF_SampleEdgeBehav_ZERO = 0L /* Treat pixels outside image as alpha 0; + * Default behavior in After Effects 1.x */ +/* Sorry, not supported! + PF_SampleEdgeBehav_REPEAT = 1L, // Samples are clamped to nearest edge + PF_SampleEdgeBehav_WRAP = 2L // Image wraps around horizontally and vertically +*/ + +}; + +typedef A_u_long PF_SampleEdgeBehav; + +enum { + PF_Xfer_NONE = -1, + PF_Xfer_COPY, + PF_Xfer_BEHIND, + PF_Xfer_IN_FRONT, + PF_Xfer_DISSOLVE, + PF_Xfer_ADD, + PF_Xfer_MULTIPLY, + PF_Xfer_SCREEN, + PF_Xfer_OVERLAY, + PF_Xfer_SOFT_LIGHT, + PF_Xfer_HARD_LIGHT, + PF_Xfer_DARKEN, + PF_Xfer_LIGHTEN, + PF_Xfer_DIFFERENCE, // original < PS5.5 Difference + PF_Xfer_HUE, + PF_Xfer_SATURATION, + PF_Xfer_COLOR, + PF_Xfer_LUMINOSITY, + PF_Xfer_MULTIPLY_ALPHA, // dest alpha *= src alpha + PF_Xfer_MULTIPLY_ALPHA_LUMA, // dest alpha *= src luminance + PF_Xfer_MULTIPLY_NOT_ALPHA, // dest alpha *= ~(src alpha) + PF_Xfer_MULTIPLY_NOT_ALPHA_LUMA, // dest alpha *= ~(src luminance) + PF_Xfer_ADDITIVE_PREMUL, + PF_Xfer_ALPHA_ADD, + PF_Xfer_COLOR_DODGE, // original < PS5.5 Color Dodge + PF_Xfer_COLOR_BURN, // original < PS5.5 Color Burn + PF_Xfer_EXCLUSION, + + PF_Xfer_DIFFERENCE2, // PS >= 6.0, PDF 1.4 Difference + PF_Xfer_COLOR_DODGE2, // PS >= 6.0, PDF 1.4 Color Dodge + PF_Xfer_COLOR_BURN2, // PS >= 6.0, PDF 1.4 Color Burn + + PF_Xfer_LINEAR_DODGE, + PF_Xfer_LINEAR_BURN, + PF_Xfer_LINEAR_LIGHT, + PF_Xfer_VIVID_LIGHT, + PF_Xfer_PIN_LIGHT, + + PF_Xfer_HARD_MIX, + + PF_Xfer_LIGHTER_COLOR, // new in AE8 + PF_Xfer_DARKER_COLOR, + + PF_Xfer_SUBTRACT, // new in AE10 + PF_Xfer_DIVIDE, + + PF_Xfer_RESERVED0, // private/useless + PF_Xfer_RESERVED1, // ditto + + PF_Xfer_NUM_MODES +}; +typedef A_long PF_TransferMode; +typedef PF_TransferMode PF_XferMode; + +// obsolete xfer mode names +enum { + PF_Xfer_TINT = PF_Xfer_LINEAR_DODGE, + PF_Xfer_SHADE = PF_Xfer_LINEAR_BURN, + PF_Xfer_INTENSE_LIGHT = PF_Xfer_VIVID_LIGHT +}; + +typedef struct { + PF_TransferMode xfer; + A_long rand_seed; // for PF_Xfer_DISSOLVE_RANDOMIZED + A_u_char opacity; // 0 - 255 + PF_Boolean rgb_only; // ignored for PF_Xfer_MULTIPLY_ALPHA modes + A_u_short opacitySu; // for deep color only +} PF_CompositeMode; + + + +#define PF_TransferMode_ZERO_SRC_ALPHA_CLEARS_DST_ALPHA(TMODE) \ + ((TMODE) == PF_Xfer_MULTIPLY_ALPHA || \ + (TMODE) == PF_Xfer_MULTIPLY_ALPHA_LUMA) + + +// PF_TransferMode_ZERO_ALPHA_NOP is deprecated because it was +// confusing -- you probably want PF_TransferMode_ZERO_SRC_ALPHA_CLEARS_DST_ALPHA +// instead + +// WARNING: this macro is incorrect for PF_Xfer_COPY (returns true), but it's been like this for so long +// that we are leaving it unchanged so as not to create bugs by changing it. +#define PF_TransferMode_ZERO_SRC_ALPHA_LEAVES_DST_UNCHANGED(TMODE) \ + (((TMODE) == PF_Xfer_MULTIPLY_ALPHA || \ + (TMODE) == PF_Xfer_MULTIPLY_ALPHA_LUMA || \ + (TMODE) == PF_Xfer_ADDITIVE_PREMUL) == 0) + +enum { + PF_MaskFlag_NONE = 0, /* just use the alpha, thank you */ + PF_MaskFlag_INVERTED = 1L << 0, /* invert the result of the mask */ + PF_MaskFlag_LUMINANCE = 1L << 1 /* use the luminance values */ + +}; + + +typedef A_long PF_MaskFlags; + + +typedef struct { + + PF_EffectWorld mask; + PF_Point offset; + PF_MaskFlags what_is_mask; + +} PF_MaskWorld; + + +/** ---------- PF_SampPB ---------- + + There are calls to sample an a non-integral point in an image, + and to sample an area of an image. This parameter block describes + some information needed for these image resampling routines. + +**/ +typedef struct { + + /* parameters needed for single point or area sample */ + + PF_Fixed x_radius; /* radii are used for area sample, 0 for point sample */ + PF_Fixed y_radius; + PF_Fixed area; /* must fit in a Fixed; must be correct */ + PF_EffectWorld *src; /* the world to sample from */ + PF_SampleEdgeBehav samp_behave; + A_long allow_asynch; /* It's okay if I don't get the result until end_sampling */ + + + /* parameters needed for batch sampling & compositing, motion blur, etc. */ + + A_long motion_blur; /* requires pointer to 2 starting points and 2 dxdy's */ + PF_CompositeMode comp_mode; /* compositing mode info */ + PF_PixelPtr mask0; /* per-pixel extra masking, before xfer mode */ + + A_u_char *fcm_table; + A_u_char *fcd_table; + A_long reserved[8]; /* Set to zero at beginsampling */ + +} PF_SampPB; + + +/** ---------- Callback Selectors ---------- + + Some callbacks have different high and low quality versions. + The parameter block of function pointers will automatically + be filled with the appropriate versions for the current quality + setting, but some filters may wish to override this and access + a callback of different quality. To do this, a get_callback_addr + callback is provided which will take a callback selector and a + desired quality and return the callback of that quality. The + selectors for the various callbacks are listed here. Also, a + typedef for the function pointer that will be returned is given. + +**/ + +enum { + PF_Callback_NONE = 0, + PF_Callback_BEGIN_SAMPLING, + PF_Callback_SUBPIXEL_SAMPLE, + PF_Callback_AREA_SAMPLE, + PF_Callback_OBSOLETE0, + PF_Callback_END_SAMPLING, + PF_Callback_COMPOSITE_RECT, + PF_Callback_BLEND, + PF_Callback_CONVOLVE, + PF_Callback_COPY, + PF_Callback_FILL, + PF_Callback_GAUSSIAN, + PF_Callback_ITERATE, + PF_Callback_PREMUL, + PF_Callback_PREMUL_COLOR, + PF_Callback_RGB_TO_HLS, + PF_Callback_HLS_TO_RGB, + PF_Callback_RGB_TO_YIQ, + PF_Callback_YIQ_TO_RGB, + PF_Callback_LUMINANCE, + PF_Callback_HUE, + PF_Callback_LIGHTNESS, + PF_Callback_SATURATION, + PF_Callback_NEW_WORLD, + PF_Callback_DISPOSE_WORLD, + PF_Callback_ITERATE_ORIGIN, + PF_Callback_ITERATE_LUT, + PF_Callback_TRANSFER_RECT, + PF_Callback_TRANSFORM_WORLD, + PF_Callback_ITERATE_ORIGIN_NON_CLIP_SRC, + PF_Callback_ITERATE_GENERIC, + PF_Callback_SUBPIXEL_SAMPLE16, + PF_Callback_AREA_SAMPLE16, + PF_Callback_FILL16, + PF_Callback_PREMUL_COLOR16, + PF_Callback_ITERATE16, + PF_Callback_ITERATE_ORIGIN16, + PF_Callback_ITERATE_ORIGIN_NON_CLIP_SRC16, + PF_Callback_ITERATE_GENERIC_NO_MAX_THREADS, + PF_Callback_ITERATE_NO_MAX_THREADS, + PF_Callback_ITERATE_ORIGIN_NO_MAX_THREADS, + PF_Callback_ITERATE_ORIGIN_NON_CLIP_SRC_NO_MAX_THREADS, + PF_Callback_ITERATE16_NO_MAX_THREADS, + PF_Callback_ITERATE_ORIGIN16_NO_MAX_THREADS, + PF_Callback_ITERATE_ORIGIN_NON_CLIP_SRC16_NO_MAX_THREADS, +}; +typedef A_long PF_CallbackID; + +/** + Previous versions of PF_CallbackFunc were defined using varargs in attempt to enforce + the effect_ref passed as the first argument to all callbacks. The actual host + implementations are generally *not* varargs, and on some platforms the calling + conventions between normal C ABI and C varargs ABI are not compatible. If your + code is trying to call through a PF_CallbackFunc it is unsafe; with this definition + it will now no longer compile. To fix, cast to the proper API signature before + calling. Or better, use the extensive Suite implementations which are explicitly typed +**/ + +typedef struct PF_YouMustCastThisToActualFunctionType *PF_CallbackFunc; + +#define AEFX_MAX_PATH 260 + +enum { + PF_PlatData_MAIN_WND = 0, // windows only (output data => HWND) + PF_PlatData_EXE_FILE_PATH_DEPRECATED, // deprecated in CS6. Use _W versions below + PF_PlatData_RES_FILE_PATH_DEPRECATED, // deprecated in CS6. Use _W versions below + PF_PlatData_RES_REFNUM, // deprecated in AE 2015. Use PF_PlatData_BUNDLE_REF instead + PF_PlatData_RES_DLLINSTANCE, // windows only (output data => HANDLE) + PF_PlatData_SP_PLUG_REF, // unimplemented + PF_PlatData_BUNDLE_REF, // mac only (output data => CFBundleRef) + PF_PlatData_EXE_FILE_PATH_W, // mac and windows (output data => A_UTF16Char[AEFX_MAX_PATH]) + PF_PlatData_RES_FILE_PATH_W //// mac and windows (output data => A_UTF16Char[AEFX_MAX_PATH]) +}; + +typedef A_long PF_PlatDataID; + + +/** ---------- Image Plane Selectors ---------- + + These constants can be used to specify a subset + of the planes of the 32-bit image. + +**/ + +enum { + PF_Plane_ALPHA = 1, + PF_Plane_RED = 2, + PF_Plane_GREEN = 4, + PF_Plane_BLUE = 8 +}; +typedef A_u_long PF_Plane; + + +/** ---------- ANSI Routines Block ---------- + + Within the callback routines block there is a block of ANSI + routines, so that the filter will not need to link with the + ANSI library. The following structure describes that block + and is included in the larger Callback Routines block below. + + All angles are expressed in radians; use PF_RAD_PER_DEGREE + to convert from degrees to radians, if necessary. Be aware + that angle parameter types use degrees (in fixed point). + + Sprintf and strcpy are provided to facilitate string usage, + such as printing for names and supervised controls. + + None of these callbacks vary based on the Quality setting. + +**/ + +typedef struct { + A_FpLong (*atan)(A_FpLong); + A_FpLong (*atan2)(A_FpLong y, A_FpLong x); /* returns atan(y/x) - note param order! */ + A_FpLong (*ceil)(A_FpLong); /* returns next int above x */ + A_FpLong (*cos)(A_FpLong); + A_FpLong (*exp)(A_FpLong); /* returns e to the x power */ + A_FpLong (*fabs)(A_FpLong); /* returns absolute value of x */ + A_FpLong (*floor)(A_FpLong); /* returns closest int below x */ + A_FpLong (*fmod)(A_FpLong x, A_FpLong y); /* returns x mod y */ + A_FpLong (*hypot)(A_FpLong x, A_FpLong y); /* returns sqrt(x*x + y*y) */ + A_FpLong (*log)(A_FpLong); /* returns natural log of x */ + A_FpLong (*log10)(A_FpLong); /* returns log base 10 of x */ + A_FpLong (*pow)(A_FpLong x, A_FpLong y); /* returns x to the y power */ + A_FpLong (*sin)(A_FpLong); + A_FpLong (*sqrt)(A_FpLong); + A_FpLong (*tan)(A_FpLong); + + int (*sprintf)(A_char *, const A_char *, ...); + A_char * (*strcpy)(A_char *, const A_char *); + + A_FpLong (*asin)(A_FpLong); + A_FpLong (*acos)(A_FpLong); + + A_long ansi_procs[1]; +} PF_ANSICallbacks; + + + +/** ---------- Colorspace Conversion Callbacks + ** + **/ + +typedef struct { + PF_Err (*RGBtoHLS)( + PF_ProgPtr effect_ref, /* reference from in_data */ + PF_Pixel *rgb, + PF_HLS_Pixel hls); + + PF_Err (*HLStoRGB)( + PF_ProgPtr effect_ref, /* reference from in_data */ + PF_HLS_Pixel hls, + PF_Pixel *rgb); + + PF_Err (*RGBtoYIQ)( + PF_ProgPtr effect_ref, /* reference from in_data */ + PF_Pixel *rgb, + PF_YIQ_Pixel yiq); + + PF_Err (*YIQtoRGB)( + PF_ProgPtr effect_ref, /* reference from in_data */ + PF_YIQ_Pixel yiq, + PF_Pixel *rgb); + + PF_Err (*Luminance)( + PF_ProgPtr effect_ref, /* reference from in_data */ + PF_Pixel *rgb, + A_long *lum100); /* << 100 * luminance */ + + PF_Err (*Hue)( + PF_ProgPtr effect_ref, /* reference from in_data */ + PF_Pixel *rgb, + A_long *hue); /* << 0-255 maps to 0-360 */ + + PF_Err (*Lightness)( + PF_ProgPtr effect_ref, /* reference from in_data */ + PF_Pixel *rgb, + A_long *lightness); /* << goes from 0-255 */ + + PF_Err (*Saturation)( + PF_ProgPtr effect_ref, /* reference from in_data */ + PF_Pixel *rgb, + A_long *saturation); /* << goes from 0-255 */ + +} PF_ColorCallbacks; + + + +typedef void * PF_BatchSampleFunc; /* <<> see comment above !! */ + A_long xL, /* >> */ + A_long yL, /* >> */ + PF_Pixel *inP, /* <> */ + PF_Pixel *outP); /* <> */ + +typedef PF_Err (*PF_IteratePixel16Func) ( void* refconP, /* >> see comment above !! */ + A_long xL, /* >> */ + A_long yL, /* >> */ + PF_Pixel16 *inP, /* <> */ + PF_Pixel16 *outP); /* <> */ + +typedef PF_Err (*PF_IteratePixelFloatFunc) ( void* refconP, /* >> see comment above !! */ + A_long xL, /* >> */ + A_long yL, /* >> */ + PF_PixelFloat *inP, /* <> */ + PF_PixelFloat *outP); /* <> */ + + +typedef struct _PF_UtilCallbacks { + PF_Err (*begin_sampling)( + PF_ProgPtr effect_ref, /* reference from in_data */ + PF_Quality qual, + PF_ModeFlags mf, + PF_SampPB *params); + + PF_Err (*subpixel_sample)( + PF_ProgPtr effect_ref, /* reference from in_data */ + PF_Fixed x, + PF_Fixed y, + const PF_SampPB *params, + PF_Pixel *dst_pixel); + + PF_Err (*area_sample)( + PF_ProgPtr effect_ref, /* reference from in_data */ + PF_Fixed x, + PF_Fixed y, + const PF_SampPB *params, + PF_Pixel *dst_pixel); + + void *get_batch_func_is_deprecated; + + PF_Err (*end_sampling)( + PF_ProgPtr effect_ref, /* reference from in_data */ + PF_Quality qual, + PF_ModeFlags mf, + PF_SampPB *params); + + PF_Err (*composite_rect)( + PF_ProgPtr effect_ref, /* from in_data */ + PF_Rect *src_rect, /* rectangle in source image */ + A_long src_opacity, /* opacity of src */ + PF_EffectWorld *source_wld, /* src PF world */ + A_long dest_x, /* upper left-hand corner of src rect...*/ + A_long dest_y, /* ... in composite image */ + PF_Field field_rdr, /* which scanlines to render (all, upper, lower) */ + PF_XferMode xfer_mode, /* Copy, Composite Behind, Composite In Front */ + PF_EffectWorld *dest_wld); /* Destination buffer. Already filled */ + + PF_Err (*blend)( + PF_ProgPtr effect_ref, /* reference from in_data */ + const PF_EffectWorld *src1, + const PF_EffectWorld *src2, + PF_Fixed ratio, /* 0 == full src1, 0x00010000 == full src2 */ + PF_EffectWorld *dst); + + PF_Err (*convolve)( + PF_ProgPtr effect_ref, /* reference from in_data */ + PF_EffectWorld *src, + const PF_Rect *area, /* pass NULL for all pixels */ + PF_KernelFlags flags, + A_long kernel_size, + void *a_kernel, + void *r_kernel, + void *g_kernel, + void *b_kernel, + PF_EffectWorld *dst); + + PF_Err (*copy)( + PF_ProgPtr effect_ref, /* reference from in_data */ + PF_EffectWorld *src, + PF_EffectWorld *dst, + PF_Rect *src_r, /* pass NULL for whole world */ + PF_Rect *dst_r); /* pass NULL for whole world */ + + PF_Err (*fill)( + PF_ProgPtr effect_ref, /* reference from in_data */ + const PF_Pixel *color, + const PF_Rect *dst_rect, /* pass NULL for whole world */ + PF_EffectWorld *world); + + PF_Err (*gaussian_kernel)( + PF_ProgPtr effect_ref, /* reference from in_data */ + A_FpLong kRadius, /* desired gaussian radius */ + PF_KernelFlags flags, /* see kernel flags commented above */ + A_FpLong multiplier, + A_long *diameter, + void *kernel); + + PF_Err (*iterate)( + PF_InData *in_data, + A_long progress_base, + A_long progress_final, + PF_EffectWorld *src, + const PF_Rect *area, /* pass NULL for all pixels */ + void* refcon, + PF_IteratePixel8Func pix_fn, + PF_EffectWorld *dst); + + PF_Err (*premultiply)( + PF_ProgPtr effect_ref, /* reference from in_data */ + A_long forward, /* TRUE means convert non-premul to premul, FALSE mean reverse */ + PF_EffectWorld *dst); + + PF_Err (*premultiply_color)( + PF_ProgPtr effect_ref, /* reference from in_data */ + PF_EffectWorld *src, + const PF_Pixel *color, /* color to premultiply/unmultiply with */ + A_long forward, /* TRUE means convert non-premul to premul, FALSE mean reverse */ + PF_EffectWorld *dst); + + PF_Err (*new_world)( + PF_ProgPtr effect_ref, /* reference from in_data */ + A_long width, + A_long height, + PF_NewWorldFlags flags, /* should would be pre-cleared to zeroes */ + PF_EffectWorld *world); /* always 32 bit */ + + PF_Err (*dispose_world)( + PF_ProgPtr effect_ref, /* reference from in_data */ + PF_EffectWorld *world); + + PF_Err (*iterate_origin)( + PF_InData *in_data, + A_long progress_base, + A_long progress_final, + PF_EffectWorld *src, + const PF_Rect *area, /* pass NULL for all pixels */ + const PF_Point *origin, + void* refcon, + PF_IteratePixel8Func pix_fn, + PF_EffectWorld *dst); + + PF_Err (*iterate_lut)( + PF_InData *in_data, + A_long progress_base, + A_long progress_final, + PF_EffectWorld *src, + const PF_Rect *area, /* pass NULL for all pixels */ + A_u_char *a_lut0, /* pass NULL for identity */ + A_u_char *r_lut0, /* pass NULL for identity */ + A_u_char *g_lut0, /* pass NULL for identity */ + A_u_char *b_lut0, /* pass NULL for identity */ + PF_EffectWorld *dst); + + + PF_Err (*transfer_rect)( + PF_ProgPtr effect_ref, + PF_Quality quality, + PF_ModeFlags m_flags, + PF_Field field, + const PF_Rect *src_rec, + const PF_EffectWorld *src_world, + const PF_CompositeMode *comp_mode, + const PF_MaskWorld *mask_world0, + A_long dest_x, + A_long dest_y, + PF_EffectWorld *dst_world); + + PF_Err (*transform_world)( + PF_ProgPtr effect_ref, + PF_Quality quality, + PF_ModeFlags m_flags, + PF_Field field, + const PF_EffectWorld *src_world, + const PF_CompositeMode *comp_mode, + const PF_MaskWorld *mask_world0, + const PF_FloatMatrix *matrices, + A_long num_matrices, + PF_Boolean src2dst_matrix, + const PF_Rect *dest_rect, + PF_EffectWorld *dst_world); + + PF_Handle (*host_new_handle)( + A_u_longlong size); + + void * (*host_lock_handle)( + PF_Handle pf_handle); + + void (*host_unlock_handle)( + PF_Handle pf_handle); + + void (*host_dispose_handle)( + PF_Handle pf_handle); + + PF_Err (*get_callback_addr)( + PF_ProgPtr effect_ref, /* reference from in_data */ + PF_Quality quality, + PF_ModeFlags mode_flags, + PF_CallbackID which_callback, + PF_CallbackFunc *fn_ptr); + + PF_Err (*app)(PF_ProgPtr, A_long, ...); /* application specific callback */ + + PF_ANSICallbacks ansi; /* ANSI callback block, see above */ + PF_ColorCallbacks colorCB; /* colorspace conversion callbacks */ + + PF_Err (*get_platform_data)( + PF_ProgPtr effect_ref, + PF_PlatDataID which, + void *data); + + A_u_longlong (*host_get_handle_size)( + PF_Handle pf_handle); + + PF_Err (*iterate_origin_non_clip_src)( + PF_InData *in_data, + A_long progress_base, + A_long progress_final, + PF_EffectWorld *src, + const PF_Rect *area, + const PF_Point *origin, + void* refcon, + PF_IteratePixel8Func pix_fn, + PF_EffectWorld *dst); + + PF_Err (*iterate_generic)( + A_long iterationsL, /* >> */ // can be PF_Iterations_ONCE_PER_PROCESSOR + void *refconPV, /* >> */ + PF_Err (*fn_func)( void *refconPV, /* >> */ + A_long thread_indexL, // only call abort and progress from thread_indexL == 0. + A_long i, + A_long iterationsL)); // never sends PF_Iterations_ONCE_PER_PROCESSOR + + PF_Err (*host_resize_handle)( + A_u_longlong new_sizeL, /* >> */ + PF_Handle *handlePH); /* <> Handle Value May Change */ + + + PF_Err (*subpixel_sample16)( + PF_ProgPtr effect_ref, /* reference from in_data */ + PF_Fixed x, + PF_Fixed y, + const PF_SampPB *params, + PF_Pixel16 *dst_pixel); + + PF_Err (*area_sample16)( + PF_ProgPtr effect_ref, /* reference from in_data */ + PF_Fixed x, + PF_Fixed y, + const PF_SampPB *params, + PF_Pixel16 *dst_pixel); + + PF_Err (*fill16)( + PF_ProgPtr effect_ref, /* reference from in_data */ + const PF_Pixel16 *color, + const PF_Rect *dst_rect, /* pass NULL for whole world */ + PF_EffectWorld *world); + + PF_Err (*premultiply_color16)( + PF_ProgPtr effect_ref, /* reference from in_data */ + PF_EffectWorld *src, + const PF_Pixel16 *color, /* color to premultiply/unmultiply with */ + A_long forward, /* TRUE means convert non-premul to premul, FALSE mean reverse */ + PF_EffectWorld *dst); + + PF_Err (*iterate16)( + PF_InData *in_data, + A_long progress_base, + A_long progress_final, + PF_EffectWorld *src, + const PF_Rect *area, /* pass NULL for all pixels */ + void* refcon, + PF_IteratePixel16Func pix_fn, + PF_EffectWorld *dst); + + PF_Err (*iterate_origin16)( + PF_InData *in_data, + A_long progress_base, + A_long progress_final, + PF_EffectWorld *src, + const PF_Rect *area, /* pass NULL for all pixels */ + const PF_Point *origin, + void* refcon, + PF_IteratePixel16Func pix_fn, + PF_EffectWorld *dst); + + PF_Err (*iterate_origin_non_clip_src16)( + PF_InData *in_data, + A_long progress_base, + A_long progress_final, + PF_EffectWorld *src, + const PF_Rect *area, + const PF_Point *origin, + void* refcon, + PF_IteratePixel16Func pix_fn, + PF_EffectWorld *dst); + + PF_Err (*get_pixel_data8)( + PF_EffectWorld *worldP, + PF_PixelPtr pixelsP0, // NULL to use data in PF_EffectWorld + PF_Pixel8 **pixPP); // will return NULL if depth mismatch + + PF_Err (*get_pixel_data16)( + PF_EffectWorld *worldP, + PF_PixelPtr pixelsP0, // NULL to use data in PF_EffectWorld + PF_Pixel16 **pixPP); // will return NULL if depth mismatch + + + // and we're done. all future expansion + // is thru suite mechanism. (for example, + // this is where you'll find the floating + // pt pixel callbacks) + A_long reserved[1]; + +} PF_UtilCallbacks; + + +/** ---------- Callback Access Macros ---------- + + Each of these macros _ASSUMES_ that the (PF_InData *) parameter to + the effects module was passed as a parameter named "in_data". I know + this is a heinous assumption, but the template code all declares the + parameter like that, and by making that assumption, I can simplify + all these macros very much. If you absolutely need to change the + name of that parameter, you will have to pick apart these macros and + invoke the callbacks by yourself. It's not too hard... + + For efficiency, most notably with the image resampling functions (i.e. + subpixel_sample and area_sample), you may wish to declare a local function + pointer and bypass these macros to avoid the multiple dereferences in + your inner loop. The sample code will show how to do this. + + The prototypes and comments about each function are given above in + the PF_UtilCallbacks structure definition. + +**/ +#define PF_BEGIN_SAMPLING(QUALITY, PARAMS) \ + (*in_data->utils->begin_sampling)( \ + in_data->effect_ref, (QUALITY), PF_MF_Alpha_STRAIGHT, (PARAMS)) + +#define PF_SUBPIXEL_SAMPLE(X, Y, PARAMS, DST_PXL) \ + (*in_data->utils->subpixel_sample)( \ + in_data->effect_ref, (X), (Y), (PARAMS), (DST_PXL)) + +#define PF_AREA_SAMPLE(X, Y, PARAMS, DST_PXL) \ + (*in_data->utils->area_sample)( \ + in_data->effect_ref, (X), (Y), (PARAMS), (DST_PXL)) + +#define PF_END_SAMPLING(QUALITY, PARAMS) \ + (*in_data->utils->end_sampling)( \ + in_data->effect_ref, (QUALITY), PF_MF_Alpha_STRAIGHT, (PARAMS)) + +#define PF_BLEND(SRC1, SRC2, RATIO, DST) \ + (*in_data->utils->blend)( \ + in_data->effect_ref, (SRC1), (SRC2), (RATIO), (DST)) + +#define PF_CONVOLVE(SRC, RCT_P, FLAGS, KRNL_SZ, AK, RK, GK, BK, DST) \ + (*in_data->utils->convolve)( \ + in_data->effect_ref, (SRC), (RCT_P), (FLAGS), (KRNL_SZ), (AK), (RK), (GK), (BK), (DST)) + +#define PF_COPY(SRC, DST, SRC_RECT, DST_RECT) \ + (*in_data->utils->copy)( \ + in_data->effect_ref, (SRC), (DST), (SRC_RECT), (DST_RECT)) + +#define PF_FILL(COLOR, DST_RECT, DST) \ + (*in_data->utils->fill)( \ + in_data->effect_ref, (COLOR), (DST_RECT), (DST)) + +#define PF_GAUSSIAN_KERNEL(K_RAD, FLAGS, MULT, DIAM, KERNEL) \ + (*in_data->utils->gaussian_kernel)( \ + in_data->effect_ref, (K_RAD), (FLAGS), (MULT), (DIAM), (KERNEL)) + +#define PF_ITERATE(PROG_BASE, PROG_FINAL, SRC, RCT_P, REFCON, PIX_FUNC, DST) \ + (*in_data->utils->iterate)( \ + in_data, (PROG_BASE), (PROG_FINAL), (SRC), (RCT_P), (REFCON), (PIX_FUNC), (DST)) + +#define PF_ITERATE16(PROG_BASE, PROG_FINAL, SRC, RCT_P, REFCON, PIX_FUNC, DST) \ + (*in_data->utils->iterate16)( \ + in_data, (PROG_BASE), (PROG_FINAL), (SRC), (RCT_P), (REFCON), (PIX_FUNC), (DST)) + +#define PF_PREMUL(FORWARD, DST) \ + (*in_data->utils->premultiply)( \ + in_data->effect_ref, (FORWARD), (DST)) + +#define PF_PREMUL_COLOR(SRC, COLOR, FORWARD, DST) \ + (*in_data->utils->premultiply_color)( \ + in_data->effect_ref, (SRC), (COLOR), (FORWARD), (DST)) + +#define PF_NEW_WORLD(WIDTH, HEIGHT, FLAGS, WORLD) \ + (*in_data->utils->new_world)( \ + in_data->effect_ref, (WIDTH), (HEIGHT), (FLAGS), (WORLD)) + +#define PF_DISPOSE_WORLD(WORLD) \ + (*in_data->utils->dispose_world)( \ + in_data->effect_ref, (WORLD)) + +#define PF_ITERATE_ORIGIN(PROG_BASE, PROG_FINAL, SRC, RCT_P, OR, REFCON, PIX_FUNC, DST) \ + (*in_data->utils->iterate_origin)( \ + in_data, (PROG_BASE), (PROG_FINAL), (SRC), (RCT_P), (OR), (REFCON), (PIX_FUNC), (DST)) + +#define PF_ITERATE_ORIGIN16(PROG_BASE, PROG_FINAL, SRC, RCT_P, OR, REFCON, PIX_FUNC, DST) \ + (*in_data->utils->iterate_origin16)( \ + in_data, (PROG_BASE), (PROG_FINAL), (SRC), (RCT_P), (OR), (REFCON), (PIX_FUNC), (DST)) + +#define PF_ITERATE_LUT(PROG_BASE, PROG_FINAL, SRC, RCT_P, A_LUT, R_LUT, G_LUT, B_LUT, DST) \ + (*in_data->utils->iterate_lut)( \ + in_data, (PROG_BASE), (PROG_FINAL), (SRC), (RCT_P), (A_LUT), \ + (R_LUT), (G_LUT), (B_LUT), (DST)) + +#define PF_TRANSFER_RECT(QUALITY, M_FLAGS, FIELD, SRC_REC, SRC_WORLD, COMP_MODE, \ + MASK_WORLD_0, DST_X, DST_Y, DST) \ + (*in_data->utils->transfer_rect)( \ + in_data->effect_ref, (QUALITY), (M_FLAGS), (FIELD), (SRC_REC), (SRC_WORLD), \ + (COMP_MODE), (MASK_WORLD_0), (DST_X), (DST_Y), (DST)) + +#define PF_TRANSFORM_WORLD(QUALITY, M_FLAGS, FIELD, SRC_WORLD, COMP_MODE, \ + MASK_WORLD_0, MATRICES, NUM_MATRICES, SRC2DST_MATRIX, \ + DST_RECT, DST) \ + (*in_data->utils->transform_world)( \ + in_data->effect_ref, (QUALITY), (M_FLAGS), (FIELD), (SRC_WORLD), \ + (COMP_MODE), (MASK_WORLD_0), (MATRICES), (NUM_MATRICES), (SRC2DST_MATRIX), \ + (DST_RECT), (DST)) + +#define PF_ITERATE_ORIGIN_NON_SRC_CLIP(PROG_BASE, PROG_FINAL, SRC, RCT_P, OR, REFCON, PIX_FUNC, DST) \ + (*in_data->utils->iterate_origin_non_clip_src)( \ + in_data, (PROG_BASE), (PROG_FINAL), (SRC), (RCT_P), (OR), (REFCON), (PIX_FUNC), (DST)) + + +#define PF_NEW_HANDLE(SIZE) \ + (*in_data->utils->host_new_handle)((SIZE)) + +#define PF_DISPOSE_HANDLE(PF_HANDLE) \ + (*in_data->utils->host_dispose_handle)((PF_Handle)(PF_HANDLE)) + +#define PF_LOCK_HANDLE(PF_HANDLE) \ + (*in_data->utils->host_lock_handle)((PF_Handle)(PF_HANDLE)) + +#define PF_UNLOCK_HANDLE(PF_HANDLE) \ + (*in_data->utils->host_unlock_handle)((PF_Handle)(PF_HANDLE)) + +#define PF_GET_HANDLE_SIZE(PF_HANDLE) \ + (*in_data->utils->host_get_handle_size)((PF_Handle)(PF_HANDLE)) + + +// Takes a pointer to a handle. Handle may change. 4.1 and later ONLY. +#define PF_RESIZE_HANDLE(NEW_SIZE, PF_HANDLE_P) \ + (*in_data->utils->host_resize_handle)((NEW_SIZE), (PF_Handle*)(PF_HANDLE_P)) + + + +#define PF_GET_PLATFORM_DATA(ID, DATA) \ + (*in_data->utils->get_platform_data)(in_data->effect_ref, (ID), (DATA)) + +#define PF_GET_PIXEL_DATA8(WORLDP, PIXELPTR0, PIXEL8PP) \ + (*in_data->utils->get_pixel_data8)((WORLDP), (PIXELPTR0), (PIXEL8PP)) + +#define PF_GET_PIXEL_DATA16(WORLDP, PIXELPTR0, PIXEL16PP) \ + (*in_data->utils->get_pixel_data16)((WORLDP), (PIXELPTR0), (PIXEL16PP)) + + + + +#define PF_ACOS(X) (*in_data->utils->ansi.acos)(X) +#define PF_ASIN(X) (*in_data->utils->ansi.asin)(X) +#define PF_ATAN(X) (*in_data->utils->ansi.atan)(X) +#define PF_ATAN2(Y, X) (*in_data->utils->ansi.atan2)((Y), (X)) +#define PF_CEIL(X) (*in_data->utils->ansi.ceil)(X) +#define PF_COS(X) (*in_data->utils->ansi.cos)(X) +#define PF_EXP(X) (*in_data->utils->ansi.exp)(X) +#define PF_FABS(X) (*in_data->utils->ansi.fabs)(X) +#define PF_FLOOR(X) (*in_data->utils->ansi.floor)(X) +#define PF_FMOD(X, Y) (*in_data->utils->ansi.fmod)((X), (Y)) +#define PF_HYPOT(X, Y) (*in_data->utils->ansi.hypot)((X), (Y)) +#define PF_LOG(X) (*in_data->utils->ansi.log)(X) +#define PF_LOG10(X) (*in_data->utils->ansi.log10)(X) +#define PF_POW(X, Y) (*in_data->utils->ansi.pow)((X), (Y)) +#define PF_SIN(X) (*in_data->utils->ansi.sin)(X) +#define PF_SQRT(X) (*in_data->utils->ansi.sqrt)(X) +#define PF_TAN(X) (*in_data->utils->ansi.tan)(X) + +/* This is kind of a hack to deal with the varargs params to sprintf */ + +#define PF_SPRINTF (*in_data->utils->ansi.sprintf) + +#define PF_STRCPY(DST, SRC) \ + (*in_data->utils->ansi.strcpy)((DST), (SRC)) + + + +#define PF_RGB_TO_HLS(RGB, HLS) \ + (*in_data->utils->colorCB.RGBtoHLS)(in_data->effect_ref, (RGB), (HLS)) + +#define PF_HLS_TO_RGB(HLS, RGB) \ + (*in_data->utils->colorCB.HLStoRGB)(in_data->effect_ref, (HLS), (RGB)) + +#define PF_RGB_TO_YIQ(RGB, YIQ) \ + (*in_data->utils->colorCB.RGBtoYIQ)(in_data->effect_ref, (RGB), (YIQ)) + +#define PF_YIQ_TO_RGB(YIQ, RGB) \ + (*in_data->utils->colorCB.YIQtoRGB)(in_data->effect_ref, (YIQ), (RGB)) + +#define PF_LUMINANCE(RGB, LUM100) \ + (*in_data->utils->colorCB.Luminance)(in_data->effect_ref, (RGB), (LUM100)) + +#define PF_HUE(RGB, HUE) \ + (*in_data->utils->colorCB.Hue)(in_data->effect_ref, (RGB), (HUE)) + +#define PF_LIGHTNESS(RGB, LIGHTNESS) \ + (*in_data->utils->colorCB.Lightness)(in_data->effect_ref, (RGB), (LIGHTNESS)) + +#define PF_SATURATION(RGB, SATURATION) \ + (*in_data->utils->colorCB.Saturation)(in_data->effect_ref, (RGB), (SATURATION)) + + + + +#ifdef __cplusplus + } // end extern "C" +#endif + + + +#include + + +#endif /* _H_AE_EffectCB */ diff --git a/External/AE SDK/Headers/AE_EffectCBSuites.h b/External/AE SDK/Headers/AE_EffectCBSuites.h new file mode 100644 index 00000000..901023fe --- /dev/null +++ b/External/AE SDK/Headers/AE_EffectCBSuites.h @@ -0,0 +1,914 @@ +/*******************************************************************/ +/* */ +/* ADOBE CONFIDENTIAL */ +/* _ _ _ _ _ _ _ _ _ _ _ _ _ */ +/* */ +/* Copyright 2007 Adobe Systems Incorporated */ +/* All Rights Reserved. */ +/* */ +/* NOTICE: All information contained herein is, and remains the */ +/* property of Adobe Systems Incorporated and its suppliers, if */ +/* any. The intellectual and technical concepts contained */ +/* herein are proprietary to Adobe Systems Incorporated and its */ +/* suppliers and may be covered by U.S. and Foreign Patents, */ +/* patents in process, and are protected by trade secret or */ +/* copyright law. Dissemination of this information or */ +/* reproduction of this material is strictly forbidden unless */ +/* prior written permission is obtained from Adobe Systems */ +/* Incorporated. */ +/* */ +/*******************************************************************/ + + +#ifndef _H_AE_EffectCBSuites +#define _H_AE_EffectCBSuites + + +#include +#include +#include + +#include + +#ifdef __cplusplus + extern "C" { +#endif + +// note: many of these suites are not SPAPI because they are shared with the +// old-style PF_UtilCallback definitions and we want calls to them to +// be object compatible + +#define kPFHandleSuite "PF Handle Suite" +#define kPFHandleSuiteVersion1 2 /* frozen in AE 10.0 */ + +//Keeping the same version for compatibility reasons but bumping the actual value for 64-bit SDK. Please define A_HandleSize +//as A_u_long to get the same suite working with 32-bit SDK. + +typedef struct PF_HandleSuite1 { + PF_Handle (*host_new_handle)( + A_HandleSize size); + + void * (*host_lock_handle)( + PF_Handle pf_handle); + + void (*host_unlock_handle)( + PF_Handle pf_handle); + + void (*host_dispose_handle)( + PF_Handle pf_handle); + + A_HandleSize (*host_get_handle_size)( + PF_Handle pf_handle); + + PF_Err (*host_resize_handle)( + A_HandleSize new_sizeL, /* >> */ + PF_Handle *handlePH); /* <> Handle Value May Change */ + +} PF_HandleSuite1; + + +#define kPFANSISuite "PF ANSI Suite" +#define kPFANSISuiteVersion1 1 /* frozen in AE 5.0 */ + +typedef struct PF_ANSICallbacksSuite1 { + A_FpLong (*atan)(A_FpLong); + A_FpLong (*atan2)(A_FpLong y, A_FpLong x); /* returns atan(y/x) - note param order! */ + A_FpLong (*ceil)(A_FpLong); /* returns next int above x */ + A_FpLong (*cos)(A_FpLong); + A_FpLong (*exp)(A_FpLong); /* returns e to the x power */ + A_FpLong (*fabs)(A_FpLong); /* returns absolute value of x */ + A_FpLong (*floor)(A_FpLong); /* returns closest int below x */ + A_FpLong (*fmod)(A_FpLong x, A_FpLong y); /* returns x mod y */ + A_FpLong (*hypot)(A_FpLong x, A_FpLong y); /* returns sqrt(x*x + y*y) */ + A_FpLong (*log)(A_FpLong); /* returns natural log of x */ + A_FpLong (*log10)(A_FpLong); /* returns log base 10 of x */ + A_FpLong (*pow)(A_FpLong x, A_FpLong y); /* returns x to the y power */ + A_FpLong (*sin)(A_FpLong); + A_FpLong (*sqrt)(A_FpLong); + A_FpLong (*tan)(A_FpLong); + + int (*sprintf)(A_char *, const A_char *, ...); + A_char * (*strcpy)(A_char *, const A_char *); + + A_FpLong (*asin)(A_FpLong); + A_FpLong (*acos)(A_FpLong); + +} PF_ANSICallbacksSuite1; + + +#define kPFPixelDataSuite "PF Pixel Data Suite" +#define kPFPixelDataSuiteVersion1 1 /* frozen in AE 7.0 */ + +typedef struct PF_PixelDataSuite1 { + + PF_Err (*get_pixel_data8)( + PF_EffectWorld *worldP, + PF_PixelPtr pixelsP0, // NULL to use data in PF_EffectWorld + PF_Pixel8 **pixPP); // will return NULL if depth mismatch + + PF_Err (*get_pixel_data16)( + PF_EffectWorld *worldP, + PF_PixelPtr pixelsP0, // NULL to use data in PF_EffectWorld + PF_Pixel16 **pixPP); // will return NULL if depth mismatch + + PF_Err (*get_pixel_data_float)( + PF_EffectWorld *worldP, + PF_PixelPtr pixelsP0, // NULL to use data in PF_EffectWorld + PF_PixelFloat **pixPP); // will return NULL if depth mismatch + + +} PF_PixelDataSuite1; + + +#define kPFPixelDataSuiteVersion2 2 /* frozen in AE 16.0 */ + +typedef struct PF_PixelDataSuite2 { + + PF_Err (*get_pixel_data8)( + PF_EffectWorld *worldP, + PF_PixelPtr pixelsP0, // NULL to use data in PF_EffectWorld + PF_Pixel8 **pixPP); // will return NULL if depth mismatch + + PF_Err (*get_pixel_data16)( + PF_EffectWorld *worldP, + PF_PixelPtr pixelsP0, // NULL to use data in PF_EffectWorld + PF_Pixel16 **pixPP); // will return NULL if depth mismatch + + PF_Err (*get_pixel_data_float)( + PF_EffectWorld *worldP, + PF_PixelPtr pixelsP0, // NULL to use data in PF_EffectWorld + PF_PixelFloat **pixPP); // will return NULL if depth mismatch + + PF_Err (*get_pixel_data_float_gpu)( + PF_EffectWorld *worldP, + void **pixPP); // will return NULL if depth mismatch + +} PF_PixelDataSuite2; + + +#define kPFColorCallbacksSuite "PF Color Suite" +#define kPFColorCallbacksSuiteVersion1 1 /* frozen in AE 5.0 */ + + +typedef struct PF_ColorCallbacksSuite1 { + PF_Err (*RGBtoHLS)( + PF_ProgPtr effect_ref, /* reference from in_data */ + PF_Pixel *rgb, + PF_HLS_Pixel hls); + + PF_Err (*HLStoRGB)( + PF_ProgPtr effect_ref, /* reference from in_data */ + PF_HLS_Pixel hls, + PF_Pixel *rgb); + + PF_Err (*RGBtoYIQ)( + PF_ProgPtr effect_ref, /* reference from in_data */ + PF_Pixel *rgb, + PF_YIQ_Pixel yiq); + + PF_Err (*YIQtoRGB)( + PF_ProgPtr effect_ref, /* reference from in_data */ + PF_HLS_Pixel yiq, + PF_Pixel *rgb); + + PF_Err (*Luminance)( + PF_ProgPtr effect_ref, /* reference from in_data */ + PF_Pixel *rgb, + A_long *lum100); /* << 100 * luminance */ + + PF_Err (*Hue)( + PF_ProgPtr effect_ref, /* reference from in_data */ + PF_Pixel *rgb, + A_long *hue); /* << 0-255 maps to 0-360 */ + + PF_Err (*Lightness)( + PF_ProgPtr effect_ref, /* reference from in_data */ + PF_Pixel *rgb, + A_long *lightness); /* << goes from 0-255 */ + + PF_Err (*Saturation)( + PF_ProgPtr effect_ref, /* reference from in_data */ + PF_Pixel *rgb, + A_long *saturation); /* << goes from 0-255 */ + +} PF_ColorCallbacksSuite1; + +#define kPFColorCallbacks16Suite "PF Color16 Suite" +#define kPFColorCallbacks16SuiteVersion1 1 /* frozen in AE 5.0 */ + + +typedef struct PF_ColorCallbacks16Suite1 { + PF_Err (*RGBtoHLS)( + PF_ProgPtr effect_ref, /* reference from in_data */ + PF_Pixel16 *rgb, + PF_HLS_Pixel hls); + + PF_Err (*HLStoRGB)( + PF_ProgPtr effect_ref, /* reference from in_data */ + PF_HLS_Pixel hls, + PF_Pixel16 *rgb); + + PF_Err (*RGBtoYIQ)( + PF_ProgPtr effect_ref, /* reference from in_data */ + PF_Pixel16 *rgb, + PF_YIQ_Pixel yiq); + + PF_Err (*YIQtoRGB)( + PF_ProgPtr effect_ref, /* reference from in_data */ + PF_HLS_Pixel yiq, + PF_Pixel16 *rgb); + + PF_Err (*Luminance)( + PF_ProgPtr effect_ref, /* reference from in_data */ + PF_Pixel16 *rgb, + A_long *lum100); /* << 100 * luminance */ + + PF_Err (*Hue)( + PF_ProgPtr effect_ref, /* reference from in_data */ + PF_Pixel16 *rgb, + A_long *hue); /* << 0-255 maps to 0-360 */ + + PF_Err (*Lightness)( + PF_ProgPtr effect_ref, /* reference from in_data */ + PF_Pixel16 *rgb, + A_long *lightness); /* << goes from 0-32768 */ + + PF_Err (*Saturation)( + PF_ProgPtr effect_ref, /* reference from in_data */ + PF_Pixel16 *rgb, + A_long *saturation); /* << goes from 0-32768 */ + +} PF_ColorCallbacks16Suite1; + + + + +#define kPFColorCallbacksFloatSuite "PF ColorFloat Suite" +#define kPFColorCallbacksFloatSuiteVersion1 1 /* frozen in AE 7.0 */ + + +typedef struct PF_ColorCallbacksFloatSuite1 { + PF_Err (*RGBtoHLS)( + PF_ProgPtr effect_ref, /* reference from in_data */ + PF_PixelFloat *rgb, + PF_HLS_Pixel hls); + + PF_Err (*HLStoRGB)( + PF_ProgPtr effect_ref, /* reference from in_data */ + PF_HLS_Pixel hls, + PF_PixelFloat *rgb); + + PF_Err (*RGBtoYIQ)( + PF_ProgPtr effect_ref, /* reference from in_data */ + PF_PixelFloat *rgb, + PF_YIQ_Pixel yiq); + + PF_Err (*YIQtoRGB)( + PF_ProgPtr effect_ref, /* reference from in_data */ + PF_HLS_Pixel yiq, + PF_PixelFloat *rgb); + + PF_Err (*Luminance)( + PF_ProgPtr effect_ref, /* reference from in_data */ + PF_PixelFloat *rgb, + float *lumP); /* << luminance -- note *not* 100*lum */ + + PF_Err (*Hue)( + PF_ProgPtr effect_ref, /* reference from in_data */ + PF_PixelFloat *rgb, + float *hue); /* 0..360 float */ + + PF_Err (*Lightness)( + PF_ProgPtr effect_ref, /* reference from in_data */ + PF_PixelFloat *rgb, + float *lightness); /* << */ + + PF_Err (*Saturation)( + PF_ProgPtr effect_ref, /* reference from in_data */ + PF_PixelFloat *rgb, + float *saturation); /* << */ + +} PF_ColorCallbacksFloatSuite1; + + + +#define kPFBatchSamplingSuite "PF Batch Sampling Suite" +#define kPFBatchSamplingSuiteVersion1 1 /* frozen in AE 5.0 */ + + +typedef struct PF_BatchSamplingSuite1 { + PF_Err (*begin_sampling)( + PF_ProgPtr effect_ref, /* reference from in_data */ + PF_Quality qual, + PF_ModeFlags mf, + PF_SampPB *params); + + PF_Err (*end_sampling)( + PF_ProgPtr effect_ref, /* reference from in_data */ + PF_Quality qual, + PF_ModeFlags mf, + PF_SampPB *params); + + PF_Err (*get_batch_func)( + PF_ProgPtr effect_ref, /* reference from in_data */ + PF_Quality quality, + PF_ModeFlags mode_flags, + const PF_SampPB *params, + PF_BatchSampleFunc *batch); + + PF_Err (*get_batch_func16)( + PF_ProgPtr effect_ref, /* reference from in_data */ + PF_Quality quality, + PF_ModeFlags mode_flags, + const PF_SampPB *params, + PF_BatchSample16Func *batch); + +} PF_BatchSamplingSuite1; + + +#define kPFSampling8Suite "PF Sampling8 Suite" +#define kPFSampling8SuiteVersion1 1 /* frozen in AE 5.0 */ + +typedef struct PF_Sampling8Suite1 { + + PF_Err (*nn_sample)( + PF_ProgPtr effect_ref, /* reference from in_data */ + PF_Fixed x, + PF_Fixed y, + const PF_SampPB *params, + PF_Pixel *dst_pixel); + + PF_Err (*subpixel_sample)( + PF_ProgPtr effect_ref, /* reference from in_data */ + PF_Fixed x, + PF_Fixed y, + const PF_SampPB *params, + PF_Pixel *dst_pixel); + + PF_Err (*area_sample)( + PF_ProgPtr effect_ref, /* reference from in_data */ + PF_Fixed x, + PF_Fixed y, + const PF_SampPB *params, + PF_Pixel *dst_pixel); + + +} PF_Sampling8Suite1; + +#define kPFSampling16Suite "PF Sampling16 Suite" +#define kPFSampling16SuiteVersion1 1 /* frozen in AE 5.0 */ + + +typedef struct PF_Sampling16Suite1 { + + PF_Err (*nn_sample16)( + PF_ProgPtr effect_ref, /* reference from in_data */ + PF_Fixed x, + PF_Fixed y, + const PF_SampPB *params, + PF_Pixel16 *dst_pixel); + + PF_Err (*subpixel_sample16)( + PF_ProgPtr effect_ref, /* reference from in_data */ + PF_Fixed x, + PF_Fixed y, + const PF_SampPB *params, + PF_Pixel16 *dst_pixel); + + PF_Err (*area_sample16)( + PF_ProgPtr effect_ref, /* reference from in_data */ + PF_Fixed x, + PF_Fixed y, + const PF_SampPB *params, + PF_Pixel16 *dst_pixel); + +} PF_Sampling16Suite1; + + +#define kPFSamplingFloatSuite "PF SamplingFloat Suite" +#define kPFSamplingFloatSuiteVersion1 1 /* frozen in AE 7.0 */ + + +typedef struct PF_SamplingFloatSuite1 { + + PF_Err (*nn_sample_float)( + PF_ProgPtr effect_ref, /* reference from in_data */ + PF_Fixed x, + PF_Fixed y, + const PF_SampPB *params, + PF_PixelFloat *dst_pixel); + + PF_Err (*subpixel_sample_float)( + PF_ProgPtr effect_ref, /* reference from in_data */ + PF_Fixed x, + PF_Fixed y, + const PF_SampPB *params, + PF_PixelFloat *dst_pixel); + + PF_Err (*area_sample_float)( + PF_ProgPtr effect_ref, /* reference from in_data */ + PF_Fixed x, + PF_Fixed y, + const PF_SampPB *params, + PF_PixelFloat *dst_pixel); + +} PF_SamplingFloatSuite1; + + + + +#define kPFWorldSuite "PF World Suite" +#define kPFWorldSuiteVersion2 2 /* frozen in AE 7.0 */ + + +typedef struct PF_WorldSuite2 { + + PF_Err (*PF_NewWorld)( + PF_ProgPtr effect_ref, /* reference from in_data */ + A_long widthL, + A_long heightL, + PF_Boolean clear_pixB, + PF_PixelFormat pixel_format, + PF_EffectWorld *worldP); + + PF_Err (*PF_DisposeWorld)( + PF_ProgPtr effect_ref, /* reference from in_data */ + PF_EffectWorld *worldP); + + + PF_Err (*PF_GetPixelFormat)( + const PF_EffectWorld *worldP, /* the pixel buffer of interest */ + PF_PixelFormat *pixel_formatP); /* << OUT. one of the above PF_PixelFormat types */ + + +} PF_WorldSuite2; + + + + + +#define kPFPixelFormatSuite "PF Pixel Format Suite" +#define kPFPixelFormatSuiteVersion2 2 + + +// call during global setup + +typedef struct PF_PixelFormatSuite2 { + + PF_Err (*PF_AddSupportedPixelFormat)( + PF_ProgPtr effect_ref, /* reference from in_data */ + PF_PixelFormat pixel_format); /* add a supported pixel format */ + + + PF_Err (*PF_ClearSupportedPixelFormats)( + PF_ProgPtr effect_ref); /* reference from in_data */ + +} PF_PixelFormatSuite2; + + + + + +#define kPFWorldSuite "PF World Suite" +#define kPFWorldSuiteVersion1 1 /* frozen in AE 5.0 */ + + +typedef struct PF_WorldSuite1 { + + PF_Err (*new_world)( + PF_ProgPtr effect_ref, /* reference from in_data */ + A_long width, + A_long height, + PF_NewWorldFlags flags, /* should would be pre-cleared to zeroes */ + PF_EffectWorld *world); /* always 32 bit */ + + PF_Err (*dispose_world)( + PF_ProgPtr effect_ref, /* reference from in_data */ + PF_EffectWorld *world); + + +} PF_WorldSuite1; + + + +#define kPFIterate8Suite "PF Iterate8 Suite" +#define kPFIterate8SuiteVersion1 1 /* frozen in AE 5.0 */ + + +typedef struct PF_Iterate8Suite1 { + PF_Err (*iterate)( + PF_InData *in_data, + A_long progress_base, + A_long progress_final, + PF_EffectWorld *src, + const PF_Rect *area, /* pass NULL for all pixels */ + void* refcon, + PF_Err (*pix_fn)(void* refcon, A_long x, A_long y, PF_Pixel *in, PF_Pixel *out), + PF_EffectWorld *dst); + + + PF_Err (*iterate_origin)( + PF_InData *in_data, + A_long progress_base, + A_long progress_final, + PF_EffectWorld *src, + const PF_Rect *area, /* pass NULL for all pixels */ + const PF_Point *origin, + void* refcon, + PF_Err (*pix_fn)(void* refcon, A_long x, A_long y, PF_Pixel *in, PF_Pixel *out), + PF_EffectWorld *dst); + + PF_Err (*iterate_lut)( + PF_InData *in_data, + A_long progress_base, + A_long progress_final, + PF_EffectWorld *src, + const PF_Rect *area, /* pass NULL for all pixels */ + A_u_char *a_lut0, /* pass NULL for identity */ + A_u_char *r_lut0, /* pass NULL for identity */ + A_u_char *g_lut0, /* pass NULL for identity */ + A_u_char *b_lut0, /* pass NULL for identity */ + PF_EffectWorld *dst); + + PF_Err (*iterate_origin_non_clip_src)( + PF_InData *in_data, + A_long progress_base, + A_long progress_final, + PF_EffectWorld *src, + const PF_Rect *area, + const PF_Point *origin, + void* refcon, + PF_Err (*pix_fn)(void* refcon, A_long x, A_long y, PF_Pixel *in, PF_Pixel *out), + PF_EffectWorld *dst); + + PF_Err (*iterate_generic)( + A_long iterationsL, /* >> */ // can be PF_Iterations_ONCE_PER_PROCESSOR + void *refconPV, /* >> */ + PF_Err (*fn_func)( void *refconPV, /* >> */ + A_long thread_indexL, // only call abort and progress from thread_indexL == 0. + A_long i, + A_long iterationsL)); // never sends PF_Iterations_ONCE_PER_PROCESSOR + +} PF_Iterate8Suite1; + +#define kPFIterate8SuiteVersion2 2 /* frozen in AE 22.0 */ + +typedef struct PF_Iterate8Suite2 { + PF_Err(*iterate)( + PF_InData *in_data, + A_long progress_base, + A_long progress_final, + PF_EffectWorld *src, + const PF_Rect *area, /* pass NULL for all pixels */ + void *refcon, + PF_Err(*pix_fn)(void* refcon, A_long x, A_long y, PF_Pixel* in, PF_Pixel* out), + PF_EffectWorld *dst); + + + PF_Err(*iterate_origin)( + PF_InData *in_data, + A_long progress_base, + A_long progress_final, + PF_EffectWorld *src, + const PF_Rect *area, /* pass NULL for all pixels */ + const PF_Point *origin, + void *refcon, + PF_Err(*pix_fn)(void* refcon, A_long x, A_long y, PF_Pixel* in, PF_Pixel* out), + PF_EffectWorld *dst); + + PF_Err(*iterate_lut)( + PF_InData *in_data, + A_long progress_base, + A_long progress_final, + PF_EffectWorld *src, + const PF_Rect *area, /* pass NULL for all pixels */ + A_u_char *a_lut0, /* pass NULL for identity */ + A_u_char *r_lut0, /* pass NULL for identity */ + A_u_char *g_lut0, /* pass NULL for identity */ + A_u_char *b_lut0, /* pass NULL for identity */ + PF_EffectWorld *dst); + + PF_Err(*iterate_origin_non_clip_src)( + PF_InData *in_data, + A_long progress_base, + A_long progress_final, + PF_EffectWorld *src, + const PF_Rect *area, + const PF_Point *origin, + void *refcon, + PF_Err(*pix_fn)(void* refcon, A_long x, A_long y, PF_Pixel* in, PF_Pixel* out), + PF_EffectWorld *dst); + + PF_Err(*iterate_generic)( + A_long iterationsL, /* >> */ // can be PF_Iterations_ONCE_PER_PROCESSOR + void *refconPV, /* >> */ + PF_Err(*fn_func)( + void *refconPV, /* >> */ + A_long thread_indexL, // only call abort and progress from thread_indexL == 0. + A_long i, + A_long iterationsL)); // never sends PF_Iterations_ONCE_PER_PROCESSOR + +} PF_Iterate8Suite2; + +#define kPFIterate16Suite "PF iterate16 Suite" +#define kPFIterate16SuiteVersion1 1 /* frozen in AE 5.0 */ + + +typedef struct PF_iterate16Suite1 { + PF_Err (*iterate)( + PF_InData *in_data, + A_long progress_base, + A_long progress_final, + PF_EffectWorld *src, + const PF_Rect *area, /* pass NULL for all pixels */ + void* refcon, + PF_Err (*pix_fn)(void* refcon, A_long x, A_long y, PF_Pixel16 *in, PF_Pixel16 *out), + PF_EffectWorld *dst); + + + PF_Err (*iterate_origin)( + PF_InData *in_data, + A_long progress_base, + A_long progress_final, + PF_EffectWorld *src, + const PF_Rect *area, /* pass NULL for all pixels */ + const PF_Point *origin, + void* refcon, + PF_Err (*pix_fn)(void* refcon, A_long x, A_long y, PF_Pixel16 *in, PF_Pixel16 *out), + PF_EffectWorld *dst); + + PF_Err (*iterate_origin_non_clip_src)( + PF_InData *in_data, + A_long progress_base, + A_long progress_final, + PF_EffectWorld *src, + const PF_Rect *area, + const PF_Point *origin, + void* refcon, + PF_Err (*pix_fn)(void* refcon, A_long x, A_long y, PF_Pixel16 *in, PF_Pixel16 *out), + PF_EffectWorld *dst); + +} PF_Iterate16Suite1; + +#define kPFIterate16SuiteVersion2 2 /* frozen in AE 22.0 */ + +typedef struct PF_iterate16Suite2 { + PF_Err(*iterate)( + PF_InData *in_data, + A_long progress_base, + A_long progress_final, + PF_EffectWorld *src, + const PF_Rect *area, /* pass NULL for all pixels */ + void *refcon, + PF_Err(*pix_fn)(void* refcon, A_long x, A_long y, PF_Pixel16* in, PF_Pixel16* out), + PF_EffectWorld *dst); + + + PF_Err(*iterate_origin)( + PF_InData *in_data, + A_long progress_base, + A_long progress_final, + PF_EffectWorld *src, + const PF_Rect *area, /* pass NULL for all pixels */ + const PF_Point *origin, + void *refcon, + PF_Err(*pix_fn)(void* refcon, A_long x, A_long y, PF_Pixel16* in, PF_Pixel16* out), + PF_EffectWorld *dst); + + PF_Err(*iterate_origin_non_clip_src)( + PF_InData *in_data, + A_long progress_base, + A_long progress_final, + PF_EffectWorld *src, + const PF_Rect *area, + const PF_Point *origin, + void *refcon, + PF_Err(*pix_fn)(void* refcon, A_long x, A_long y, PF_Pixel16* in, PF_Pixel16* out), + PF_EffectWorld *dst); + +} PF_Iterate16Suite2; + +#define kPFIterateFloatSuite "PF iterateFloat Suite" +#define kPFIterateFloatSuiteVersion1 1 /* frozen in AE 7.0 */ + + +typedef struct PF_iterateFloatSuite1 { + PF_Err (*iterate)( + PF_InData *in_data, + A_long progress_base, + A_long progress_final, + PF_EffectWorld *src, + const PF_Rect *area, /* pass NULL for all pixels */ + void* refcon, + PF_IteratePixelFloatFunc pix_fn, + PF_EffectWorld *dst); + + + PF_Err (*iterate_origin)( + PF_InData *in_data, + A_long progress_base, + A_long progress_final, + PF_EffectWorld *src, + const PF_Rect *area, /* pass NULL for all pixels */ + const PF_Point *origin, + void* refcon, + PF_IteratePixelFloatFunc pix_fn, + PF_EffectWorld *dst); + + PF_Err (*iterate_origin_non_clip_src)( + PF_InData *in_data, + A_long progress_base, + A_long progress_final, + PF_EffectWorld *src, + const PF_Rect *area, + const PF_Point *origin, + void* refcon, + PF_IteratePixelFloatFunc pix_fn, + PF_EffectWorld *dst); + +} PF_IterateFloatSuite1; + +#define kPFIterateFloatSuiteVersion2 2 /* frozen in AE 22.0 */ + +typedef struct PF_iterateFloatSuite2 { + PF_Err (*iterate)( + PF_InData *in_data, + A_long progress_base, + A_long progress_final, + PF_EffectWorld *src, + const PF_Rect *area, /* pass NULL for all pixels */ + void* refcon, + PF_IteratePixelFloatFunc pix_fn, + PF_EffectWorld *dst); + + + PF_Err (*iterate_origin)( + PF_InData *in_data, + A_long progress_base, + A_long progress_final, + PF_EffectWorld *src, + const PF_Rect *area, /* pass NULL for all pixels */ + const PF_Point *origin, + void* refcon, + PF_IteratePixelFloatFunc pix_fn, + PF_EffectWorld *dst); + + PF_Err (*iterate_origin_non_clip_src)( + PF_InData *in_data, + A_long progress_base, + A_long progress_final, + PF_EffectWorld *src, + const PF_Rect *area, + const PF_Point *origin, + void* refcon, + PF_IteratePixelFloatFunc pix_fn, + PF_EffectWorld *dst); + +} PF_IterateFloatSuite2; + +#define kPFWorldTransformSuite "PF World Transform Suite" +#define kPFWorldTransformSuiteVersion1 1 /* frozen in AE 5.0 */ + +typedef struct PF_WorldTransformSuite1 { + + PF_Err (*composite_rect)( + PF_ProgPtr effect_ref, /* from in_data */ + PF_Rect *src_rect, /* rectangle in source image */ + A_long src_opacity, /* opacity of src */ + PF_EffectWorld *source_wld, /* src PF world */ + A_long dest_x, /* upper left-hand corner of src rect...*/ + A_long dest_y, /* ... in composite image */ + PF_Field field_rdr, /* which scanlines to render (all, upper, lower) */ + PF_XferMode xfer_mode, /* Copy, Composite Behind, Composite In Front */ + PF_EffectWorld *dest_wld); /* Destination buffer. Already filled */ + + PF_Err (*blend)( + PF_ProgPtr effect_ref, /* reference from in_data */ + const PF_EffectWorld *src1, + const PF_EffectWorld *src2, + PF_Fixed ratio, /* 0 == full src1, 0x00010000 == full src2 */ + PF_EffectWorld *dst); + + PF_Err (*convolve)( + PF_ProgPtr effect_ref, /* reference from in_data */ + PF_EffectWorld *src, + const PF_Rect *area, /* pass NULL for all pixels */ + PF_KernelFlags flags, + A_long kernel_size, + void *a_kernel, + void *r_kernel, + void *g_kernel, + void *b_kernel, + PF_EffectWorld *dst); + + PF_Err (*copy)( + PF_ProgPtr effect_ref, /* reference from in_data */ + PF_EffectWorld *src, + PF_EffectWorld *dst, + PF_Rect *src_r, /* pass NULL for whole world */ + PF_Rect *dst_r); /* pass NULL for whole world */ + + PF_Err (*copy_hq)( + PF_ProgPtr effect_ref, /* reference from in_data */ + PF_EffectWorld *src, + PF_EffectWorld *dst, + PF_Rect *src_r, /* pass NULL for whole world */ + PF_Rect *dst_r); /* pass NULL for whole world */ + + + PF_Err (*transfer_rect)( + PF_ProgPtr effect_ref, + PF_Quality quality, + PF_ModeFlags m_flags, + PF_Field field, + const PF_Rect *src_rec, + const PF_EffectWorld *src_world, + const PF_CompositeMode *comp_mode, + const PF_MaskWorld *mask_world0, + A_long dest_x, + A_long dest_y, + PF_EffectWorld *dst_world); + + PF_Err (*transform_world)( + PF_ProgPtr effect_ref, + PF_Quality quality, + PF_ModeFlags m_flags, + PF_Field field, + const PF_EffectWorld *src_world, + const PF_CompositeMode *comp_mode, + const PF_MaskWorld *mask_world0, + const PF_FloatMatrix *matrices, + A_long num_matrices, + PF_Boolean src2dst_matrix, + const PF_Rect *dest_rect, + PF_EffectWorld *dst_world); + + +} PF_WorldTransformSuite1; + + +#define kPFFillMatteSuite "PF Fill Matte Suite" + + +#define kPFFillMatteSuiteVersion2 2 /* frozen in AE 7.0 */ +typedef struct PF_FillMatteSuite2 { + + PF_Err (*fill)( + PF_ProgPtr effect_ref, /* reference from in_data */ + const PF_Pixel *color, + const PF_Rect *dst_rect, /* pass NULL for whole world */ + PF_EffectWorld *world); + + PF_Err (*fill16)( + PF_ProgPtr effect_ref, /* reference from in_data */ + const PF_Pixel16 *color, + const PF_Rect *dst_rect, /* pass NULL for whole world */ + PF_EffectWorld *world); + + PF_Err (*fill_float)( + PF_ProgPtr effect_ref, /* reference from in_data */ + const PF_PixelFloat *color, + const PF_Rect *dst_rect, /* pass NULL for whole world */ + PF_EffectWorld *world); + + PF_Err (*premultiply)( + PF_ProgPtr effect_ref, /* reference from in_data */ + A_long forward, /* TRUE means convert non-premul to premul, FALSE mean reverse */ + PF_EffectWorld *dst); + + PF_Err (*premultiply_color)( + PF_ProgPtr effect_ref, /* reference from in_data */ + PF_EffectWorld *src, + const PF_Pixel *color, /* color to premultiply/unmultiply with */ + A_long forward, /* TRUE means convert non-premul to premul, FALSE mean reverse */ + PF_EffectWorld *dst); + + PF_Err (*premultiply_color16)( + PF_ProgPtr effect_ref, /* reference from in_data */ + PF_EffectWorld *src, + const PF_Pixel16 *color, /* color to premultiply/unmultiply with */ + A_long forward, /* TRUE means convert non-premul to premul, FALSE mean reverse */ + PF_EffectWorld *dst); + + PF_Err (*premultiply_color_float)( + PF_ProgPtr effect_ref, /* reference from in_data */ + PF_EffectWorld *src, + const PF_PixelFloat *color, /* color to premultiply/unmultiply with */ + A_long forward, /* TRUE means convert non-premul to premul, FALSE mean reverse */ + PF_EffectWorld *dst); + +} PF_FillMatteSuite2; + + + +#ifdef __cplusplus + } // end extern "C" +#endif + + + +#include + + +#endif + diff --git a/External/AE SDK/Headers/AE_EffectGPUSuites.h b/External/AE SDK/Headers/AE_EffectGPUSuites.h new file mode 100644 index 00000000..9874b46f --- /dev/null +++ b/External/AE SDK/Headers/AE_EffectGPUSuites.h @@ -0,0 +1,221 @@ +/*******************************************************************/ +/* */ +/* ADOBE CONFIDENTIAL */ +/* _ _ _ _ _ _ _ _ _ _ _ _ _ */ +/* */ +/* Copyright 2018 Adobe Systems Incorporated */ +/* All Rights Reserved. */ +/* */ +/* NOTICE: All information contained herein is, and remains the */ +/* property of Adobe Systems Incorporated and its suppliers, if */ +/* any. The intellectual and technical concepts contained */ +/* herein are proprietary to Adobe Systems Incorporated and its */ +/* suppliers and may be covered by U.S. and Foreign Patents, */ +/* patents in process, and are protected by trade secret or */ +/* copyright law. Dissemination of this information or */ +/* reproduction of this material is strictly forbidden unless */ +/* prior written permission is obtained from Adobe Systems */ +/* Incorporated. */ +/* */ +/*******************************************************************/ + +#ifndef _H_AE_EffectGPUSuites +#define _H_AE_EffectGPUSuites + +#include +#include + +#include + +#ifdef __cplusplus + extern "C" { +#endif + + +#define PF_CUDAVersion 10010 + + +#define kPFGPUDeviceSuite "PF GPU Device Suite" +#define kPFGPUDeviceSuiteVersion1 1 /* frozen in AE 16.0 */ + +typedef struct +{ + PF_GPU_Framework device_framework; + PF_Boolean compatibleB; // device meets minimum requriement for acceleration + + void* platformPV; // cl_platform_id + void* devicePV; // CUdevice or cl_device_id or MTLDevice + void* contextPV; // CUcontext or cl_context + void* command_queuePV; // CUstream or cl_command_queue or MTLCommandQueue + void* offscreen_opengl_contextPV; // CGLContextObj or HGLRC - only available on the primary device + void* offscreen_opengl_devicePV; // HDC - only available on the primary device + +} PF_GPUDeviceInfo; + + + +typedef struct PF_GPUDeviceSuite1 { + + /** + ** This will return the number of gpu devices the host supports. + ** + ** @param effect_ref Comes with PF_InData. + ** @param device_countP Return number of devices available. + */ + SPAPI PF_Err (*GetDeviceCount)( PF_ProgPtr effect_ref, + A_u_long *device_countP); /* << */ + + /** + ** This will return the device info with given device index, which includes necessary context/queue information + ** needed to dispatch task to the device. Refer PF_GPUDeviceInfo for details. + ** + ** @param effect_ref Comes with PF_InData. + ** @param device_index The device index for the requested device. + ** @param PF_GPUDeviceInfo The device info will to be filled. + */ + SPAPI PF_Err (*GetDeviceInfo)( PF_ProgPtr effect_ref, + A_u_long device_index, + PF_GPUDeviceInfo *device_infoP); /* << */ + + + /** + ** Acquire/release exclusive access to inDeviceIndex. All calls below this point generally require access be held. + ** For full GPU plugins (those that use a separate entry point for GPU rendering) exclusive access is always held. + ** These calls do not need to be made in that case. + ** For CUDA calls cuCtxPushCurrent/cuCtxPopCurrent on the current thread to manage the devices context. + */ + SPAPI PF_Err (*AcquireExclusiveDeviceAccess)( PF_ProgPtr effect_ref, + A_u_long device_index); + + SPAPI PF_Err (*ReleaseExclusiveDeviceAccess)( PF_ProgPtr effect_ref, + A_u_long device_index); + + /** + ** All device memory must be allocated through this suite. + ** Purge should be called only in emergency situations when working with GPU memory + ** that cannot be allocated through this suite (eg OpenGL memory). + ** Returned pointer value represents memory allocated through cuMemAlloc or clCreateBuffer. + */ + + SPAPI PF_Err (*AllocateDeviceMemory)( PF_ProgPtr effect_ref, + A_u_long device_index, + size_t size_bytes, + void **memoryPP); /* << */ + + SPAPI PF_Err (*FreeDeviceMemory)( PF_ProgPtr effect_ref, + A_u_long device_index, + void *memoryP); + + SPAPI PF_Err (*PurgeDeviceMemory)( PF_ProgPtr effect_ref, + A_u_long device_index, + size_t size_bytes, + size_t *bytes_purgedP0); /* << */ + + /** + ** All host (pinned) memory must be allocated through this suite. + ** Purge should be called only in emergency situations when working with GPU memory + ** that cannot be allocated through this suite (eg OpenGL memory). + ** Returned pointer value represents memory allocated through cuMemHostAlloc or malloc. + */ + SPAPI PF_Err (*AllocateHostMemory)( PF_ProgPtr effect_ref, + A_u_long device_index, + size_t size_bytes, + void **memoryPP); /* << */ + + + SPAPI PF_Err (*FreeHostMemory)( PF_ProgPtr effect_ref, + A_u_long device_index, + void *memoryP); + + + SPAPI PF_Err (*PurgeHostMemory)( PF_ProgPtr effect_ref, + A_u_long device_index, + size_t bytes_to_purge, + size_t *bytes_purgedP0); /* << */ + + /** + ** This will allocate a gpu effect world. Caller is responsible for deallocating the buffer with + ** PF_GPUDeviceSuite1::DisposeGPUWorld. + ** + ** @param effect_ref Comes with PF_InData. + ** @param device_index The device you want your gpu effect world allocated with. + ** @param width Width of the effect world. + ** @param height Height of the effect world. + ** @param pixel_aspect_ratio Pixel Aspect Ratio of the effect world. + ** @param field_type The field of the effect world. + ** @param pixel_format The pixel format of the effect world, only gpu formats are accepted. + ** @param clear_pixB Pass in 'true' for a transparent black frame. + ** @param worldPP The handle to the effect world to be created. + */ + SPAPI PF_Err (*CreateGPUWorld)( PF_ProgPtr effect_ref, + A_u_long device_index, + A_long width, + A_long height, + PF_RationalScale pixel_aspect_ratio, + PF_Field field_type, + PF_PixelFormat pixel_format, + PF_Boolean clear_pixB, + PF_EffectWorld **worldPP); /* << */ + + + /** + ** This will free this effect world. The effect world is no longer valid after this function is called. + ** Plugin module is only allowed to dispose of effect worlds they create. + ** + ** @param effect_ref Comes with PF_InData. + ** @param worldP The effect world you want to dispose. + */ + SPAPI PF_Err (*DisposeGPUWorld)( PF_ProgPtr effect_ref, + PF_EffectWorld *worldP); + + + /** + ** This will return the gpu buffer address of the given effect world. + ** + ** @param effect_ref Comes with PF_InData. + ** @param worldP The effect world you want to operate on, has to be a gpu effect world. + ** @param pixPP Returns the gpu buffer address. + */ + SPAPI PF_Err (*GetGPUWorldData)( PF_ProgPtr effect_ref, + PF_EffectWorld *worldP, + void **pixPP); /* << */ + + /** + ** This will return the size of the total data in the effect world. + ** + ** @param effect_ref Comes with PF_InData. + ** @param worldP The effect world you want to operate on, has to be a gpu effect world. + ** @param device_indexP Returns the size of the total data in the effect world. + */ + SPAPI PF_Err (*GetGPUWorldSize)( PF_ProgPtr effect_ref, + PF_EffectWorld *worldP, + size_t *size_in_bytesP); /* << */ + + + /** + ** This will return device index the gpu effect world is associated with. + ** + ** @param effect_ref Comes with PF_InData. + ** @param worldP The effect world you want to operate on, has to be a gpu effect world. + ** @param device_indexP Returns the device index of the given effect world. + */ + SPAPI PF_Err (*GetGPUWorldDeviceIndex)( PF_ProgPtr effect_ref, + PF_EffectWorld *worldP, + A_u_long *device_indexP); /* << */ + + +} PF_GPUDeviceSuite1; + + + +/**********************************************************/ +/**********************************************************/ + +#ifdef __cplusplus + } +#endif + + +#include + +#endif diff --git a/External/AE SDK/Headers/AE_EffectPixelFormat.h b/External/AE SDK/Headers/AE_EffectPixelFormat.h new file mode 100644 index 00000000..44635a64 --- /dev/null +++ b/External/AE SDK/Headers/AE_EffectPixelFormat.h @@ -0,0 +1,110 @@ +#ifndef _H_AE_PIXEL_FORMAT +#define _H_AE_PIXEL_FORMAT + +#include "A.h" + +/* data types for PF_EffectWorlds that are not just 8bpc ARGB + * + * see AE_EffectCBSuites.h for more details + * + */ + +#ifndef MAKE_PIXEL_FORMAT_FOURCC + +#define MAKE_PIXEL_FORMAT_FOURCC(ch0, ch1, ch2, ch3) \ + ((A_u_long)(A_u_char)(ch0) | ((A_u_long)(A_u_char)(ch1) << 8) | \ + ((A_u_long)(A_u_char)(ch2) << 16) | ((A_u_long)(A_u_char)(ch3) << 24 )) + +#endif + + +// +// note! MAKE_PIXEL_FORMAT_FOURCC('a', 'r', 'g', 'b') does not give the same result +// as the literal 'argb' in your compiler +// +// MS image compression interfaces define FOURCC this way (unlike QuickTime) so please +// be careful and use the enums as defined rather than rolling your own. +// + +enum { + PF_PixelFormat_ARGB32 = MAKE_PIXEL_FORMAT_FOURCC('a', 'r', 'g', 'b'), // After Effects-style ARGB, 8 bits per channel, range 0...255 + // trillions of pixels served since 1992. support required for After Effects + + PF_PixelFormat_ARGB64 = MAKE_PIXEL_FORMAT_FOURCC('a', 'e', '1', '6'), // After Effects-style ARGB, 16 bits per channel, range 0...32768 + PF_PixelFormat_ARGB128 = MAKE_PIXEL_FORMAT_FOURCC('a', 'e', '3', '2'), // After Effects-style ARGB, 32 bits floating point per channel, 1.0 is "white" + + + /* -------------------------------------------------------------------------------------- */ + + PF_PixelFormat_GPU_BGRA128 = MAKE_PIXEL_FORMAT_FOURCC('@', 'C', 'D', 'A'), // GPU, BGRA, 32 bits floating point per channel. + + PF_PixelFormat_RESERVED = MAKE_PIXEL_FORMAT_FOURCC('@', 'C', 'D', 'a'), // reserved for future use. + + /* -------------------------------------------------------------------------------------- */ + + PF_PixelFormat_BGRA32 = MAKE_PIXEL_FORMAT_FOURCC('b', 'g', 'r', 'a'), // Premiere-style BGRA, 8 bits per channel. Premiere-only; support required for Premiere + PF_PixelFormat_VUYA32 = MAKE_PIXEL_FORMAT_FOURCC('v', 'u', 'y', 'a'), // Premiere-style YUVA, 8 bits per channel. Premiere-only + + PF_PixelFormat_NTSCDV25 = MAKE_PIXEL_FORMAT_FOURCC('d', 'v', 'n', '2'), // compressed DV-25. Premiere only. + PF_PixelFormat_PALDV25 = MAKE_PIXEL_FORMAT_FOURCC('d', 'v', 'p', '2'), // compressed DV-25. Premiere only. + + PF_PixelFormat_INVALID = MAKE_PIXEL_FORMAT_FOURCC('b', 'a', 'd', 'f'), // invalid pixel format - this is used for intialization and error conditions + + + PF_PixelFormat_FORCE_LONG_INT = 0xFFFFFFFF +}; + +typedef A_long PF_PixelFormat; + + +#ifdef PREMIERE +// for Premiere-specific pixel format support +// some of these are aliases of formats already available as a PF_PixelFormat + +#ifndef PRSDKPIXELFORMAT_H +typedef PF_PixelFormat PrPixelFormat; + +enum { + // Uncompressed formats - these are most common for effects + PrPixelFormat_BGRA_4444_8u = PF_PixelFormat_BGRA32, + PrPixelFormat_VUYA_4444_8u = PF_PixelFormat_VUYA32, + PrPixelFormat_ARGB_4444_8u = PF_PixelFormat_ARGB32, + PrPixelFormat_BGRA_4444_16u = MAKE_PIXEL_FORMAT_FOURCC('B', 'g', 'r', 'a'), // 16 bit integer per component BGRA + PrPixelFormat_VUYA_4444_16u = MAKE_PIXEL_FORMAT_FOURCC('V', 'u', 'y', 'a'), // 16 bit integer per component VUYA + PrPixelFormat_ARGB_4444_16u = MAKE_PIXEL_FORMAT_FOURCC('A', 'r', 'g', 'b'), // 16 bit integer per component ARGB + PrPixelFormat_BGRA_4444_32f = MAKE_PIXEL_FORMAT_FOURCC('B', 'G', 'r', 'a'), // 32 bit float per component BGRA + PrPixelFormat_VUYA_4444_32f = MAKE_PIXEL_FORMAT_FOURCC('V', 'U', 'y', 'a'), // 32 bit float per component VUYA + PrPixelFormat_ARGB_4444_32f = MAKE_PIXEL_FORMAT_FOURCC('A', 'R', 'g', 'b'), // 32 bit float per component ARGB + + // Packed formats + PrPixelFormat_YUYV_422_8u_601 = MAKE_PIXEL_FORMAT_FOURCC('y', 'u', 'y', '2'), // 8 bit 422 YUY2 601 colorspace + PrPixelFormat_YUYV_422_8u_709 = MAKE_PIXEL_FORMAT_FOURCC('y', 'u', 'y', '3'), // 8 bit 422 YUY2 709 colorspace + PrPixelFormat_UYVY_422_8u_601 = MAKE_PIXEL_FORMAT_FOURCC('u', 'y', 'v', 'y'), // 8 bit 422 UYVY 601 colorspace + PrPixelFormat_UYVY_422_8u_709 = MAKE_PIXEL_FORMAT_FOURCC('u', 'y', 'v', '7'), // 8 bit 422 UYVY 709 colorspace + PrPixelFormat_V210_422_10u_601 = MAKE_PIXEL_FORMAT_FOURCC('v', '2', '1', '0'), // packed uncompressed 10 bit 422 YUV aka V210 601 colorspace + PrPixelFormat_V210_422_10u_709 = MAKE_PIXEL_FORMAT_FOURCC('v', '2', '1', '1'), + + // Planar formats + PrPixelFormat_YUV_420_MPEG2_FRAME_PICTURE_PLANAR_8u = MAKE_PIXEL_FORMAT_FOURCC('y', 'v', '1', '2'), // YUV with 2x2 chroma subsampling. Planar. (for MPEG-2) + PrPixelFormat_YUV_420_MPEG2_FIELD_PICTURE_PLANAR_8u = MAKE_PIXEL_FORMAT_FOURCC('y', 'v', 'i', '2'), // YUV with 2x2 chroma subsampling. Planar. (for MPEG-2) + + // Compressed formats + PrPixelFormat_NTSCDV25 = PF_PixelFormat_NTSCDV25, // compressed DV-25 + PrPixelFormat_PALDV25 = PF_PixelFormat_PALDV25, // compressed DV-25 + PrPixelFormat_720pDV100 = MAKE_PIXEL_FORMAT_FOURCC('d', 'v', '7', '1'), // compressed DV-100 720p + PrPixelFormat_1080iDV100 = MAKE_PIXEL_FORMAT_FOURCC('d', 'v', '1', '1'), // compressed DV-100 1080i + + // Raw, opaque data formats + PrPixelFormat_Raw = MAKE_PIXEL_FORMAT_FOURCC('r', 'a', 'w', 'w'), // raw, opaque data, with no row bytes or height + + // Invalid + PrPixelFormat_Invalid = PF_PixelFormat_INVALID, // invalid pixel format - this is used for intialization and error conditions + + PrPixelFormat_Any = 0 +}; + +#endif // PRSDKPIXELFORMAT_H + +#endif // PREMIERE + +#endif // AE_PixelFormat diff --git a/External/AE SDK/Headers/AE_EffectSuites.h b/External/AE SDK/Headers/AE_EffectSuites.h new file mode 100644 index 00000000..63a85492 --- /dev/null +++ b/External/AE SDK/Headers/AE_EffectSuites.h @@ -0,0 +1,728 @@ +/*******************************************************************/ +/* */ +/* ADOBE CONFIDENTIAL */ +/* _ _ _ _ _ _ _ _ _ _ _ _ _ */ +/* */ +/* Copyright 2007 Adobe Systems Incorporated */ +/* All Rights Reserved. */ +/* */ +/* NOTICE: All information contained herein is, and remains the */ +/* property of Adobe Systems Incorporated and its suppliers, if */ +/* any. The intellectual and technical concepts contained */ +/* herein are proprietary to Adobe Systems Incorporated and its */ +/* suppliers and may be covered by U.S. and Foreign Patents, */ +/* patents in process, and are protected by trade secret or */ +/* copyright law. Dissemination of this information or */ +/* reproduction of this material is strictly forbidden unless */ +/* prior written permission is obtained from Adobe Systems */ +/* Incorporated. */ +/* */ +/*******************************************************************/ + +#ifndef _H_AE_EffectSuites +#define _H_AE_EffectSuites + +#include +#include // for PF_CursorType +#include + +#include + +#ifdef __cplusplus + extern "C" { +#endif + + + +#define kPFPathQuerySuite "PF Path Query Suite" +#define kPFPathQuerySuiteVersion1 1 /* frozen in AE 5.0 */ + + +typedef struct PF_PathOutline *PF_PathOutlinePtr; +typedef struct PF_PathSegPrep *PF_PathSegPrepPtr; + +typedef struct PF_PathQuerySuite1 { + + SPAPI PF_Err (*PF_NumPaths)( PF_ProgPtr effect_ref, + A_long *num_pathsPL); /* << */ + + SPAPI PF_Err (*PF_PathInfo)( PF_ProgPtr effect_ref, + A_long indexL, + PF_PathID *unique_idP); /* << */ + + SPAPI PF_Err (*PF_CheckoutPath)( PF_ProgPtr effect_ref, + PF_PathID unique_id, + A_long what_time, + A_long time_step, + A_u_long time_scale, + PF_PathOutlinePtr *pathPP); /* << */ // can return NULL ptr if path doesn't exist + + SPAPI PF_Err (*PF_CheckinPath)( PF_ProgPtr effect_ref, + PF_PathID unique_id, + PF_Boolean changedB, + PF_PathOutlinePtr pathP); + +} PF_PathQuerySuite1; + + + +/* -------------------------------------------------------------------- */ + + +#define kPFPathDataSuite "PF Path Data Suite" +#define kPFPathDataSuiteVersion1 1 /* frozen in AE 5.0 */ + + +typedef struct { + + PF_FpLong x, y; + PF_FpLong tan_in_x, tan_in_y; + PF_FpLong tan_out_x, tan_out_y; + +} PF_PathVertex; + +#define PF_MAX_PATH_NAME_LEN 31 + + +typedef struct PF_PathDataSuite1 { + + SPAPI PF_Err (*PF_PathIsOpen)( PF_ProgPtr effect_ref0, + PF_PathOutlinePtr pathP, + PF_Boolean *openPB); + + // N segments means there are segments [0..N-1]; segment J is defined by vertex J & J+1 + SPAPI PF_Err (*PF_PathNumSegments)( PF_ProgPtr effect_ref0, + PF_PathOutlinePtr pathP, + A_long *num_segmentsPL); + + // which_pointL range: [0..num_segments]; for closed paths vertex[0] == vertex[num_segments] + SPAPI PF_Err (*PF_PathVertexInfo)( PF_ProgPtr effect_ref0, + PF_PathOutlinePtr pathP, + A_long which_pointL, + PF_PathVertex *vertexP); + + SPAPI PF_Err (*PF_PathPrepareSegLength)( + PF_ProgPtr effect_ref0, + PF_PathOutlinePtr pathP, + A_long which_segL, + A_long frequencyL, + PF_PathSegPrepPtr *lengthPrepPP); + + SPAPI PF_Err (*PF_PathGetSegLength)( PF_ProgPtr effect_ref0, + PF_PathOutlinePtr pathP, + A_long which_segL, + PF_PathSegPrepPtr *lengthPrepP0, + PF_FpLong *lengthPF); + + SPAPI PF_Err (*PF_PathEvalSegLength)(PF_ProgPtr effect_ref0, + PF_PathOutlinePtr pathP, + PF_PathSegPrepPtr *lengthPrepPP0, + A_long which_segL, + PF_FpLong lengthF, + PF_FpLong *x, + PF_FpLong *y); + + SPAPI PF_Err (*PF_PathEvalSegLengthDeriv1)( + PF_ProgPtr effect_ref0, + PF_PathOutlinePtr pathP, + PF_PathSegPrepPtr *lengthPrepPP0, + A_long which_segL, + PF_FpLong lengthF, + PF_FpLong *x, + PF_FpLong *y, + PF_FpLong *deriv1x, + PF_FpLong *deriv1y); + + + SPAPI PF_Err (*PF_PathCleanupSegLength)( + PF_ProgPtr effect_ref0, + PF_PathOutlinePtr pathP, + A_long which_segL, + PF_PathSegPrepPtr *lengthPrepPP); + + + SPAPI PF_Err (*PF_PathIsInverted)( PF_ProgPtr effect_ref, + PF_PathID unique_id, + PF_Boolean *invertedB); + + SPAPI PF_Err (*PF_PathGetMaskMode)( PF_ProgPtr effect_ref, + PF_PathID unique_id, + PF_MaskMode *modeP); + + SPAPI PF_Err (*PF_PathGetName)( PF_ProgPtr effect_ref, + PF_PathID unique_id, + A_char *nameZ); /* << can be up to PF_MAX_PATH_NAME_LEN+1 bytes long */ + + +} PF_PathDataSuite1; + + +/* -------------------------------------------------------------------- */ + +// New versions of state related APIs added in CS6 + +#define kPFParamUtilsSuite "PF Param Utils Suite" +#define kPFParamUtilsSuiteVersion3 3 // Frozen in AE CS6 [aka AE11.0] + +typedef struct { + A_long reservedAL[4]; +} PF_State; + + +#define PF_ParamIndex_NONE (-1L) +#define PF_ParamIndex_CHECK_ALL (-2L) +#define PF_ParamIndex_CHECK_ALL_EXCEPT_LAYER_PARAMS (-3L) +#define PF_ParamIndex_CHECK_ALL_HONOR_EXCLUDE (-4L) // Like PF_ParamIndex_CHECK_ALL, but honor PF_ParamFlag_EXCLUDE_FROM_HAVE_INPUTS_CHANGED + +#define PF_KeyIndex_NONE (-1L) + + +enum { + PF_TimeDir_GREATER_THAN = 0x0000, + PF_TimeDir_LESS_THAN = 0x0001, + PF_TimeDir_GREATER_THAN_OR_EQUAL = 0x1000, + PF_TimeDir_LESS_THAN_OR_EQUAL = 0x1001 +}; +typedef A_long PF_TimeDir; + +typedef A_long PF_KeyIndex; + + +/** PF_ParamUtilsSuite3 + + PF_UpdateParamUI() + + You can call this function for each param whose UI settings you + want to change when handling a PF_Cmd_USER_CHANGED_PARAM or + PF_Cmd_UPDATE_PARAMS_UI. These changes are cosmetic only, and don't + go into the undo buffer. + + The ONLY fields that can be changed in this way are: + + PF_ParamDef + ui_flags: PF_PUI_ECW_SEPARATOR, PF_PUI_DISABLED only (and PF_PUI_INVISIBLE in Premiere). + ui_width + ui_height + name + flags: PF_ParamFlag_COLLAPSE_TWIRLY only + + PF_ParamDefUnion: + slider_min, slider_max, precision, display_flags of any slider type + + For PF_PUI_STD_CONTROL_ONLY params, you can also change the value field by setting + PF_ChangeFlag_CHANGED_VALUE before returning. But you are not allowed to change + the value during PF_Cmd_UPDATE_PARAMS_UI. + + PF_GetCurrentState() / PF_AreStatesIdentical() + This API lets you determine if a set of your inputs (either layers, other properties, or both) + are different between when you first called PF_GetCurrentState() and a current call, so it can + be used for caching. You can specify a range of time to consider or all of time. + + For effects that do simulation across time and therefore set PF_OutFlag2_AUTOMATIC_WIDE_TIME_INPUT, + when you ask about a time range, it will be expanded to include any times needed to produce + that range. + + See doc on the old PF_HaveInputsChangedOverTimeSpan() for historical context. + +**/ + +typedef struct PF_ParamUtilsSuite3 { + + SPAPI PF_Err (*PF_UpdateParamUI)( + PF_ProgPtr effect_ref, + PF_ParamIndex param_index, + const PF_ParamDef *defP); + + // IMPORTANT: as of 13.5 to avoid threading deadlock problems, PF_GetCurrentState() returns a random state + // if used in the context of UPDATE_PARAMS_UI only. In other selectors this will behave normally. + SPAPI PF_Err (*PF_GetCurrentState)( + PF_ProgPtr effect_ref, + PF_ParamIndex param_index, + const A_Time *startPT0, // NULL for both start & duration means over all of time + const A_Time *durationPT0, + PF_State *stateP); /* << */ + + SPAPI PF_Err (*PF_AreStatesIdentical)( + PF_ProgPtr effect_ref, + const PF_State *state1P, + const PF_State *state2P, + A_Boolean *samePB); /* << */ + + SPAPI PF_Err (*PF_IsIdenticalCheckout)( + PF_ProgPtr effect_ref, + PF_ParamIndex param_index, + A_long what_time1, + A_long time_step1, + A_u_long time_scale1, + A_long what_time2, + A_long time_step2, + A_u_long time_scale2, + PF_Boolean *identicalPB); /* << */ + + SPAPI PF_Err (*PF_FindKeyframeTime)( + PF_ProgPtr effect_ref, + PF_ParamIndex param_index, + A_long what_time, + A_u_long time_scale, + PF_TimeDir time_dir, + PF_Boolean *foundPB, /* << */ + PF_KeyIndex *key_indexP0, /* << */ + A_long *key_timeP0, /* << */ // you can ask for either: + A_u_long *key_timescaleP0); /* << */ // time×cale OR neither + + SPAPI PF_Err (*PF_GetKeyframeCount)( + PF_ProgPtr effect_ref, + PF_ParamIndex param_index, + PF_KeyIndex *key_countP); /* << */ // returns PF_KeyIndex_NONE for constant + + SPAPI PF_Err (*PF_CheckoutKeyframe)( + PF_ProgPtr effect_ref, + PF_ParamIndex param_index, + PF_KeyIndex key_index, // zero-based + A_long *key_timeP0, /* << */ // you can ask for either: + A_u_long *key_timescaleP0, /* << */ // time×cale OR neither + PF_ParamDef *paramP0); /* << */ + + SPAPI PF_Err (*PF_CheckinKeyframe)( + PF_ProgPtr effect_ref, + PF_ParamDef *paramP); + + SPAPI PF_Err (*PF_KeyIndexToTime)( + PF_ProgPtr effect_ref, + PF_ParamIndex param_index, + PF_KeyIndex key_indexP, /* >> */ + A_long *key_timeP, /* >> */ + A_u_long *key_timescaleP); /* << */ + +} PF_ParamUtilsSuite3; + + + + +/* -------------------------------------------------------------------- */ + + +#define kPFColorParamSuite "PF ColorParamSuite" +#define kPFColorParamSuiteVersion1 1 /* frozen in AE 7.0 */ + +/** PF_ColorParamSuite1 + +**/ + +typedef struct PF_ColorParamSuite1 { + + // floating point color is in the working space of + // your effect, i.e. the same color space + // as the pixels you get + + // note that overrange and underrange values are possible + // even when project is not set to 32bpc + + SPAPI PF_Err (*PF_GetFloatingPointColorFromColorDef)( + PF_ProgPtr effect_ref, /* >> */ + const PF_ParamDef *color_defP, /* >> */ + PF_PixelFloat *fp_colorP); /* << */ + +} PF_ColorParamSuite1; + + + + +/* -------------------------------------------------------------------- */ + +#define kPFPointParamSuite "PF PointParamSuite" +#define kPFPointParamSuiteVersion1 1 /* frozen in AE 10.5 */ + +/** PF_PointParamSuite1 + +**/ + +typedef struct PF_PointParamSuite1 { + + // this api returns floating point value of a point parameter. + + SPAPI PF_Err (*PF_GetFloatingPointValueFromPointDef)( + PF_ProgPtr effect_ref, /* >> */ + const PF_ParamDef *point_defP, /* >> */ + A_FloatPoint *fp_pointP); /* << */ + +} PF_PointParamSuite1; + + +/* -------------------------------------------------------------------- */ + +#define kPFAngleParamSuite "PF AngleParamSuite" +#define kPFAngleParamSuiteVersion1 1 /* frozen in AE 11.0.x */ + +/** PF_AngleParamSuite1 + +**/ + +typedef struct PF_AngleParamSuite1 { + + // this api returns floating point value of an angle parameter. + + SPAPI PF_Err (*PF_GetFloatingPointValueFromAngleDef)( + PF_ProgPtr effect_ref, /* >> */ + const PF_ParamDef *angle_defP, /* >> */ + A_FpLong *fp_valueP); /* << */ + +} PF_AngleParamSuite1; + + +/* -------------------------------------------------------------------- */ + +#define kPFAppSuite "PF AE App Suite" +#define kPFAppSuiteVersion6 1 /* frozen in AE 13.1 */ + +enum { + PF_App_Color_NONE = -1, + + PF_App_Color_FRAME, + PF_App_Color_FILL, + PF_App_Color_TEXT, + PF_App_Color_LIGHT_TINGE, + PF_App_Color_DARK_TINGE, + PF_App_Color_HILITE, + PF_App_Color_SHADOW, + + PF_App_Color_BUTTON_FRAME, + PF_App_Color_BUTTON_FILL, + PF_App_Color_BUTTON_TEXT, + PF_App_Color_BUTTON_LIGHT_TINGE, + PF_App_Color_BUTTON_DARK_TINGE, + PF_App_Color_BUTTON_HILITE, + PF_App_Color_BUTTON_SHADOW, + + PF_App_Color_BUTTON_PRESSED_FRAME, + PF_App_Color_BUTTON_PRESSED_FILL, + PF_App_Color_BUTTON_PRESSED_TEXT, + PF_App_Color_BUTTON_PRESSED_LIGHT_TINGE, + PF_App_Color_BUTTON_PRESSED_DARK_TINGE, + PF_App_Color_BUTTON_PRESSED_HILITE, + PF_App_Color_BUTTON_PRESSED_SHADOW, + + /********************************/ + + PF_App_Color_FRAME_DISABLED, + PF_App_Color_FILL_DISABLED, + PF_App_Color_TEXT_DISABLED, + PF_App_Color_LIGHT_TINGE_DISABLED, + PF_App_Color_DARK_TINGE_DISABLED, + PF_App_Color_HILITE_DISABLED, + PF_App_Color_SHADOW_DISABLED, + + PF_App_Color_BUTTON_FRAME_DISABLED, + PF_App_Color_BUTTON_FILL_DISABLED, + PF_App_Color_BUTTON_TEXT_DISABLED, + PF_App_Color_BUTTON_LIGHT_TINGE_DISABLED, + PF_App_Color_BUTTON_DARK_TINGE_DISABLED, + PF_App_Color_BUTTON_HILITE_DISABLED, + PF_App_Color_BUTTON_SHADOW_DISABLED, + + PF_App_Color_BUTTON_PRESSED_FRAME_DISABLED, + PF_App_Color_BUTTON_PRESSED_FILL_DISABLED, + PF_App_Color_BUTTON_PRESSED_TEXT_DISABLED, + PF_App_Color_BUTTON_PRESSED_LIGHT_TINGE_DISABLED, + PF_App_Color_BUTTON_PRESSED_DARK_TINGE_DISABLED, + PF_App_Color_BUTTON_PRESSED_HILITE_DISABLED, + PF_App_Color_BUTTON_PRESSED_SHADOW_DISABLED, + + /********************************/ + PF_App_Color_BLACK, + PF_App_Color_WHITE, + PF_App_Color_GRAY, + PF_App_Color_RED, + PF_App_Color_YELLOW, + PF_App_Color_GREEN, + PF_App_Color_CYAN, + + /********************************/ + PF_App_Color_TLW_NEEDLE_CURRENT_TIME, + PF_App_Color_TLW_NEEDLE_PREVIEW_TIME, + PF_App_Color_TLW_CACHE_MARK_MEM, + PF_App_Color_TLW_CACHE_MARK_DISK, + PF_App_Color_TLW_CACHE_MARK_MIX, + PF_App_Color_FILL_LIGHT, + PF_App_Color_HOT_TEXT, + PF_App_Color_HOT_TEXT_DISABLED, + + /********************************/ + PF_App_Color_LABEL_0, + PF_App_Color_LABEL_1, + PF_App_Color_LABEL_2, + PF_App_Color_LABEL_3, + PF_App_Color_LABEL_4, + PF_App_Color_LABEL_5, + PF_App_Color_LABEL_6, + PF_App_Color_LABEL_7, + PF_App_Color_LABEL_8, + PF_App_Color_LABEL_9, + PF_App_Color_LABEL_10, + PF_App_Color_LABEL_11, + PF_App_Color_LABEL_12, + PF_App_Color_LABEL_13, + PF_App_Color_LABEL_14, + PF_App_Color_LABEL_15, + PF_App_Color_LABEL_16, + + /********************************/ + PF_App_Color_TLW_CACHE_MARK_MEM_DUBIOUS, + PF_App_Color_TLW_CACHE_MARK_DISK_DUBIOUS, + PF_App_Color_TLW_CACHE_MARK_MIX_DUBIOUS, + PF_App_Color_HOT_TEXT_PRESSED, + PF_App_Color_HOT_TEXT_WARNING, + PF_App_Color_PURE_BLACK, + PF_App_Color_PURE_WHITE, + + PF_App_Color_PANEL_BACKGROUND = 1000, + PF_App_Color_LIST_BOX_FILL, + PF_App_Color_DARK_CAPTION_FILL, + PF_App_Color_DARK_CAPTION_TEXT, + PF_App_Color_TEXT_ON_LIGHTER_BG, + + PF_App_Color_NUMTYPES +}; +typedef A_short PF_App_ColorType; + +enum { + // the first entry allows the user to do it the way they normally do with + // ae native color pickers (straight is the default, shift gives you premul) + PF_EyeDropperSampleMode_DEFAULT, + PF_EyeDropperSampleMode_STRAIGHT, + PF_EyeDropperSampleMode_PREMUL +}; + +typedef A_short PF_EyeDropperSampleMode; + +typedef struct PF_App_Color { + A_u_short red; + A_u_short green; + A_u_short blue; +} PF_App_Color; + + +#define PF_APP_MAX_PERS_LEN 63 + +typedef struct PF_AppPersonalTextInfo { + A_char name[PF_APP_MAX_PERS_LEN + 1]; + A_char org[PF_APP_MAX_PERS_LEN + 1]; + A_char serial_str[PF_APP_MAX_PERS_LEN + 1]; +} PF_AppPersonalTextInfo; + + +enum { + PF_FontStyle_NONE = -1, // sentinel + PF_FontStyle_SYS = 0, // system font, system size, system style (0, 0, 0) + PF_FontStyle_SMALL, // usually small annotation text + PF_FontStyle_SMALL_BOLD, // more important small annotations + PF_FontStyle_SMALL_ITALIC, // missing things, etc. + PF_FontStyle_MED, // times in in/out panels + PF_FontStyle_MED_BOLD, // + PF_FontStyle_APP, // + PF_FontStyle_APP_BOLD, // time in TL window + PF_FontStyle_APP_ITALIC // +}; +typedef A_LegacyEnumType PF_FontStyleSheet; + + + +#define PF_FONT_NAME_LEN 255 + +typedef struct PF_FontName { + A_char font_nameAC[PF_FONT_NAME_LEN+1]; +} PF_FontName; + + +#define PF_APP_LANG_TAG_SIZE (5 + 1) + +typedef struct _PF_AppProgressDialog *PF_AppProgressDialogP; + + +typedef struct PFAppSuite6 { /* frozen in AE 13.1 */ + + SPAPI PF_Err (*PF_AppGetBgColor)( PF_App_Color *bg_colorP); /* << */ + + SPAPI PF_Err (*PF_AppGetColor)( PF_App_ColorType color_type, /* >> */ + PF_App_Color *app_colorP); /* << */ + + // Provides the active displayed language of AE UI so plugin can match. e.g. "en_US" + SPAPI PF_Err (*PF_AppGetLanguage)( A_char *lang_tagZ); /* << up to PF_APP_LANG_TAG_SIZE-1 */ + + SPAPI PF_Err (*PF_GetPersonalInfo)( PF_AppPersonalTextInfo *ptiP); /* << */ + + SPAPI PF_Err (*PF_GetFontStyleSheet)(PF_FontStyleSheet sheet, /* >> */ + PF_FontName *font_nameP0, /* << */ + A_short *font_numPS0, /* << */ + A_short *sizePS0, /* << */ + A_short *stylePS0); /* << */ + + // normally the effect should respond to PF_Event_ADJUST_CURSOR, but for changing + // the cursor during modal situations, you can use this API + SPAPI PF_Err (*PF_SetCursor)( PF_CursorType cursor); /* >> */ + + // as of AE6.5, this function returns TRUE if installed app is the render engine (as before) + // OR if the app is being run with no UI OR if the app is in watch-folder mode + SPAPI PF_Err (*PF_IsRenderEngine)( PF_Boolean *render_enginePB); /* >> */ + + // will return PF_Interrupt_CANCEL if user cancels dialog. color is in project working colorspace + // if use_ws_to_monitor_xformB is TRUE, then the color chips and pickers are run through the + // working space -> display transformation while interacting. set FALSE to have the raw RGB values + // pushed directly to the screen. TRUE is intended for when the returned color is used in rendering, FALSE + // is intended if the color is for UI elements or other nonrenderables. + + SPAPI PF_Err (*PF_AppColorPickerDialog)( const A_char *dialog_titleZ0, /* >> */ + const PF_PixelFloat *sample_colorP, /* >> */ + PF_Boolean use_ws_to_monitor_xformB, /* >> */ + PF_PixelFloat *new_colorP); /* << */ + + // for use only when processing an event in an effect with custom UI + SPAPI PF_Err (*PF_GetMouse)(PF_Point* pointP); + + // NEW api in version 4. + // Use it to invalidate rect of current window being drawn. Invalidated rect will be updated during idle time. + // Specify PF_EO_UPDATE_NOW out flag to update the window immediately after the event returns. Specify rectP0 + // as NULL to invalidate the whole window. + // Only valid while handling an non-draw event in the effect. + SPAPI PF_Err (*PF_InvalidateRect)( const PF_ContextH contextH, + const PF_Rect* rectP0); + + // only safe to use when processing an event from a custom UI event. + SPAPI PF_Err (*PF_ConvertLocalToGlobal)(const PF_Point* localP, PF_Point* globalP); + + // this will return a deep color if over a content window containing 32bpc. + // eyeSize == 0 will use the application pref as set by the user. + SPAPI PF_Err (*PF_GetColorAtGlobalPoint)(const PF_Point* globalP, A_short eyeSize, PF_EyeDropperSampleMode mode, PF_PixelFloat* outColorP); + + + // Manages a modal progress dialog session for use inside of time-consuming AEGP commands + // Only one dialog active at a time is supported, and it may not get displayed in cases where AE UI is disabled (become no-ops) + // These calls must be used from the AE main/UI thread + // The app busy cursor will automatically set/reset as needed, regardless of whether dialog is displayed + SPAPI PF_Err (*PF_CreateNewAppProgressDialog)( + const A_UTF16Char* titleZ, // >> title of the progress dialog + const A_UTF16Char* cancel_strZ0, // >> [optional] what the name on the button should be. + // If NULL, AE localized Cancel used by default + PF_Boolean indeterminateB, // >> TRUE shows "barber pole" style animation with no incremental progress + PF_AppProgressDialogP *prog_dlgPP); // <> Returns allocated ProgressDialog session (may not display actual dialog yet) + + // This will trigger initial dialog display once timeout elapses. + // While dialog is displayed, this updates animation/progress status. + // If the session is disposed before the elapsed time the dialog is never displayed. + // This must be called frequently during your algorithm to keep UI responsive and animation moving. About 100ms interval would be a good target. + // Returns PF_Interrupt_CANCEL if user canceled the dialog + SPAPI PF_Err (*PF_AppProgressDialogUpdate)( + PF_AppProgressDialogP prog_dlgP, // >> The allocated session + A_long countL, A_long totalL); // >> count/total is the fraction of progress to display (when not indeterminate style) + // (pass zeros to keep barber-pole animation alive) + + // PF_AppProgressDialogP MUST be disposed whether the actual dialog is displayed or not + SPAPI PF_Err (*PF_DisposeAppProgressDialog)(PF_AppProgressDialogP prog_dlgP); // >> The allocated session. MUST be disposed. + +} PFAppSuite6; + + + +#define kPFEffectUISuite "PF Effect UI Suite" +#define kPFEffectUISuiteVersion1 1 /* frozen in 5.5 */ + +typedef struct PF_EffectUISuite1 { + + SPAPI PF_Err (*PF_SetOptionsButtonName)( PF_ProgPtr effect_ref, + const A_char *nameZ); + +} PF_EffectUISuite1; + + + + +#define kPFEffectCustomUISuite "PF Effect Custom UI Suite" +#define kPFEffectCustomUISuiteVersion2 2 /* frozen in 13.5 */ + +typedef struct _PF_AsyncManager *PF_AsyncManagerP; // manage multiple asynchronous render requests during lifetime, especially for better caching on UI thread + +// apis that relate to + +typedef struct PF_EffectCustomUISuite2 { + + // This provides basic apis needed for custom ui drawing in any window (Comp/Layer/ECW) + // Get the drawing reference for custom ui drawing. + SPAPI PF_Err (*PF_GetDrawingReference)( const PF_ContextH effect_contextH, /* >> */ + DRAWBOT_DrawRef *referenceP0); /* << */ + + // NEW in version 2 (ae13.5) + // When using PF_OutFlag2_CUSTOM_UI_ASYNC_MANAGER, use this to get the async manager associated with the effect PF_ContextH. + // The managed can then be asked to do Async render requests + SPAPI PF_Err (*PF_GetContextAsyncManager)( PF_InData* in_data, PF_EventExtra* extra, PF_AsyncManagerP* managerPP0); + +} PF_EffectCustomUISuite2; + + + + +#define kPFEffectCustomUIOverlayThemeSuite "PF Effect Custom UI Overlay Theme Suite" +#define kPFEffectCustomUIOverlayThemeSuiteVersion1 1 /* frozen in 10.0 */ + +// This suite should be used for stroking/filling paths, vertices etc on Comp/Layer window. After Effects is internally using it +// so use it to make custom ui look consistent across effects. The foreground/shadow colors are computed based on the app brightness +// level so custom ui is always visible regardless of app brightness. + +typedef struct PF_EffectCustomUIOverlayThemeSuite1 { + + // Get foreground/shadow colors preferred for custom ui drawing in AE. + // These colors are used by AE custom ui effects. + SPAPI PF_Err (*PF_GetPreferredForegroundColor)( DRAWBOT_ColorRGBA *foreground_colorP); /* << */ + + SPAPI PF_Err (*PF_GetPreferredShadowColor) ( DRAWBOT_ColorRGBA *shadow_colorP); /* << */ + + + // Get foreground & shadow stroke width, vertex size and shadow offset preferred for custom ui drawing in AE. + // These settings are used by AE custom ui effects. + SPAPI PF_Err (*PF_GetPreferredStrokeWidth)( float *stroke_widthPF); /* << for both foreground and shadow stroke */ + + SPAPI PF_Err (*PF_GetPreferredVertexSize)( float *vertex_sizePF); /* << */ + + SPAPI PF_Err (*PF_GetPreferredShadowOffset)( A_LPoint *shadow_offsetP); /* << */ + + + // Stroke the path with overlay theme foreground color. It can also draw shadow using overlay theme shadow color. + // It uses overlay theme stroke width for stroking foreground and shadow strokes. + SPAPI PF_Err (*PF_StrokePath) ( const DRAWBOT_DrawRef drawbot_ref, /* >> */ + const DRAWBOT_PathRef path_ref, /* >> */ + PF_Boolean draw_shadowB); /* >> */ + + + // Fills the path with overlay theme foreground color. It can also draw shadow using overlay theme shadow color. + // It can be used for drawing in any Comp/Layer/EC windows. + SPAPI PF_Err (*PF_FillPath) ( const DRAWBOT_DrawRef drawbot_ref, /* >> */ + const DRAWBOT_PathRef path_ref, /* >> */ + PF_Boolean draw_shadowB); /* >> */ + + + // Fills a square (vertex) around the center point using overlay theme foreground color and vertex size. + SPAPI PF_Err (*PF_FillVertex) ( const DRAWBOT_DrawRef drawbot_ref, /* >> */ + const A_FloatPoint *center_pointP, /* >> */ + PF_Boolean draw_shadowB); /* >> */ + +} PF_EffectCustomUIOverlayThemeSuite1; + + +// we include this at the end here to maintain source-level compatibility with +// files that #include AE_EffectSuite but are still using the old suites +// note: this is _inside_ the pre/post & ifdefs, as this is just a snippet, +// and not designed to be #include by anyone else +#define _H_AE_EffectSuitesOld + #include "AE_EffectSuitesOld.h" +#undef _H_AE_EffectSuitesOld + +/**********************************************************/ +/**********************************************************/ + +#ifdef __cplusplus + } +#endif + + +#include + +#endif diff --git a/External/AE SDK/Headers/AE_EffectSuitesHelper.h b/External/AE SDK/Headers/AE_EffectSuitesHelper.h new file mode 100644 index 00000000..0dc74657 --- /dev/null +++ b/External/AE SDK/Headers/AE_EffectSuitesHelper.h @@ -0,0 +1,152 @@ +/*******************************************************************/ +/* */ +/* ADOBE CONFIDENTIAL */ +/* _ _ _ _ _ _ _ _ _ _ _ _ _ */ +/* */ +/* Copyright 2007 Adobe Systems Incorporated */ +/* All Rights Reserved. */ +/* */ +/* NOTICE: All information contained herein is, and remains the */ +/* property of Adobe Systems Incorporated and its suppliers, if */ +/* any. The intellectual and technical concepts contained */ +/* herein are proprietary to Adobe Systems Incorporated and its */ +/* suppliers and may be covered by U.S. and Foreign Patents, */ +/* patents in process, and are protected by trade secret or */ +/* copyright law. Dissemination of this information or */ +/* reproduction of this material is strictly forbidden unless */ +/* prior written permission is obtained from Adobe Systems */ +/* Incorporated. */ +/* */ +/* Adobe Premiere Device Control plug-in definitions */ +/* */ +/* AE_EffectSuitesHelper.h */ +/* */ +/* After Effects 5.0 PICA Suites (extended 3/8/00) */ +/* */ +/* */ +/*******************************************************************/ + +#ifndef _H_AE_EffectSuitesHelper +#define _H_AE_EffectSuitesHelper + +#include +#include + +#include + +#ifdef __cplusplus + extern "C" { +#endif + + +/** PF_HelperSuite1 + + PF_GetCurrentTool() + + retrieves the type of the current tool palette tool selected + +**/ + +#define kPFHelperSuite "AE Plugin Helper Suite" +#define kPFHelperSuiteVersion1 1 +#define kPFHelperSuiteVersion kPFHelperSuiteVersion1 + +enum { + PF_SuiteTool_NONE = 0, + PF_SuiteTool_ARROW, + PF_SuiteTool_ROTATE, + PF_SuiteTool_SHAPE, + PF_SuiteTool_OBSOLETE, + PF_SuiteTool_PEN, + PF_SuiteTool_PAN, + PF_SuiteTool_HAND, + PF_SuiteTool_MAGNIFY, + PF_SuiteTool_ROUNDED_RECT, + PF_SuiteTool_POLYGON, + PF_SuiteTool_STAR, + PF_SuiteTool_PIN, + PF_SuiteTool_PIN_STARCH, + PF_SuiteTool_PIN_DEPTH +}; +typedef A_LegacyEnumType PF_SuiteTool; + + + +typedef struct PF_HelperSuite1 { + // obsolete, use PF_HelperSuite2 + SPAPI PF_Err (*PF_GetCurrentTool)( PF_SuiteTool *toolP ); /* << */ +} PF_HelperSuite1; + + +/** PF_HelperSuite2 + + PF_ParseClipboard() + + causes After Effects to parse the clipboard immediately + +**/ +enum { + PF_ExtendedSuiteTool_NONE = 0, + PF_ExtendedSuiteTool_ARROW, + PF_ExtendedSuiteTool_ROTATE, + PF_ExtendedSuiteTool_PEN_NORMAL, + PF_ExtendedSuiteTool_PEN_ADD_POINT, + PF_ExtendedSuiteTool_PEN_DELETE_POINT, + PF_ExtendedSuiteTool_PEN_CONVERT_POINT, + PF_ExtendedSuiteTool_RECT, + PF_ExtendedSuiteTool_OVAL, + PF_ExtendedSuiteTool_CAMERA_ORBIT_CAMERA, + PF_ExtendedSuiteTool_CAMERA_PAN_CAMERA, //changed from PF_ExtendedSuiteTool_CAMERA_TRACK_XY + PF_ExtendedSuiteTool_CAMERA_DOLLY_CAMERA, //changed from PF_ExtendedSuiteTool_CAMERA_TRACK_Z + PF_ExtendedSuiteTool_PAN_BEHIND, + PF_ExtendedSuiteTool_HAND, + PF_ExtendedSuiteTool_MAGNIFY, + PF_ExtendedSuiteTool_PAINTBRUSH, // All below added in 6.0 + PF_ExtendedSuiteTool_PENCIL, + PF_ExtendedSuiteTool_CLONE_STAMP, + PF_ExtendedSuiteTool_ERASER, + PF_ExtendedSuiteTool_TEXT, + PF_ExtendedSuiteTool_TEXT_VERTICAL, + PF_ExtendedSuiteTool_PIN, + PF_ExtendedSuiteTool_PIN_STARCH, + PF_ExtendedSuiteTool_PIN_DEPTH, + PF_ExtendedSuiteTool_ROUNDED_RECT, + PF_ExtendedSuiteTool_POLYGON, + PF_ExtendedSuiteTool_STAR, + PF_ExtendedSuiteTool_QUICKSELECT, + PF_ExtendedSuiteTool_CAMERA_MAYA, + PF_ExtendedSuiteTool_HAIRBRUSH, + PF_ExtendedSuiteTool_FEATHER, + PF_ExtendedSuiteTool_PIN_BEND, + PF_ExtendedSuiteTool_PIN_ADVANCED, + PF_ExtendedSuiteTool_CAMERA_ORBIT_CURSOR, //new cursors should go at the end to avoid messing with sdk order + PF_ExtendedSuiteTool_CAMERA_ORBIT_SCENE, + PF_ExtendedSuiteTool_CAMERA_PAN_CURSOR, + PF_ExtendedSuiteTool_CAMERA_DOLLY_TOWARDS_CURSOR, + PF_ExtendedSuiteTool_CAMERA_DOLLY_TO_CURSOR, +}; +typedef A_LegacyEnumType PF_ExtendedSuiteTool; + + +#define kPFHelperSuite2 "AE Plugin Helper Suite2" +#define kPFHelperSuite2Version1 1 +#define kPFHelperSuite2Version2 2 +#define kPFHelperSuite2Version kPFHelperSuite2Version2 + +typedef struct PF_HelperSuite2 { + SPAPI PF_Err (*PF_ParseClipboard)( void ); + // Do not call PF_SetCurrentExtendedTool until the UI is built. i.e. Do not call it from + // your plugin init function. + SPAPI PF_Err (*PF_SetCurrentExtendedTool)(PF_ExtendedSuiteTool tool); + SPAPI PF_Err (*PF_GetCurrentExtendedTool)(PF_ExtendedSuiteTool *tool); +} PF_HelperSuite2; + +#ifdef __cplusplus + } +#endif + +#include + + + +#endif diff --git a/External/AE SDK/Headers/AE_EffectSuitesOld.h b/External/AE SDK/Headers/AE_EffectSuitesOld.h new file mode 100644 index 00000000..a3f0d51a --- /dev/null +++ b/External/AE SDK/Headers/AE_EffectSuitesOld.h @@ -0,0 +1,283 @@ +// AE_EffectSuitesOld.h +// +// Copyright (c) 2011 Adobe Systems Inc, Seattle WA +// All Rights Reserved +// +// These are old, deprecated versions of some suites. Please use the ones in AE_EffectSuites.h instead if at all possible. +// +// + +// +#ifndef _H_AE_EffectSuitesOld + #error this file is designed to be included only by AE_EffectSuites.h; do not include directly +#endif + +/** PF_ParamUtilsSuite1 + + PF_UpdateParamUI() + + You can call this function for each param whose UI settings you + want to change when handling a PF_Cmd_USER_CHANGED_PARAM or + PF_Cmd_UPDATE_PARAMS_UI. These changes are cosmetic only, and don't + go into the undo buffer. + + The ONLY fields that can be changed in this way are: + + PF_ParamDef + ui_flags: PF_PUI_ECW_SEPARATOR, PF_PUI_DISABLED only (and PF_PUI_INVISIBLE in Premiere). + ui_width + ui_height + name + flags: PF_ParamFlag_COLLAPSE_TWIRLY only + + PF_ParamDefUnion: + slider_min, slider_max, precision, display_flags of any slider type + + For PF_PUI_STD_CONTROL_ONLY params, you can also change the value field by setting + PF_ChangeFlag_CHANGED_VALUE before returning. But you are not allowed to change + the value during PF_Cmd_UPDATE_PARAMS_UI. + + PF_HaveInputsChangedOverTimeSpan() -- OBSOLETE, see PF_AreStatesIdentical() instead. + This API is handy for effects that do simulation across time, where frame N is + dependent on frame N-1, and you have a cache in your sequence data that needs validating. + When asked to render frame N, assume you have your cached data from frame N-1, you'd call + PF_HaveInputsChangedOverTimeSpan(start=0, duration=N-1) to see if your cache is still valid. + The state of all parameters (except those with PF_ParamFlag_EXCLUDE_FROM_HAVE_INPUTS_CHANGED + set), including layer parameters (including param[0]) are checked over the passed time + span. This is done efficiently, as the change tracking is done with timestamps. + + Requires PF_OutFlag2_AUTOMATIC_WIDE_TIME_INPUT to be set by the effect. If validating a + cache for use during a render, the call to PF_HaveInputsChangedOverTimeSpan() must + happen during one of the rendering PF_Cmds (PF_Cmd_FRAME_SETUP, PF_Cmd_RENDER, + PF_Cmd_FRAME_SETDOWN,PF_Cmd_SMART_PRE_RENDER, PF_Cmd_SMART_RENDER). + + If *changedPB is returned FALSE, you can safely use your cache, AND the internal + caching system will assume that you have a temporal dependency on the passed range, + so if something changes upstream, AE's caches will be properly invalidated. + +**/ + +#define kPFParamUtilsSuiteVersion1 2 /* 64-bit version frozen in AE 10.0 */ + + +typedef struct PF_ParamUtilsSuite1 { + + SPAPI PF_Err (*PF_UpdateParamUI)( + PF_ProgPtr effect_ref, + PF_ParamIndex param_index, + const PF_ParamDef *defP); + + // The next 3 methods have had "Obsolete" added to their name to intentionally + // break compile compatibility. They continue to work and are binary compatible, but + // are more conservative and inefficient than in previous versions. Please + // switch to the current version of this suite for maximum benefit. + SPAPI PF_Err (*PF_GetCurrentStateObsolete)( + PF_ProgPtr effect_ref, + PF_State *stateP); /* << */ + + SPAPI PF_Err (*PF_HasParamChangedObsolete)( + PF_ProgPtr effect_ref, + const PF_State *stateP, // has param changed since this state was grabbed + PF_ParamIndex param_index, // ignored, always treated as PF_ParamIndex_CHECK_ALL_HONOR_EXCLUDE - go use the modern version of this suite! + // have changed including layer param[0]; + // pass PF_ParamIndex_CHECK_ALL_EXCEPT_LAYER_PARAMS to see + // if any non-layer param values have changed + PF_Boolean *changedPB); /* << */ + + SPAPI PF_Err (*PF_HaveInputsChangedOverTimeSpanObsolete)( // see comment above + PF_ProgPtr effect_ref, + const PF_State *stateP, // has param changed since this state was grabbed + const A_Time *startPT0, // NULL for both start & duration mean at any time + const A_Time *durationPT0, + PF_Boolean *changedPB); /* << */ + + SPAPI PF_Err (*PF_IsIdenticalCheckout)( + PF_ProgPtr effect_ref, + PF_ParamIndex param_index, + A_long what_time1, + A_long time_step1, + A_u_long time_scale1, + A_long what_time2, + A_long time_step2, + A_u_long time_scale2, + PF_Boolean *identicalPB); /* << */ + + + SPAPI PF_Err (*PF_FindKeyframeTime)( + PF_ProgPtr effect_ref, + PF_ParamIndex param_index, + A_long what_time, + A_u_long time_scale, + PF_TimeDir time_dir, + PF_Boolean *foundPB, /* << */ + PF_KeyIndex *key_indexP0, /* << */ + A_long *key_timeP0, /* << */ // you can ask for either: + A_u_long *key_timescaleP0); /* << */ // time×cale OR neither + + SPAPI PF_Err (*PF_GetKeyframeCount)( + PF_ProgPtr effect_ref, + PF_ParamIndex param_index, + PF_KeyIndex *key_countP); /* << */ // returns PF_KeyIndex_NONE for constant + + SPAPI PF_Err (*PF_CheckoutKeyframe)( + PF_ProgPtr effect_ref, + PF_ParamIndex param_index, + PF_KeyIndex key_index, // zero-based + A_long *key_timeP0, /* << */ // you can ask for either: + A_u_long *key_timescaleP0, /* << */ // time×cale OR neither + PF_ParamDef *paramP0); /* << */ + + SPAPI PF_Err (*PF_CheckinKeyframe)( + PF_ProgPtr effect_ref, + PF_ParamDef *paramP); + + SPAPI PF_Err (*PF_KeyIndexToTime)( + PF_ProgPtr effect_ref, + PF_ParamIndex param_index, + PF_KeyIndex key_indexP, /* >> */ + A_long *key_timeP, /* >> */ + A_u_long *key_timescaleP); /* << */ + +} PF_ParamUtilsSuite1; + + +/* -------------------------------------------------------------------- */ + +#define kPFAppSuite "PF AE App Suite" +#define kPFAppSuiteVersion4 6 /* frozen in AE 10.0 */ + + +typedef struct PFAppSuite4 { /* frozen in AE 10.0 */ + + SPAPI PF_Err (*PF_AppGetBgColor)( PF_App_Color *bg_colorP); /* << */ + + SPAPI PF_Err (*PF_AppGetColor)( PF_App_ColorType color_type, /* >> */ + PF_App_Color *app_colorP); /* << */ + + SPAPI PF_Err (*PF_GetPersonalInfo)( PF_AppPersonalTextInfo *ptiP); /* << */ + + SPAPI PF_Err (*PF_GetFontStyleSheet)(PF_FontStyleSheet sheet, /* >> */ + PF_FontName *font_nameP0, /* << */ + A_short *font_numPS0, /* << */ + A_short *sizePS0, /* << */ + A_short *stylePS0); /* << */ + + // normally the effect should respond to PF_Event_ADJUST_CURSOR, but for changing + // the cursor during modal situations, you can use this API + SPAPI PF_Err (*PF_SetCursor)( PF_CursorType cursor); /* >> */ + + // as of AE6.5, this function returns TRUE if installed app is the render engine (as before) + // OR if the app is being run with no UI OR if the app is in watch-folder mode + SPAPI PF_Err (*PF_IsRenderEngine)( PF_Boolean *render_enginePB); /* >> */ + + // will return PF_Interrupt_CANCEL if user cancels dialog. color is in project working colorspace + // if use_ws_to_monitor_xformB is TRUE, then the color chips and pickers are run through the + // working space -> display transformation while interacting. set FALSE to have the raw RGB values + // pushed directly to the screen. TRUE is intended for when the returned color is used in rendering, FALSE + // is intended if the color is for UI elements or other nonrenderables. + + SPAPI PF_Err (*PF_AppColorPickerDialog)( const A_char *dialog_titleZ0, /* >> */ + const PF_PixelFloat *sample_colorP, /* >> */ + PF_Boolean use_ws_to_monitor_xformB, /* >> */ + PF_PixelFloat *new_colorP); /* << */ + + // for use only when processing an event in an effect with custom UI + SPAPI PF_Err (*PF_GetMouse)(PF_Point* pointP); + + // NEW api in version 4. + // Use it to invalidate rect of current window being drawn. Invalidated rect will be updated during idle time. + // Specify PF_EO_UPDATE_NOW out flag to update the window immediately after the event returns. Specify rectP0 + // as NULL to invalidate the whole window. + // Only valid while handling an non-draw event in the effect. + SPAPI PF_Err (*PF_InvalidateRect)( const PF_ContextH contextH, + const PF_Rect* rectP0); + + // only safe to use when processing an event from a custom UI event. + SPAPI PF_Err (*PF_ConvertLocalToGlobal)(const PF_Point* localP, PF_Point* globalP); + + // this will return a deep color if over a content window containing 32bpc. + // eyeSize == 0 will use the application pref as set by the user. + SPAPI PF_Err (*PF_GetColorAtGlobalPoint)(const PF_Point* globalP, A_short eyeSize, PF_EyeDropperSampleMode mode, PF_PixelFloat* outColorP); + +} PFAppSuite4; + + +/* -------------------------------------------------------------------- */ + + +#define kPFAppSuiteVersion5 7 /* frozen in AE 12.0 */ + +typedef struct PFAppSuite5 { /* frozen in AE 12.0 */ + + SPAPI PF_Err (*PF_AppGetBgColor)( PF_App_Color *bg_colorP); /* << */ + + SPAPI PF_Err (*PF_AppGetColor)( PF_App_ColorType color_type, /* >> */ + PF_App_Color *app_colorP); /* << */ + + // Provides the active displayed language of AE UI so plugin can match. e.g. "en_US" + SPAPI PF_Err (*PF_AppGetLanguage)( A_char *lang_tagZ); /* << up to PF_APP_LANG_TAG_SIZE-1 */ + + SPAPI PF_Err (*PF_GetPersonalInfo)( PF_AppPersonalTextInfo *ptiP); /* << */ + + SPAPI PF_Err (*PF_GetFontStyleSheet)(PF_FontStyleSheet sheet, /* >> */ + PF_FontName *font_nameP0, /* << */ + A_short *font_numPS0, /* << */ + A_short *sizePS0, /* << */ + A_short *stylePS0); /* << */ + + // normally the effect should respond to PF_Event_ADJUST_CURSOR, but for changing + // the cursor during modal situations, you can use this API + SPAPI PF_Err (*PF_SetCursor)( PF_CursorType cursor); /* >> */ + + // as of AE6.5, this function returns TRUE if installed app is the render engine (as before) + // OR if the app is being run with no UI OR if the app is in watch-folder mode + SPAPI PF_Err (*PF_IsRenderEngine)( PF_Boolean *render_enginePB); /* >> */ + + // will return PF_Interrupt_CANCEL if user cancels dialog. color is in project working colorspace + // if use_ws_to_monitor_xformB is TRUE, then the color chips and pickers are run through the + // working space -> display transformation while interacting. set FALSE to have the raw RGB values + // pushed directly to the screen. TRUE is intended for when the returned color is used in rendering, FALSE + // is intended if the color is for UI elements or other nonrenderables. + + SPAPI PF_Err (*PF_AppColorPickerDialog)( const A_char *dialog_titleZ0, /* >> */ + const PF_PixelFloat *sample_colorP, /* >> */ + PF_Boolean use_ws_to_monitor_xformB, /* >> */ + PF_PixelFloat *new_colorP); /* << */ + + // for use only when processing an event in an effect with custom UI + SPAPI PF_Err (*PF_GetMouse)(PF_Point* pointP); + + // NEW api in version 4. + // Use it to invalidate rect of current window being drawn. Invalidated rect will be updated during idle time. + // Specify PF_EO_UPDATE_NOW out flag to update the window immediately after the event returns. Specify rectP0 + // as NULL to invalidate the whole window. + // Only valid while handling an non-draw event in the effect. + SPAPI PF_Err (*PF_InvalidateRect)( const PF_ContextH contextH, + const PF_Rect* rectP0); + + // only safe to use when processing an event from a custom UI event. + SPAPI PF_Err (*PF_ConvertLocalToGlobal)(const PF_Point* localP, PF_Point* globalP); + + // this will return a deep color if over a content window containing 32bpc. + // eyeSize == 0 will use the application pref as set by the user. + SPAPI PF_Err (*PF_GetColorAtGlobalPoint)(const PF_Point* globalP, A_short eyeSize, PF_EyeDropperSampleMode mode, PF_PixelFloat* outColorP); + + +} PFAppSuite5; + +/* -------------------------------------------------------------------- */ + +#define kPFEffectCustomUISuite "PF Effect Custom UI Suite" +#define kPFEffectCustomUISuiteVersion1 1 /* frozen in 10.0 */ + +// This suite provides basic apis needed for custom ui drawing in any window (Comp/Layer/ECW) + +typedef struct PF_EffectCustomUISuite1 { + + // Get the drawing reference for custom ui drawing. + SPAPI PF_Err (*PF_GetDrawingReference)( const PF_ContextH effect_contextH, /* >> */ + DRAWBOT_DrawRef *referenceP0); /* << */ + +} PF_EffectCustomUISuite1; + + diff --git a/External/AE SDK/Headers/AE_EffectUI.h b/External/AE SDK/Headers/AE_EffectUI.h new file mode 100644 index 00000000..18371a00 --- /dev/null +++ b/External/AE SDK/Headers/AE_EffectUI.h @@ -0,0 +1,580 @@ +/*******************************************************************/ +/* */ +/* ADOBE CONFIDENTIAL */ +/* _ _ _ _ _ _ _ _ _ _ _ _ _ */ +/* */ +/* Copyright 2007 Adobe Systems Incorporated */ +/* All Rights Reserved. */ +/* */ +/* NOTICE: All information contained herein is, and remains the */ +/* property of Adobe Systems Incorporated and its suppliers, if */ +/* any. The intellectual and technical concepts contained */ +/* herein are proprietary to Adobe Systems Incorporated and its */ +/* suppliers and may be covered by U.S. and Foreign Patents, */ +/* patents in process, and are protected by trade secret or */ +/* copyright law. Dissemination of this information or */ +/* reproduction of this material is strictly forbidden unless */ +/* prior written permission is obtained from Adobe Systems */ +/* Incorporated. */ +/* */ +/*******************************************************************/ + +/** AE_EffectUI.h + + Part of the After Effects SDK. + + Describes structures and callbacks used by plug-ins with Custom + composition window and effect palette UIs. + +**/ + +#ifndef _H_AE_EffectUI +#define _H_AE_EffectUI + + +#include + +#ifdef ADOBE_SDK_INTERNAL + #include +#else + #include +#endif + + +#include + + + + + +#ifdef __cplusplus + extern "C" { +#endif + + +/** PF_CustomFlags + ** + ** kinds of events and actions the custom parameter type might require + ** + **/ + +enum { + PF_CustomEFlag_NONE = 0, + + PF_CustomEFlag_COMP = 1L << 0, + PF_CustomEFlag_LAYER = 1L << 1, + PF_CustomEFlag_EFFECT = 1L << 2, + PF_CustomEFlag_PREVIEW = 1L << 3 +}; +typedef A_long PF_CustomEventFlags; + + +enum { + PF_Window_NONE = -1, + PF_Window_COMP, + PF_Window_LAYER, + PF_Window_EFFECT, + PF_Window_PREVIEW +}; +typedef A_long PF_WindowType; + + +/* $$$ document! + + new context -> evt extra has context and type, but everything else should be ignored + fill in plugin_state[4] + close context -> + all other evts -> params set up, but no layers + +*/ +enum { + PF_Event_NONE = -1, + PF_Event_NEW_CONTEXT, + PF_Event_ACTIVATE, + PF_Event_DO_CLICK, + PF_Event_DRAG, + PF_Event_DRAW, + PF_Event_DEACTIVATE, + PF_Event_CLOSE_CONTEXT, + PF_Event_IDLE, + PF_Event_KEYDOWN_OBSOLETE, // As of AE 7, this is no longer used. + PF_Event_ADJUST_CURSOR, // new for AE 4.0, sent when mouse moves over custom UI + PF_Event_KEYDOWN, // new for AE 7.0, replaces previous keydown event with cross platform codes and unicode characters. + PF_Event_MOUSE_EXITED, // new for AE 11.0, notification that the mouse is no longer over a specific view (layer or comp only). + + PF_Event_NUM_EVENTS +}; +typedef A_long PF_EventType; + + +enum { + PF_Cursor_NONE = 0, // see comment in PF_AdjustCursorEventInfo + PF_Cursor_CUSTOM, // means effect set cursor itself with platform-specific calls + PF_Cursor_ARROW, + PF_Cursor_HOLLOW_ARROW, + PF_Cursor_WATCH_N_WAIT, // watch on the Mac, wait (hourglass) on Windows + PF_Cursor_MAGNIFY, + PF_Cursor_MAGNIFY_PLUS, + PF_Cursor_MAGNIFY_MINUS, + PF_Cursor_CROSSHAIRS, + PF_Cursor_CROSS_RECT, + PF_Cursor_CROSS_OVAL, + PF_Cursor_CROSS_ROTATE, + PF_Cursor_PAN, + PF_Cursor_EYEDROPPER, + PF_Cursor_HAND, + PF_Cursor_PEN, + PF_Cursor_PEN_ADD, + PF_Cursor_PEN_DELETE, + PF_Cursor_PEN_CLOSE, + PF_Cursor_PEN_DRAG, + PF_Cursor_PEN_CORNER, + PF_Cursor_RESIZE_VERTICAL, + PF_Cursor_RESIZE_HORIZONTAL, + PF_Cursor_FINGER_POINTER, + PF_Cursor_SCALE_HORIZ, + PF_Cursor_SCALE_DIAG_LR, + PF_Cursor_SCALE_VERT, + PF_Cursor_SCALE_DIAG_UR, + PF_Cursor_ROT_TOP, + PF_Cursor_ROT_TOP_RIGHT, + PF_Cursor_ROT_RIGHT, + PF_Cursor_ROT_BOT_RIGHT, + PF_Cursor_ROT_BOTTOM, + PF_Cursor_ROT_BOT_LEFT, + PF_Cursor_ROT_LEFT, + PF_Cursor_ROT_TOP_LEFT, + PF_Cursor_DRAG_CENTER, + PF_Cursor_COPY, + PF_Cursor_ALIAS, + PF_Cursor_CONTEXT, + PF_Cursor_SLIP_EDIT, + PF_Cursor_CAMERA_ORBIT_CAMERA, //changed from PF_Cursor_ORBIT + PF_Cursor_CAMERA_PAN_CAMERA, //changed from PF_Cursor_TRACK_XY + PF_Cursor_CAMERA_DOLLY_CAMERA, //changed from PF_Cursor_TRACK_Z + PF_Cursor_ROTATE_X, + PF_Cursor_ROTATE_Y, + PF_Cursor_ROTATE_Z, + PF_Cursor_ARROW_X, + PF_Cursor_ARROW_Y, + PF_Cursor_ARROW_Z, + PF_Cursor_SCISSORS, + PF_Cursor_FAT_EYEDROPPER, + PF_Cursor_FINGER_POINTER_SCRUB, + PF_Cursor_HORZ_I_BEAM, + PF_Cursor_VERT_I_BEAM, + PF_Cursor_HORZ_BOX_I_BEAM, + PF_Cursor_VERT_BOX_I_BEAM, + PF_Cursor_I_BEAM_0, + PF_Cursor_I_BEAM_11_25, + PF_Cursor_I_BEAM_22_5, + PF_Cursor_I_BEAM_33_75, + PF_Cursor_I_BEAM_45, + PF_Cursor_I_BEAM_56_25, + PF_Cursor_I_BEAM_67_5, + PF_Cursor_I_BEAM_78_75, + PF_Cursor_I_BEAM_90, + PF_Cursor_I_BEAM_101_25, + PF_Cursor_I_BEAM_112_5, + PF_Cursor_I_BEAM_123_75, + PF_Cursor_I_BEAM_135, + PF_Cursor_I_BEAM_146_25, + PF_Cursor_I_BEAM_157_5, + PF_Cursor_I_BEAM_168_75, + PF_Cursor_CROSSHAIRS_PICKUP, + PF_Cursor_ARROW_SELECTOR, + PF_Cursor_LAYER_MOVE, + PF_Cursor_MOVE_START_MARGIN, + PF_Cursor_MOVE_END_MARGIN, + PF_Cursor_SOLID_ARROW, + PF_Cursor_HOLLOW_ARROW_PLUS, + PF_Cursor_BRUSH_CENTER, + PF_Cursor_CLONE_SOURCE, + PF_Cursor_CLONE_SOURCE_OFFSET, + PF_Cursor_HOLLOW_LAYER_MOVE, + PF_Cursor_MOVE_TRACK_SEARCH_REGION, + PF_Cursor_MOVE_TRACK_ATTACH_POINT, + PF_Cursor_COLOR_CUBE_CROSS_SECTION, + PF_Cursor_PEN_CORNER_ROTOBEZ_TENSION, + PF_Cursor_PIN, + PF_Cursor_PIN_ADD, + PF_Cursor_MESH_ADD, + PF_Cursor_MARQUEE, + PF_Cursor_CROSS_ROUNDED_RECT, + PF_Cursor_CROSS_POLYGON, + PF_Cursor_CROSS_STAR, + PF_Cursor_PIN_STARCH, + PF_Cursor_PIN_OVERLAP, + PF_Cursor_STOPWATCH, + PF_Cursor_DRAG_DOT, + PF_Cursor_DRAG_CIRCLE, + PF_Cursor_DIRECT_SELECT, + PF_Cursor_DRAG_COPY_MOVE, + PF_Cursor_DRAG_COPY_ROTATE, + PF_Cursor_CAMERA_MAYA, //Changed from PF_Cursor_MAYA + PF_Cursor_RESIZE_HORIZONTAL_LEFT, + PF_Cursor_RESIZE_HORIZONTAL_RIGHT, + PF_Cursor_FEATHER, + PF_Cursor_FEATHER_ADD, + PF_Cursor_FEATHER_DELETE, + PF_Cursor_FEATHER_MOVE, + PF_Cursor_FEATHER_TENSION, + PF_Cursor_FEATHER_MARQUEE, + PF_Cursor_LASSO_ARROW, + PF_Cursor_DRAG_NO_DROP, + PF_Cursor_DRAG_COPY, + PF_Cursor_DRAG_LINK, + PF_Cursor_PIN_BEND, + PF_Cursor_PIN_ADVANCED, + PF_Cursor_CAMERA_ORBIT_CURSOR, + PF_Cursor_CAMERA_ORBIT_SCENE, + PF_Cursor_CAMERA_PAN_CURSOR, + PF_Cursor_CAMERA_DOLLY_TOWARDS_CURSOR, + PF_Cursor_CAMERA_DOLLY_TO_CURSOR, + + PF_MAX_CURSOR_PLUS_ONE +}; +typedef A_long PF_CursorType; + + +enum { + PF_Mod_NONE = 0x0000, + PF_Mod_CMD_CTRL_KEY = 0x0100, // cmd on Mac, ctrl on Windows + PF_Mod_SHIFT_KEY = 0x0200, + PF_Mod_CAPS_LOCK_KEY = 0x0400, + PF_Mod_OPT_ALT_KEY = 0x0800, // option on Mac, alt on Windows + PF_Mod_MAC_CONTROL_KEY = 0x1000 // Mac control key only +}; +typedef A_long PF_Modifiers; + + +typedef struct { + PF_Point screen_point; /* >> where the mouse is right now */ + PF_Modifiers modifiers; /* >> modifiers right now */ + PF_CursorType set_cursor; /* << set this to your desired cursor, or PF_Cursor_CUSTOM if you + set the cursor yourself, or PF_Cursor_NONE if you don't + want to override the cursor (i.e. the app will set the + cursor however it wants) */ +} PF_AdjustCursorEventInfo; + +typedef struct { + A_u_long when; + PF_Point screen_point; + A_long num_clicks; + PF_Modifiers modifiers; + A_intptr_t continue_refcon[4]; /* <> if send_drag is TRUE, set this */ + PF_Boolean send_drag; /* << set this from a do_click to get a drag */ + PF_Boolean last_time; /* >> set the last time you get a drag */ +} PF_DoClickEventInfo; + + +typedef struct { + PF_UnionableRect update_rect; // in window's coordinate system + A_long depth; +} PF_DrawEventInfo; + + +typedef struct { + A_u_long when; + PF_Point screen_point; + A_long char_code; + A_long key_code; + PF_Modifiers modifiers; +} PF_KeyDownEventObsolete; // As of AE 7, this is no longer used. + + +typedef A_u_long PF_KeyCode; // For printable characters, we use the unshifted upper case version (A not a, 7 not &). +typedef A_u_short PF_ControlCode; + +typedef struct { + A_u_long when; + PF_Point screen_point; + PF_KeyCode keycode; // as of AE 7, this is either a control code, or character code + PF_Modifiers modifiers; + +} PF_KeyDownEvent; + + +enum { + PF_KEYCODE_FLAG_Printable = 1 << 31, // a printable key, otherwise a control code like page up + PF_KEYCODE_FLAG_Extended = 1 << 30 // an alternate key, typically on the numeric keypad. +}; + +#define PF_GENERATE_KEYBOARD_CODE_VALUE(CODE_VALUE, FLAGS) (((CODE_VALUE) & 0xFFFF) | (FLAGS)) +#define PF_GENERATE_KEYBOARD_CODE_VALUE_FROM_CHARACTER(CHAR) PF_GENERATE_KEYBOARD_CODE_VALUE(CHAR, PF_KEYCODE_FLAG_Printable) +#define PF_GENERATE_KEYBOARD_CODE_VALUE_FROM_CHARACTER_EXTENDED(CHAR) PF_GENERATE_KEYBOARD_CODE_VALUE(CHAR, PF_KEYCODE_FLAG_Printable | PF_KEYCODE_FLAG_Extended) +#define PF_GENERATE_KEYBOARD_CODE_VALUE_FROM_CONTROL_CODE(CODE) PF_GENERATE_KEYBOARD_CODE_VALUE(CODE, 0) +#define PF_GENERATE_KEYBOARD_CODE_VALUE_FROM_CONTROL_CODE_EXTENDED(CODE) PF_GENERATE_KEYBOARD_CODE_VALUE(CODE, PF_KEYCODE_FLAG_Extended) + +#define PF_KEYCODE_IS_PRINTABLE(_KEY_CODE) (((_KEY_CODE) & PF_KEYCODE_FLAG_Printable ) != 0) +#define PF_KEYCODE_IS_EXTENDED(_KEY_CODE) (((_KEY_CODE) & PF_KEYCODE_FLAG_Extended ) != 0) + +#define PF_KEYCODE_GET_SHORTCUT_CHARACTER(_KEY_CODE) (PF_KEYCODE_IS_PRINTABLE(_KEY_CODE)) ? ((_KEY_CODE) & 0xFFFF) : 0 +#define PF_KEYCODE_GET_CONTROL_CODE(_KEY_CODE) (!PF_KEYCODE_IS_PRINTABLE(_KEY_CODE)) ? ((_KEY_CODE) & 0xFFFF) : 0 + +enum { + PF_ControlCode_Unknown = (PF_ControlCode)0xFFFF, + + PF_ControlCode_Space = 1, + PF_ControlCode_Backspace, + PF_ControlCode_Tab, + PF_ControlCode_Return, + PF_ControlCode_Enter, + + PF_ControlCode_Escape, + + PF_ControlCode_F1, + PF_ControlCode_F2, + PF_ControlCode_F3, + PF_ControlCode_F4, + PF_ControlCode_F5, + PF_ControlCode_F6, + PF_ControlCode_F7, + PF_ControlCode_F8, + PF_ControlCode_F9, + PF_ControlCode_F10, + PF_ControlCode_F11, + PF_ControlCode_F12, + PF_ControlCode_F13, + PF_ControlCode_F14, + PF_ControlCode_F15, + PF_ControlCode_F16, + PF_ControlCode_F17, + PF_ControlCode_F18, + PF_ControlCode_F19, + PF_ControlCode_F20, + PF_ControlCode_F21, + PF_ControlCode_F22, + PF_ControlCode_F23, + PF_ControlCode_F24, + + PF_ControlCode_PrintScreen, + PF_ControlCode_ScrollLock, + PF_ControlCode_Pause, + + PF_ControlCode_Insert, + PF_ControlCode_Delete, + PF_ControlCode_Home, + PF_ControlCode_End, + PF_ControlCode_PageUp, + PF_ControlCode_PageDown, + PF_ControlCode_Help, + PF_ControlCode_Clear, + + PF_ControlCode_Left, + PF_ControlCode_Right, + PF_ControlCode_Up, + PF_ControlCode_Down, + + PF_ControlCode_NumLock, + + PF_ControlCode_Command, + PF_ControlCode_Option, + PF_ControlCode_Alt = PF_ControlCode_Option, + PF_ControlCode_Control, + PF_ControlCode_Shift, + PF_ControlCode_CapsLock, + + PF_ControlCode_ContextMenu +}; + + +typedef union { + PF_DoClickEventInfo do_click; // also drag + PF_DrawEventInfo draw; + PF_KeyDownEvent key_down; + PF_AdjustCursorEventInfo adjust_cursor; + + // add other event types here + +} PF_EventUnion; + +#if defined(A_INTERNAL) && defined (__cplusplus) + class FLT_FCSeqSpec; + typedef FLT_FCSeqSpec *PF_ContextRefcon; +#else + typedef struct _PF_ContextRefcon *PF_ContextRefcon; +#endif + +#define PF_CONTEXT_MAGIC 0x05ea771e +typedef struct { + A_u_long magic; + PF_WindowType w_type; + PF_ContextRefcon reserved_flt; + A_intptr_t plugin_state[4]; // plug-in specific data + DRAWBOT_DrawRef reserved_drawref; + void *reserved_paneP; + void *reserved_job_manageP; // used for managing async job requests for UI in the context of Effect pane custom UI +} PF_Context, *PF_ContextPtr, **PF_ContextH; + +typedef enum { + PenTip, + PenEraser +} PF_StylusTool; + +typedef struct { + // only applies when stylus_dataB == true; + A_FpShort stylus_tiltxF; // -1.0 to 1.0 0.0 == vertical + A_FpShort stylus_tiltyF; // -1.0 to 1.0 0.0 == vertical + A_FpShort stylus_pressureF; // 0.0 to 1.0 1.0 == full pressure + A_FpShort stylus_wheelF; // -1.0 to 1.0 0.0 == none +} PF_StylusEventInfo; + +typedef struct PF_PointerEventInfo { + A_FpLong when_secondsF; + PF_Point screen_point; + A_short num_clicksS; + A_long mod_keysL; + + PF_StylusTool stylus_tool; // set to PenTip when using mouse + PF_Boolean stylus_extra_dataB; + PF_StylusEventInfo stylus_extra_data; // only valid when stylus_extra_dataB == true +} PF_PointerEventInfo; + +typedef struct { + void *refcon; // front-end's refcon + + PF_Err (*layer_to_comp)(void *refcon, /* >> */ + PF_ContextH context, /* >> */ + A_long curr_time, /* >> */ + A_long time_scale, /* >> */ + PF_FixedPoint *pt); /* << */ + + PF_Err (*comp_to_layer)(void *refcon, /* >> */ + PF_ContextH context, /* >> */ + A_long curr_time, /* >> */ + A_long time_scale, /* >> */ + PF_FixedPoint *pt); /* << */ + + PF_Err (*get_comp2layer_xform)(void *refcon, /* >> */ + PF_ContextH context, /* >> */ + A_long curr_time, /* >> */ + A_long time_scale, /* >> */ + A_long *exists, /* << non-zero if exists */ + PF_FloatMatrix *c2l); /* << */ + + PF_Err (*get_layer2comp_xform)(void *refcon, /* >> */ + PF_ContextH context, /* >> */ + A_long curr_time, /* >> */ + A_long time_scale, /* >> */ + PF_FloatMatrix *l2c); /* << */ + + PF_Err (*source_to_frame)(void *refcon, PF_ContextH context, PF_FixedPoint *pt); + PF_Err (*frame_to_source)(void *refcon, PF_ContextH context, PF_FixedPoint *pt); + + PF_Err (*info_draw_color)(void *refcon, PF_Pixel color); + + // 2 lines of text, same as calling PF_InfoDrawText3( line1Z0, line2Z0, NULL) + PF_Err (*info_draw_text)(void *refcon, const A_char *text1Z0, const A_char *text2Z0); // Cstrings + + // Due to this structure's containment within PF_EventExtra, + // we are unable to add new functions to this structure in order + // to remain backwards compatible. In other words, do not add any + // new functions here, add them to the PF_AdvAppSuite1 suite + // within AE_AdvEffectSuites.h. -jja 10-24-2000 + +} PF_EventCallbacks, *PF_EventCallbacksPtr; + +enum { + PF_EA_NONE = 0, + PF_EA_PARAM_TITLE, + PF_EA_CONTROL +}; +typedef A_long PF_EffectArea; + +typedef struct { + PF_ParamIndex index; + PF_EffectArea area; + PF_UnionableRect current_frame; // full frame of the current area + PF_UnionableRect param_title_frame; // full frame of the param title area + A_long horiz_offset; // h offset to draw into title +} PF_EffectWindowInfo; + +enum { + PF_EO_NONE = 0, + PF_EO_HANDLED_EVENT = (1L << 0), + PF_EO_ALWAYS_UPDATE = (1L << 1), //rerender the comp + PF_EO_NEVER_UPDATE = (1L << 2), //do not rerender the comp + PF_EO_UPDATE_NOW = (1L << 3) //update the view immediately after the event returns when using PF_InvalidateRect +}; +typedef A_long PF_EventOutFlags; + +enum { + PF_EI_NONE = 0, + PF_EI_DONT_DRAW = 1L << 0 // don't draw controls in comp or layer window +}; +typedef A_long PF_EventInFlags; + +// this info is passed for ALL event types, except those in the Effect Control Window +// in ECW, you get the PF_EffectWindowInfo, during all events +typedef struct { + PF_UnionableRect port_rect; +} PF_ItemWindowInfo; + +/* + to know what union to take, look in + (**contextH).w_type. if == effect win, you get effect win, else you get item win +*/ +typedef union { + PF_EffectWindowInfo effect_win; /* >> only for Effect window do_click, draw, and adjust-cursor */ + PF_ItemWindowInfo item_win; /* >> comp or layer */ +} PF_WindowUnion; + +// uncomment if you want to get the port rect during most events +// #define PF_USE_NEW_WINDOW_UNION +typedef struct { + PF_ContextH contextH; /* >> */ + PF_EventType e_type; /* >> */ + PF_EventUnion u; /* >> based on e_type */ + + #ifdef PF_USE_NEW_WINDOW_UNION + PF_WindowUnion window_union; /* >> union of window-specific handy information */ + #else + PF_EffectWindowInfo effect_win; /* >> only for Effect window do_click, draw, and adjust-cursor */ + #endif + + PF_EventCallbacks cbs; /* >> not for new_context or close_context */ + PF_EventInFlags evt_in_flags; /* >> */ + PF_EventOutFlags evt_out_flags; /* << */ +} PF_EventExtra; + +enum { + PF_UIAlignment_NONE = 0, // No values other than PF_UIAlignment_NONE are honored, in AE or PPro. + PF_UIAlignment_TOP = 1L << 0, + PF_UIAlignment_LEFT = 1L << 1, + PF_UIAlignment_BOTTOM = 1L << 2, + PF_UIAlignment_RIGHT = 1L << 3 +}; + +typedef A_long PF_UIAlignment; + +struct _PF_CustomUIInfo { + + A_long reserved; + PF_CustomEventFlags events; + + A_long comp_ui_width; + A_long comp_ui_height; + PF_UIAlignment comp_ui_alignment; // unused + + A_long layer_ui_width; + A_long layer_ui_height; + PF_UIAlignment layer_ui_alignment; // unused + + A_long preview_ui_width; // unused + A_long preview_ui_height; // unused + PF_UIAlignment preview_ui_alignment; // unused + +}; + + +#ifdef __cplusplus +} +#endif + + +#include + + + +#endif /* _H_AE_EffectUI */ diff --git a/External/AE SDK/Headers/AE_EffectVers.h b/External/AE SDK/Headers/AE_EffectVers.h new file mode 100644 index 00000000..f9ab54a3 --- /dev/null +++ b/External/AE SDK/Headers/AE_EffectVers.h @@ -0,0 +1,17 @@ +#ifndef _H_AE_EffectVers +#define _H_AE_EffectVers + + +#define AEFX_API_VERSION 8 +#define AEFX_API_SUBVERS ' ' +#define AEFXp_CODE_VERSION 0 // no longer user, we have p4 now + +// these are here as copies -> when these change in AE_Effect.h, AEFX won't compile +// when they change, decide how to update above versions +// NOTE: this file is included by effect\shared\AEFX_PiPL.r and these versions are +// used when building PiPLs +#define PF_PLUG_IN_VERSION 13 // auto-set by prep_codeline_for_release.py, adjust comment if manually edit is okay +#define PF_PLUG_IN_SUBVERS 27 // manually set for SDK changes to allow more than 32 max threads for PF_Iterate + + +#endif diff --git a/External/AE SDK/Headers/AE_GeneralPlug.h b/External/AE SDK/Headers/AE_GeneralPlug.h new file mode 100644 index 00000000..ea0f7de9 --- /dev/null +++ b/External/AE SDK/Headers/AE_GeneralPlug.h @@ -0,0 +1,5779 @@ +/*******************************************************************/ +/* */ +/* ADOBE CONFIDENTIAL */ +/* _ _ _ _ _ _ _ _ _ _ _ _ _ */ +/* */ +/* Copyright 2007 Adobe Systems Incorporated */ +/* All Rights Reserved. */ +/* */ +/* NOTICE: All information contained herein is, and remains the */ +/* property of Adobe Systems Incorporated and its suppliers, if */ +/* any. The intellectual and technical concepts contained */ +/* herein are proprietary to Adobe Systems Incorporated and its */ +/* suppliers and may be covered by U.S. and Foreign Patents, */ +/* patents in process, and are protected by trade secret or */ +/* copyright law. Dissemination of this information or */ +/* reproduction of this material is strictly forbidden unless */ +/* prior written permission is obtained from Adobe Systems */ +/* Incorporated. */ +/* */ +/*******************************************************************/ + +#ifndef _H_AE_PlugGeneral +#define _H_AE_PlugGeneral + +#include +#include +#include +#include +#include + +#include +#include +#include +#ifdef AEGP_INTERNAL +#include +#endif +#include +#include + + +#include + +#define AEGP_PLUGIN_TYPE 'AEgx' + +#define AEGP_INITFUNC_MAJOR_VERSION 1 +#define AEGP_INITFUNC_MINOR_VERSION 9 + +#ifndef AEGP_INTERNAL + typedef struct _AEGP_Project **AEGP_ProjectH; + typedef struct _AEGP_Item **AEGP_ItemH; + typedef struct _AEGP_Comp **AEGP_CompH; + typedef struct _AEGP_Footage **AEGP_FootageH; + typedef struct _AEGP_Layer **AEGP_LayerH; + typedef struct _AEGP_Effect **AEGP_EffectRefH; + typedef struct _AEGP_Mask **AEGP_MaskRefH; + typedef struct _AEGPp_Stream **AEGP_StreamRefH; + typedef struct _AEGP_LayerContext **AEGP_RenderLayerContextH; + typedef struct _AEGP_PersistentBlob **AEGP_PersistentBlobH; + typedef struct _AEGP_MaskOutline **AEGP_MaskOutlineValH; + typedef struct _AEGP_Collection **AEGP_CollectionH; + typedef struct _AEGP_Collection2 **AEGP_Collection2H; + typedef struct _AEGP_SoundData **AEGP_SoundDataH; + typedef struct _AEGP_AddKeyframesInfo **AEGP_AddKeyframesInfoH; + typedef struct _AEGP_RenderReceipt **AEGP_RenderReceiptH; + typedef struct _AEGP_World **AEGP_WorldH; + typedef struct _AEGP_RenderOptions **AEGP_RenderOptionsH; + typedef struct _AEGP_LayerRenderOptions **AEGP_LayerRenderOptionsH; + typedef struct _AEGP_FrameReceipt **AEGP_FrameReceiptH; + typedef struct _AEGP_RenderQueueItem **AEGP_RQItemRefH; + typedef struct _AEGP_OutputModule **AEGP_OutputModuleRefH; + typedef struct _AEGP_TextDocument **AEGP_TextDocumentH; + typedef struct _AEGP_MarkerVal *AEGP_MarkerValP; + // AEGP_ConstMarkerValP is defined in AE_IO.h; + typedef struct _AEGP_TextOutlines **AEGP_TextOutlinesH; + typedef struct _AEGP_TimeStamp{A_char a[4];} AEGP_TimeStamp; + typedef struct _AEGP_PlatformWorld **AEGP_PlatformWorldH; + typedef struct _AEGP_ItemView *AEGP_ItemViewP; + typedef struct _AEGP_ColorProfile *AEGP_ColorProfileP; + typedef const struct _AEGP_ColorProfile *AEGP_ConstColorProfileP; +#endif + +typedef A_long AEGP_SubLayerIndex; + +#define AEGP_SubLayer_ALL (-1L) + +typedef A_long AEGP_PluginID; +// define a _AEGP_Refcon1 struct to use a typesafe refcon. +typedef struct _AEGP_GlobalRefcon *AEGP_GlobalRefcon; +typedef struct _AEGP_CommandRefcon *AEGP_CommandRefcon; +typedef struct _AEGP_UpdateMenuRefcon *AEGP_UpdateMenuRefcon; +typedef struct _AEGP_DeathRefcon *AEGP_DeathRefcon; +typedef struct _AEGP_VersionRefcon *AEGP_VersionRefcon; +typedef struct _AEGP_AboutStringRefcon *AEGP_AboutStringRefcon; +typedef struct _AEGP_AboutRefcon *AEGP_AboutRefcon; +typedef struct _AEGP_AsyncFrameRequestRefcon *AEGP_AsyncFrameRequestRefcon; +typedef struct _AEGP_IdleRefcon *AEGP_IdleRefcon; +typedef struct _AEGP_IORefcon *AEGP_IORefcon; +typedef struct _AEGP_CancelRefcon *AEGP_CancelRefcon; + + +// _SIZE constants include space for the terminating null. -1 for string length. +#define AEGP_MAX_PATH_SIZE 260 +#define AEGP_MAX_ABOUT_STRING_SIZE 256 +#define AEGP_MAX_RQITEM_COMMENT_SIZE 256 +#define AEGP_MAX_TYPE_NAME_SIZE 32 +#define AEGP_MAX_ITEM_NAME_SIZE 32 +#define AEGP_MAX_ITEM_NAME_SIZE 32 +#define AEGP_MAX_LAYER_NAME_SIZE 32 +#define AEGP_MAX_MASK_NAME_SIZE 32 +#define AEGP_MAX_EFFECT_NAME_SIZE (PF_MAX_EFFECT_NAME_LEN + 17) +#define AEGP_MAX_EFFECT_MATCH_NAME_SIZE (PF_MAX_EFFECT_NAME_LEN + 17) +#define AEGP_MAX_EFFECT_CATEGORY_NAME_SIZE (PF_MAX_EFFECT_CATEGORY_NAME_LEN + 1) +#define AEGP_MAX_STREAM_NAME_SIZE (PF_MAX_EFFECT_PARAM_NAME_LEN + 1) +#define AEGP_MAX_STREAM_UNITS_SIZE (PF_MAX_EFFECT_PARAM_NAME_LEN + 1) +#define AEGP_MAX_PROJ_NAME_SIZE 48 +#define AEGP_MAX_PLUGIN_NAME_SIZE 32 + +#define AEGP_MAX_MARKER_NAME_SIZE 64 +#define AEGP_MAX_MARKER_URL_SIZE 1024 +#define AEGP_MAX_MARKER_TARGET_SIZE 128 +#define AEGP_MAX_MARKER_CHAPTER_SIZE 128 + + +enum { + AEGP_Platform_MAC, + AEGP_Platform_WIN +}; +typedef A_long AEGP_Platform; + +enum { + AEGP_ProjBitDepth_8 = 0, + AEGP_ProjBitDepth_16, + AEGP_ProjBitDepth_32, + AEGP_ProjBitDepth_NUM_VALID_DEPTHS +}; +typedef A_char AEGP_ProjBitDepth; + +#define AEGP_Index_NONE ((A_long)0x80000000) +#define AEGP_Index_START ((A_long)0) +#define AEGP_Index_END ((A_long)-1) + +typedef A_long AEGP_Index; + +#define AEGP_LayerIDVal_NONE (0L) + +typedef A_long AEGP_LayerIDVal; + +#define AEGP_MaskIDVal_NONE (0L) + +typedef A_long AEGP_MaskIDVal; + +typedef struct { + A_FpLong alphaF, redF, greenF, blueF; // in the range [0.0 - 1.0] +} AEGP_ColorVal; + + +enum { + AEGP_CameraType_NONE = -1, + + AEGP_CameraType_PERSPECTIVE, + AEGP_CameraType_ORTHOGRAPHIC, + + AEGP_CameraType_NUM_TYPES +}; + +typedef A_u_long AEGP_CameraType; + +enum { + AEGP_FootageDepth_1 = 1, + AEGP_FootageDepth_2 = 2, + AEGP_FootageDepth_4 = 4, + AEGP_FootageDepth_8 = 8, + AEGP_FootageDepth_16 = 16, + AEGP_FootageDepth_24 = 24, + AEGP_FootageDepth_30 = 30, + AEGP_FootageDepth_32 = 32, + AEGP_FootageDepth_GRAY_2 = 34, + AEGP_FootageDepth_GRAY_4 = 36, + AEGP_FootageDepth_GRAY_8 = 40, + AEGP_FootageDepth_48 = 48, + AEGP_FootageDepth_64 = 64, + AEGP_FootageDepth_GRAY_16 = -16 +}; + + +enum { + AEGP_FilmSizeUnits_NONE = 0, + AEGP_FilmSizeUnits_HORIZONTAL, + AEGP_FilmSizeUnits_VERTICAL, + AEGP_FilmSizeUnits_DIAGONAL +}; +typedef A_long AEGP_FilmSizeUnits; + + +enum { + AEGP_LightType_NONE = -1, + + AEGP_LightType_PARALLEL, + AEGP_LightType_SPOT, + AEGP_LightType_POINT, + AEGP_LightType_AMBIENT, + + AEGP_LightType_NUM_TYPES +}; + +typedef A_u_long AEGP_LightType; + + +enum { + AEGP_LightFalloff_NONE = 0, + AEGP_LightFalloff_SMOOTH, + AEGP_LightFalloff_INVERSE_SQUARE_CLAMPED +}; + +typedef A_u_long AEGP_LightFalloffType; + + +/* -------------------------------------------------------------------- */ + +enum { + AEGP_TimeDisplayType_TIMECODE = 0, + AEGP_TimeDisplayType_FRAMES, + AEGP_TimeDisplayType_FEET_AND_FRAMES +}; +typedef A_char AEGP_TimeDisplayType; + +#define AEGP_FramesPerFoot_35MM 16 +#define AEGP_FramesPerFoot_16MM 40 + +typedef struct { // note: unused values are still stored in settings and used when cycling through + // the 3 types using cmd/ctrl-click on timecode + AEGP_TimeDisplayType time_display_type; + A_char timebaseC; // only used for AEGP_TimeDisplayType_TIMECODE, 1 to 100 + A_Boolean non_drop_30B; // only used for AEGP_TimeDisplayType_TIMECODE, + // when timebaseC == 30 && item framerate == 29.97, use drop frame or non-drop? + A_char frames_per_footC; // only used for AEGP_TimeDisplayType_FEET_AND_FRAMES + A_long starting_frameL; // usually 0 or 1, not used for AEGP_TimeDisplayType_TIMECODE + A_Boolean auto_timecode_baseB; +} AEGP_TimeDisplay2; + +enum { + AEGP_TimeDisplay_TIMECODE = 0, + AEGP_TimeDisplay_FRAMES +}; +typedef char AEGP_TimeDisplayMode; + +enum { + AEGP_SourceTimecode_ZERO = 0, + AEGP_SourceTimecode_SOURCE_TIMECODE +}; +typedef char AEGP_SourceTimecodeDisplayMode; + +enum { + AEGP_Frames_ZERO_BASED = 0, + AEGP_Frames_ONE_BASED, + AEGP_Frames_TIMECODE_CONVERSION +}; +typedef char AEGP_FramesDisplayMode; + +typedef struct { + AEGP_TimeDisplayMode display_mode; + AEGP_SourceTimecodeDisplayMode footage_display_mode; + A_Boolean display_dropframeB; + A_Boolean use_feet_framesB; + A_char timebaseC; + A_char frames_per_footC; + AEGP_FramesDisplayMode frames_display_mode; +} AEGP_TimeDisplay3; + + + +#define kAEGPProjSuite "AEGP Proj Suite" +#define kAEGPProjSuiteVersion6 9 /* frozen in AE 10.5 */ + +typedef struct AEGP_ProjSuite6 { + + SPAPI A_Err (*AEGP_GetNumProjects)( /* will always (in 5.0) return 1 if project is open */ + A_long *num_projPL); /* << */ + + SPAPI A_Err (*AEGP_GetProjectByIndex)( + A_long proj_indexL, /* >> */ + AEGP_ProjectH *projPH); /* << */ + + SPAPI A_Err (*AEGP_GetProjectName)( + AEGP_ProjectH projH, /* >> */ + A_char *nameZ); /* << space for A_char[AEGP_MAX_PROJ_NAME_SIZE] */ + + SPAPI A_Err (*AEGP_GetProjectPath)( + AEGP_ProjectH projH, /* >> */ + AEGP_MemHandle *unicode_pathPH); // << empty string if no file. handle of A_UTF16Char (contains null terminated UTF16 string); must be disposed with AEGP_FreeMemHandle + + SPAPI A_Err (*AEGP_GetProjectRootFolder)( + AEGP_ProjectH projH, /* >> */ + AEGP_ItemH *root_folderPH); /* << */ + + SPAPI A_Err (*AEGP_SaveProjectToPath)( + AEGP_ProjectH projH, /* >> */ + const A_UTF16Char *pathZ); // >> null terminated unicode path with platform separators + + SPAPI A_Err (*AEGP_GetProjectTimeDisplay)( + AEGP_ProjectH projH, /* >> */ + AEGP_TimeDisplay3 *time_displayP); /* << */ + + SPAPI A_Err (*AEGP_SetProjectTimeDisplay)( /* UNDOABLE */ + AEGP_ProjectH projH, /* <> */ + const AEGP_TimeDisplay3 *time_displayP); /* >> */ + + SPAPI A_Err (*AEGP_ProjectIsDirty)( + AEGP_ProjectH projH, /* >> */ + A_Boolean *is_dirtyPB); /* << */ + + SPAPI A_Err (*AEGP_SaveProjectAs)( + AEGP_ProjectH projH, /* >> */ + const A_UTF16Char *pathZ); // >> null terminated unicode path with platform separators + + SPAPI A_Err (*AEGP_NewProject)( + AEGP_ProjectH *new_projectPH); /* << WARNING: Will close any open projects! */ + + // WARNING: Will close any open projects! + SPAPI A_Err (*AEGP_OpenProjectFromPath)( + const A_UTF16Char *pathZ, // >> null terminated unicode path with platform separators + AEGP_ProjectH *projectPH); /* << */ + + SPAPI A_Err (*AEGP_GetProjectBitDepth)( + AEGP_ProjectH projectH, /* >> */ + AEGP_ProjBitDepth *bit_depthP); /* << */ + + SPAPI A_Err (*AEGP_SetProjectBitDepth)( /* UNDOABLE */ + AEGP_ProjectH projectH, /* >> */ + AEGP_ProjBitDepth bit_depth); /* >> */ + +} AEGP_ProjSuite6; + +/* -------------------------------------------------------------------- */ + +enum { + AEGP_SoundEncoding_UNSIGNED_PCM = 3, + AEGP_SoundEncoding_SIGNED_PCM, + AEGP_SoundEncoding_FLOAT, + AEGP_SoundEncoding_END, + AEGP_SoundEncoding_BEGIN = AEGP_SoundEncoding_UNSIGNED_PCM +}; +typedef A_long AEGP_SoundEncoding; + +typedef struct AEGP_SoundDataFormat { + A_FpLong sample_rateF; + AEGP_SoundEncoding encoding; + A_long bytes_per_sampleL; /* 1, 2, or 4 only (ignored if encoding == AEGP_SoundEncoding_FLOAT) */ + A_long num_channelsL; /* 1 for mono, 2 for stereo */ +}AEGP_SoundDataFormat; + + +enum { + AEGP_ItemType_NONE, + AEGP_ItemType_FOLDER, + AEGP_ItemType_COMP, + AEGP_ItemType_SOLID_defunct, // as of AE6, solids are now just AEGP_ItemType_FOOTAGE with AEGP_FootageSignature_SOLID + AEGP_ItemType_FOOTAGE, + AEGP_ItemType_NUM_TYPES1 +}; +typedef A_short AEGP_ItemType; + + +enum { + AEGP_ItemFlag_MISSING = 0x1, /* footage property: here for convenience */ + AEGP_ItemFlag_HAS_PROXY = 0x2, + AEGP_ItemFlag_USING_PROXY = 0x4, /* is using the proxy as source */ + AEGP_ItemFlag_MISSING_PROXY = 0x8, /* footage property: here for convenience */ + AEGP_ItemFlag_HAS_VIDEO = 0x10, /* is there a video track? */ + AEGP_ItemFlag_HAS_AUDIO = 0x20, /* is there an audio track? */ + AEGP_ItemFlag_STILL = 0x40, /* are all frames exactly the same */ + AEGP_ItemFlag_HAS_ACTIVE_AUDIO = 0x80 /* new in AE CS 5.5: is there an audio track, and is it also turned on right now? */ +}; +typedef A_long AEGP_ItemFlags; + + +enum { + AEGP_Label_NONE = -1, /* undefined sentinel value */ + AEGP_Label_NO_LABEL = 0, + AEGP_Label_1, + AEGP_Label_2, + AEGP_Label_3, + AEGP_Label_4, + AEGP_Label_5, + AEGP_Label_6, + AEGP_Label_7, + AEGP_Label_8, + AEGP_Label_9, + AEGP_Label_10, + AEGP_Label_11, + AEGP_Label_12, + AEGP_Label_13, + AEGP_Label_14, + AEGP_Label_15, + AEGP_Label_16, // label 16 is new in AE 10.0 (CS5) + + AEGP_Label_NUMTYPES +}; +typedef A_char AEGP_LabelID; + +/* -------------------------------------------------------------------- */ + +enum { + AEGP_PersistentType_MACHINE_SPECIFIC, + AEGP_PersistentType_MACHINE_INDEPENDENT, + AEGP_PersistentType_MACHINE_INDEPENDENT_RENDER, + AEGP_PersistentType_MACHINE_INDEPENDENT_OUTPUT, + AEGP_PersistentType_MACHINE_INDEPENDENT_COMPOSITION, + AEGP_PersistentType_MACHINE_SPECIFIC_TEXT, + AEGP_PersistentType_MACHINE_SPECIFIC_PAINT, + + AEGP_PersistentType_NUMTYPES +}; +typedef A_long AEGP_PersistentType; + + +#define kAEGPItemSuite "AEGP Item Suite" +#define kAEGPItemSuiteVersion9 14 /* frozen in AE 14.1 */ + +typedef struct AEGP_ItemSuite9 { + + SPAPI A_Err (*AEGP_GetFirstProjItem)( + AEGP_ProjectH projectH, /* >> */ + AEGP_ItemH *itemPH); /* << */ + + SPAPI A_Err (*AEGP_GetNextProjItem)( + AEGP_ProjectH projectH, /* >> */ + AEGP_ItemH itemH, /* >> */ + AEGP_ItemH *next_itemPH); /* << NULL after last item */ + + SPAPI A_Err (*AEGP_GetActiveItem)( + AEGP_ItemH *itemPH); /* << NULL if none is active */ + + SPAPI A_Err (*AEGP_IsItemSelected)( + AEGP_ItemH itemH, /* >> */ + A_Boolean *selectedPB); /* << */ + + SPAPI A_Err (*AEGP_SelectItem)( + AEGP_ItemH itemH, /* >> */ + A_Boolean selectB, /* >> allows to select or deselect the item */ + A_Boolean deselect_othersB); /* >> */ + + SPAPI A_Err (*AEGP_GetItemType)( + AEGP_ItemH itemH, /* >> */ + AEGP_ItemType *item_typeP); /* << */ + + SPAPI A_Err (*AEGP_GetTypeName)( + AEGP_ItemType item_type, /* << */ + A_char *nameZ); /* << space for A_char[AEGP_MAX_TYPE_NAME_SIZE] */ + + SPAPI A_Err (*AEGP_GetItemName)( + AEGP_PluginID pluginID, // in + AEGP_ItemH itemH, /* >> */ + AEGP_MemHandle *unicode_namePH); // << handle of A_UTF16Char (contains null terminated UTF16 string); must be disposed with AEGP_FreeMemHandle + + SPAPI A_Err (*AEGP_SetItemName)( /* UNDOABLE */ + AEGP_ItemH itemH, /* >> */ + const A_UTF16Char *nameZ); /* >> null terminated UTF16 */ + + SPAPI A_Err (*AEGP_GetItemID)( + AEGP_ItemH itemH, /* >> */ + A_long *item_idPL); /* << */ + + SPAPI A_Err (*AEGP_GetItemFlags)( + AEGP_ItemH itemH, /* >> */ + AEGP_ItemFlags *item_flagsP); /* << */ + + SPAPI A_Err (*AEGP_SetItemUseProxy)( /* UNDOABLE */ + AEGP_ItemH itemH, /* >> error if has_proxy is FALSE! */ + A_Boolean use_proxyB); /* >> */ + + SPAPI A_Err (*AEGP_GetItemParentFolder)( + AEGP_ItemH itemH, /* >> */ + AEGP_ItemH *parent_folder_itemPH); /* << */ + + SPAPI A_Err (*AEGP_SetItemParentFolder)( + AEGP_ItemH itemH, /* <> */ + AEGP_ItemH parent_folder_itemH); /* >> */ + + SPAPI A_Err (*AEGP_GetItemDuration)( /* Returns the result in the item's native timespace: */ + AEGP_ItemH itemH, /* >> Comp -> comp time, */ + A_Time *durationPT); /* << Footage -> footage time, */ + /* Folder -> 0 (no duration) */ + + SPAPI A_Err (*AEGP_GetItemCurrentTime)( /* Returns the result in the item's native timespace (not updated while rendering)*/ + AEGP_ItemH itemH, /* >> */ + A_Time *curr_timePT); /* << */ + + SPAPI A_Err (*AEGP_GetItemDimensions)( + AEGP_ItemH itemH, /* >> */ + A_long *widthPL, /* << */ + A_long *heightPL); /* << */ + + SPAPI A_Err (*AEGP_GetItemPixelAspectRatio)( + AEGP_ItemH itemH, /* >> */ + A_Ratio *pix_aspect_ratioPRt); /* << */ + + SPAPI A_Err (*AEGP_DeleteItem)( /* UNDOABLE */ + AEGP_ItemH itemH); /* >> removes item from all comps */ + + SPAPI A_Err (*AEGP_CreateNewFolder)( + const A_UTF16Char *nameZ, /* >> null terminated UTF16 */ + AEGP_ItemH parent_folderH0, /* >> */ + AEGP_ItemH *new_folderPH); /* << allocated and owned by AE */ + + SPAPI A_Err (*AEGP_SetItemCurrentTime)( /* UNDOABLE. Use the item's native timespace */ + AEGP_ItemH itemH, /* >> */ + const A_Time *new_timePT); /* >> */ + + SPAPI A_Err (*AEGP_GetItemComment)( + AEGP_ItemH itemH, /* >> */ + AEGP_MemHandle *unicode_namePH); /* << */ + + SPAPI A_Err (*AEGP_SetItemComment)( + AEGP_ItemH itemH, /* >> UNDOABLE */ + const A_UTF16Char *commentZ); /* >> */ + + SPAPI A_Err (*AEGP_GetItemLabel)( + AEGP_ItemH itemH, /* >> */ + AEGP_LabelID *labelP); /* << */ + + SPAPI A_Err (*AEGP_SetItemLabel)( + AEGP_ItemH itemH, /* >> UNDOABLE */ + AEGP_LabelID label); /* >> */ + + SPAPI A_Err (*AEGP_GetItemMRUView)( + AEGP_ItemH itemH, // >> + AEGP_ItemViewP *mru_viewP); // << + +} AEGP_ItemSuite9; + + +/* -------------------------------------------------------------------- */ + +#define kAEGPItemViewSuite "AEGP Item View Suite" +#define kAEGPItemViewSuiteVersion1 1 /* frozen in AE 13.6 */ + +typedef struct AEGP_ItemViewSuite1 { + // Each item view can have its own playback time, if previewing is active, otherwise the current associated item time + SPAPI A_Err (*AEGP_GetItemViewPlaybackTime)( + AEGP_ItemViewP item_viewP, /* >> */ + A_Boolean *is_currently_previewingPB0, /* >> whether the time is actually playback time (TRUE), FALSE is default item current_time */ + A_Time *curr_timePT ); /* << */ + +} AEGP_ItemViewSuite1; + + + +/* -------------------------------------------------------------------- */ + +#define kAEGPSoundDataSuite "AEGP Sound Data Suite" +#define kAEGPSoundDataVersion1 1 /* frozen in AE 5.0 */ + + +typedef struct AEGP_SoundDataSuite1 { + SPAPI A_Err (*AEGP_NewSoundData)( /* Must be disposed with DisposeSoundData */ + const AEGP_SoundDataFormat* sound_formatP, + AEGP_SoundDataH *new_sound_dataPH); /* << can return NULL if no audio */ + + SPAPI A_Err (*AEGP_DisposeSoundData)( + AEGP_SoundDataH sound_dataH); /* >> */ + + SPAPI A_Err (*AEGP_GetSoundDataFormat)( + AEGP_SoundDataH soundH, /* >> */ + AEGP_SoundDataFormat *sound_formatP); /* << */ + + + /* + If the sound format has two channels, the data is interleaved + left (0), right(1), left(0), right(1), ... + + AEGP_SoundEncoding_FLOAT has a type of FpShort + + For bytes_per_sample == 1 + AEGP_SoundEncoding_UNSIGNED_PCM == A_u_char + AEGP_SoundEncoding_SIGNED_PCM == A_char + + For bytes_per_sample == 2 + AEGP_SoundEncoding_UNSIGNED_PCM == A_u_short + AEGP_SoundEncoding_SIGNED_PCM == A_short + + For bytes_per_sample == 4 + AEGP_SoundEncoding_UNSIGNED_PCM == A_u_long + AEGP_SoundEncoding_SIGNED_PCM == A_long + + usage: + void * sound_dataP; + sds->AEGP_LockSoundDataSamples( soundH, &sound_dataP); + A_u_long* correct_samples = (A_u_long*)sound_dataP; // for AEGP_SoundEncoding_UNSIGNED_PCM + */ + + SPAPI A_Err (*AEGP_LockSoundDataSamples)( + AEGP_SoundDataH soundH, /* >> */ + void **samples); /* << use the correct combination of unsigned/signed/float and bytes_per_sample to determine type */ + + SPAPI A_Err (*AEGP_UnlockSoundDataSamples)( + AEGP_SoundDataH soundH); /* >> */ + + SPAPI A_Err (*AEGP_GetNumSamples)( + AEGP_SoundDataH soundH, /* >> */ + A_long *num_samplesPL); /* << */ + +} AEGP_SoundDataSuite1 ; + + + +/* -------------------------------------------------------------------- */ + + +typedef struct { + A_short xS, yS; +} AEGP_DownsampleFactor; + +enum { + AEGP_CompFlag_SHOW_ALL_SHY = 0x1, + AEGP_CompFlag_RESERVED_1 = 0x2, + AEGP_CompFlag_RESERVED_2 = 0x4, + AEGP_CompFlag_ENABLE_MOTION_BLUR = 0x8, + AEGP_CompFlag_ENABLE_TIME_FILTER = 0x10, + AEGP_CompFlag_GRID_TO_FRAMES = 0x20, + AEGP_CompFlag_GRID_TO_FIELDS = 0x40, + AEGP_CompFlag_USE_LOCAL_DSF = 0x80, // If on, use the dsf in the comp, not the RO + AEGP_CompFlag_DRAFT_3D = 0x100, + AEGP_CompFlag_SHOW_GRAPH = 0x200, + AEGP_CompFlag_RESERVED_3 = 0x400 + +}; +typedef A_long AEGP_CompFlags; + + + + +#define kAEGPCompSuite "AEGP Comp Suite" +#define kAEGPCompSuiteVersion11 25 /* frozen in AE 14.2 */ + +typedef struct AEGP_CompSuite11 { + + SPAPI A_Err (*AEGP_GetCompFromItem)( // error if item isn't AEGP_ItemType_COMP! + AEGP_ItemH itemH, /* >> */ + AEGP_CompH *compPH); /* << */ + + SPAPI A_Err (*AEGP_GetItemFromComp)( + AEGP_CompH compH, /* >> */ + AEGP_ItemH *itemPH); /* << */ + + SPAPI A_Err (*AEGP_GetCompDownsampleFactor)( + AEGP_CompH compH, /* >> */ + AEGP_DownsampleFactor *dsfP); /* << */ + + SPAPI A_Err (*AEGP_SetCompDownsampleFactor)( + AEGP_CompH compH, /* <> */ + const AEGP_DownsampleFactor *dsfP); /* >> */ + + SPAPI A_Err (*AEGP_GetCompBGColor)( + AEGP_CompH compH, /* >> */ + AEGP_ColorVal *bg_colorP); /* << */ + + SPAPI A_Err (*AEGP_SetCompBGColor)( + AEGP_CompH compH, /* >> */ + const AEGP_ColorVal *bg_colorP); /* >> */ + + SPAPI A_Err (*AEGP_GetCompFlags)( + AEGP_CompH compH, /* >> */ + AEGP_CompFlags *comp_flagsP); /* << */ + + /*Opens the comp*/ + SPAPI A_Err (*AEGP_GetShowLayerNameOrSourceName)( + AEGP_CompH compH, /* >> */ + A_Boolean *layer_names_shownPB); /* << true if layer names, false if source names */ + + /*Opens the comp*/ + SPAPI A_Err (*AEGP_SetShowLayerNameOrSourceName)( + AEGP_CompH compH, /* >> */ + A_Boolean show_layer_namesB); /* >> true to show layer names, false to show source names */ + + /*Opens the comp*/ + SPAPI A_Err (*AEGP_GetShowBlendModes)( + AEGP_CompH compH, /* >> */ + A_Boolean *blend_modes_shownPB); /* << */ + + /*Opens the comp*/ + SPAPI A_Err (*AEGP_SetShowBlendModes)( + AEGP_CompH compH, /* >> */ + A_Boolean show_blend_modesB); /* << */ + + SPAPI A_Err (*AEGP_GetCompFramerate)( + AEGP_CompH compH, /* >> */ + A_FpLong *fpsPF); /* << */ + + SPAPI A_Err (*AEGP_SetCompFrameRate)( + AEGP_CompH compH, /* >> */ + const A_FpLong *fpsPF); /* >> */ + + SPAPI A_Err (*AEGP_GetCompShutterAnglePhase)( + AEGP_CompH compH, /* >> */ + A_Ratio *angle, /* << */ + A_Ratio *phase); /* << */ + + SPAPI A_Err (*AEGP_GetCompShutterFrameRange)( + AEGP_CompH compH, /* >> */ + const A_Time *comp_timeP, /* >> */ + A_Time *start, /* << */ + A_Time *duration); /* << */ + + SPAPI A_Err (*AEGP_GetCompSuggestedMotionBlurSamples)( + AEGP_CompH compH, /* >> */ + A_long *samplesPL); /* << */ + + SPAPI A_Err (*AEGP_SetCompSuggestedMotionBlurSamples)( /* UNDOABLE */ + AEGP_CompH compH, /* >> */ + A_long samplesL); /* >> */ + + SPAPI A_Err (*AEGP_GetCompMotionBlurAdaptiveSampleLimit)( + AEGP_CompH compH, /* >> */ + A_long *samplesPL); /* << */ + + SPAPI A_Err (*AEGP_SetCompMotionBlurAdaptiveSampleLimit)( /* UNDOABLE */ + AEGP_CompH compH, /* >> */ + A_long samplesL); /* >> */ + + SPAPI A_Err (*AEGP_GetCompWorkAreaStart)( + AEGP_CompH compH, /* >> */ + A_Time *work_area_startPT); /* << */ + + SPAPI A_Err (*AEGP_GetCompWorkAreaDuration)( + AEGP_CompH compH, /* >> */ + A_Time *work_area_durationPT); /* << */ + + SPAPI A_Err (*AEGP_SetCompWorkAreaStartAndDuration)( /* UNDOABLE */ + AEGP_CompH compH, /* >> */ + const A_Time *work_area_startPT, /* >> */ + const A_Time *work_area_durationPT); /* >> */ + + SPAPI A_Err (*AEGP_CreateSolidInComp)( + const A_UTF16Char *utf_nameZ, /* >> */ + A_long width, /* >> */ + A_long height, /* >> */ + const AEGP_ColorVal *color, /* >> */ + AEGP_CompH parent_compH, /* >> */ + const A_Time *durationPT0, /* >> */ + AEGP_LayerH *new_solidPH); /* << */ + + SPAPI A_Err (*AEGP_CreateCameraInComp)( + const A_UTF16Char *utf_nameZ, /* >> */ + A_FloatPoint center_point, /* >> */ + AEGP_CompH parent_compH, /* >> */ + AEGP_LayerH *new_cameraPH); /* << */ + + SPAPI A_Err (*AEGP_CreateLightInComp)( + const A_UTF16Char *utf_nameZ, /* >> */ + A_FloatPoint center_point, /* >> */ + AEGP_CompH parent_compH, /* >> */ + AEGP_LayerH *new_lightPH); /* << */ + + SPAPI A_Err (*AEGP_CreateComp)( + AEGP_ItemH parent_folderH0, /* >> */ + const A_UTF16Char *utf_nameZ, /* >> */ + A_long widthL, /* >> */ + A_long heightL, /* >> */ + const A_Ratio *pixel_aspect_ratioPRt, /* >> */ + const A_Time *durationPT, /* >> */ + const A_Ratio *frameratePRt, /* >> */ + AEGP_CompH *new_compPH); /* << */ + + SPAPI A_Err (*AEGP_GetNewCollectionFromCompSelection)( + AEGP_PluginID plugin_id, /* >> */ + AEGP_CompH compH, /* >> */ + AEGP_Collection2H *collectionPH); /* << */ + + SPAPI A_Err (*AEGP_SetSelection)( + AEGP_CompH compH, /* >> */ + AEGP_Collection2H collectionH); /* >> not adopted */ + + SPAPI A_Err (*AEGP_GetCompDisplayStartTime)( + AEGP_CompH compH, /* >> */ + A_Time *start_timePT); /* << */ + + SPAPI A_Err (*AEGP_SetCompDisplayStartTime)( /* NOT Undoable! */ + AEGP_CompH compH, /* >> */ + const A_Time *start_timePT); /* >> */ + + SPAPI A_Err (*AEGP_SetCompDuration)( + AEGP_CompH compH, /* >> */ + const A_Time *durationPT); /* >> */ + + SPAPI A_Err (*AEGP_CreateNullInComp)( + const A_UTF16Char *utf_nameZ, /* >> */ + AEGP_CompH parent_compH, /* >> */ + const A_Time *durationPT0, /* >> */ + AEGP_LayerH *new_null_solidPH); /* << */ + + SPAPI A_Err (*AEGP_SetCompPixelAspectRatio)( + AEGP_CompH compH, /* >> */ + const A_Ratio *pix_aspectratioPRt); /* >> */ + + SPAPI A_Err (*AEGP_CreateTextLayerInComp)( + AEGP_CompH parent_compH, /* >> */ + A_Boolean select_new_layerB, /* >> */ + AEGP_LayerH *new_text_layerPH); /* << */ + + SPAPI A_Err (*AEGP_CreateBoxTextLayerInComp)( + AEGP_CompH parent_compH, /* >> */ + A_Boolean select_new_layerB, /* >> */ + A_FloatPoint box_dimensions, /* >> */ // (width and height) + AEGP_LayerH *new_text_layerPH); /* << */ + + SPAPI A_Err (*AEGP_SetCompDimensions)( + AEGP_CompH compH, /* >> */ + A_long widthL, /* >> */ + A_long heightL); /* >> */ + + SPAPI A_Err (*AEGP_DuplicateComp)( + AEGP_CompH compH, /* >> */ + AEGP_CompH *new_compPH); /* << */ + + SPAPI A_Err (*AEGP_GetCompFrameDuration)( + AEGP_CompH compH, /* >> */ + A_Time *timeP); /* << */ + + SPAPI A_Err (*AEGP_GetMostRecentlyUsedComp)( + AEGP_CompH *compPH); /* << If compPH returns NULL, there's no available comp */ + + SPAPI A_Err (*AEGP_CreateVectorLayerInComp)( + AEGP_CompH parent_compH, /* >> */ + AEGP_LayerH *new_vector_layerPH); /* << */ + + SPAPI A_Err (*AEGP_GetNewCompMarkerStream)( + AEGP_PluginID aegp_plugin_id, /* >> */ + AEGP_CompH parent_compH, /* >> */ + AEGP_StreamRefH *streamPH); /* << must be disposed by caller */ + + SPAPI A_Err (*AEGP_GetCompDisplayDropFrame)( + AEGP_CompH compH, /* >> */ + A_Boolean *dropFramePB); /* << */ + + SPAPI A_Err (*AEGP_SetCompDisplayDropFrame)( + AEGP_CompH compH, /* >> */ + A_Boolean dropFrameB); /* << */ + + SPAPI A_Err (*AEGP_ReorderCompSelection)( + AEGP_CompH compH, /* >> */ + A_long index); /* >> */ + +} AEGP_CompSuite11; + + +/* -------------------------------------------------------------------- */ + + +#define kAEGPMemorySuite "AEGP Memory Suite" +#define kAEGPMemorySuiteVersion1 1 /* frozen in AE 5.0 */ + +enum { + AEGP_MemFlag_NONE = 0x0, + AEGP_MemFlag_CLEAR = 0x01, + AEGP_MemFlag_QUIET = 0x02 +}; +typedef A_long AEGP_MemFlag; + +typedef A_u_long AEGP_MemSize; + + +typedef struct AEGP_MemorySuite1 { + + + SPAPI A_Err (*AEGP_NewMemHandle)( AEGP_PluginID plugin_id, /* >> */ + const A_char *whatZ, /* >> */ + AEGP_MemSize size, /* >> */ + AEGP_MemFlag flags, /* >> */ + AEGP_MemHandle *memPH); /* << */ + + SPAPI A_Err (*AEGP_FreeMemHandle)( AEGP_MemHandle memH); + + SPAPI A_Err (*AEGP_LockMemHandle)( AEGP_MemHandle memH, /* nestable */ + void **ptr_to_ptr); /* << */ + + SPAPI A_Err (*AEGP_UnlockMemHandle)( AEGP_MemHandle memH); + + SPAPI A_Err (*AEGP_GetMemHandleSize)( AEGP_MemHandle memH, + AEGP_MemSize *sizeP); /* << */ + + SPAPI A_Err (*AEGP_ResizeMemHandle)( const A_char *whatZ, /* >> */ + AEGP_MemSize new_size, /* >> */ + AEGP_MemHandle memH); /* <> */ + + SPAPI A_Err (*AEGP_SetMemReportingOn)( A_Boolean turn_OnB); + + SPAPI A_Err (*AEGP_GetMemStats)( AEGP_PluginID plugin_id, /* >> */ + A_long *countPL, /* << */ + A_long *sizePL); /* << */ +} AEGP_MemorySuite1; + +/* -------------------------------------------------------------------- */ + + +enum { + AEGP_TransferFlag_PRESERVE_ALPHA = 0x1, + AEGP_TransferFlag_RANDOMIZE_DISSOLVE = 0x2 +}; +typedef A_long AEGP_TransferFlags; + +enum { + AEGP_TrackMatte_NO_TRACK_MATTE, + AEGP_TrackMatte_ALPHA, + AEGP_TrackMatte_NOT_ALPHA, + AEGP_TrackMatte_LUMA, + AEGP_TrackMatte_NOT_LUMA +}; +typedef A_long AEGP_TrackMatte; + +typedef struct { + PF_TransferMode mode; // defined in AE_EffectCB.h + AEGP_TransferFlags flags; + AEGP_TrackMatte track_matte; +} AEGP_LayerTransferMode; + + + +enum { + AEGP_LayerQual_NONE = -1, // sentinel + AEGP_LayerQual_WIREFRAME, // wire-frames only + AEGP_LayerQual_DRAFT, // LO-qual filters, LO-qual geom + AEGP_LayerQual_BEST // HI-qual filters, HI-qual geom +}; +typedef A_short AEGP_LayerQuality; + + +enum { + AEGP_LayerSamplingQual_BILINEAR, // bilinear interpolation + AEGP_LayerSamplingQual_BICUBIC // bicubic interpolation +}; +typedef A_short AEGP_LayerSamplingQuality; + +enum { + AEGP_LayerFlag_NONE = 0x00000000, + AEGP_LayerFlag_VIDEO_ACTIVE = 0x00000001, + AEGP_LayerFlag_AUDIO_ACTIVE = 0x00000002, + AEGP_LayerFlag_EFFECTS_ACTIVE = 0x00000004, + AEGP_LayerFlag_MOTION_BLUR = 0x00000008, + AEGP_LayerFlag_FRAME_BLENDING = 0x00000010, + AEGP_LayerFlag_LOCKED = 0x00000020, + AEGP_LayerFlag_SHY = 0x00000040, + AEGP_LayerFlag_COLLAPSE = 0x00000080, + AEGP_LayerFlag_AUTO_ORIENT_ROTATION = 0x00000100, + AEGP_LayerFlag_ADJUSTMENT_LAYER = 0x00000200, + AEGP_LayerFlag_TIME_REMAPPING = 0x00000400, + AEGP_LayerFlag_LAYER_IS_3D = 0x00000800, + AEGP_LayerFlag_LOOK_AT_CAMERA = 0x00001000, + AEGP_LayerFlag_LOOK_AT_POI = 0x00002000, + AEGP_LayerFlag_SOLO = 0x00004000, + AEGP_LayerFlag_MARKERS_LOCKED = 0x00008000, + AEGP_LayerFlag_NULL_LAYER = 0x00010000, + AEGP_LayerFlag_HIDE_LOCKED_MASKS = 0x00020000, + AEGP_LayerFlag_GUIDE_LAYER = 0x00040000, + AEGP_LayerFlag_ADVANCED_FRAME_BLENDING = 0x00080000, + AEGP_LayerFlag_SUBLAYERS_RENDER_SEPARATELY = 0x00100000, + AEGP_LayerFlag_ENVIRONMENT_LAYER = 0x00200000 +}; +typedef A_long AEGP_LayerFlags; + + +// Layers are always one of the following types. + +enum { + AEGP_ObjectType_NONE = -1, + AEGP_ObjectType_AV, /* Includes all pre-AE 5.0 layer types (audio or video source, including adjustment layers) */ + AEGP_ObjectType_LIGHT, + AEGP_ObjectType_CAMERA, + AEGP_ObjectType_TEXT, + AEGP_ObjectType_VECTOR, + + AEGP_ObjectType_NUM_TYPES +}; +typedef A_long AEGP_ObjectType; + +enum { + AEGP_LTimeMode_LayerTime, + AEGP_LTimeMode_CompTime +}; +typedef A_short AEGP_LTimeMode; + +#define AEGP_REORDER_LAYER_TO_END -1 + +#define kAEGPLayerSuite "AEGP Layer Suite" +#define kAEGPLayerSuiteVersion7 13 /* frozen AE 10.0 build 396 */ + +typedef struct AEGP_LayerSuite7 { + + SPAPI A_Err (*AEGP_GetCompNumLayers)( + AEGP_CompH compH, /* >> */ + A_long *num_layersPL); /* << */ + + SPAPI A_Err (*AEGP_GetCompLayerByIndex)( + AEGP_CompH compH, /* >> */ + A_long layer_indexL, /* >> */ + AEGP_LayerH *layerPH); /* << */ + + SPAPI A_Err (*AEGP_GetActiveLayer)( + AEGP_LayerH *layerPH); /* << returns non null only if one layer is selected */ + + SPAPI A_Err (*AEGP_GetLayerIndex)( + AEGP_LayerH layerH, /* >> */ + A_long *layer_indexPL); /* << */ + + SPAPI A_Err (*AEGP_GetLayerSourceItem)( + AEGP_LayerH layerH, /* >> */ + AEGP_ItemH *source_itemPH); /* << */ + + SPAPI A_Err (*AEGP_GetLayerSourceItemID)( + AEGP_LayerH layerH, /* >> */ + A_long *source_item_idPL); /* << */ + + SPAPI A_Err (*AEGP_GetLayerParentComp)( + AEGP_LayerH layerH, /* >> */ + AEGP_CompH *compPH); /* << */ + + SPAPI A_Err (*AEGP_GetLayerName)( + AEGP_PluginID pluginID, // in + AEGP_LayerH layerH, /* >> */ + AEGP_MemHandle *utf_layer_namePH0, // << handle of A_UTF16Char (contains null terminated UTF16 string); must be disposed with AEGP_FreeMemHandle + AEGP_MemHandle *utf_source_namePH0); // << handle of A_UTF16Char (contains null terminated UTF16 string); must be disposed with AEGP_FreeMemHandle + + SPAPI A_Err (*AEGP_GetLayerQuality)( + AEGP_LayerH layerH, /* >> */ + AEGP_LayerQuality *qualityP); /* << */ + + SPAPI A_Err (*AEGP_SetLayerQuality)( /* UNDOABLE */ + AEGP_LayerH layerH, /* >> */ + AEGP_LayerQuality quality); /* >> */ + + SPAPI A_Err (*AEGP_GetLayerFlags)( + AEGP_LayerH layerH, /* >> */ + AEGP_LayerFlags *layer_flagsP); /* << */ + + SPAPI A_Err (*AEGP_SetLayerFlag)( + AEGP_LayerH layerH, /* >> */ + AEGP_LayerFlags single_flag, /* >> */ + A_Boolean valueB); /* >> */ + + SPAPI A_Err (*AEGP_IsLayerVideoReallyOn)( // accounts for solo status of other layers in comp + AEGP_LayerH layerH, /* >> */ + A_Boolean *onPB); /* << */ + + SPAPI A_Err (*AEGP_IsLayerAudioReallyOn)( // accounts for solo status of other layers in comp + AEGP_LayerH layerH, /* >> */ + A_Boolean *onPB); /* << */ + + SPAPI A_Err (*AEGP_GetLayerCurrentTime)( // not updated while rendering + AEGP_LayerH layerH, /* >> */ + AEGP_LTimeMode time_mode, /* >> */ + A_Time *curr_timePT); /* << */ + + SPAPI A_Err (*AEGP_GetLayerInPoint)( + AEGP_LayerH layerH, /* >> */ + AEGP_LTimeMode time_mode, /* >> */ + A_Time *in_pointPT); /* << */ + + SPAPI A_Err (*AEGP_GetLayerDuration)( + AEGP_LayerH layerH, /* >> */ + AEGP_LTimeMode time_mode, /* >> */ + A_Time *durationPT); /* << */ + + SPAPI A_Err (*AEGP_SetLayerInPointAndDuration)( /* UNDOABLE */ + AEGP_LayerH layerH, /* >> */ + AEGP_LTimeMode time_mode, /* >> */ + const A_Time *in_pointPT, /* >> */ + const A_Time *durationPT); /* >> */ + + SPAPI A_Err (*AEGP_GetLayerOffset)( + AEGP_LayerH layerH, /* >> */ + A_Time *offsetPT); /* << always in comp time */ + + SPAPI A_Err (*AEGP_SetLayerOffset)( /* UNDOABLE */ + AEGP_LayerH layerH, /* >> */ + const A_Time *offsetPT); /* >> always in comp time */ + + SPAPI A_Err (*AEGP_GetLayerStretch)( + AEGP_LayerH layerH, /* >> */ + A_Ratio *stretchPRt); /* << */ + + SPAPI A_Err (*AEGP_SetLayerStretch)( /* UNDOABLE */ + AEGP_LayerH layerH, /* >> */ + const A_Ratio *stretchPRt); /* >> */ + + SPAPI A_Err (*AEGP_GetLayerTransferMode)( + AEGP_LayerH layerH, /* >> */ + AEGP_LayerTransferMode *transfer_modeP); /* << */ + + SPAPI A_Err (*AEGP_SetLayerTransferMode)( /* UNDOABLE */ + AEGP_LayerH layerH, /* >> */ + const AEGP_LayerTransferMode *transfer_modeP); /* >> */ + + SPAPI A_Err (*AEGP_IsAddLayerValid)( + AEGP_ItemH item_to_addH, /* >> */ + AEGP_CompH into_compH, /* >> */ + A_Boolean *validPB); /* << */ + + SPAPI A_Err (*AEGP_AddLayer)( /* UNDOABLE */ + AEGP_ItemH item_to_addH, /* >> check AEGP_IsAddLayerValid() before using */ + AEGP_CompH into_compH, /* >> */ + AEGP_LayerH *added_layerPH0); /* << */ + + SPAPI A_Err (*AEGP_ReorderLayer)( /* UNDOABLE */ + AEGP_LayerH layerH, /* >> */ + A_long layer_indexL); /* >> */ + + SPAPI A_Err (*AEGP_GetLayerMaskedBounds)( + AEGP_LayerH layerH, /* >> */ + AEGP_LTimeMode time_mode, /* >> */ + const A_Time *timePT, /* >> */ + A_FloatRect *boundsPR); /* << */ + + SPAPI A_Err (*AEGP_GetLayerObjectType)( + AEGP_LayerH layerH, /* >> */ + AEGP_ObjectType *object_type); /* << */ + + SPAPI A_Err (*AEGP_IsLayer3D)( + AEGP_LayerH layerH, /* >> */ + A_Boolean *is_3DPB); /* << */ + + SPAPI A_Err (*AEGP_IsLayer2D)( + AEGP_LayerH layerH, /* >> */ + A_Boolean *is_2DPB); /* << */ + + SPAPI A_Err (*AEGP_IsVideoActive)( + AEGP_LayerH layerH, /* >> */ + AEGP_LTimeMode time_mode, /* >> */ + const A_Time *timePT, /* >> */ + A_Boolean *is_activePB); /* << */ + + SPAPI A_Err (*AEGP_IsLayerUsedAsTrackMatte)( + AEGP_LayerH layerH, /* >> */ + A_Boolean fill_must_be_activeB, /* >> */ + A_Boolean *is_track_mattePB); /* << */ + + SPAPI A_Err (*AEGP_DoesLayerHaveTrackMatte)( + AEGP_LayerH layerH, /* >> */ + A_Boolean *has_track_mattePB); /* << */ + + SPAPI A_Err (*AEGP_ConvertCompToLayerTime)( + AEGP_LayerH layerH, /* >> */ + const A_Time *comp_timePT, /* >> */ + A_Time *layer_timePT); /* << */ + + SPAPI A_Err (*AEGP_ConvertLayerToCompTime)( + AEGP_LayerH layerH, /* >> */ + const A_Time *layer_timePT, /* >> */ + A_Time *comp_timePT) ; /* << */ + + SPAPI A_Err (*AEGP_GetLayerDancingRandValue)( + AEGP_LayerH layerH, /* >> */ + const A_Time *comp_timePT, /* >> */ + A_long *rand_valuePL); /* << */ + + SPAPI A_Err (*AEGP_GetLayerID)( + AEGP_LayerH layerH, /* >> */ + AEGP_LayerIDVal *id_valP); /* << */ + + SPAPI A_Err (*AEGP_GetLayerToWorldXform)( + AEGP_LayerH aegp_layerH, /* >> */ + const A_Time *comp_timeP, /* >> */ + A_Matrix4 *transform); /* << */ + + SPAPI A_Err (*AEGP_GetLayerToWorldXformFromView)( + AEGP_LayerH aegp_layerH, /* >> */ + const A_Time *view_timeP, /* >> */ + const A_Time *comp_timeP, /* >> */ + A_Matrix4 *transform); /* << */ + + SPAPI A_Err (*AEGP_SetLayerName)( + AEGP_LayerH aegp_layerH, /* >> */ + const A_UTF16Char *new_nameZ); /* >> null terminated UTF16 */ + + SPAPI A_Err (*AEGP_GetLayerParent)( + const AEGP_LayerH layerH, /* >> */ + AEGP_LayerH *parent_layerPH); /* << NULL if no parent */ + + SPAPI A_Err (*AEGP_SetLayerParent)( + AEGP_LayerH layerH, /* >> */ + const AEGP_LayerH parent_layerH0); /* >> */ + + SPAPI A_Err (*AEGP_DeleteLayer)( + AEGP_LayerH layerH); /* >> UNDOABLE */ + + SPAPI A_Err (*AEGP_DuplicateLayer)( + AEGP_LayerH orig_layerH, /* >> */ + AEGP_LayerH *duplicate_layerPH); /* << */ + + SPAPI A_Err (*AEGP_GetLayerFromLayerID)( + AEGP_CompH parent_compH, /* >> */ + AEGP_LayerIDVal id, /* >> */ + AEGP_LayerH *layerPH); /* << */ + + SPAPI A_Err (*AEGP_GetLayerLabel)( + AEGP_LayerH layerH, /* >> */ + AEGP_LabelID *labelP); /* << */ + + SPAPI A_Err (*AEGP_SetLayerLabel)( /* UNDOABLE */ + AEGP_LayerH layerH, /* >> */ + AEGP_LabelID label); /* >> */ + +} AEGP_LayerSuite7; + +#define kAEGPLayerSuiteVersion8 14 /* frozen AE 12.0 x300 */ + +typedef struct AEGP_LayerSuite8 { + + SPAPI A_Err (*AEGP_GetCompNumLayers)( + AEGP_CompH compH, /* >> */ + A_long *num_layersPL); /* << */ + + SPAPI A_Err (*AEGP_GetCompLayerByIndex)( + AEGP_CompH compH, /* >> */ + A_long layer_indexL, /* >> */ + AEGP_LayerH *layerPH); /* << */ + + SPAPI A_Err (*AEGP_GetActiveLayer)( + AEGP_LayerH *layerPH); /* << returns non null only if one layer is selected */ + + SPAPI A_Err (*AEGP_GetLayerIndex)( + AEGP_LayerH layerH, /* >> */ + A_long *layer_indexPL); /* << */ + + SPAPI A_Err (*AEGP_GetLayerSourceItem)( + AEGP_LayerH layerH, /* >> */ + AEGP_ItemH *source_itemPH); /* << */ + + SPAPI A_Err (*AEGP_GetLayerSourceItemID)( + AEGP_LayerH layerH, /* >> */ + A_long *source_item_idPL); /* << */ + + SPAPI A_Err (*AEGP_GetLayerParentComp)( + AEGP_LayerH layerH, /* >> */ + AEGP_CompH *compPH); /* << */ + + SPAPI A_Err (*AEGP_GetLayerName)( + AEGP_PluginID pluginID, // in + AEGP_LayerH layerH, /* >> */ + AEGP_MemHandle *utf_layer_namePH0, // << handle of A_UTF16Char (contains null terminated UTF16 string); must be disposed with AEGP_FreeMemHandle + AEGP_MemHandle *utf_source_namePH0); // << handle of A_UTF16Char (contains null terminated UTF16 string); must be disposed with AEGP_FreeMemHandle + + SPAPI A_Err (*AEGP_GetLayerQuality)( + AEGP_LayerH layerH, /* >> */ + AEGP_LayerQuality *qualityP); /* << */ + + SPAPI A_Err (*AEGP_SetLayerQuality)( /* UNDOABLE */ + AEGP_LayerH layerH, /* >> */ + AEGP_LayerQuality quality); /* >> */ + + SPAPI A_Err (*AEGP_GetLayerFlags)( + AEGP_LayerH layerH, /* >> */ + AEGP_LayerFlags *layer_flagsP); /* << */ + + SPAPI A_Err (*AEGP_SetLayerFlag)( + AEGP_LayerH layerH, /* >> */ + AEGP_LayerFlags single_flag, /* >> */ + A_Boolean valueB); /* >> */ + + SPAPI A_Err (*AEGP_IsLayerVideoReallyOn)( // accounts for solo status of other layers in comp + AEGP_LayerH layerH, /* >> */ + A_Boolean *onPB); /* << */ + + SPAPI A_Err (*AEGP_IsLayerAudioReallyOn)( // accounts for solo status of other layers in comp + AEGP_LayerH layerH, /* >> */ + A_Boolean *onPB); /* << */ + + SPAPI A_Err (*AEGP_GetLayerCurrentTime)( // not updated while rendering + AEGP_LayerH layerH, /* >> */ + AEGP_LTimeMode time_mode, /* >> */ + A_Time *curr_timePT); /* << */ + + SPAPI A_Err (*AEGP_GetLayerInPoint)( + AEGP_LayerH layerH, /* >> */ + AEGP_LTimeMode time_mode, /* >> */ + A_Time *in_pointPT); /* << */ + + SPAPI A_Err (*AEGP_GetLayerDuration)( + AEGP_LayerH layerH, /* >> */ + AEGP_LTimeMode time_mode, /* >> */ + A_Time *durationPT); /* << */ + + SPAPI A_Err (*AEGP_SetLayerInPointAndDuration)( /* UNDOABLE */ + AEGP_LayerH layerH, /* >> */ + AEGP_LTimeMode time_mode, /* >> */ + const A_Time *in_pointPT, /* >> */ + const A_Time *durationPT); /* >> */ + + SPAPI A_Err (*AEGP_GetLayerOffset)( + AEGP_LayerH layerH, /* >> */ + A_Time *offsetPT); /* << always in comp time */ + + SPAPI A_Err (*AEGP_SetLayerOffset)( /* UNDOABLE */ + AEGP_LayerH layerH, /* >> */ + const A_Time *offsetPT); /* >> always in comp time */ + + SPAPI A_Err (*AEGP_GetLayerStretch)( + AEGP_LayerH layerH, /* >> */ + A_Ratio *stretchPRt); /* << */ + + SPAPI A_Err (*AEGP_SetLayerStretch)( /* UNDOABLE */ + AEGP_LayerH layerH, /* >> */ + const A_Ratio *stretchPRt); /* >> */ + + SPAPI A_Err (*AEGP_GetLayerTransferMode)( + AEGP_LayerH layerH, /* >> */ + AEGP_LayerTransferMode *transfer_modeP); /* << */ + + SPAPI A_Err (*AEGP_SetLayerTransferMode)( /* UNDOABLE */ + AEGP_LayerH layerH, /* >> */ + const AEGP_LayerTransferMode *transfer_modeP); /* >> */ + + SPAPI A_Err (*AEGP_IsAddLayerValid)( + AEGP_ItemH item_to_addH, /* >> */ + AEGP_CompH into_compH, /* >> */ + A_Boolean *validPB); /* << */ + + SPAPI A_Err (*AEGP_AddLayer)( /* UNDOABLE */ + AEGP_ItemH item_to_addH, /* >> check AEGP_IsAddLayerValid() before using */ + AEGP_CompH into_compH, /* >> */ + AEGP_LayerH *added_layerPH0); /* << */ + + SPAPI A_Err (*AEGP_ReorderLayer)( /* UNDOABLE */ + AEGP_LayerH layerH, /* >> */ + A_long layer_indexL); /* >> */ + + SPAPI A_Err (*AEGP_GetLayerMaskedBounds)( + AEGP_LayerH layerH, /* >> */ + AEGP_LTimeMode time_mode, /* >> */ + const A_Time *timePT, /* >> */ + A_FloatRect *boundsPR); /* << */ + + SPAPI A_Err (*AEGP_GetLayerObjectType)( + AEGP_LayerH layerH, /* >> */ + AEGP_ObjectType *object_type); /* << */ + + SPAPI A_Err (*AEGP_IsLayer3D)( + AEGP_LayerH layerH, /* >> */ + A_Boolean *is_3DPB); /* << */ + + SPAPI A_Err (*AEGP_IsLayer2D)( + AEGP_LayerH layerH, /* >> */ + A_Boolean *is_2DPB); /* << */ + + SPAPI A_Err (*AEGP_IsVideoActive)( + AEGP_LayerH layerH, /* >> */ + AEGP_LTimeMode time_mode, /* >> */ + const A_Time *timePT, /* >> */ + A_Boolean *is_activePB); /* << */ + + SPAPI A_Err (*AEGP_IsLayerUsedAsTrackMatte)( + AEGP_LayerH layerH, /* >> */ + A_Boolean fill_must_be_activeB, /* >> */ + A_Boolean *is_track_mattePB); /* << */ + + SPAPI A_Err (*AEGP_DoesLayerHaveTrackMatte)( + AEGP_LayerH layerH, /* >> */ + A_Boolean *has_track_mattePB); /* << */ + + SPAPI A_Err (*AEGP_ConvertCompToLayerTime)( + AEGP_LayerH layerH, /* >> */ + const A_Time *comp_timePT, /* >> */ + A_Time *layer_timePT); /* << */ + + SPAPI A_Err (*AEGP_ConvertLayerToCompTime)( + AEGP_LayerH layerH, /* >> */ + const A_Time *layer_timePT, /* >> */ + A_Time *comp_timePT) ; /* << */ + + SPAPI A_Err (*AEGP_GetLayerDancingRandValue)( + AEGP_LayerH layerH, /* >> */ + const A_Time *comp_timePT, /* >> */ + A_long *rand_valuePL); /* << */ + + SPAPI A_Err (*AEGP_GetLayerID)( + AEGP_LayerH layerH, /* >> */ + AEGP_LayerIDVal *id_valP); /* << */ + + SPAPI A_Err (*AEGP_GetLayerToWorldXform)( + AEGP_LayerH aegp_layerH, /* >> */ + const A_Time *comp_timeP, /* >> */ + A_Matrix4 *transform); /* << */ + + SPAPI A_Err (*AEGP_GetLayerToWorldXformFromView)( + AEGP_LayerH aegp_layerH, /* >> */ + const A_Time *view_timeP, /* >> */ + const A_Time *comp_timeP, /* >> */ + A_Matrix4 *transform); /* << */ + + SPAPI A_Err (*AEGP_SetLayerName)( + AEGP_LayerH aegp_layerH, /* >> */ + const A_UTF16Char *new_nameZ); /* >> null terminated UTF16 */ + + SPAPI A_Err (*AEGP_GetLayerParent)( + const AEGP_LayerH layerH, /* >> */ + AEGP_LayerH *parent_layerPH); /* << NULL if no parent */ + + SPAPI A_Err (*AEGP_SetLayerParent)( + AEGP_LayerH layerH, /* >> */ + const AEGP_LayerH parent_layerH0); /* >> */ + + SPAPI A_Err (*AEGP_DeleteLayer)( + AEGP_LayerH layerH); /* >> UNDOABLE */ + + SPAPI A_Err (*AEGP_DuplicateLayer)( + AEGP_LayerH orig_layerH, /* >> */ + AEGP_LayerH *duplicate_layerPH); /* << */ + + SPAPI A_Err (*AEGP_GetLayerFromLayerID)( + AEGP_CompH parent_compH, /* >> */ + AEGP_LayerIDVal id, /* >> */ + AEGP_LayerH *layerPH); /* << */ + + SPAPI A_Err (*AEGP_GetLayerLabel)( + AEGP_LayerH layerH, /* >> */ + AEGP_LabelID *labelP); /* << */ + + SPAPI A_Err (*AEGP_SetLayerLabel)( /* UNDOABLE */ + AEGP_LayerH layerH, /* >> */ + AEGP_LabelID label); /* >> */ + + SPAPI A_Err (*AEGP_GetLayerSamplingQuality)( + AEGP_LayerH layerH, /* >> */ + AEGP_LayerSamplingQuality *qualityP); /* << */ + + /* Option is explicitly set on the layer independent of layer quality. + If you want to force it on you must also set the layer quality to + AEGP_LayerQual_BEST with AEGP_SetLayerQuality. Otherwise it will only be using + the specified layer sampling quality whenever the layer quality is set to AEGP_LayerQual_BEST*/ + SPAPI A_Err (*AEGP_SetLayerSamplingQuality)( /* UNDOABLE */ + AEGP_LayerH layerH, /* >> */ + AEGP_LayerSamplingQuality quality); /* >> */ + +} AEGP_LayerSuite8; + + + + + + +/* -------------------------------------------------------------------- */ + + +enum { + /* + WARNING!! + don't reorder these items, don't add in the middle + these IDs are saved to disk! + + only ever add to the end of the list, right before AEGP_LayerStream_NUMTYPES + */ + + AEGP_LayerStream_NONE = -1, + AEGP_LayerStream_ANCHORPOINT, + AEGP_LayerStream_POSITION, + AEGP_LayerStream_SCALE, + AEGP_LayerStream_ROTATION, + AEGP_LayerStream_ROTATE_Z = AEGP_LayerStream_ROTATION, /* for 3D streams */ + AEGP_LayerStream_OPACITY, + AEGP_LayerStream_AUDIO, + AEGP_LayerStream_MARKER, + AEGP_LayerStream_TIME_REMAP, + AEGP_LayerStream_ROTATE_X, + AEGP_LayerStream_ROTATE_Y, + AEGP_LayerStream_ORIENTATION, + + // only valid for AEGP_ObjectType == AEGP_ObjectType_CAMERA + AEGP_LayerStream_ZOOM, + AEGP_LayerStream_DEPTH_OF_FIELD, + AEGP_LayerStream_FOCUS_DISTANCE, + AEGP_LayerStream_APERTURE, + AEGP_LayerStream_BLUR_LEVEL, + + // only valid for AEGP_ObjectType == AEGP_ObjectType_LIGHT + AEGP_LayerStream_INTENSITY, + AEGP_LayerStream_COLOR, + AEGP_LayerStream_CONE_ANGLE, + AEGP_LayerStream_CONE_FEATHER, + AEGP_LayerStream_SHADOW_DARKNESS, + AEGP_LayerStream_SHADOW_DIFFUSION, + + // only valid for AEGP_ObjectType == AEGP_ObjectType_AV + AEGP_LayerStream_ACCEPTS_SHADOWS, + AEGP_LayerStream_ACCEPTS_LIGHTS, + AEGP_LayerStream_AMBIENT_COEFF, + AEGP_LayerStream_DIFFUSE_COEFF, + AEGP_LayerStream_SPECULAR_INTENSITY, + AEGP_LayerStream_SPECULAR_SHININESS, + + AEGP_LayerStream_CASTS_SHADOWS, // LIGHT, and AV only, no CAMERA + AEGP_LayerStream_LIGHT_TRANSMISSION, // AV Layer only + AEGP_LayerStream_METAL, // AV layer only + + AEGP_LayerStream_SOURCE_TEXT, + + // only valid for AEGP_ObjectType == AEGP_ObjectType_CAMERA + AEGP_LayerStream_IRIS_SHAPE, + AEGP_LayerStream_IRIS_ROTATION, + AEGP_LayerStream_IRIS_ROUNDNESS, + AEGP_LayerStream_IRIS_ASPECT_RATIO, + AEGP_LayerStream_IRIS_DIFFRACTION_FRINGE, + AEGP_LayerStream_IRIS_HIGHLIGHT_GAIN, + AEGP_LayerStream_IRIS_HIGHLIGHT_THRESHOLD, + AEGP_LayerStream_IRIS_HIGHLIGHT_SATURATION, + + // only valid for AEGP_ObjectType == AEGP_ObjectType_LIGHT + AEGP_LayerStream_LIGHT_FALLOFF_TYPE, + AEGP_LayerStream_LIGHT_FALLOFF_START, + AEGP_LayerStream_LIGHT_FALLOFF_DISTANCE, + + // only valid for AEGP_ObjectType == AEGP_ObjectType_AV + AEGP_LayerStream_REFLECTION_INTENSITY, + AEGP_LayerStream_REFLECTION_SHARPNESS, + AEGP_LayerStream_REFLECTION_ROLLOFF, + AEGP_LayerStream_TRANSPARENCY_COEFF, + AEGP_LayerStream_TRANSPARENCY_ROLLOFF, + AEGP_LayerStream_INDEX_OF_REFRACTION, + + AEGP_LayerStream_EXTRUSION_BEVEL_STYLE, + AEGP_LayerStream_EXTRUSION_BEVEL_DIRECTION, + AEGP_LayerStream_EXTRUSION_BEVEL_DEPTH, + AEGP_LayerStream_EXTRUSION_HOLE_BEVEL_DEPTH, + AEGP_LayerStream_EXTRUSION_DEPTH, + AEGP_LayerStream_PLANE_CURVATURE, + AEGP_LayerStream_PLANE_SUBDIVISION, + + /*********************************************************/ + AEGP_LayerStream_NUMTYPES, + AEGP_LayerStream_BEGIN = AEGP_LayerStream_NONE + 1, + AEGP_LayerStream_END = AEGP_LayerStream_NUMTYPES + +}; +typedef A_long AEGP_LayerStream; + +enum { + AEGP_MaskStream_OUTLINE = 400, + AEGP_MaskStream_OPACITY, + AEGP_MaskStream_FEATHER, + AEGP_MaskStream_EXPANSION, + + // useful for iteration + AEGP_MaskStream_BEGIN = AEGP_MaskStream_OUTLINE, + AEGP_MaskStream_END = AEGP_MaskStream_EXPANSION+1 +}; +typedef A_long AEGP_MaskStream; + + +enum { + AEGP_StreamFlag_NONE = 0, + AEGP_StreamFlag_HAS_MIN = 0x01, + AEGP_StreamFlag_HAS_MAX = 0x02, + AEGP_StreamFlag_IS_SPATIAL = 0x04 +}; +typedef A_long AEGP_StreamFlags; + + +typedef A_FpLong AEGP_OneDVal; + +typedef struct { + A_FpLong x,y; +} AEGP_TwoDVal; // if audio, rt is x, left is y + +typedef struct { + A_FpLong x,y,z; +} AEGP_ThreeDVal; + +typedef A_FpLong AEGP_FourDVal[4]; + +typedef A_Handle AEGP_ArbBlockVal; + +enum { + AEGP_KeyInterp_NONE = 0, + AEGP_KeyInterp_LINEAR, + AEGP_KeyInterp_BEZIER, + AEGP_KeyInterp_HOLD, + + AEGP_Interp_NUM_VALUES +}; +typedef A_long AEGP_KeyframeInterpolationType; + +/* AEGP_KeyInterpMask -- allowed interpolation mask constants and type + */ +enum { + AEGP_KeyInterpMask_NONE = 0, + AEGP_KeyInterpMask_LINEAR = 1 << 0, + AEGP_KeyInterpMask_BEZIER = 1 << 1, + AEGP_KeyInterpMask_HOLD = 1 << 2, + AEGP_KeyInterpMask_CUSTOM = 1 << 3, + + AEGP_KeyInterpMask_ANY = 0xFFFF +}; +typedef A_long AEGP_KeyInterpolationMask; + +typedef struct { + A_FpLong speedF; + A_FpLong influenceF; +} AEGP_KeyframeEase; + + +typedef union { + AEGP_FourDVal four_d; + AEGP_ThreeDVal three_d; + AEGP_TwoDVal two_d; + AEGP_OneDVal one_d; + AEGP_ColorVal color; + AEGP_ArbBlockVal arbH; + AEGP_MarkerValP markerP; + AEGP_LayerIDVal layer_id; + AEGP_MaskIDVal mask_id; + AEGP_MaskOutlineValH mask; + AEGP_TextDocumentH text_documentH; +} AEGP_StreamVal2; + +typedef struct { + AEGP_StreamRefH streamH; + AEGP_StreamVal2 val; +} AEGP_StreamValue2; + +enum { + AEGP_StreamType_NO_DATA, + AEGP_StreamType_ThreeD_SPATIAL, + AEGP_StreamType_ThreeD, + AEGP_StreamType_TwoD_SPATIAL, + AEGP_StreamType_TwoD, + AEGP_StreamType_OneD, + AEGP_StreamType_COLOR, + AEGP_StreamType_ARB, + AEGP_StreamType_MARKER, + AEGP_StreamType_LAYER_ID, + AEGP_StreamType_MASK_ID, + AEGP_StreamType_MASK, + AEGP_StreamType_TEXT_DOCUMENT +}; +typedef A_long AEGP_StreamType; + + +#define kAEGPStreamSuite "AEGP Stream Suite" +#define kAEGPStreamSuiteVersion5 10 /* frozen in AE 15 */ + +typedef struct AEGP_StreamSuite5 { + // the only diff from this vs. last rev is that routines that pass AEGP_StreamValue2, when referring to a marker, + // (comp or layer) the struct now contains the NEW markerP type, which is compatible with the new Marker Suite + + SPAPI A_Err (*AEGP_IsStreamLegal)( + AEGP_LayerH layerH, /* >> */ + AEGP_LayerStream which_stream, /* >> */ + A_Boolean* is_legalP); /* << */ + + + SPAPI A_Err (*AEGP_CanVaryOverTime)( + AEGP_StreamRefH streamH, /* >> */ + A_Boolean* can_varyPB); /* << */ + + SPAPI A_Err (*AEGP_GetValidInterpolations)( + AEGP_StreamRefH streamH, /* >> */ + AEGP_KeyInterpolationMask* valid_interpolationsP); /* << */ + + SPAPI A_Err (*AEGP_GetNewLayerStream)( + AEGP_PluginID aegp_plugin_id, /* >> */ + AEGP_LayerH layerH, /* >> */ + AEGP_LayerStream which_stream, /* >> */ + AEGP_StreamRefH *streamPH); /* << must be disposed by caller! */ + + SPAPI A_Err (*AEGP_GetEffectNumParamStreams)( + AEGP_EffectRefH effect_refH, /* >> */ + A_long *num_paramsPL); /* << */ + + SPAPI A_Err (*AEGP_GetNewEffectStreamByIndex)( + AEGP_PluginID aegp_plugin_id, /* >> */ + AEGP_EffectRefH effect_refH, /* >> */ + PF_ParamIndex param_index, /* >> valid in range [0 to AEGP_GetEffectNumParamStreams - 1], where 0 is the effect's input layer */ + AEGP_StreamRefH *streamPH); /* << must be disposed by caller! */ + + SPAPI A_Err (*AEGP_GetNewMaskStream)( + AEGP_PluginID aegp_plugin_id, /* >> */ + AEGP_MaskRefH mask_refH, /* >> */ + AEGP_MaskStream which_stream, /* >> */ + AEGP_StreamRefH *mask_streamPH); /* << must be disposed by caller! */ + + SPAPI A_Err (*AEGP_DisposeStream)( + AEGP_StreamRefH streamH); /* >> */ + + SPAPI A_Err (*AEGP_GetStreamName)( + AEGP_PluginID pluginID, // in + AEGP_StreamRefH streamH, /* >> */ + A_Boolean force_englishB, /* >> */ + AEGP_MemHandle *utf_stream_namePH); // << handle of A_UTF16Char (contains null terminated UTF16 string); must be disposed with AEGP_FreeMemHandle + + SPAPI A_Err (*AEGP_GetStreamUnitsText)( + AEGP_StreamRefH streamH, /* >> */ + A_Boolean force_englishB, /* >> */ + A_char *unitsZ); /* << space for A_char[AEGP_MAX_STREAM_UNITS_SIZE] */ + + SPAPI A_Err (*AEGP_GetStreamProperties)( + AEGP_StreamRefH streamH, /* >> */ + AEGP_StreamFlags *flagsP, /* << */ + A_FpLong *minP0, /* << */ + A_FpLong *maxP0); /* << */ + + SPAPI A_Err (*AEGP_IsStreamTimevarying)( /* takes expressions into account */ + AEGP_StreamRefH streamH, /* >> */ + A_Boolean *is_timevaryingPB); /* << */ + + SPAPI A_Err (*AEGP_GetStreamType)( + AEGP_StreamRefH streamH, /* >> */ + AEGP_StreamType *stream_typeP); /* << */ + + SPAPI A_Err (*AEGP_GetNewStreamValue)( + AEGP_PluginID aegp_plugin_id, /* >> */ + AEGP_StreamRefH streamH, /* >> */ + AEGP_LTimeMode time_mode, /* >> */ + const A_Time *timePT, /* >> */ + A_Boolean pre_expressionB, /* >> sample the stream before evaluating the expression */ + AEGP_StreamValue2 *valueP); /* << must be disposed */ + + SPAPI A_Err (*AEGP_DisposeStreamValue)( + AEGP_StreamValue2 *valueP); /* <> */ + + + SPAPI A_Err (*AEGP_SetStreamValue)( // only legal to call when AEGP_GetStreamNumKFs==0 or NO_DATA + AEGP_PluginID aegp_plugin_id, /* >> */ + AEGP_StreamRefH streamH, /* >> */ + AEGP_StreamValue2 *valueP); /* << */ + + // this is only valid on streams with primitive types. It is illegal on + // AEGP_ArbBlockVal || AEGP_MarkerValP || AEGP_MaskOutlineValH + + SPAPI A_Err (*AEGP_GetLayerStreamValue)( + AEGP_LayerH layerH, /* >> */ + AEGP_LayerStream which_stream, /* >> */ + AEGP_LTimeMode time_mode, /* >> */ + const A_Time *timePT, /* >> */ + A_Boolean pre_expressionB, /* >> sample the stream before evaluating the expression */ + AEGP_StreamVal2 *stream_valP, /* << */ + AEGP_StreamType *stream_typeP0); /* << */ + + SPAPI A_Err (*AEGP_GetExpressionState)( /* expressions can be disabled automatically by the parser on playback */ + AEGP_PluginID aegp_plugin_id, /* >> */ + AEGP_StreamRefH streamH, /* >> */ + A_Boolean *enabledPB); /* >> */ + + SPAPI A_Err (*AEGP_SetExpressionState)( /* expressions can be disabled automatically by the parser on playback */ + AEGP_PluginID aegp_plugin_id, /* >> */ + AEGP_StreamRefH streamH, /* >> */ + A_Boolean enabledB); /* >> */ + + SPAPI A_Err(*AEGP_GetExpression)( + AEGP_PluginID aegp_plugin_id, /* >> */ + AEGP_StreamRefH streamH, /* >> */ + AEGP_MemHandle *unicodeHZ); /* << must be disposed with AEGP_FreeMemHandle */ + + SPAPI A_Err(*AEGP_SetExpression)( + AEGP_PluginID aegp_plugin_id, /* >> */ + AEGP_StreamRefH streamH, /* >> */ + const A_UTF16Char* expressionP); /* >> not adopted */ + + SPAPI A_Err (*AEGP_DuplicateStreamRef)( // must dispose yourself + AEGP_PluginID aegp_plugin_id, // in + AEGP_StreamRefH streamH, // in + AEGP_StreamRefH *dup_streamPH); // out +} AEGP_StreamSuite5; + + +/* -------------------------------------------------------------------- */ +/* new Dynamic Streams API for AE6 + + Used to access new tracker, text, & paint streams. Eventually + will work for all streams & groups on a layer. + +*/ + +#define AEGP_MAX_STREAM_MATCH_NAME_SIZE 40 + + +enum { + AEGP_StreamGroupingType_NONE = -1, + AEGP_StreamGroupingType_LEAF, + AEGP_StreamGroupingType_NAMED_GROUP, + AEGP_StreamGroupingType_INDEXED_GROUP +}; +typedef A_long AEGP_StreamGroupingType; + +enum { + AEGP_DynStreamFlag_ACTIVE_EYEBALL = 1L << 0, // read/write + AEGP_DynStreamFlag_HIDDEN = 1L << 1, // read/write, shown in UI at the moment? + AEGP_DynStreamFlag_DISABLED = 1L << 4, // read-only, greyed out in UI? + AEGP_DynStreamFlag_ELIDED = 1L << 5, // read-only, user never sees, children still seen and not indented + AEGP_DynStreamFlag_SHOWN_WHEN_EMPTY = 1L << 10, // read-only, should this group be shown when empty? + AEGP_DynStreamFlag_SKIP_REVEAL_WHEN_UNHIDDEN = 1L << 16 // read-only, do not auto reveal this property when un-hidden +}; +typedef A_u_long AEGP_DynStreamFlags; + +// Here are some matchnames for use with +// AEGP_GetNewStreamRefByMatchname(). + +#define AEGP_StreamGroupName_MASK_PARADE "ADBE Mask Parade" +#define AEGP_StreamGroupName_MASK_ATOM "ADBE Mask Atom" +#define AEGP_StreamName_MASK_FEATHER "ADBE Mask Feather" +#define AEGP_StreamName_MASK_OPACITY "ADBE Mask Opacity" +#define AEGP_StreamName_MASK_OFFSET "ADBE Mask Offset" +#define AEGP_StreamGroupName_EFFECT_PARADE "ADBE Effect Parade" +#define AEGP_StreamGroupName_LAYER "ADBE Abstract Layer" +#define AEGP_StreamGroupName_AV_LAYER "ADBE AV Layer" +#define AEGP_StreamGroupName_TEXT_LAYER "ADBE Text Layer" +#define AEGP_StreamGroupName_CAMERA_LAYER "ADBE Camera Layer" +#define AEGP_StreamGroupName_LIGHT_LAYER "ADBE Light Layer" +#define AEGP_StreamGroupName_AUDIO "ADBE Audio Group" +#define AEGP_StreamGroupName_MATERIAL_OPTIONS "ADBE Material Options Group" +#define AEGP_StreamGroupName_TRANSFORM "ADBE Transform Group" +#define AEGP_StreamGroupName_LIGHT_OPTIONS "ADBE Light Options Group" +#define AEGP_StreamGroupName_CAMERA_OPTIONS "ADBE Camera Options Group" + +#define kAEGPDynamicStreamSuite "AEGP Dynamic Stream Suite" +#define kAEGPDynamicStreamSuiteVersion4 5 /* frozen in AE 9.0 */ + +typedef struct AEGP_DynamicStreamSuite4 { + + SPAPI A_Err (*AEGP_GetNewStreamRefForLayer)( // used to start recursive walk of layer, + AEGP_PluginID aegp_plugin_id, /* >> */ + AEGP_LayerH layerH, /* >> */ + AEGP_StreamRefH *streamPH); /* << must be disposed by caller! */ + + SPAPI A_Err (*AEGP_GetNewStreamRefForMask)( // used to start recursive walk of layer, + AEGP_PluginID aegp_plugin_id, /* >> */ + AEGP_MaskRefH maskH, /* >> */ + AEGP_StreamRefH *streamPH); /* << must be disposed by caller! */ + + + SPAPI A_Err (*AEGP_GetStreamDepth)( // layer is depth 0 + AEGP_StreamRefH streamH, /* >> */ + A_long *depthPL); /* << */ + + + SPAPI A_Err (*AEGP_GetStreamGroupingType)( + AEGP_StreamRefH streamH, /* >> */ + AEGP_StreamGroupingType *group_typeP); /* << */ + + SPAPI A_Err (*AEGP_GetNumStreamsInGroup)( // error on leaf + AEGP_StreamRefH streamH, /* >> */ + A_long *num_streamsPL); /* << */ + + + SPAPI A_Err (*AEGP_GetDynamicStreamFlags)( + AEGP_StreamRefH streamH, /* >> */ + AEGP_DynStreamFlags *stream_flagsP); /* << */ + + SPAPI A_Err (*AEGP_SetDynamicStreamFlag)( + AEGP_StreamRefH streamH, /* >> */ + AEGP_DynStreamFlags one_flag, /* >> */ + A_Boolean undoableB, /* true if you want this to be an undoable change */ + /* if false, the only legal flag is AEGP_DynStreamFlag_HIDDEN */ + A_Boolean setB); /* >> */ + + + SPAPI A_Err (*AEGP_GetNewStreamRefByIndex)( // legal for namedgroup, indexedgroup, not leaf + AEGP_PluginID aegp_plugin_id, /* >> */ + AEGP_StreamRefH parent_groupH, /* >> */ + A_long indexL, /* >> */ + AEGP_StreamRefH *streamPH); /* << must be disposed by caller! */ + + SPAPI A_Err (*AEGP_GetNewStreamRefByMatchname)( // legal for namedgroup + AEGP_PluginID aegp_plugin_id, /* >> */ + AEGP_StreamRefH parent_groupH, /* >> */ + const A_char *utf8_match_nameZ, /* >> */ + AEGP_StreamRefH *streamPH); /* << must be disposed by caller! */ + + SPAPI A_Err (*AEGP_DeleteStream)( /* UNDOABLE, only valid for children of AEGP_StreamGroupingType_INDEXED_GROUP */ + AEGP_StreamRefH streamH); /* >> */ // must still dispose the streamref later + + SPAPI A_Err (*AEGP_ReorderStream)( /* UNDOABLE, only valid for children of AEGP_StreamGroupingType_INDEXED_GROUP */ + AEGP_StreamRefH streamH, /* <> updated to refer to newly ordered stream */ + A_long new_indexL); /* >> */ + + SPAPI A_Err (*AEGP_DuplicateStream)( /* UNDOABLE, only valid for children of AEGP_StreamGroupingType_INDEXED_GROUP */ + AEGP_PluginID aegp_plugin_id, /* >> */ + AEGP_StreamRefH streamH, /* >> */ + A_long *new_indexPL0); /* << */ + + /* GetStreamName is in main kAEGPStreamSuite, and works on dynamic streams including groups */ + + SPAPI A_Err (*AEGP_SetStreamName)( /* UNDOABLE, only valid for children of AEGP_StreamGroupingType_INDEXED_GROUP */ + AEGP_StreamRefH streamH, /* >> */ + const A_UTF16Char *nameZ); /* >> null terminated UTF16 */ + + SPAPI A_Err (*AEGP_CanAddStream)( + AEGP_StreamRefH group_streamH, /* >> */ + const A_char *utf8_match_nameZ, /* >> make note: this is now defined as a UTF8 string! */ + A_Boolean *can_addPB); /* << */ + + SPAPI A_Err (*AEGP_AddStream)( /* UNDOABLE, only valid for AEGP_StreamGroupingType_INDEXED_GROUP */ + AEGP_PluginID aegp_plugin_id, /* >> */ + AEGP_StreamRefH indexed_group_streamH, /* >> */ + const A_char *utf8_match_nameZ, /* >> make note: this is now defined as a UTF8 string! */ + AEGP_StreamRefH *streamPH0); /* << must be disposed by caller! */ + + SPAPI A_Err (*AEGP_GetMatchName)( + AEGP_StreamRefH streamH, /* >> */ + A_char *utf8_match_nameZ); /* << UTF8!! use A_char[AEGP_MAX_STREAM_MATCH_NAME_SIZE] for buffer */ + + SPAPI A_Err (*AEGP_GetNewParentStreamRef)( + AEGP_PluginID aegp_plugin_id, /* >> */ + AEGP_StreamRefH streamH, /* >> */ + AEGP_StreamRefH *parent_streamPH); /* << must be disposed by caller! */ + + SPAPI A_Err (*AEGP_GetStreamIsModified)( // i.e. changed from defaults, like the UU key + AEGP_StreamRefH streamH, /* >> */ + A_Boolean *modifiedPB); /* << */ + + SPAPI A_Err (*AEGP_GetStreamIndexInParent)( // only valid for children of AEGP_StreamGroupingType_INDEXED_GROUP + AEGP_StreamRefH streamH, /* >> */ + A_long *indexPL); /* << */ + + // Valid on leaf streams only. Returns true if this stream is a multidimensional stream + // that can have its dimensions separated, though they may not be currently separated. + // Terminology: A Leader is the stream that can be separated, a Follower is one + // of N automatically streams that correspond to the N dimensions of the Leader. + // A Leader isn't always separated, call AEGP_AreDimensionsSeparated to find out if it is. + // As of 8/20/2007, the only stream that is ever separarated is the layer's Position property. + // Please *do not* write code assuming that, we anticipate allowing separation of more streams in the future. + SPAPI A_Err (*AEGP_IsSeparationLeader)( + AEGP_StreamRefH streamH, /* >> */ + A_Boolean *leaderPB); /* << */ + + // Valid on leaf streams only. Returns true if AEGP_IsSeparationLeader() is true and the + // dimensions are currently separated. If this is the case, this stream will have + // AEGP_DynStreamFlag_HIDDEN set, and AEGP_GetSeparationFollower() will help you find the individual + // dimension streams. However, some simple APIs can continue to be used on this leader, and + // they will simply automatically propagate to the follower, including: + // + // AEGP_GetNewStreamValue + // AEGP_SetStreamValue + // AEGP_GetLayerStreamValue + // + // Methods such as AEGP_GetNewKeyframeValue that work on keyframe indices will most definitely *not* work on the Leader property, + // you will need to retrieve and operate on the Followers explicitly. + SPAPI A_Err (*AEGP_AreDimensionsSeparated)( + AEGP_StreamRefH leader_streamH, /* >> */ + A_Boolean *separatedPB); /* << */ + + // Valid only if AEGP_IsSeparationLeader() is true. + SPAPI A_Err (*AEGP_SetDimensionsSeparated)( + AEGP_StreamRefH leader_streamH, /* >> */ + A_Boolean separatedB); /* << */ + + // Retrieve the Follower stream corresponding to a given dimension of the Leader stream. dimS + // can range from 0 to AEGP_GetStreamValueDimensionality(leader_streamH) - 1. + SPAPI A_Err (*AEGP_GetSeparationFollower)( + AEGP_StreamRefH leader_streamH, /* >> */ + A_short dimS, /* >> */ + AEGP_StreamRefH *follower_streamPH); /* << */ + + // Valid on leaf streams only. Returns true if this stream is a one dimensional property + // that represents one of the dimensions of a Leader. You can retrieve stream from the Leader + // using AEGP_GetSeparationFollower(). + SPAPI A_Err (*AEGP_IsSeparationFollower)( + AEGP_StreamRefH streamH, /* >> */ + A_Boolean *followerPB); /* << */ + + // Valid on separation Followers only, returns the Leader it is part of + SPAPI A_Err (*AEGP_GetSeparationLeader)( + AEGP_StreamRefH follower_streamH, /* >> */ + AEGP_StreamRefH *leader_streamPH); /* << */ + + // Valid on separation Followers only, returns which dimension of the Leader it corresponds to + SPAPI A_Err (*AEGP_GetSeparationDimension)( + AEGP_StreamRefH follower_streamH, /* >> */ + A_short *dimPS); /* << */ + +} AEGP_DynamicStreamSuite4; + + + +/* -------------------------------------------------------------------- */ + +typedef A_long AEGP_KeyframeIndex; + +enum { + AEGP_KeyframeFlag_NONE = 0x00, + AEGP_KeyframeFlag_TEMPORAL_CONTINUOUS = 0x01, + AEGP_KeyframeFlag_TEMPORAL_AUTOBEZIER = 0x02, + AEGP_KeyframeFlag_SPATIAL_CONTINUOUS = 0x04, + AEGP_KeyframeFlag_SPATIAL_AUTOBEZIER = 0x08, + AEGP_KeyframeFlag_ROVING = 0x10 +}; +typedef A_long AEGP_KeyframeFlags; + + +enum { + AEGP_NumKF_NO_DATA = -1 +}; + +#define kAEGPKeyframeSuite "AEGP Keyframe Suite" +#define kAEGPKeyframeSuiteVersion4 4 /* frozen in 8 */ + +typedef struct AEGP_KeyframeSuite4 { + // the only diff from this vs. last rev is that routines that pass AEGP_StreamValue2, when referring to a marker, + // (comp or layer) the struct now contains the NEW markerP type, which is compatible with the new Marker Suite + + // returns AEGP_NumKF_NO_DATA if it's a AEGP_StreamType_NO_DATA, and you can't retrieve any values + // returns zero if no keyframes (but might have an expression, so not necessarily constant) + SPAPI A_Err (*AEGP_GetStreamNumKFs)( + AEGP_StreamRefH streamH, /* >> */ + A_long *num_kfsPL); /* << */ + + + SPAPI A_Err (*AEGP_GetKeyframeTime)( + AEGP_StreamRefH streamH, /* >> */ + AEGP_KeyframeIndex key_index, /* >> */ + AEGP_LTimeMode time_mode, /* >> */ + A_Time *timePT); /* << */ + + // leaves stream unchanged if a keyframe already exists at specified time + SPAPI A_Err (*AEGP_InsertKeyframe)( /* UNDOABLE */ + AEGP_StreamRefH streamH, /* <> */ + AEGP_LTimeMode time_mode, /* >> */ + const A_Time *timePT, /* >> */ + AEGP_KeyframeIndex *key_indexP); /* << */ + + SPAPI A_Err (*AEGP_DeleteKeyframe)( /* UNDOABLE */ + AEGP_StreamRefH streamH, /* <> */ + AEGP_KeyframeIndex key_index); /* >> */ + + SPAPI A_Err (*AEGP_GetNewKeyframeValue)( // dispose using AEGP_DisposeStreamValue() + AEGP_PluginID aegp_plugin_id, /* >> */ + AEGP_StreamRefH streamH, /* >> */ + AEGP_KeyframeIndex key_index, /* >> */ + AEGP_StreamValue2 *valueP); /* << */ + + SPAPI A_Err (*AEGP_SetKeyframeValue)( /* UNDOABLE */ + AEGP_StreamRefH streamH, /* >> */ + AEGP_KeyframeIndex key_index, /* >> */ + const AEGP_StreamValue2 *valueP); /* >> not adopted */ + + SPAPI A_Err (*AEGP_GetStreamValueDimensionality)( + AEGP_StreamRefH streamH, /* >> */ + A_short *value_dimPS); /* << */ + + SPAPI A_Err (*AEGP_GetStreamTemporalDimensionality)( + AEGP_StreamRefH streamH, /* >> */ + A_short *temporal_dimPS); /* << */ + + SPAPI A_Err (*AEGP_GetNewKeyframeSpatialTangents)( // dispose using AEGP_DisposeStreamValue() + AEGP_PluginID aegp_plugin_id, /* >> */ + AEGP_StreamRefH streamH, /* >> */ + AEGP_KeyframeIndex key_index, /* >> */ + AEGP_StreamValue2 *in_tanP0, /* << */ + AEGP_StreamValue2 *out_tanP0); /* << */ + + SPAPI A_Err (*AEGP_SetKeyframeSpatialTangents)( /* UNDOABLE */ + AEGP_StreamRefH streamH, /* >> */ + AEGP_KeyframeIndex key_index, /* >> */ + const AEGP_StreamValue2 *in_tanP0, /* >> not adopted */ + const AEGP_StreamValue2 *out_tanP0); /* >> not adopted */ + + SPAPI A_Err (*AEGP_GetKeyframeTemporalEase)( + AEGP_StreamRefH streamH, /* >> */ + AEGP_KeyframeIndex key_index, /* >> */ + A_long dimensionL, /* >> ranges from 0..TemporalDimensionality-1 */ + AEGP_KeyframeEase *in_easeP0, /* << */ + AEGP_KeyframeEase *out_easeP0); /* << */ + + SPAPI A_Err (*AEGP_SetKeyframeTemporalEase)( /* UNDOABLE */ + AEGP_StreamRefH streamH, /* >> */ + AEGP_KeyframeIndex key_index, /* >> */ + A_long dimensionL, /* >> ranges from 0..TemporalDimensionality-1 */ + const AEGP_KeyframeEase *in_easeP0, /* >> not adopted */ + const AEGP_KeyframeEase *out_easeP0); /* >> not adopted */ + + SPAPI A_Err (*AEGP_GetKeyframeFlags)( + AEGP_StreamRefH streamH, /* >> */ + AEGP_KeyframeIndex key_index, /* >> */ + AEGP_KeyframeFlags *flagsP); /* << */ + + SPAPI A_Err (*AEGP_SetKeyframeFlag)( /* UNDOABLE */ + AEGP_StreamRefH streamH, /* >> */ + AEGP_KeyframeIndex key_index, /* >> */ + AEGP_KeyframeFlags flag, /* >> set one flag at a time */ + A_Boolean true_falseB); /* >> */ + + SPAPI A_Err (*AEGP_GetKeyframeInterpolation)( + AEGP_StreamRefH streamH, /* >> */ + AEGP_KeyframeIndex key_index, /* >> */ + AEGP_KeyframeInterpolationType *in_interpP0, /* << */ + AEGP_KeyframeInterpolationType *out_interpP0); /* << */ + + SPAPI A_Err (*AEGP_SetKeyframeInterpolation)( /* UNDOABLE */ + AEGP_StreamRefH streamH, /* >> */ + AEGP_KeyframeIndex key_index, /* >> */ + AEGP_KeyframeInterpolationType in_interp, /* >> */ + AEGP_KeyframeInterpolationType out_interp); /* >> */ + + SPAPI A_Err (*AEGP_StartAddKeyframes)( + AEGP_StreamRefH streamH, + AEGP_AddKeyframesInfoH *akPH); /* << */ + + + SPAPI A_Err (*AEGP_AddKeyframes)( + AEGP_AddKeyframesInfoH akH, /* <> */ + AEGP_LTimeMode time_mode, /* >> */ + const A_Time *timePT, /* >> */ + A_long *key_indexPL); /* >> */ + + SPAPI A_Err (*AEGP_SetAddKeyframe)( + AEGP_AddKeyframesInfoH akH, /* <> */ + A_long key_indexL, /* >> */ + const AEGP_StreamValue2 *valueP); /* >> */ + + SPAPI A_Err (*AEGP_EndAddKeyframes)( /* UNDOABLE */ + A_Boolean addB, + AEGP_AddKeyframesInfoH akH); /* >> */ + +} AEGP_KeyframeSuite4; + + +/* -------------------------------------------------------------------- */ + +#define kAEGPTextDocumentSuite "AEGP Text Document Suite" +#define kAEGPTextDocumentSuiteVersion1 1 /* frozen in AE 6.0 */ + +typedef struct AEGP_TextDocumentSuite1 { + + SPAPI A_Err (*AEGP_GetNewText)( + AEGP_PluginID aegp_plugin_id, /* >> */ + AEGP_TextDocumentH text_documentH, /* >> */ + AEGP_MemHandle *unicodePH); /* << handle of A_u_short, UTF16, NULL terminated. must be disposed with AEGP_FreeMemHandle */ + + SPAPI A_Err (*AEGP_SetText)( + AEGP_TextDocumentH text_documentH, /* >> */ + const A_u_short *unicodePS, /* >> */ + A_long lengthL); /* >> number of characters */ + +} AEGP_TextDocumentSuite1; + +/* -------------------------------------------------------------------- */ + +#define kAEGPMarkerSuite "AEGP Marker Suite" +#define kAEGPMarkerSuiteVersion3 3 /* frozen in AE 16.0 */ + +enum { + AEGP_MarkerString_NONE, + + AEGP_MarkerString_COMMENT, + AEGP_MarkerString_CHAPTER, + AEGP_MarkerString_URL, + AEGP_MarkerString_FRAME_TARGET, + AEGP_MarkerString_CUE_POINT_NAME, + + AEGP_MarkerString_NUMTYPES +}; +typedef A_long AEGP_MarkerStringType; + +enum { + AEGP_MarkerFlag_NONE = 0x00000000, + AEGP_MarkerFlag_NAVIGATION = 0x00000001, // if this bit is zero, then the marker is for "Event" rather than "Navigation" + AEGP_MarkerFlag_PROTECT_REGION = 0x00000002 // if this bit is 1, then the marker is for a protected region (protected against timestretching, when existing on a precomp layer) +}; +typedef A_long AEGP_MarkerFlagType; + +typedef struct AEGP_MarkerSuite3 { + + SPAPI A_Err (*AEGP_NewMarker)( + AEGP_MarkerValP *markerPP); + + SPAPI A_Err (*AEGP_DisposeMarker)( + AEGP_MarkerValP markerP); + + SPAPI A_Err (*AEGP_DuplicateMarker)( + AEGP_MarkerValP markerP, // >> + AEGP_MarkerValP *new_markerP); // << + + SPAPI A_Err (*AEGP_SetMarkerFlag)( + AEGP_MarkerValP markerP, // >> + AEGP_MarkerFlagType flagType, // >> + A_Boolean valueB); // >> + + SPAPI A_Err (*AEGP_GetMarkerFlag)( + AEGP_ConstMarkerValP markerP, // >> + AEGP_MarkerFlagType flagType, // >> + A_Boolean *valueBP); // << + + SPAPI A_Err (*AEGP_GetMarkerString)( + AEGP_PluginID aegp_plugin_id, /* >> */ + AEGP_ConstMarkerValP markerP, // >> + AEGP_MarkerStringType strType, // >> + AEGP_MemHandle *unicodePH); /* << handle of A_u_short, UTF16, NULL terminated, must be disposed with AEGP_FreeMemHandle */ + + SPAPI A_Err (*AEGP_SetMarkerString)( + AEGP_MarkerValP markerP, // <<>> + AEGP_MarkerStringType strType, // >> + const A_u_short *unicodeP, // >> + A_long lengthL); // >> number of characters + + SPAPI A_Err (*AEGP_CountCuePointParams)( + AEGP_ConstMarkerValP markerP, // >> + A_long *paramsLP); // << + + SPAPI A_Err (*AEGP_GetIndCuePointParam)( + AEGP_PluginID aegp_plugin_id, // >> + AEGP_ConstMarkerValP markerP, // >> + A_long param_indexL, // >> must be between 0 and count - 1. else error + AEGP_MemHandle *unicodeKeyPH, // << handle of A_u_short, UTF16, NULL terminated, must be disposed with AEGP_FreeMemHandle + AEGP_MemHandle *unicodeValuePH); // << handle of A_u_short, UTF16, NULL terminated, must be disposed with AEGP_FreeMemHandle + + SPAPI A_Err (*AEGP_SetIndCuePointParam)( + AEGP_MarkerValP markerP, // >> + A_long param_indexL, // must be between 0 and count - 1. else error + const A_u_short *unicodeKeyP, // >> UTF16 + A_long key_lengthL, // >> number of characters + const A_u_short *unicodeValueP, // >> UTF16 + A_long value_lengthL); // >> number of characters + + // this call is followed by AEGP_SetIndCuePointParam() to actually set the data + // the ONLY thing this function does is reserve the space for the param, at the provided index + SPAPI A_Err (*AEGP_InsertCuePointParam)( + AEGP_MarkerValP markerP, // >> + A_long param_indexL); // must be between 0 and count. else error + + SPAPI A_Err (*AEGP_DeleteIndCuePointParam)( + AEGP_MarkerValP markerP, // >> + A_long param_indexL); // must be between 0 and count - 1. else error + + SPAPI A_Err (*AEGP_SetMarkerDuration)( + AEGP_MarkerValP markerP, // >> + const A_Time *durationPT); // >> + + + SPAPI A_Err (*AEGP_GetMarkerDuration)( + AEGP_ConstMarkerValP markerP, // >> + A_Time *durationPT); // << + + SPAPI A_Err (*AEGP_SetMarkerLabel)( + AEGP_MarkerValP markerP, // >> + A_long value); // >> + + SPAPI A_Err (*AEGP_GetMarkerLabel)( + AEGP_ConstMarkerValP markerP, // >> + A_long *valueP); // << + +} AEGP_MarkerSuite3; + + +/* -------------------------------------------------------------------- */ + +#define kAEGPTextLayerSuite "AEGP Text Layer Suite" +#define kAEGPTextLayerSuiteVersion1 1 /* frozen in AE 6.0 */ + +typedef struct AEGP_TextLayerSuite1 { + + SPAPI A_Err (*AEGP_GetNewTextOutlines)( + AEGP_LayerH layerH, /* >> must be a text layer */ + const A_Time *layer_timePT, /* >> */ + AEGP_TextOutlinesH *outlinesPH); /* << must be disposed with AEGP_DisposeTextOutlines */ + + SPAPI A_Err (*AEGP_DisposeTextOutlines)( + AEGP_TextOutlinesH outlinesH); /* >> */ + + SPAPI A_Err (*AEGP_GetNumTextOutlines)( + AEGP_TextOutlinesH outlinesH, /* >> */ + A_long *num_outlinesPL); /* << */ + + SPAPI A_Err (*AEGP_GetIndexedTextOutline)( + AEGP_TextOutlinesH outlinesH, /* >> */ + A_long path_indexL, /* >> */ + PF_PathOutlinePtr *pathPP); /* << DO NOT DISPOSE */ + +} AEGP_TextLayerSuite1; + + +/* -------------------------------------------------------------------- */ + + +typedef A_long AEGP_InstalledEffectKey; +#define AEGP_InstalledEffectKey_NONE 0 + +#define RQ_ITEM_INDEX_NONE -1 + +enum { + AEGP_EffectFlags_NONE =0, + AEGP_EffectFlags_ACTIVE =0x01L << 0, + AEGP_EffectFlags_AUDIO_ONLY =0x01L << 1, + AEGP_EffectFlags_AUDIO_TOO =0x01L << 2, + AEGP_EffectFlags_MISSING =0x01L << 3 +}; +typedef A_long AEGP_EffectFlags; + +typedef A_long AEGP_EffectIndex; + + +#define kAEGPEffectSuite "AEGP Effect Suite" +#define kAEGPEffectSuiteVersion4 4 /* frozen in AE 13.0 */ + +typedef struct AEGP_EffectSuite4 { + + SPAPI A_Err (*AEGP_GetLayerNumEffects)( + AEGP_LayerH layerH, /* >> */ + A_long *num_effectsPL); /* << */ + + SPAPI A_Err (*AEGP_GetLayerEffectByIndex)( + AEGP_PluginID aegp_plugin_id, /* >> */ + AEGP_LayerH layerH, /* >> */ + AEGP_EffectIndex layer_effect_indexL, /* >> */ + AEGP_EffectRefH *effectPH); /* << MUST dispose with DisposeEffect*/ + + SPAPI A_Err (*AEGP_GetInstalledKeyFromLayerEffect)( + AEGP_EffectRefH effect_refH, /* >> */ + AEGP_InstalledEffectKey *installed_effect_keyP); /* << */ + + SPAPI A_Err (*AEGP_GetEffectParamUnionByIndex)( + AEGP_PluginID aegp_plugin_id, /* >> */ + AEGP_EffectRefH effect_refH, /* >> */ + PF_ParamIndex param_index, /* >> valid in range [0 to AEGP_GetEffectNumParamStreams - 1], where 0 is the effect's input layer */ + PF_ParamType *param_typeP, /* << */ + PF_ParamDefUnion *uP0); /* << DO NOT USE THE VALUE FROM THIS PARAMDEF! */ + + SPAPI A_Err (*AEGP_GetEffectFlags)( + AEGP_EffectRefH effect_refH, /* >> */ + AEGP_EffectFlags *effect_flagsP); /* << */ + + SPAPI A_Err (*AEGP_SetEffectFlags)( + AEGP_EffectRefH effect_refH, /* >> */ + AEGP_EffectFlags effect_flags_set_mask, /* >> */ + AEGP_EffectFlags effect_flags); /* >> */ + + SPAPI A_Err (*AEGP_ReorderEffect)( /* UNDOABLE */ + AEGP_EffectRefH effect_refH, /* >> */ + A_long effect_indexL); /* >> */ + + /** new command parameter addded. To get old behaviour pass in PF_Cmd_COMPLETELY_GENERAL for effect_command **/ + SPAPI A_Err (*AEGP_EffectCallGeneric)( + AEGP_PluginID aegp_plugin_id, /* >> */ + AEGP_EffectRefH effect_refH, /* >> */ + const A_Time *timePT, /* >> Use the timebase of the layer to which effect is applied. */ + PF_Cmd effect_cmd, /* >> new parameter from version 2 */ + void *effect_extraPV); /* <> */ + + SPAPI A_Err (*AEGP_DisposeEffect)( + AEGP_EffectRefH effect_refH ); /* >> */ + + SPAPI A_Err (*AEGP_ApplyEffect)( + AEGP_PluginID aegp_plugin_id, /* >> */ + AEGP_LayerH layerH, /* >> */ + AEGP_InstalledEffectKey installed_effect_key, /* >> */ + AEGP_EffectRefH *effect_refPH); /* << MUST BE DISPOSED with AEGP_DisposeEffect */ + + SPAPI A_Err (*AEGP_DeleteLayerEffect)( + AEGP_EffectRefH effect_refH); /* >> undoable */ + + SPAPI A_Err (*AEGP_GetNumInstalledEffects)( + A_long *num_installed_effectsPL); /* << */ + + // pass in AEGP_InstalledEffectKey_NONE for installed_effect_key to get first effect key + + SPAPI A_Err (*AEGP_GetNextInstalledEffect)( + AEGP_InstalledEffectKey installed_effect_key, /* >> */ + AEGP_InstalledEffectKey *next_effectPH); /* << */ + + SPAPI A_Err (*AEGP_GetEffectName)( + AEGP_InstalledEffectKey installed_effect_key, /* >> */ + A_char *nameZ); /* << space for A_char[AEGP_MAX_EFFECT_NAME_SIZE] */ + + SPAPI A_Err (*AEGP_GetEffectMatchName)( + AEGP_InstalledEffectKey installed_effect_key, /* >> */ + A_char *utf8_match_nameZ); /* << UTF8!! space for A_char[AEGP_MAX_EFFECT_MATCH_NAME_SIZE] */ + + SPAPI A_Err (*AEGP_GetEffectCategory)( + AEGP_InstalledEffectKey installed_effect_key, /* >> */ + A_char *categoryZ); /* << space for A_char[AEGP_MAX_EFFECT_CATEGORY_NAME_SIZE] */ + + SPAPI A_Err (*AEGP_DuplicateEffect)( + AEGP_EffectRefH original_effect_refH, /* >> */ + AEGP_EffectRefH *duplicate_effect_refPH); /* << */ + + /** new in AE 13.0: effect masks */ + SPAPI A_Err (*AEGP_NumEffectMask)( + AEGP_EffectRefH effect_refH, /* >> */ + A_u_long *num_masksPL); /* << */ + + SPAPI A_Err (*AEGP_GetEffectMaskID)( + AEGP_EffectRefH effect_refH, /* >> */ + A_u_long mask_indexL, /* >> */ + AEGP_MaskIDVal *id_valP); /* << */ + + SPAPI A_Err (*AEGP_AddEffectMask)( /* UNDOABLE */ + AEGP_EffectRefH effect_refH, /* >> */ + AEGP_MaskIDVal id_val, /* >> */ + AEGP_StreamRefH *streamPH0); /* << must be disposed by caller! */ + + SPAPI A_Err (*AEGP_RemoveEffectMask)( /* UNDOABLE */ + AEGP_EffectRefH effect_refH, /* >> */ + AEGP_MaskIDVal id_val); /* >> */ + + SPAPI A_Err (*AEGP_SetEffectMask)( /* UNDOABLE */ + AEGP_EffectRefH effect_refH, /* >> */ + A_u_long mask_indexL, /* >> */ + AEGP_MaskIDVal id_val, /* >> */ + AEGP_StreamRefH *streamPH0); /* << must be disposed by caller! */ +} AEGP_EffectSuite4; + + +/* -------------------------------------------------------------------- */ + +typedef A_long AEGP_MaskIndex; + +enum { + AEGP_MaskMBlur_SAME_AS_LAYER, + AEGP_MaskMBlur_OFF, + AEGP_MaskMBlur_ON +}; +typedef A_u_char AEGP_MaskMBlur; // This must be A_u_char, used in disk safe BEE_MaskInfo + +enum { + AEGP_MaskFeatherFalloff_SMOOTH, + AEGP_MaskFeatherFalloff_LINEAR +}; +typedef A_u_char AEGP_MaskFeatherFalloff; // This must be A_u_char, used in disk safe BEE_MaskInfo + +enum { + AEGP_MaskFeatherInterp_NORMAL, + AEGP_MaskFeatherInterp_HOLD_CW +}; +typedef A_u_char AEGP_MaskFeatherInterp; + +enum { + AEGP_MaskFeatherType_OUTER, + AEGP_MaskFeatherType_INNER +}; +typedef A_u_char AEGP_MaskFeatherType; + +#define kAEGPMaskSuite "AEGP Layer Mask Suite" +#define kAEGPMaskSuiteVersion6 7 /* frozen AE 11 */ + +typedef struct AEGP_MaskSuite6 { + + SPAPI A_Err (*AEGP_GetLayerNumMasks)( + AEGP_LayerH aegp_layerH, /* >> */ + A_long *num_masksPL); /* << */ + + SPAPI A_Err (*AEGP_GetLayerMaskByIndex)( + AEGP_LayerH aegp_layerH, /* >> */ + AEGP_MaskIndex mask_indexL, /* >> */ + AEGP_MaskRefH *maskPH); /* << must be disposed by calling AEGP_DisposeMask() */ + + SPAPI A_Err (*AEGP_DisposeMask)( + AEGP_MaskRefH mask_refH); /* >> */ + + SPAPI A_Err (*AEGP_GetMaskInvert)( + AEGP_MaskRefH mask_refH, /* >> */ + A_Boolean *invertPB); /* << */ + + SPAPI A_Err (*AEGP_SetMaskInvert)( + AEGP_MaskRefH mask_refH, /* >> */ + A_Boolean invertB); /* << */ + + SPAPI A_Err (*AEGP_GetMaskMode)( + AEGP_MaskRefH mask_refH, /* >> */ + PF_MaskMode *modeP); /* << */ + + SPAPI A_Err (*AEGP_SetMaskMode)( + AEGP_MaskRefH maskH, /* >> */ + PF_MaskMode mode); /* >> */ + + SPAPI A_Err (*AEGP_GetMaskMotionBlurState)( + AEGP_MaskRefH mask_refH, /* >> */ + AEGP_MaskMBlur *blur_stateP); /* << */ + + SPAPI A_Err (*AEGP_SetMaskMotionBlurState)( + AEGP_MaskRefH mask_refH, /* >> */ + AEGP_MaskMBlur blur_state); /* >> */ + + SPAPI A_Err (*AEGP_GetMaskFeatherFalloff)( + AEGP_MaskRefH mask_refH, /* >> */ + AEGP_MaskFeatherFalloff *feather_falloffP); /* << */ + + SPAPI A_Err (*AEGP_SetMaskFeatherFalloff)( + AEGP_MaskRefH mask_refH, /* >> */ + AEGP_MaskFeatherFalloff feather_falloffP); /* >> */ + + // AEGP_GetMaskName/SetMaskName are obsoleted. Use AEGP_GetNewDynamicStreamForMask + // and the name functions there + + SPAPI A_Err (*AEGP_GetMaskID)( + AEGP_MaskRefH mask_refH, /* >> */ + AEGP_MaskIDVal *id_valP); /* << */ + + SPAPI A_Err (*AEGP_CreateNewMask)( /* UNDOABLE */ + AEGP_LayerH layerH, /* >> */ + AEGP_MaskRefH *mask_refPH, /* << */ + A_long *mask_indexPL0); /* << */ + + SPAPI A_Err (*AEGP_DeleteMaskFromLayer)( /* UNDOABLE */ + AEGP_MaskRefH mask_refH); /* >> still need to Dispose MaskRefH */ + + SPAPI A_Err (*AEGP_GetMaskColor)( + AEGP_MaskRefH mask_refH, /* >> */ + AEGP_ColorVal *colorP); /* << */ + + SPAPI A_Err (*AEGP_SetMaskColor)( + AEGP_MaskRefH mask_refH, /* >> */ + const AEGP_ColorVal *colorP); /* >> */ + + SPAPI A_Err (*AEGP_GetMaskLockState)( + AEGP_MaskRefH mask_refH, /* <> */ + A_Boolean *is_lockedPB); /* >> */ + + SPAPI A_Err (*AEGP_SetMaskLockState)( + AEGP_MaskRefH mask_refH, /* <> */ + A_Boolean lockB); /* >> */ + + SPAPI A_Err (*AEGP_GetMaskIsRotoBezier)( + AEGP_MaskRefH mask_refH, /* <> */ + A_Boolean *is_roto_bezierPB); /* << */ + + SPAPI A_Err (*AEGP_SetMaskIsRotoBezier)( + AEGP_MaskRefH mask_refH, /* <> */ + A_Boolean is_roto_bezierB); /* >> */ + + SPAPI A_Err (*AEGP_DuplicateMask)( + AEGP_MaskRefH orig_mask_refH, /* >> */ + AEGP_MaskRefH *duplicate_mask_refPH); /* << */ + +} AEGP_MaskSuite6; + + +/* -------------------------------------------------------------------- */ + +typedef struct { + A_long segment; /* mask segment where feather is located */ + PF_FpLong segment_sF; /* 0-1: feather location on segment */ + PF_FpLong radiusF; /* negative value allowed if type == AEGP_MaskFeatherType_INNER */ + PF_FpShort ui_corner_angleF; /* 0-1: angle of UI handle on corners */ + PF_FpShort tensionF; /* 0-1: tension of boundary at feather pt */ + AEGP_MaskFeatherInterp interp; + AEGP_MaskFeatherType type; +} AEGP_MaskFeather; + +typedef A_long AEGP_FeatherIndex; + +typedef PF_PathVertex AEGP_MaskVertex; + +typedef A_long AEGP_VertexIndex; +#define AEGP_VertexIndex_END 10922 + +#define kAEGPMaskOutlineSuite "AEGP Mask Outline Suite" +#define kAEGPMaskOutlineSuiteVersion3 5 /* frozen in AE 11 */ + +typedef struct AEGP_MaskOutlineSuite3 { + + SPAPI A_Err (*AEGP_IsMaskOutlineOpen)( + AEGP_MaskOutlineValH mask_outlineH, /* >> */ + A_Boolean *openPB); /* << */ + + SPAPI A_Err (*AEGP_SetMaskOutlineOpen)( + AEGP_MaskOutlineValH mask_outlineH, /* >> */ + A_Boolean openB); /* >> */ + + // N segments means there are segments [0..N-1]; segment J is defined by vertex J & J+1 + SPAPI A_Err (*AEGP_GetMaskOutlineNumSegments)( + AEGP_MaskOutlineValH mask_outlineH, /* >> */ + A_long *num_segmentsPL); /* << */ + + // which_pointL range: [0..num_segments]; for closed masks vertex[0] == vertex[num_segments] + SPAPI A_Err (*AEGP_GetMaskOutlineVertexInfo)( + AEGP_MaskOutlineValH mask_outlineH, /* >> */ + AEGP_VertexIndex which_pointL, /* >> */ + AEGP_MaskVertex *vertexP); /* << tangents are relative to position */ + + // Setting vertex 0 is special. Its in tangent will actually set the out tangent + // of the last vertex in the outline. + SPAPI A_Err (*AEGP_SetMaskOutlineVertexInfo)( + AEGP_MaskOutlineValH mask_outlineH, /* >> */ + AEGP_VertexIndex which_pointL, /* >> must already exists (use Create) */ + const AEGP_MaskVertex *vertexP); /* >> tangents are relative to position */ + + SPAPI A_Err (*AEGP_CreateVertex)( + AEGP_MaskOutlineValH mask_outlineH, /* >> */ + AEGP_VertexIndex insert_position); /* >> will insert at this index. moving other verticies index++*/ + + SPAPI A_Err (*AEGP_DeleteVertex)( + AEGP_MaskOutlineValH mask_outlineH, /* >> */ + AEGP_VertexIndex index); /* >> */ + + + SPAPI A_Err (*AEGP_GetMaskOutlineNumFeathers)( + AEGP_MaskOutlineValH mask_outlineH, /* >> */ + A_long *num_feathersPL); /* << */ + + SPAPI A_Err (*AEGP_GetMaskOutlineFeatherInfo)( + AEGP_MaskOutlineValH mask_outlineH, /* >> */ + AEGP_FeatherIndex which_featherL, /* >> */ + AEGP_MaskFeather *featherP); /* << */ + + SPAPI A_Err (*AEGP_SetMaskOutlineFeatherInfo)( + AEGP_MaskOutlineValH mask_outlineH, /* >> */ + AEGP_VertexIndex which_featherL, /* >> must already exists (use Create) */ + const AEGP_MaskFeather *featherP); /* >> */ + + SPAPI A_Err (*AEGP_CreateMaskOutlineFeather)( + AEGP_MaskOutlineValH mask_outlineH, /* >> */ + const AEGP_MaskFeather *featherP0, /* >> */ + AEGP_FeatherIndex *insert_positionP); /* << index of new feather */ + + SPAPI A_Err (*AEGP_DeleteMaskOutlineFeather)( + AEGP_MaskOutlineValH mask_outlineH, /* >> */ + AEGP_FeatherIndex index); /* >> */ + +} AEGP_MaskOutlineSuite3; + + +/* -------------------------------------------------------------------- */ + + +typedef FIEL_Label AEGP_InterlaceLabel; + +enum { + AEGP_AlphaPremul = 0x1, /* otherwise straight */ + AEGP_AlphaInverted = 0x2, /* 255 = transparent */ + AEGP_AlphaIgnore = 0x4 +}; +typedef A_u_long AEGP_AlphaFlags; + +typedef struct { + AEGP_AlphaFlags flags; + A_u_char redCu; // color that was matted (if premul) + A_u_char greenCu; + A_u_char blueCu; +} AEGP_AlphaLabel; + +enum { + AEGP_PulldownPhase_NO_PULLDOWN = 0, + AEGP_PulldownPhase_WSSWW = 1, + AEGP_PulldownPhase_SSWWW, + AEGP_PulldownPhase_SWWWS, + AEGP_PulldownPhase_WWWSS, + AEGP_PulldownPhase_WWSSW, + AEGP_PulldownPhase_WWWSW, + AEGP_PulldownPhase_WWSWW, + AEGP_PulldownPhase_WSWWW, + AEGP_PulldownPhase_SWWWW, + AEGP_PulldownPhase_WWWWS +}; +typedef A_long AEGP_PulldownPhase; + +typedef struct { + A_long loops; + A_long reserved; /* set to 0; reserved for future use (palindrome, etc.) */ +} AEGP_LoopBehavior; + +typedef struct { + AEGP_InterlaceLabel il; + AEGP_AlphaLabel al; + AEGP_PulldownPhase pd; + AEGP_LoopBehavior loop; + A_Ratio pix_aspect_ratio; + A_FpLong native_fpsF; + A_FpLong conform_fpsF; + A_long depthL; + A_Boolean motion_dB; +} AEGP_FootageInterp; + +#define AEGP_FOOTAGE_LAYER_NAME_LEN (63) +#define AEGP_LayerIndex_UNKNOWN (-2) +#define AEGP_LayerIndex_MERGED (-1) +#define AEGP_LayerID_UNKNOWN (-1) + +enum { + AEGP_LayerDrawStyle_LAYER_BOUNDS = 0, + AEGP_LayerDrawStyle_DOCUMENT_BOUNDS +}; + +typedef A_long AEGP_LayerDrawStyle; + + +typedef struct { + A_long layer_idL; /* unique ID for layer, as contained in a Photoshop document's 'lyid' resource. */ + /* pass AEGP_LayerID_UNKNOWN if you don't know this */ + A_long layer_indexL; /* zero-based layer index. pass AEGP_LayerIndex_MERGED for merged layers */ + A_char nameAC[AEGP_FOOTAGE_LAYER_NAME_LEN + 1]; /* used for sequences and backup for linking */ + AEGP_LayerDrawStyle layer_draw_style; + +} AEGP_FootageLayerKey; + +#define AEGP_ANY_FRAME -1 + +typedef struct { + A_Boolean all_in_folderB; /* TRUE means intepret as a sequence, FALSE means still frame. + If FALSE, other parameters in this structure have no effect. */ + A_Boolean force_alphabeticalB; /* if TRUE, filenames of sequence will be forced to alphabetical order */ + A_long start_frameL; /* first frame of sequence, AEGP_ANY_FRAME means earliest frame found */ + A_long end_frameL; /* last frame of sequence, AEGP_ANY_FRAME means last frame found */ +} AEGP_FileSequenceImportOptions; + +enum { + AEGP_FootageSignature_NONE = -1, // invalid sig + AEGP_FootageSignature_MISSING = 0, // placeholder + AEGP_FootageSignature_SOLID = 'Soli' +}; +typedef A_long AEGP_FootageSignature; + + +#define AEGP_FOOTAGE_MAIN_FILE_INDEX 0 + +#define kAEGPFootageSuite "AEGP Footage Suite" + +#define kAEGPFootageSuiteVersion5 11 /* frozen in AE 10.0 */ + + +enum { + AEGP_InterpretationStyle_NO_DIALOG_GUESS = 0, // FALSE for backwards compatability: will guess alpha interpretation even if file contains unknown alpha interpretation and user pref says to ask user + AEGP_InterpretationStyle_DIALOG_OK = 1, // TRUE for backwards comptability. Optionally can show a dialog. + AEGP_InterpretationStyle_NO_DIALOG_NO_GUESS = 2 // used for replace footage implementation +}; +typedef A_u_char AEGP_InterpretationStyle; + +typedef struct AEGP_FootageSuite5 { + + SPAPI A_Err (*AEGP_GetMainFootageFromItem)( /* error if item isn't AEGP_ItemType_FOOTAGE! */ + AEGP_ItemH itemH, /* >> */ + AEGP_FootageH *footagePH); /* << */ + + SPAPI A_Err (*AEGP_GetProxyFootageFromItem)( /* error if has_proxy is false! (note, item could still be a comp) */ + AEGP_ItemH itemH, /* >> */ + AEGP_FootageH *proxy_footagePH); /* << */ + + SPAPI A_Err (*AEGP_GetFootageNumFiles)( + AEGP_FootageH footageH, /* >> */ + A_long *num_main_filesPL0, /* << */ + A_long *files_per_framePL0); /* << includes main file. e.g. 1 for no aux data */ + + SPAPI A_Err (*AEGP_GetFootagePath)( + AEGP_FootageH footageH, /* >> */ + A_long frame_numL, /* >> range is 0 to num_main_files */ + A_long file_indexL, /* >> AEGP_FOOTAGE_MAIN_FILE_INDEX is main file */ + AEGP_MemHandle *unicode_pathPH); // << empty string if no file. handle of A_UTF16Char (contains null terminated UTF16 string); must be disposed with AEGP_FreeMemHandle + + SPAPI A_Err (*AEGP_GetFootageSignature)( + AEGP_FootageH footageH, /* >> */ + AEGP_FootageSignature *sigP); /* << like filetype, but also for non-file types like solids, etc. */ + + SPAPI A_Err (*AEGP_NewFootage)( + AEGP_PluginID aegp_plugin_id, /* >> */ + const A_UTF16Char *pathZ, // >> null terminated unicode path with platform separators + const AEGP_FootageLayerKey *layer_infoP0, /* >> optional layer info; pass NULL for merged layers */ + const AEGP_FileSequenceImportOptions *sequence_optionsP0, /* >> optional sequence info; passing NULL means not a sequence */ + AEGP_InterpretationStyle interp_style, /* >> (in) */ + void *reserved, /* >> pass NULL */ + AEGP_FootageH *footagePH); /* << caller owns until disposed or added to project */ + + SPAPI A_Err (*AEGP_AddFootageToProject)( /* UNDOABLE */ + AEGP_FootageH footageH, /* >> will be adopted by project, may not be added more than once */ + AEGP_ItemH folderH, /* >> add to this folder */ + AEGP_ItemH *added_itemPH0); /* << */ + + SPAPI A_Err (*AEGP_SetItemProxyFootage)( /* UNDOABLE */ + AEGP_FootageH footageH, /* >> will be adopted by project, may not be set more than once */ + AEGP_ItemH itemH); /* >> set for this item */ + + SPAPI A_Err (*AEGP_ReplaceItemMainFootage)( /* UNDOABLE */ + AEGP_FootageH footageH, /* >> will be adopted by project, may not be set more than once */ + AEGP_ItemH itemH); /* >> replace main footage for this item */ + + SPAPI A_Err (*AEGP_DisposeFootage)( + AEGP_FootageH footageH); /* >> do not dipose footage that is owned or has been adopted by project */ + + SPAPI A_Err (*AEGP_GetFootageInterpretation)( + AEGP_ItemH itemH, /* >> note: item that contains footage */ + A_Boolean proxyB, /* >> TRUE = get proxy interp; FALSE = get main interp */ + AEGP_FootageInterp *interpP); /* << */ + + SPAPI A_Err (*AEGP_SetFootageInterpretation)( /* UNDOABLE */ + AEGP_ItemH itemH, /* >> note: item that contains footage */ + A_Boolean proxyB, /* >> TRUE = set proxy interp; FALSE = set main interp */ + const AEGP_FootageInterp *interpP); /* >> */ + + SPAPI A_Err (*AEGP_GetFootageLayerKey) ( + AEGP_FootageH footageH, /* >> */ + AEGP_FootageLayerKey *layerKeyP); /* << the footages layer info */ + + SPAPI A_Err (*AEGP_NewPlaceholderFootage)( /* doesn't modify project, creates footage with AEGP_FootageSignature_MISSING */ + AEGP_PluginID plugin_id, /* >> */ + const A_char *nameZ, /* >> file name, not the path! */ + A_long width, /* >> */ + A_long height, /* >> */ + const A_Time *durationPT, /* >> */ + AEGP_FootageH *footagePH); /* << caller owns until disposed or added to project */ + + SPAPI A_Err (*AEGP_NewPlaceholderFootageWithPath)( /* doesn't modify project, creates footage with AEGP_FootageSignature_MISSING */ + AEGP_PluginID plugin_id, /* >> */ + const A_UTF16Char *pathZ, // >> null terminated unicode path with platform separators + AEGP_Platform path_platform, /* >> Mac or Win */ + AEIO_FileType file_type, // >> AEIO_FileType_NONE is now a warning condition. If you pass AEIO_FileType_ANY, then path MUST exist. if path may not exist: pass AEIO_FileType_DIR for folder, or AEIO_FileType_GENERIC for a file + A_long widthL, /* >> */ + A_long heightL, /* >> */ + const A_Time *durationPT, /* >> */ + AEGP_FootageH *footagePH); /* << caller owns until disposed or added to project */ + + SPAPI A_Err (*AEGP_NewSolidFootage)( /* doesn't modify project, creates footage with AEGP_FootageSignature_SOLID */ + const A_char *nameZ, /* >> file name, not the path! */ + A_long width, /* >> */ + A_long height, /* >> */ + const AEGP_ColorVal *colorP, /* >> */ + AEGP_FootageH *footagePH); /* << caller owns until disposed or added to project */ + + SPAPI A_Err (*AEGP_GetSolidFootageColor)( /* error if footage isn't AEGP_FootageSignature_SOLID */ + AEGP_ItemH itemH, /* >> note: item that contains footage */ + A_Boolean proxyB, /* >> TRUE = get proxy solid color; FALSE = get main solid color */ + AEGP_ColorVal *colorP); /* << */ + + SPAPI A_Err (*AEGP_SetSolidFootageColor)( /* UNDOABLE, error if footage isn't AEGP_FootageSignature_SOLID */ + AEGP_ItemH itemH, /* >> note: item that contains footage */ + A_Boolean proxyB, /* >> TRUE = set proxy solid color; FALSE = set main solid color */ + const AEGP_ColorVal *colorP); /* >> */ + + SPAPI A_Err (*AEGP_SetSolidFootageDimensions)( /* UNDOABLE, error if footage isn't AEGP_FootageSignature_SOLID */ + AEGP_ItemH itemH, /* >> note: item that contains footage */ + A_Boolean proxyB, /* >> TRUE = set proxy solid size; FALSE = set main solid size */ + A_long widthL, /* >> min 1, max 30,000 */ + A_long heightL); /* >> min 1, max 30,000 */ + + SPAPI A_Err (*AEGP_GetFootageSoundDataFormat)( + AEGP_FootageH footageH, /* >> */ + AEGP_SoundDataFormat* sound_formatP); /* << */ + + SPAPI A_Err (*AEGP_GetFootageSequenceImportOptions)( + AEGP_FootageH footageH, /* >> */ + AEGP_FileSequenceImportOptions *optionsP); /* << */ + +} AEGP_FootageSuite5; + +/* -------------------------------------------------------------------- */ + + +typedef A_long AEGP_Command; + +#define AEGP_Command_ALL 0 + +enum { + AEGP_WindType_NONE, + AEGP_WindType_PROJECT, + AEGP_WindType_COMP, + AEGP_WindType_TIME_LAYOUT, + AEGP_WindType_LAYER, + AEGP_WindType_FOOTAGE, + AEGP_WindType_RENDER_QUEUE, + AEGP_WindType_QT, + AEGP_WindType_DIALOG, + AEGP_WindType_FLOWCHART, + AEGP_WindType_EFFECT, + AEGP_WindType_OTHER +}; +typedef A_LegacyEnumType AEGP_WindowType; + + +enum { + AEGP_HP_BeforeAE = 0x1, // call hook before AE handles event (if AE handles) + AEGP_HP_AfterAE = 0x2 // call hook after AE handles event (if AE handles) +}; +typedef A_u_long AEGP_HookPriority; + + +typedef A_Err (*AEGP_CommandHook)( + AEGP_GlobalRefcon plugin_refconP, /* >> */ + AEGP_CommandRefcon refconP, /* >> */ + AEGP_Command command, /* >> */ + AEGP_HookPriority hook_priority, /* >> currently always AEGP_HP_BeforeAE */ + A_Boolean already_handledB, /* >> */ + A_Boolean *handledPB); /* << whether you handled */ + +typedef A_Err (*AEGP_UpdateMenuHook)( + AEGP_GlobalRefcon plugin_refconP, /* >> */ + AEGP_UpdateMenuRefcon refconP, /* >> */ + AEGP_WindowType active_window); /* >> */ + +typedef A_Err (*AEGP_DeathHook)( + AEGP_GlobalRefcon plugin_refconP, /* >> */ + AEGP_DeathRefcon refconP); /* >> */ + +typedef A_Err (*AEGP_VersionHook)( /* As of 5.0, not called */ + AEGP_GlobalRefcon plugin_refconP, /* >> */ + AEGP_VersionRefcon refconP, /* >> */ + A_u_long *pf_versionPLu); /* << use PF_VERSION() macro to build and PF_Version_XXX() macros to access */ + + // one line description. when displaying, AE will prepend name and version information. + // this will be used to display a list of about info for all plugins + +typedef A_Err (*AEGP_AboutStringHook)( /* As of 5.0, not called */ + AEGP_GlobalRefcon plugin_refconP, /* >> */ + AEGP_AboutStringRefcon refconP, /* >> */ + A_char *aboutZ); /* << space for A_char[AEGP_MAX_ABOUT_STRING_SIZE] */ + + // bring up a dialog and tell us about yourself +typedef A_Err (*AEGP_AboutHook)( /* As of 5.0, not called */ + AEGP_GlobalRefcon plugin_refconP, /* >> */ + AEGP_AboutRefcon refconP); /* >> */ + +typedef A_Err (*AEGP_IdleHook)( + AEGP_GlobalRefcon plugin_refconP, /* >> */ + AEGP_IdleRefcon refconP, /* >> */ + A_long *max_sleepPL); /* <> in 1/60 of a second*/ + + + + +#define kAEGPRegisterSuite "AEGP Register Suite" +#define kAEGPRegisterSuiteVersion5 6 /* frozen AE 10.0 */ + +typedef struct AEGP_RegisterSuite5 { + + SPAPI A_Err (*AEGP_RegisterCommandHook)( + AEGP_PluginID aegp_plugin_id, /* >> */ + AEGP_HookPriority hook_priority, /* >> */ + AEGP_Command command, /* >> use AEGP_Command_ALL to get all commands */ + AEGP_CommandHook command_hook_func, /* >> */ + AEGP_CommandRefcon refconP); /* >> */ + + // this will be called anytime any menu is about to be drawn. it isn't specific to a menu so you + // must enable all appropriate menu items when this hook is called. + + SPAPI A_Err (*AEGP_RegisterUpdateMenuHook)( + AEGP_PluginID plugin_id, /* >> */ + AEGP_UpdateMenuHook update_menu_hook_func, /* >> */ + AEGP_UpdateMenuRefcon refconP); /* >> */ + + SPAPI A_Err (*AEGP_RegisterDeathHook)( + AEGP_PluginID aegp_plugin_id, /* >> */ + AEGP_DeathHook death_hook_func, /* >> */ + AEGP_DeathRefcon refconP); /* >> */ + + SPAPI A_Err (*AEGP_RegisterVersionHook)( + AEGP_PluginID aegp_plugin_id, /* >> */ + AEGP_VersionHook version_hook_func, /* >> */ + AEGP_VersionRefcon refconP); /* >> */ + + SPAPI A_Err (*AEGP_RegisterAboutStringHook)( + AEGP_PluginID aegp_plugin_id, /* >> */ + AEGP_AboutStringHook about_string_hook_func, /* >> */ + AEGP_AboutStringRefcon refconP); /* >> */ + + SPAPI A_Err (*AEGP_RegisterAboutHook)( + AEGP_PluginID aegp_plugin_id, /* >> */ + AEGP_AboutHook about_hook_func, /* >> */ + AEGP_AboutRefcon refconP); /* >> */ + + SPAPI A_Err (*AEGP_RegisterArtisan) ( + A_Version api_version, /* >> */ + A_Version artisan_version, /* >> */ + AEGP_PluginID aegp_plugin_id, /* >> */ + void *aegp_refconPV, /* <> */ + const A_char *utf8_match_nameZ, /* >> */ + const A_char *artisan_nameZ, /* >> */ + PR_ArtisanEntryPoints *entry_funcs); /* >> */ + + SPAPI A_Err (*AEGP_RegisterIO) ( + AEGP_PluginID aegp_plugin_id, /* >> */ + AEGP_IORefcon aegp_refconP, /* >> */ + const AEIO_ModuleInfo *io_infoP, /* >> */ + const AEIO_FunctionBlock4 *aeio_fcn_blockP); /* >> */ + + SPAPI A_Err (*AEGP_RegisterIdleHook)( + AEGP_PluginID aegp_plugin_id, /* >> */ + AEGP_IdleHook idle_hook_func, /* >> */ + AEGP_IdleRefcon refconP); /* >> */ + + + SPAPI A_Err (*AEGP_RegisterTracker)( + A_Version api_version, /* >> */ + A_Version tracker_version, /* >> */ + AEGP_PluginID aegp_plugin_id, /* >> */ + const AEGP_GlobalRefcon refconP, /* >> */ + const A_char *utf8_match_nameZ, /* >> */ + const A_char *tracker_nameZ, /* >> */ + const PT_TrackerEntryPoints *entry_pointsP); /* >> */ + + SPAPI A_Err (*AEGP_RegisterInteractiveArtisan) ( + A_Version api_version, /* >> */ + A_Version artisan_version, /* >> */ + AEGP_PluginID aegp_plugin_id, /* >> */ + void *aegp_refconPV, /* <> */ + const A_char *utf8_match_nameZ, /* >> */ + const A_char *artisan_nameZ, /* >> */ + PR_ArtisanEntryPoints *entry_funcs); /* >> */ + + // Call this to register as many strings as you like for name-replacement + // when presets are loaded. Any time a Property name is found, or referred + // to in an expression, and it starts with an ASCII tab character ('\t'), followed + // by one of the english names, it will be replaced with the localized name. (In + // English the tab character will simply be removed). + SPAPI A_Err (*AEGP_RegisterPresetLocalizationString) ( + const A_char *english_nameZ, /* >> */ + const A_char *localized_nameZ); /* >> */ + + + +} AEGP_RegisterSuite5; + + +/* -------------------------------------------------------------------- */ + + +enum { + AEGP_Menu_NONE, + AEGP_Menu_APPLE, + AEGP_Menu_FILE, + AEGP_Menu_EDIT, + AEGP_Menu_COMPOSITION, + AEGP_Menu_LAYER, + AEGP_Menu_EFFECT, + AEGP_Menu_WINDOW, + AEGP_Menu_FLOATERS, + AEGP_Menu_KF_ASSIST, + AEGP_Menu_IMPORT, + AEGP_Menu_SAVE_FRAME_AS, + AEGP_Menu_PREFS, + AEGP_Menu_EXPORT, + AEGP_Menu_ANIMATION, + AEGP_Menu_PURGE, + //the following menu options only valid for AE 12.0 and up + AEGP_Menu_NEW +}; +typedef A_LegacyEnumType AEGP_MenuID; + + +#define AEGP_MENU_INSERT_SORTED (-2) +#define AEGP_MENU_INSERT_AT_BOTTOM (-1) +#define AEGP_MENU_INSERT_AT_TOP 0 + + +#define kAEGPCommandSuite "AEGP Command Suite" +#define kAEGPCommandSuiteVersion1 1 /* frozen in AE 5.0 */ + +typedef struct AEGP_CommandSuite1 { + + SPAPI A_Err (*AEGP_GetUniqueCommand)( + AEGP_Command *unique_commandP); /* << */ + + SPAPI A_Err (*AEGP_InsertMenuCommand)( + AEGP_Command command, /* >> */ + const A_char *nameZ, /* >> */ + AEGP_MenuID menu_id, /* >> */ + A_long after_itemL); /* >> */ + + SPAPI A_Err (*AEGP_RemoveMenuCommand)( + AEGP_Command command); /* >> */ + + SPAPI A_Err (*AEGP_SetMenuCommandName)( + AEGP_Command command, /* >> */ + const A_char *nameZ); /* >> */ + + SPAPI A_Err (*AEGP_EnableCommand)( + AEGP_Command command); /* >> */ + + SPAPI A_Err (*AEGP_DisableCommand)( + AEGP_Command command); /* >> */ + + SPAPI A_Err (*AEGP_CheckMarkMenuCommand)( + AEGP_Command command, /* >> */ + A_Boolean checkB); /* >> */ + + SPAPI A_Err (*AEGP_DoCommand)( + AEGP_Command command); /* >> */ + +} AEGP_CommandSuite1; + + + + +/* -------------------------------------------------------------------- */ + + +typedef struct { + A_long reservedAL[12]; +} AEGP_ErrReportState; + + +enum { + AEGP_GetPathTypes_PLUGIN = 0, // (Not Implemented) The path to the executable of the plugin itself. + AEGP_GetPathTypes_USER_PLUGIN, // The suite specific location of user specific plugins. + AEGP_GetPathTypes_ALLUSER_PLUGIN, // The suite specific location of plugins shared by all users. + AEGP_GetPathTypes_APP // The After Effects exe or .app location. Not plugin specific. + }; +typedef A_u_long AEGP_GetPathTypes; + + +#define kAEGPUtilitySuite "AEGP Utility Suite" +#define kAEGPUtilitySuiteVersion6 13 /* frozen in AE 12.0 */ + +typedef struct AEGP_UtilitySuite6 { + + SPAPI A_Err (*AEGP_ReportInfo)( /* displays dialog with name of plugin followed by info string. See also: ReportInfoUnicode */ + AEGP_PluginID aegp_plugin_id, /* >> */ + const A_char *info_stringZ); /* >> */ + + SPAPI A_Err (*AEGP_ReportInfoUnicode)( /* displays dialog with name of plugin followed by info string */ + AEGP_PluginID aegp_plugin_id, /* >> */ + const A_UTF16Char *info_stringP); /* >> */ + + SPAPI A_Err (*AEGP_GetDriverPluginInitFuncVersion)( + A_short *major_versionPS, /* << */ + A_short *minor_versionPS); /* << */ + + SPAPI A_Err (*AEGP_GetDriverImplementationVersion)( + A_short *major_versionPS, /* << */ + A_short *minor_versionPS); /* << */ + + SPAPI A_Err (*AEGP_StartQuietErrors)( + AEGP_ErrReportState *err_stateP); /* << */ + + SPAPI A_Err (*AEGP_EndQuietErrors)( + A_Boolean report_quieted_errorsB, /* >> currently reports last quieted error */ + AEGP_ErrReportState *err_stateP); /* >> */ + + SPAPI A_Err (*AEGP_GetLastErrorMessage)( + A_long buffer_size, /* >> size of character buffer */ + A_char *error_string, /* << */ + A_Err *error_num); /* << */ + + SPAPI A_Err (*AEGP_StartUndoGroup)( /* MUST be balanced with call to AEGP_EndUndoGroup() */ + const A_char *undo_nameZ); /* >> */ + + SPAPI A_Err (*AEGP_EndUndoGroup)(void); + + SPAPI A_Err (*AEGP_RegisterWithAEGP)( + AEGP_GlobalRefcon global_refcon, /* >> global refcon passed in command handlers */ + const A_char *plugin_nameZ, /* >> name of this plugin. AEGP_MAX_PLUGIN_NAME_SIZE */ + AEGP_PluginID *plugin_id); /* << id for plugin to use in other AEGP calls */ + + SPAPI A_Err (*AEGP_GetMainHWND)( + void *main_hwnd); /* << */ + + SPAPI A_Err (*AEGP_ShowHideAllFloaters)( + A_Boolean include_tool_palB); /* >> */ + + SPAPI A_Err (*AEGP_PaintPalGetForeColor)( + AEGP_ColorVal *fore_colorP); /* << */ + + SPAPI A_Err (*AEGP_PaintPalGetBackColor)( + AEGP_ColorVal *back_colorP); /* << */ + + SPAPI A_Err (*AEGP_PaintPalSetForeColor)( + const AEGP_ColorVal *fore_colorP); /* >> */ + + SPAPI A_Err (*AEGP_PaintPalSetBackColor)( + const AEGP_ColorVal *back_colorP); /* >> */ + + SPAPI A_Err (*AEGP_CharPalGetFillColor)( + A_Boolean *is_fill_color_definedPB, /* << */ + AEGP_ColorVal *fill_colorP); /* << only valid if is_fill_color_definedPB == TRUE */ + + SPAPI A_Err (*AEGP_CharPalGetStrokeColor)( + A_Boolean *is_stroke_color_definedPB, /* << */ + AEGP_ColorVal *stroke_colorP); /* << only valid if is_stroke_color_definedPB == TRUE */ + + SPAPI A_Err (*AEGP_CharPalSetFillColor)( + const AEGP_ColorVal *fill_colorP); /* >> */ + + SPAPI A_Err (*AEGP_CharPalSetStrokeColor)( + const AEGP_ColorVal *stroke_colorP); /* >> */ + + SPAPI A_Err (*AEGP_CharPalIsFillColorUIFrontmost)( /* Otherwise, StrokeColor is frontmost */ + A_Boolean *is_fill_color_selectedPB); /* << */ + + SPAPI A_Err (*AEGP_ConvertFpLongToHSFRatio)( + A_FpLong numberF, /* >> */ + A_Ratio *ratioPR); /* << */ + + SPAPI A_Err (*AEGP_ConvertHSFRatioToFpLong)( + A_Ratio ratioR, /* << */ + A_FpLong *numberPF); /* >> */ + + // this routine is safe to call from the non-main + // thread. It is asynchronous and will return before the idle handler is called. + // The Suite routines to get this pointer are not + // thread safe, therefore you need to save it off + // in the main thread for use by the child thread. + SPAPI A_Err (*AEGP_CauseIdleRoutinesToBeCalled)(void); + + + // Determine if after effects is running in a mode where there is no + // user interface, and attempting to interact with the user (via a modal dialog) + // will hang the application. + // This will not change during a run. Use it to optimize your plugin at startup + // to not create a user interface and make AE launch faster, and not break + // when running multiple instances of a service. + SPAPI A_Err (*AEGP_GetSuppressInteractiveUI)(A_Boolean* ui_is_suppressedPB); // out + + // this call writes text to the console if one is available. One is guaranteed to be available + // if ui_is_suppressedB == true. + // In general use the call AEGP_ReportInfo() as it will write to the console in + // non-interactive modes, and use a dialog in interactive modes. + SPAPI A_Err (*AEGP_WriteToOSConsole)(const A_char* textZ); // in + + // this writes an entry into the debug log, or to the command line if launched + // with the -debug flag. + SPAPI A_Err (*AEGP_WriteToDebugLog)(const A_char* subsystemZ, // in + const A_char* event_typeZ, // in + const A_char * infoZ); // in + + + SPAPI A_Err (*AEGP_IsScriptingAvailable)(A_Boolean* outAvailablePB); + + // Execute a script. + // The script text can either be in UTF-8, or the current + // application encoding. + // The result is the result string if OK. It is optional. + // The error is the error string if an error occurred. It is optional. + // the result and error are in the encoding specified by platform_encodingB + SPAPI A_Err (*AEGP_ExecuteScript)(AEGP_PluginID inPlugin_id, + const A_char* inScriptZ, // in + const A_Boolean platform_encodingB, // in + AEGP_MemHandle* outResultPH0, + AEGP_MemHandle* outErrorStringPH0); + + SPAPI A_Err (*AEGP_HostIsActivated)(A_Boolean *is_activatedPB); + + SPAPI A_Err (*AEGP_GetPluginPlatformRef)(AEGP_PluginID plug_id, void** plat_refPPV); // on the Mac, it is a CFBundleRef to your mach-o plugin or NULL for a CFM plug-in; on Windows it is set to NULL for now + + SPAPI A_Err (*AEGP_UpdateFontList)(void); // Rescan the system font list. This will return quickly if the font list hasn't changed. + + // return a particular path associated with the plugin + SPAPI A_Err (*AEGP_GetPluginPaths)( + AEGP_PluginID aegp_plugin_id, // >> which plugin we are talking about + AEGP_GetPathTypes path_type, // >> which path type to retrieve + AEGP_MemHandle *unicode_pathPH); // << UTF16 mem handle must be disposed with AEGP_FreeMemHandle + +} AEGP_UtilitySuite6; + + + +/* -------------------------------------------------------------------- */ + + +#define kAEGPMathSuite "AEGP Math Suite" +#define kAEGPMathSuiteVersion1 1 /* frozen AE 15.0 */ + +typedef struct AEGP_MathSuite1 { + + // Matrices + // right-hand rule, Y down, origin in upper left corner of comp. + + SPAPI A_Err(*AEGP_IdentityMatrix4)(A_Matrix4 *matrixP); + + SPAPI A_Err(*AEGP_MultiplyMatrix4)(const A_Matrix4 *A, const A_Matrix4 *B, A_Matrix4 *resultP); + + SPAPI A_Err(*AEGP_Matrix3ToMatrix4)(const A_Matrix3 *A, A_Matrix4 *B); + + SPAPI A_Err(*AEGP_MultiplyMatrix4by3)(const A_Matrix4 *A, const A_Matrix3 *B, A_Matrix4 *resultP); + + SPAPI A_Err(*AEGP_MatrixDecompose4)(const A_Matrix4 *A, A_FloatPoint3* posVP, A_FloatPoint3* scaleVP, A_FloatPoint3* shearVP, A_FloatPoint3* rotVP); + +} AEGP_MathSuite1; + + +/* -------------------------------------------------------------------- */ + + + +typedef struct _PF_OpaqueBlendingTables *PF_EffectBlendingTables; + +#define kAEGPColorSettingsSuite "PF Color Settings Suite" +#define kAEGPColorSettingsSuiteVersion3 4 // frozen in AE 16.1; adding an API to set working color space + +typedef struct AEGP_ColorSettingsSuite3 { + + SPAPI A_Err (*AEGP_GetBlendingTables)( + PR_RenderContextH render_contextH, + PF_EffectBlendingTables *blending_tables); + + SPAPI A_Err (*AEGP_DoesViewHaveColorSpaceXform)( + AEGP_ItemViewP viewP, // >> + A_Boolean *has_xformPB); // << + + SPAPI A_Err (*AEGP_XformWorkingToViewColorSpace)( + AEGP_ItemViewP viewP, // >> + AEGP_WorldH srcH, // in + AEGP_WorldH dstH); // out; must be the same size (can be the same as source) + + SPAPI A_Err (*AEGP_GetNewWorkingSpaceColorProfile)( + AEGP_PluginID aegp_plugin_id, // >> + AEGP_CompH compH, // >> + AEGP_ColorProfileP *color_profilePP); // << caller must dispose with AEGP_DisposeColorProfile + + SPAPI A_Err (*AEGP_GetNewColorProfileFromICCProfile)( + AEGP_PluginID aegp_plugin_id, // >> + A_long icc_sizeL, // >> icc profile size + const void *icc_dataPV, // >> icc profile + AEGP_ColorProfileP *color_profilePP); // << builds AEGP_ColorProfile from icc profile; caller must dispose with AEGP_DisposeColorProfile + + SPAPI A_Err (*AEGP_GetNewICCProfileFromColorProfile)( + AEGP_PluginID aegp_plugin_id, // >> + AEGP_ConstColorProfileP color_profileP, // >> + AEGP_MemHandle *icc_profilePH); // << extract icc profile from AEGP_ColorProfile; caller must dispose with AEGP_FreeMemHandle + + SPAPI A_Err (*AEGP_GetNewColorProfileDescription)( + AEGP_PluginID aegp_plugin_id, // >> + AEGP_ConstColorProfileP color_profileP, // >> + AEGP_MemHandle *unicode_descPH); // << handle of A_UTF16Char (contains null terminated UTF16 string); must be disposed with AEGP_FreeMemHandle + + SPAPI A_Err (*AEGP_DisposeColorProfile)( + AEGP_ColorProfileP color_profileP); // >> + + SPAPI A_Err (*AEGP_GetColorProfileApproximateGamma)( + AEGP_ConstColorProfileP color_profileP, // >> + A_FpShort *approx_gammaP); // << + + SPAPI A_Err (*AEGP_IsRGBColorProfile)( + AEGP_ConstColorProfileP color_profileP, // << + A_Boolean *is_rgbPB); // >> + + SPAPI A_Err (*AEGP_SetWorkingColorSpace)( + AEGP_PluginID aegp_plugin_id, + AEGP_CompH compH, // >> + AEGP_ConstColorProfileP color_profileP); // >> + + +} AEGP_ColorSettingsSuite3; + + +/* -------------------------------------------------------------------- */ +/* + Render Queue Suite + Used to add, remove, and modify items in the reder queue. + + */ + +#define kAEGPRenderQueueSuite "AEGP Render Queue Suite" +#define kAEGPRenderQueueSuiteVersion1 1 /* frozen in AE 5.0 */ + +enum { + AEGP_RenderQueueState_STOPPED, + AEGP_RenderQueueState_PAUSED, + AEGP_RenderQueueState_RENDERING +}; + +typedef A_u_long AEGP_RenderQueueState; + +enum { + AEGP_RenderItemStatus_NONE = -2, + + AEGP_RenderItemStatus_WILL_CONTINUE, // -1 + AEGP_RenderItemStatus_NEEDS_OUTPUT, // 0 + AEGP_RenderItemStatus_UNQUEUED, // 1 ready to be rendered, but not included in the queue + AEGP_RenderItemStatus_QUEUED, // 2 ready AND queued + AEGP_RenderItemStatus_RENDERING, + AEGP_RenderItemStatus_USER_STOPPED, + AEGP_RenderItemStatus_ERR_STOPPED, + AEGP_RenderItemStatus_DONE, + + AEGP_RenderItemStatus_LAST_PLUS_ONE +}; + +typedef A_long AEGP_RenderItemStatusType; + +typedef struct AEGP_RenderQueueSuite1 { + SPAPI A_Err (*AEGP_AddCompToRenderQueue)( + AEGP_CompH comp, /* >> */ + const A_char* pathZ); + + // not legal to go from STOPPED to PAUSED. + SPAPI A_Err (*AEGP_SetRenderQueueState)( + AEGP_RenderQueueState state); /* >> */ + + SPAPI A_Err (*AEGP_GetRenderQueueState)( + AEGP_RenderQueueState *stateP); /* << */ + +} AEGP_RenderQueueSuite1; + +/* -------------------------------------------------------------------- */ + +enum { + AEGP_LogType_NONE = -1, + AEGP_LogType_ERRORS_ONLY, + AEGP_LogType_PLUS_SETTINGS, + AEGP_LogType_PER_FRAME_INFO, + AEGP_LogType_NUM_TYPES +}; + +typedef A_long AEGP_LogType; + +enum { + AEGP_Embedding_NONE = -1, + AEGP_Embedding_NOTHING, + AEGP_Embedding_LINK, + AEGP_Embedding_LINK_AND_COPY, + AEGP_Embedding_NUM_TYPES +}; + +typedef A_long AEGP_EmbeddingType; + +enum { + AEGP_PostRenderOptions_NONE = -1, + AEGP_PostRenderOptions_IMPORT, + AEGP_PostRenderOptions_IMPORT_AND_REPLACE_USAGE, + AEGP_PostRenderOptions_SET_PROXY, + AEGP_PostRenderOptions_NUM_OPTIONS +}; + +typedef A_long AEGP_PostRenderAction; + +enum { + AEGP_OutputType_NONE = 0, + AEGP_OutputType_VIDEO = 1L << 0, + AEGP_OutputType_AUDIO = 1L << 1, + AEGP_OutputType_NUM_TYPES +}; + +typedef A_long AEGP_OutputTypes; + +enum { + AEGP_VideoChannels_NONE = -1, + AEGP_VideoChannels_RGB, + AEGP_VideoChannels_RGBA, + AEGP_VideoChannels_ALPHA, + AEGP_VideoChannels_NUMTYPES +}; + +typedef A_long AEGP_VideoChannels; + +enum { + AEGP_StretchQual_NONE = -1, + + AEGP_StretchQual_LOW, + AEGP_StretchQual_HIGH, + + AEGP_StretchQual_NUMTYPES +}; +typedef A_long AEGP_StretchQuality; + +enum { + AEGP_OutputColorType_STRAIGHT = -1, + AEGP_OutputColorType_PREMUL +}; + +typedef A_long AEGP_OutputColorType; + +#define kAEGPRQItemSuite "AEGP Render Queue Item Suite" +#define kAEGPRQItemSuiteVersion4 5 /* frozen in AE 14.1 */ + +typedef struct AEGP_RQItemSuite4 { + + SPAPI A_Err (*AEGP_GetNumRQItems)( + A_long *num_itemsPL); /* << */ + + /* NOTE: All AEGP_RQItemRefH are invalidated by ANY + re-ordering, addition or removal of render + items. DO NOT CACHE THEM. + */ + + SPAPI A_Err (*AEGP_GetRQItemByIndex)( + A_long rq_item_index, /* >> */ + AEGP_RQItemRefH *rq_item_refPH); /* << */ + + SPAPI A_Err (*AEGP_GetNextRQItem)( /* Pass RQ_ITEM_INDEX_NONE for current_rq_itemH to get first RQItemH. */ + AEGP_RQItemRefH current_rq_itemH, /* >> */ + AEGP_RQItemRefH *next_rq_itemH); /* << */ + + SPAPI A_Err (*AEGP_GetNumOutputModulesForRQItem)( + AEGP_RQItemRefH rq_itemH, /* >> */ + A_long *num_outmodsPL); /* << */ + + SPAPI A_Err (*AEGP_GetRenderState)( + AEGP_RQItemRefH rq_itemH, /* >> */ + AEGP_RenderItemStatusType *statusP); /* << */ + + /* + the following now returns: + Err_PARAMETER if you try to call while AEGP_RenderQueueState != AEGP_RenderQueueState_STOPPED + + if that's okay then: + Err_RANGE if you pass a status that is illegal in any case + Err_PARAMETER if you try to pass a status that doesn't make sense right now (eg: trying to Que something for which you haven't set the output path) + */ + SPAPI A_Err (*AEGP_SetRenderState)( + AEGP_RQItemRefH rq_itemH, /* >> */ + AEGP_RenderItemStatusType status); /* >> */ + + SPAPI A_Err (*AEGP_GetStartedTime)( + AEGP_RQItemRefH rq_itemH, /* >> */ + A_Time *started_timePT); /* << Returns {0,1} if not started. */ + + SPAPI A_Err (*AEGP_GetElapsedTime)( + AEGP_RQItemRefH rq_itemH, /* >> */ + A_Time *render_timePT); /* << Returns {0,1} if not rendered. */ + + SPAPI A_Err (*AEGP_GetLogType)( + AEGP_RQItemRefH rq_itemH, /* >> */ + AEGP_LogType *logtypeP); /* << */ + + SPAPI A_Err (*AEGP_SetLogType)( + AEGP_RQItemRefH rq_itemH, /* >> */ + AEGP_LogType logtype); /* << */ + + SPAPI A_Err (*AEGP_RemoveOutputModule)( + AEGP_RQItemRefH rq_itemH, /* >> */ + AEGP_OutputModuleRefH outmodH); /* >> */ + + SPAPI A_Err (*AEGP_GetComment)( + AEGP_RQItemRefH rq_itemH, /* >> */ + AEGP_MemHandle *unicodeH); /* << */ + + SPAPI A_Err (*AEGP_SetComment)( + AEGP_RQItemRefH rq_itemH, /* >> */ + const A_UTF16Char *commentZ); /* >> */ + + SPAPI A_Err (*AEGP_GetCompFromRQItem)( + AEGP_RQItemRefH rq_itemH, /* >> */ + AEGP_CompH *compPH); /* << */ + + SPAPI A_Err (*AEGP_DeleteRQItem)( + AEGP_RQItemRefH rq_itemH); /* <> UNDOABLE */ + +} AEGP_RQItemSuite4; + + +#define kAEGPOutputModuleSuite "AEGP Output Module Suite" +#define kAEGPOutputModuleSuiteVersion4 4 /* frozen in AE 10.0 */ + +typedef struct AEGP_OutputModuleSuite4 { + + /* NOTE: All AEGP_OutputModuleRefHs are invalidated by ANY + re-ordering, addition or removal of output modules + from a render item. DO NOT CACHE THEM. + */ + + SPAPI A_Err (*AEGP_GetOutputModuleByIndex)( + AEGP_RQItemRefH rq_itemH, /* >> */ + A_long outmod_indexL, /* >> */ + AEGP_OutputModuleRefH *outmodPH); /* << */ + + SPAPI A_Err (*AEGP_GetEmbedOptions)( + AEGP_RQItemRefH rq_itemH, /* >> */ + AEGP_OutputModuleRefH outmodH, /* >> */ + AEGP_EmbeddingType *embed_optionsP); /* << */ + + SPAPI A_Err (*AEGP_SetEmbedOptions)( + AEGP_RQItemRefH rq_itemH, /* >> */ + AEGP_OutputModuleRefH outmodH, /* >> */ + AEGP_EmbeddingType embed_options); /* >> */ + + SPAPI A_Err (*AEGP_GetPostRenderAction)( + AEGP_RQItemRefH rq_itemH, /* >> */ + AEGP_OutputModuleRefH outmodH, /* >> */ + AEGP_PostRenderAction *post_render_actionP); /* << */ + + SPAPI A_Err (*AEGP_SetPostRenderAction)( + AEGP_RQItemRefH rq_itemH, /* >> */ + AEGP_OutputModuleRefH outmodH, /* >> */ + AEGP_PostRenderAction post_render_action); /* >> */ + + SPAPI A_Err (*AEGP_GetEnabledOutputs)( + AEGP_RQItemRefH rq_itemH, /* >> */ + AEGP_OutputModuleRefH outmodH, /* >> */ + AEGP_OutputTypes *enabled_typesP); /* << */ + + SPAPI A_Err (*AEGP_SetEnabledOutputs)( + AEGP_RQItemRefH rq_itemH, /* >> */ + AEGP_OutputModuleRefH outmodH, /* >> */ + AEGP_OutputTypes enabled_types); /* >> */ + + SPAPI A_Err (*AEGP_GetOutputChannels)( + AEGP_RQItemRefH rq_itemH, /* >> */ + AEGP_OutputModuleRefH outmodH, /* >> */ + AEGP_VideoChannels *output_channelsP); /* << */ + + SPAPI A_Err (*AEGP_SetOutputChannels)( + AEGP_RQItemRefH rq_itemH, /* >> */ + AEGP_OutputModuleRefH outmodH, /* >> */ + AEGP_VideoChannels output_channels); /* >> */ + + SPAPI A_Err (*AEGP_GetStretchInfo)( + AEGP_RQItemRefH rq_itemH, /* >> */ + AEGP_OutputModuleRefH outmodH, /* >> */ + A_Boolean *is_enabledPB, /* << */ + AEGP_StretchQuality *stretch_qualityP, /* << */ + A_Boolean *lockedPB); /* << */ + + SPAPI A_Err (*AEGP_SetStretchInfo)( + AEGP_RQItemRefH rq_itemH, /* >> */ + AEGP_OutputModuleRefH outmodH, /* >> */ + A_Boolean is_enabledB, /* >> */ + AEGP_StretchQuality stretch_quality); /* >> */ + + SPAPI A_Err (*AEGP_GetCropInfo)( + AEGP_RQItemRefH rq_itemH, /* >> */ + AEGP_OutputModuleRefH outmodH, /* >> */ + A_Boolean *is_enabledBP, /* << */ + A_Rect *crop_rectP); /* << */ + + SPAPI A_Err (*AEGP_SetCropInfo)( + AEGP_RQItemRefH rq_itemH, /* >> */ + AEGP_OutputModuleRefH outmodH, /* >> */ + A_Boolean enableB, /* >> */ + A_Rect crop_rect); /* >> */ + + SPAPI A_Err (*AEGP_GetSoundFormatInfo)( + AEGP_RQItemRefH rq_itemH, /* >> */ + AEGP_OutputModuleRefH outmodH, /* >> */ + AEGP_SoundDataFormat *sound_format_infoP, /* << */ + A_Boolean *audio_enabledPB); /* << */ + + SPAPI A_Err (*AEGP_SetSoundFormatInfo)( + AEGP_RQItemRefH rq_itemH, /* >> */ + AEGP_OutputModuleRefH outmodH, /* >> */ + AEGP_SoundDataFormat sound_format_info, /* >> */ + A_Boolean audio_enabledB); /* >> */ + + SPAPI A_Err (*AEGP_GetOutputFilePath)( + AEGP_RQItemRefH rq_itemH, /* >> */ + AEGP_OutputModuleRefH outmodH, /* >> */ + AEGP_MemHandle *unicode_pathPH); // << empty string if not specified. handle of A_UTF16Char (contains null terminated UTF16 string); must be disposed with AEGP_FreeMemHandle + + SPAPI A_Err (*AEGP_SetOutputFilePath)( + AEGP_RQItemRefH rq_itemH, /* >> */ + AEGP_OutputModuleRefH outmodH, /* >> */ + const A_UTF16Char *pathZ); // >> null terminated unicode path with platform separators + + SPAPI A_Err (*AEGP_AddDefaultOutputModule)( + AEGP_RQItemRefH rq_itemH, /* >> */ + AEGP_OutputModuleRefH *outmodPH); /* << */ + + SPAPI A_Err (*AEGP_GetExtraOutputModuleInfo)( + AEGP_RQItemRefH rq_itemH, + AEGP_OutputModuleRefH outmodH, + AEGP_MemHandle *format_unicodePH, /* << handle of A_u_short, (contains null terminated UTF16 string) must be disposed with AEGP_FreeMemHandle */ + AEGP_MemHandle *info__unicodePH, /* << handle of A_u_short, (contains null terminated UTF16 string) must be disposed with AEGP_FreeMemHandle */ + A_Boolean *is_sequenceBP, + A_Boolean *multi_frameBP); + +} AEGP_OutputModuleSuite4; + +/* -------------------------------------------------------------------- */ + +/** + ** Canvas Suite + ** Used by artisans to render layers + **/ + +#define kAEGPCanvasSuite "AEGP Canvas Suite" +#define kAEGPCanvasSuiteVersion8 14 /* frozen in AE 12.0*/ + + +enum { + AEGP_RenderHints_NONE = 0, + AEGP_RenderHints_IGNORE_EXTENTS = 0x1, + AEGP_RenderHints_NO_TRANSFER_MODE = 0x2 // prevents application of opacity & transfer mode; for RenderLayer calls +}; +typedef A_u_long AEGP_RenderHints; + + +enum { + AEGP_RenderReceiptStatus_INVALID = 0, + AEGP_RenderReceiptStatus_VALID, + AEGP_RenderReceiptStatus_VALID_BUT_INCOMPLETE +}; +typedef A_u_long AEGP_RenderReceiptStatus; + + +enum { + AEGP_BinType_NONE = -1, + AEGP_BinType_2D = 0, + AEGP_BinType_3D = 1 +}; +typedef A_long AEGP_BinType; + + +typedef void * AEGP_PlatformWindowRef; + + + +enum { + AEGP_DisplayChannel_NONE = 0, + AEGP_DisplayChannel_RED, + AEGP_DisplayChannel_GREEN, + AEGP_DisplayChannel_BLUE, + AEGP_DisplayChannel_ALPHA, + AEGP_DisplayChannel_RED_ALT, + AEGP_DisplayChannel_GREEN_ALT, + AEGP_DisplayChannel_BLUE_ALT, + AEGP_DisplayChannel_ALPHA_ALT, + AEGP_DisplayChannel_NUM_ITEMS +}; +typedef A_long AEGP_DisplayChannelType; // disk safe + +enum { + AEGP_RenderNumEffects_ALL_EFFECTS = -1 +}; + +typedef A_short AEGP_NumEffectsToRenderType; + + +typedef struct AEGP_CanvasSuite8 { + + SPAPI A_Err (*AEGP_GetCompToRender)( + PR_RenderContextH render_contextH, /* >> */ + AEGP_CompH *compPH); /* << */ + + SPAPI A_Err (*AEGP_GetNumLayersToRender)( + const PR_RenderContextH render_contextH, /* >> */ + A_long *num_to_renderPL); /* << */ + + + SPAPI A_Err (*AEGP_GetNthLayerContextToRender)( + const PR_RenderContextH render_contextH, /* >> */ + A_long n, /* >> */ + AEGP_RenderLayerContextH *layer_contextPH); /* << */ + + SPAPI A_Err (*AEGP_GetLayerFromLayerContext)( + const PR_RenderContextH render_contextH, /* >> */ + AEGP_RenderLayerContextH layer_contextH, /* >> */ + AEGP_LayerH *layerPH); /* << */ + + SPAPI A_Err (*AEGP_GetLayerAndSubLayerFromLayerContext)( + const PR_RenderContextH render_contextH, /* >> */ + AEGP_RenderLayerContextH layer_contextH, /* >> */ + AEGP_LayerH *layerPH, /* << */ + AEGP_SubLayerIndex *sublayerP); /* << */ + + /** + ** With collapsed geometrics "on" this gives the layer in the root comp + ** contining the layer context. With collapsed geometrics off + ** this is the same as AEGP_GetLayerFromLayerContext. + ** + **/ + SPAPI A_Err (*AEGP_GetTopLayerFromLayerContext)( + const PR_RenderContextH render_contextH, + AEGP_RenderLayerContextH layer_contextH, + AEGP_LayerH *layerPH); + + SPAPI A_Err (*AEGP_GetCompRenderTime)( + PR_RenderContextH render_contextH, /* >> */ + A_Time *time, /* << */ + A_Time *time_step); + + SPAPI A_Err (*AEGP_GetCompDestinationBuffer)( + PR_RenderContextH render_contextH, /* <> */ + AEGP_CompH compH, /* >> */ + AEGP_WorldH *dst); /* << */ + + SPAPI A_Err (*AEGP_GetROI)( + PR_RenderContextH render_contextH, /* <> */ + A_LegacyRect *roiPR); /* << */ + + // for rendering the texture map of a layer + SPAPI A_Err (*AEGP_RenderTexture)( + PR_RenderContextH render_contextH, /* <> */ + AEGP_RenderLayerContextH layer_contextH, /* >> */ + AEGP_RenderHints render_hints, /* >> */ + A_FloatPoint *suggested_scaleP0, /* >> */ + A_FloatRect *suggested_src_rectP0, /* >> */ + A_Matrix3 *src_matrixP0, /* << */ + AEGP_WorldH *dstPH); /* <> */ + + + SPAPI A_Err (*AEGP_DisposeTexture)( + PR_RenderContextH render_contextH, /* <> */ + AEGP_RenderLayerContextH layer_contextH, /* >> */ + AEGP_WorldH dstH0); /* <> */ + + SPAPI A_Err (*AEGP_GetFieldRender)( + PR_RenderContextH render_contextH, /* >> */ + PF_Field *field); /* << */ + + // not thread safe on MacOS + // only call when thread ID = 0 + SPAPI A_Err (*AEGP_ReportArtisanProgress)( + PR_RenderContextH render_contextH, /* >> */ + A_long countL, /* >> */ + A_long totalL); /* >> */ + + SPAPI A_Err (*AEGP_GetRenderDownsampleFactor)( + PR_RenderContextH render_contextH, /* >> */ + AEGP_DownsampleFactor *dsfP); /* << */ + + SPAPI A_Err (*AEGP_SetRenderDownsampleFactor)( + PR_RenderContextH render_contextH, /* >> */ + AEGP_DownsampleFactor *dsfP); /* >> */ + + SPAPI A_Err (*AEGP_IsBlankCanvas)( + PR_RenderContextH render_contextH, /* >> */ + A_Boolean *is_blankPB); /* << */ + + SPAPI A_Err (*AEGP_GetRenderLayerToWorldXform)( + PR_RenderContextH render_contextH, /* >> */ + AEGP_RenderLayerContextH layer_contextH, /* >> */ + const A_Time *comp_timeP, /* >> */ + A_Matrix4 *transform); /* << */ + + SPAPI A_Err (*AEGP_GetRenderLayerBounds)( + PR_RenderContextH render_contextH, /* >> */ + AEGP_RenderLayerContextH layer_contextH, /* >> */ + const A_Time *comp_timeP, /* >> */ + A_LegacyRect *boundsP); /* << */ + + SPAPI A_Err (*AEGP_GetRenderOpacity)( + PR_RenderContextH render_contextH, /* >> */ + AEGP_RenderLayerContextH layer_contextH, /* >> */ + const A_Time *comp_timePT, /* >> */ + A_FpLong *opacityPF); /* << */ + + SPAPI A_Err (*AEGP_IsRenderLayerActive)( + PR_RenderContextH render_contextH, /* >> */ + AEGP_RenderLayerContextH layer_contextH, /* >> */ + const A_Time *comp_timePT, /* >> */ + A_Boolean *activePB); /* << */ + + // set the layer index. If total > 0, set it too. + SPAPI A_Err (*AEGP_SetArtisanLayerProgress)( + PR_RenderContextH render_contextH, /* >> */ + A_long countL, /* >> */ + A_long num_layersL); + + // for track mattes. + // Returns a comp-size buffer, which must be disposed thru AEGP_Dispose in World suite + SPAPI A_Err (*AEGP_RenderLayerPlus)( + PR_RenderContextH render_contextH, /* <> */ + AEGP_LayerH layerH, /* >> */ + AEGP_RenderLayerContextH layer_contextH, /* >> */ + AEGP_RenderHints render_hints, /* >> */ + AEGP_WorldH *render_bufferPH); /* << must be disposed with AEGP_DisposeWorld */ + + + SPAPI A_Err (*AEGP_GetTrackMatteContext)( + PR_RenderContextH render_contextH, /* <> */ + AEGP_RenderLayerContextH fill_contextH, /* << */ + AEGP_RenderLayerContextH *matte_contextPH); /* >> */ + + // new for 6.0 --get receipt with the returned texture + // use receipt to determine if a subsequent call to render + // this layer can be skipped (because the artisan cached it) + SPAPI A_Err (*AEGP_RenderTextureWithReceipt)( + PR_RenderContextH render_contextH, /* <> */ + AEGP_RenderLayerContextH layer_contextH, /* >> */ + AEGP_RenderHints render_hints, /* >> */ + AEGP_NumEffectsToRenderType num_effectsS, /* >> number of effect to render, -1 for all */ + A_FloatPoint *suggested_scaleP0, /* >> */ + A_FloatRect *suggested_src_rectP0, /* >> */ + A_Matrix3 *src_matrixP0, /* << */ + AEGP_RenderReceiptH *render_receiptPH, /* << must be disposed with AEGP_DisposeRenderReceipt */ + AEGP_WorldH *dstPH); /* << */ + + + + SPAPI A_Err (*AEGP_GetNumberOfSoftwareEffects)( + PR_RenderContextH render_contextH, /* <> */ + AEGP_RenderLayerContextH layer_contextH, /* >> */ + A_short *num_software_effectsPS); + + SPAPI A_Err (*AEGP_RenderLayerPlusWithReceipt)( + PR_RenderContextH render_contextH, /* <> */ + AEGP_LayerH layerH, /* >> */ + AEGP_RenderLayerContextH layer_contextH, /* >> */ + AEGP_RenderHints render_hints, /* >> */ + AEGP_RenderReceiptH *render_receiptPH, /* << must be disposed with AEGP_DisposeRenderReceipt */ + AEGP_WorldH *render_bufferPH); /* << */ + + SPAPI A_Err (*AEGP_DisposeRenderReceipt)( + AEGP_RenderReceiptH render_receiptH); /* >> */ + + + /* modified for 7.0 - added num_effects to check against */ + SPAPI A_Err (*AEGP_CheckRenderReceipt)( + PR_RenderContextH current_render_contextH, /* in */ + AEGP_RenderLayerContextH current_layer_contextH, /* in */ + AEGP_RenderReceiptH old_render_receiptH, /* in */ + A_Boolean check_geometricsB, /* in */ + AEGP_NumEffectsToRenderType num_effectsS, /* in */ + AEGP_RenderReceiptStatus *receipt_statusP); /* out */ + + + /* new in 7.0 generate a receipt for a layer as asd if the first num_effectsS have been rendered */ + SPAPI A_Err (*AEGP_GenerateRenderReceipt)( + PR_RenderContextH current_render_contextH, /* >> */ + AEGP_RenderLayerContextH current_layer_contextH, /* >> */ + AEGP_NumEffectsToRenderType num_effectsS, /* in */ + AEGP_RenderReceiptH *render_receiptPH); /* << */ + + SPAPI A_Err (*AEGP_GetNumBinsToRender)( + const PR_RenderContextH render_contextH, /* >> */ + A_long *num_bins_to_renderPL); /* << */ + + + SPAPI A_Err (*AEGP_SetNthBin)( + const PR_RenderContextH render_contextH, /* >> */ + A_long n); /* >> */ + + SPAPI A_Err (*AEGP_GetBinType)( + const PR_RenderContextH render_contextH, /* >> */ + AEGP_BinType *bin_typeP); /* << */ + + SPAPI A_Err (*AEGP_GetRenderLayerToWorldXform2D3D)( + PR_RenderContextH render_contextH, /* >> */ + AEGP_RenderLayerContextH layer_contextH, /* >> */ + const A_Time *comp_timeP, /* >> */ + A_Boolean only_2dB, /* >> */ + A_Matrix4 *transform); /* << */ + + + // interactive artisan information + // handle to the on-screen window + SPAPI A_Err (*AEGP_GetPlatformWindowRef)( + const PR_RenderContextH render_contextH, /* >> */ + AEGP_PlatformWindowRef *window_refP); /* << */ + + + // the dsf src to frame scale factors + SPAPI A_Err (*AEGP_GetViewportScale)( + const PR_RenderContextH render_contextH, /* >> */ + A_FpLong *scale_xPF, /* << */ + A_FpLong *scale_yPF); /* << */ + + + // the dsf src to frame translate + SPAPI A_Err (*AEGP_GetViewportOrigin)( + const PR_RenderContextH render_contextH, /* >> */ + A_long *origin_xPL, /* << */ + A_long *origin_yPL); /* << */ + + + SPAPI A_Err (*AEGP_GetViewportRect)( + const PR_RenderContextH render_contextH, /* >> */ + A_LegacyRect *viewport_rectPR); /* << */ + + + SPAPI A_Err (*AEGP_GetFallowColor)( + const PR_RenderContextH render_contextH, /* >> */ + PF_Pixel8 *fallow_colorP); /* << */ + + SPAPI A_Err (*AEGP_GetInteractiveBuffer)( + const PR_RenderContextH render_contextH, /* >> */ + AEGP_WorldH *buffer); /* << */ + + SPAPI A_Err (*AEGP_GetInteractiveCheckerboard)( + const PR_RenderContextH render_contextH, /* in */ + A_Boolean *checkerboard_onPB);/* out */ + + SPAPI A_Err (*AEGP_GetInteractiveCheckerboardColors)( + const PR_RenderContextH render_contextH, /* in */ + PF_Pixel *checkerboard_color1P, /* out */ + PF_Pixel *checkerboard_color2P); /* out */ + + SPAPI A_Err (*AEGP_GetInteractiveCheckerboardSize)( + const PR_RenderContextH render_contextH, /* in */ + A_u_long *checkerboard_widthPLu, /* out - width of square*/ + A_u_long *checkerboard_heightPLu); /* out - height of square*/ + + SPAPI A_Err (*AEGP_GetInteractiveCachedBuffer)( + const PR_RenderContextH render_contextH, /* >> */ + AEGP_WorldH *buffer); /* << */ + + + // should we call AEGP_RenderLayer or AEGP_RenderTexture + SPAPI A_Err (*AEGP_ArtisanMustRenderAsLayer)( + const PR_RenderContextH render_contextH, /* >> */ + AEGP_RenderLayerContextH layer_contextH, + A_Boolean *use_render_texturePB); + + + SPAPI A_Err (*AEGP_GetInteractiveDisplayChannel)( + const PR_RenderContextH render_contextH, /* >> */ + AEGP_DisplayChannelType *display_channelP); /* << */ + + SPAPI A_Err (*AEGP_GetInteractiveExposure)( + const PR_RenderContextH render_contextH, /* >> */ + A_FpLong *exposurePF); /* << */ + + + SPAPI A_Err (*AEGP_GetColorTransform)( + const PR_RenderContextH render_contextH, /* >> */ + A_Boolean *cms_onB, + A_u_long *xform_keyLu, + void *xformP); + + + SPAPI A_Err (*AEGP_GetCompShutterTime)( + PR_RenderContextH render_contextH, /* >> */ + A_Time *shutter_time, /* << */ + A_Time *shutter_dur); + + // uses remapping if any + SPAPI A_Err (*AEGP_MapCompToLayerTime)( + PR_RenderContextH render_contextH, /* in */ + AEGP_RenderLayerContextH layer_contextH, /* in*/ + const A_Time *comp_timePT, /* in */ + A_Time *layer_timePT); /* out */ + +} AEGP_CanvasSuite8; + + + + + + + +/** + ** Artisan utility suite + ** + **/ +#define kAEGPArtisanUtilSuite "AEGP Artisan Util Suite" +#define kAEGPArtisanUtilSuiteVersion1 1 /* frozen in AE 5.0 */ + + +typedef struct AEGP_ArtisanUtilSuite1 { + + + SPAPI A_Err (*AEGP_GetGlobalContextFromInstanceContext)( + const PR_InstanceContextH instance_contextH, /* >> */ + PR_GlobalContextH *global_contextPH); /* << */ + + + SPAPI A_Err (*AEGP_GetInstanceContextFromRenderContext)( + const PR_RenderContextH render_contextH, /* >> */ + PR_InstanceContextH *instance_contextPH); /* << */ + + + + SPAPI A_Err (*AEGP_GetInstanceContextFromQueryContext)( + const PR_QueryContextH query_contextH, /* >> */ + PR_InstanceContextH *instance_contextPH); /* << */ + + + SPAPI A_Err (*AEGP_GetGlobalData)( + const PR_GlobalContextH global_contextH, /* >> */ + PR_GlobalDataH *global_dataPH); /* << */ + + + SPAPI A_Err (*AEGP_GetInstanceData)( + const PR_InstanceContextH instance_contextH, /* >> */ + PR_InstanceDataH *instance_dataPH); /* << */ + + SPAPI A_Err (*AEGP_GetRenderData)( + const PR_RenderContextH render_contextH, /* >> */ + PR_RenderDataH *render_dataPH); /* << */ + +} AEGP_ArtisanUtilSuite1; + + + +#define kAEGPCameraSuite "AEGP Camera Suite" +#define kAEGPCameraSuiteVersion2 2 /* frozen in AE 5.5 */ + +typedef struct AEGP_CameraSuite2 { + + SPAPI A_Err (*AEGP_GetCamera)( + PR_RenderContextH render_contextH, /* >> */ + const A_Time *comp_timeP, /* >> */ + AEGP_LayerH *camera_layerPH); /* << */ + + SPAPI A_Err (*AEGP_GetCameraType)( + AEGP_LayerH camera_layerH, /* >> */ + AEGP_CameraType *camera_typeP); /* << */ + + + SPAPI A_Err (*AEGP_GetDefaultCameraDistanceToImagePlane)( + AEGP_CompH compH, /* >> */ + A_FpLong *dist_to_planePF); /* << */ + + // If a camera is created using aegp, then you must set the film size units. + // No default is provided. + + SPAPI A_Err (*AEGP_GetCameraFilmSize)( + AEGP_LayerH camera_layerH, /* >> */ + AEGP_FilmSizeUnits *film_size_unitsP, /* << */ + A_FpLong *film_sizePF0); /* << in pixels */ + + SPAPI A_Err (*AEGP_SetCameraFilmSize)( + AEGP_LayerH camera_layerH, /* >> */ + AEGP_FilmSizeUnits film_size_units, /* >> */ + A_FpLong *film_sizePF0); /* >> in pixels */ + +} AEGP_CameraSuite2; + +#define kAEGPLightSuite "AEGP Light Suite" +#define kAEGPLightSuiteVersion2 2 /* frozen in AE 5.5 */ + +typedef struct AEGP_LightSuite2 { + + SPAPI A_Err (*AEGP_GetLightType)( + AEGP_LayerH light_layerH, /* >> */ + AEGP_LightType *light_typeP); /* << */ + + SPAPI A_Err (*AEGP_SetLightType)( + AEGP_LayerH light_layerH, /* >> */ + AEGP_LightType light_type); /* >> */ + +} AEGP_LightSuite2; + + + +/** + ** Query Xform suite + ** Called by artisans during a response to a Query + **/ + +#define kAEGPQueryXformSuite "AEGP QueryXform Suite" +#define kAEGPQueryXformSuiteVersion2 4 /* frozen in AE 6.0 */ + + +/** + ** the type of source or dst transformation wanted + **/ +enum { + AEGP_Query_Xform_LAYER, + AEGP_Query_Xform_WORLD, + AEGP_Query_Xform_VIEW, + AEGP_Query_Xform_SCREEN +}; + +typedef A_u_long AEGP_QueryXformType; + + + +typedef struct AEGP_QueryXformSuite2 { + + SPAPI A_Err (*AEGP_QueryXformGetSrcType)( + PR_QueryContextH query_contextH, /* <> */ + AEGP_QueryXformType *src_type); /* << */ + + SPAPI A_Err (*AEGP_QueryXformGetDstType)( + PR_QueryContextH query_contextH, /* <> */ + AEGP_QueryXformType *dst_type); /* << */ + + SPAPI A_Err (*AEGP_QueryXformGetLayer)( + PR_QueryContextH query_contextH, /* <> */ + AEGP_LayerH *layerPH); /* << */ + + SPAPI A_Err (*AEGP_QueryXformGetComp)( + PR_QueryContextH query_contextH, /* <> */ + AEGP_CompH *compPH); /* << */ + + SPAPI A_Err (*AEGP_QueryXformGetTransformTime)( + PR_QueryContextH query_contextH, /* <> */ + A_Time *time); /* << */ + + SPAPI A_Err (*AEGP_QueryXformGetViewTime)( + PR_QueryContextH query_contextH, /* <> */ + A_Time *time); /* << */ + + SPAPI A_Err (*AEGP_QueryXformGetCamera)( + PR_QueryContextH query_contextH, /* <> */ + AEGP_LayerH *camera_layerPH); /* << */ + + SPAPI A_Err (*AEGP_QueryXformGetXform)( + PR_QueryContextH query_contextH, /* <> */ + A_Matrix4 *xform); /* << */ + + SPAPI A_Err (*AEGP_QueryXformSetXform)( + PR_QueryContextH query_contextH, /* <> */ + A_Matrix4 *xform); /* >> */ + + SPAPI A_Err (*AEGP_QueryWindowRef)( + PR_QueryContextH query_contextH, /* <> */ + AEGP_PlatformWindowRef *window_refP); /* >> */ + + SPAPI A_Err (*AEGP_QueryWindowClear)( + PR_QueryContextH query_contextH, /* <> */ + AEGP_PlatformWindowRef *window_refP, /* out */ + A_LegacyRect *boundsPR); /* out */ + + SPAPI A_Err (*AEGP_QueryFrozenProxy)( + PR_QueryContextH query_contextH, /* <> */ + A_Boolean *onPB); /* out */ + + SPAPI A_Err (*AEGP_QuerySwapBuffer)( + PR_QueryContextH query_contextH, /* <> */ + AEGP_PlatformWindowRef *window_refP, /* out */ + AEGP_WorldH *dest_bufferp); /* out */ + + SPAPI A_Err (*AEGP_QueryDrawProcs)( + PR_QueryContextH query_contextH, /* <> */ + PR_InteractiveDrawProcs *window_refP); /* in */ + + + SPAPI A_Err (*AEGP_QueryPrepareForLineDrawing)( + PR_QueryContextH query_contextH, /* <> */ + AEGP_PlatformWindowRef *window_refP, + A_LegacyRect *viewportP, + A_LPoint *originP, + A_FloatPoint *scaleP); /* in */ + + SPAPI A_Err (*AEGP_QueryUnprepareForLineDrawing)( + PR_QueryContextH query_contextH, /* <> */ + AEGP_PlatformWindowRef *window_refP); /* in */ + + SPAPI A_Err (*AEGP_QueryGetData)( + PR_QueryContextH query_contextH, /* <> */ + A_long i, /* in */ + void **dataPP); /* out */ + + SPAPI A_Err (*AEGP_QuerySetData)( + PR_QueryContextH query_contextH, /* <> */ + A_long i, /* in */ + void *dataP); /* in */ + + +}AEGP_QueryXformSuite2; + + +/* -------------------------------------------------------------------- */ + + + +#define kAEGPCompositeSuite "AEGP Composite Suite" +#define kAEGPCompositeSuiteVersion2 4 /* frozen in AE 10.0 */ + +typedef struct AEGP_CompositeSuite2 { + + SPAPI A_Err (*AEGP_ClearAlphaExceptRect)( + A_Rect *clipped_dest_rectPR, /* >> */ + PF_EffectWorld *dstP); /* <> */ + + SPAPI A_Err (*AEGP_PrepTrackMatte)( + A_long num_pix, /* >> */ + A_Boolean deepB, /* >> */ + const PF_Pixel *src_mask, /* >> */ + PF_MaskFlags mask_flags, /* >> */ + PF_Pixel *dst_mask); /* << */ + + SPAPI A_Err (*AEGP_TransferRect)( + PF_Quality quality, /* >> */ + PF_ModeFlags m_flags, /* >> */ + PF_Field field, /* >> */ + const A_Rect *src_rec, /* >> */ + const PF_EffectWorld *src_world, /* >> */ + const PF_CompositeMode *comp_mode, /* >> */ + PF_EffectBlendingTables blend_tablesP0, /* >>, pass NULL to blend in workingspace*/ + const PF_MaskWorld *mask_world0, /* >> */ + A_long dest_x, /* >> */ + A_long dest_y, /* >> */ + PF_EffectWorld *dst_world); /* <> */ + + SPAPI A_Err (*AEGP_CopyBits_LQ) ( + PF_EffectWorld *src_worldP, /* >> */ + A_Rect *src_r, /* pass NULL for whole world */ + A_Rect *dst_r, /* pass NULL for whole world */ + PF_EffectWorld *dst_worldP); /* <> */ + + SPAPI A_Err (*AEGP_CopyBits_HQ_Straight) ( + PF_EffectWorld *src, /* >> */ + A_Rect *src_r, /* pass NULL for whole world */ + A_Rect *dst_r, /* pass NULL for whole world */ + PF_EffectWorld *dst); /* <> */ + + SPAPI A_Err (*AEGP_CopyBits_HQ_Premul) ( + PF_EffectWorld *src, /* >> */ + A_Rect *src_r, /* pass NULL for whole world */ + A_Rect *dst_r, /* pass NULL for whole world */ + PF_EffectWorld *dst); /* <> */ + +} AEGP_CompositeSuite2; + + + +/* -------------------------------------------------------------------- */ + +#define kAEGPIterateSuite "AEGP Iterate Suite" +#define kAEGPIterateSuiteVersion2 2 /* frozen in AE 22.0 */ + +typedef struct AEGP_IterateSuite2 { + + SPAPI A_Err (*AEGP_GetNumThreads)( + A_long *num_threadsPL); + + + SPAPI A_Err (*AEGP_IterateGeneric)( + A_long iterationsL, /* >> */ // can be PF_Iterations_ONCE_PER_PROCESSOR + void *refconPV, /* >> */ + A_Err (*fn_func)( void *refconPV, /* >> */ + A_long thread_indexL, /* >> */ + A_long i, /* >> */ + A_long iterationsL)); /* >> */ + +} AEGP_IterateSuite2; + +// Export the name of this function in your PiPL resource's EntryPoint + +typedef A_Err (AEGP_PluginInitFuncPrototype)( + struct SPBasicSuite *pica_basicP, /* >> */ + A_long driver_major_versionL, /* >> */ + A_long driver_minor_versionL, /* >> */ + AEGP_PluginID aegp_plugin_id, /* >> */ + AEGP_GlobalRefcon *plugin_refconP); /* << will be passed to all hooks! */ + +typedef AEGP_PluginInitFuncPrototype *AEGP_PluginInitFunc; + + +/* -------------------------------------------------------------------- */ + +/** AEGPPFInterfaceSuite1 + + These are basically wrappers for constructing various AEGP objects from + the information available to an effect plug-in so that various other AEGP suites + may be used. + + AEGP_GetEffectLayer -- get AEGP_LayerH corresponding to layer that effect is applied to + AEGP_GetNewEffectForEffect -- get AEGP_EffectRefH corresponding to effect + AEGP_ConvertEffectToCompTime -- return comp time from time units passed to effect (layer time) + AEGP_GetEffectCamera -- get camera AEGP_LayerH which defines current 3D view + -- NOTE : this may be null if no camera is defined + + AEGP_GetEffectCameraMatrix -- use this to get the geometry for the camera. + + These may only be called during PF_Cmd_FRAME_SETUP, PF_Cmd_RENDER, + and PF_Cmd_EVENT::PF_Event_DRAW +**/ + +#define kAEGPPFInterfaceSuite "AEGP PF Interface Suite" +#define kAEGPPFInterfaceSuiteVersion1 1 /* frozen in AE 5.0 */ + + +typedef struct AEGP_PFInterfaceSuite1 { + + SPAPI A_Err (*AEGP_GetEffectLayer)( + PF_ProgPtr effect_pp_ref, /* >> */ + AEGP_LayerH *layerPH); /* << */ + + SPAPI A_Err (*AEGP_GetNewEffectForEffect)( /* must be disposed using AEGP_DisposeEffect */ + AEGP_PluginID aegp_plugin_id, /* >> */ + PF_ProgPtr effect_pp_ref, /* >> */ + AEGP_EffectRefH *effect_refPH); /* << */ + + SPAPI A_Err (*AEGP_ConvertEffectToCompTime)( + PF_ProgPtr effect_pp_ref, /* >> */ + A_long what_timeL, /* >> */ + A_u_long time_scaleLu, /* from PF_InData */ + A_Time *comp_timePT); /* << */ + + SPAPI A_Err (*AEGP_GetEffectCamera)( + PF_ProgPtr effect_pp_ref, /* >> */ + const A_Time *comp_timePT, /* >> */ + AEGP_LayerH *camera_layerPH); /* << */ + + SPAPI A_Err (*AEGP_GetEffectCameraMatrix)( + PF_ProgPtr effect_pp_ref, /* >> */ + const A_Time *comp_timePT, /* >> */ + A_Matrix4 *camera_matrixP, /* <> */ + A_FpLong *dist_to_image_planePF, /* <> */ + A_short *image_plane_widthPL, /* <> */ + A_short *image_plane_heightPL); /* <> */ +} AEGP_PFInterfaceSuite1; + +// PIN_FileSize +typedef A_u_longlong AEIO_FileSize; + +#define kAEGPIOInSuite "AEGP IO In Suite" +#define kAEGPIOInSuiteVersion5 6 /* frozen in AE 12 */ + +typedef struct AEGP_IOInSuite5 { + + SPAPI A_Err (*AEGP_GetInSpecOptionsHandle)( + AEIO_InSpecH inH, /* >> */ + void **optionsPPV); /* << */ + + SPAPI A_Err (*AEGP_SetInSpecOptionsHandle)( + AEIO_InSpecH inH, /* >> */ + void *optionsPV, /* >> */ + void **old_optionsPPV); /* << */ + + SPAPI A_Err (*AEGP_GetInSpecFilePath)( + AEIO_InSpecH inH, /* >> */ + AEGP_MemHandle *unicode_pathPH); // << handle of A_UTF16Char (contains null terminated UTF16 string); must be disposed with AEGP_FreeMemHandle + + SPAPI A_Err (*AEGP_GetInSpecNativeFPS)( + AEIO_InSpecH inH, /* >> */ + A_Fixed *native_fpsP); /* << */ + + SPAPI A_Err (*AEGP_SetInSpecNativeFPS)( + AEIO_InSpecH inH, /* >> */ + A_Fixed native_fps); /* >> */ + + SPAPI A_Err (*AEGP_GetInSpecDepth)( + AEIO_InSpecH inH, /* >> */ + A_short *depthPS); /* << */ + + SPAPI A_Err (*AEGP_SetInSpecDepth)( + AEIO_InSpecH inH, /* >> */ + A_short depthS); /* >> */ + + SPAPI A_Err (*AEGP_GetInSpecSize)( + AEIO_InSpecH inH, /* >> */ + AEIO_FileSize *sizePL); /* << */ + + SPAPI A_Err (*AEGP_SetInSpecSize)( + AEIO_InSpecH inH, /* >> */ + AEIO_FileSize sizeL); /* >> */ + + SPAPI A_Err (*AEGP_GetInSpecInterlaceLabel)( + AEIO_InSpecH inH, /* >> */ + FIEL_Label *interlaceP); /* << */ + + SPAPI A_Err (*AEGP_SetInSpecInterlaceLabel)( + AEIO_InSpecH inH, /* >> */ + const FIEL_Label *interlaceP); /* << */ + + SPAPI A_Err (*AEGP_GetInSpecAlphaLabel)( + AEIO_InSpecH inH, /* >> */ + AEIO_AlphaLabel *alphaP); /* << */ + + SPAPI A_Err (*AEGP_SetInSpecAlphaLabel)( + AEIO_InSpecH inH, /* >> */ + const AEIO_AlphaLabel *alphaP); /* << */ + + SPAPI A_Err (*AEGP_GetInSpecDuration)( + AEIO_InSpecH inH, /* >> */ + A_Time *durationP); /* << */ + + SPAPI A_Err (*AEGP_SetInSpecDuration)( + AEIO_InSpecH inH, /* >> */ + const A_Time *durationP); /* >> */ + + SPAPI A_Err (*AEGP_GetInSpecDimensions)( + AEIO_InSpecH inH, /* >> */ + A_long *widthPL0, /* << */ + A_long *heightPL0); + + SPAPI A_Err (*AEGP_SetInSpecDimensions)( + AEIO_InSpecH inH, /* >> */ + A_long widthL, /* >> */ + A_long heightL); /* >> */ + + SPAPI A_Err (*AEGP_InSpecGetRationalDimensions)( + AEIO_InSpecH inH, /* >> */ + const AEIO_RationalScale *rs0, /* << */ + A_long *width0, /* << */ + A_long *height0, /* << */ + A_Rect *r0); /* << */ + + SPAPI A_Err (*AEGP_GetInSpecHSF)( + AEIO_InSpecH inH, /* >> */ + A_Ratio *hsfP); /* << */ + + SPAPI A_Err (*AEGP_SetInSpecHSF)( + AEIO_InSpecH inH, /* >> */ + const A_Ratio *hsfP); /* >> */ + + SPAPI A_Err (*AEGP_GetInSpecSoundRate)( + AEIO_InSpecH inH, /* >> */ + A_FpLong *ratePF); /* << */ + + SPAPI A_Err (*AEGP_SetInSpecSoundRate)( + AEIO_InSpecH inH, /* >> */ + A_FpLong rateF); /* >> */ + + SPAPI A_Err (*AEGP_GetInSpecSoundEncoding)( + AEIO_InSpecH inH, /* >> */ + AEIO_SndEncoding *encodingP); /* << */ + + SPAPI A_Err (*AEGP_SetInSpecSoundEncoding)( + AEIO_InSpecH inH, /* >> */ + AEIO_SndEncoding encoding); /* >> */ + + SPAPI A_Err (*AEGP_GetInSpecSoundSampleSize)( + AEIO_InSpecH inH, /* >> */ + AEIO_SndSampleSize *bytes_per_sampleP);/* << */ + + SPAPI A_Err (*AEGP_SetInSpecSoundSampleSize)( + AEIO_InSpecH inH, /* >> */ + AEIO_SndSampleSize bytes_per_sample); /* >> */ + + SPAPI A_Err (*AEGP_GetInSpecSoundChannels)( + AEIO_InSpecH inH, /* >> */ + AEIO_SndChannels *num_channelsP); /* << */ + + SPAPI A_Err (*AEGP_SetInSpecSoundChannels)( + AEIO_InSpecH inH, /* >> */ + AEIO_SndChannels num_channels); /* >> */ + + SPAPI A_Err (*AEGP_AddAuxExtMap)( + const A_char *extension, /* >> */ + A_long file_type, /* >> */ + A_long creator); /* >> */ + + // In case of RGB data, if there is an embedded icc profile, build AEGP_ColorProfile out of this icc profile using AEGP_GetNewColorProfileFromICCProfile and pass it to + // AEGP_SetInSpecEmbeddedColorProfile, with profile description set to NULL. + // + // In case of non-RGB data, if there is an embedded non-RGB icc profile or you know the color space the data is in, pass its description as a null-terminated unicode string + // to AEGP_SetInSpecEmbeddedColorProfile, with color profile set to NULL. Doing this disables color management UI that allows user to affect + // profile choice in the application UI. + // + // If you are unpacking non-RGB data directly into working space (to get working space use AEGP_GetNewWorkingSpaceColorProfile), you are done. + // + // If you are unpacking non-RGB data into specific RGB color space, you must pass the profile describing this space to AEGP_SetInSpecAssignedColorProfile. + // Otherwise, your RGB data will be incorrectly interpreted as being in working space. + // + // Either color profile or profile description should be NULL in AEGP_SetInSpecEmbeddedColorProfile. You cannot use both. + SPAPI A_Err (*AEGP_SetInSpecEmbeddedColorProfile)( + AEIO_InSpecH inH, // << + AEGP_ConstColorProfileP color_profileP0, // << + const A_UTF16Char *profile_descP0); // << pointer to a null-terminated unicode string + + // Assign valid RGB profile to the footage + SPAPI A_Err (*AEGP_SetInSpecAssignedColorProfile)( + AEIO_InSpecH inH, // << + AEGP_ConstColorProfileP color_profileP); // << + + + SPAPI A_Err (*AEGP_GetInSpecNativeStartTime)( + AEIO_InSpecH inH, /* >> */ + A_Time *startTimeP); /* << */ + + SPAPI A_Err (*AEGP_SetInSpecNativeStartTime)( + AEIO_InSpecH inH, /* >> */ + const A_Time *startTimeP); /* >> */ + + SPAPI A_Err (*AEGP_ClearInSpecNativeStartTime)( + AEIO_InSpecH inH); /* >> */ + + SPAPI A_Err (*AEGP_GetInSpecNativeDisplayDropFrame)( + AEIO_InSpecH inH, /* >> */ + A_Boolean *displayDropFrameBP); /* << */ + + SPAPI A_Err (*AEGP_SetInSpecNativeDisplayDropFrame)( + AEIO_InSpecH inH, /* >> */ + A_Boolean displayDropFrameB); /* >> */ + + SPAPI A_Err (*AEGP_SetInSpecStillSequenceNativeFPS)( + AEIO_InSpecH inH, /* >> */ + A_Fixed native_still_seq_fps); /* >> */ + +} AEGP_IOInSuite5; + +#define kAEGPIOOutSuite "AEGP IO Out Suite" +#define kAEGPIOOutSuiteVersion5 8 /* frozen in AE 17.0 */ + +typedef struct AEGP_IOOutSuite5 { + SPAPI A_Err (*AEGP_GetOutSpecOptionsHandle)( + AEIO_OutSpecH outH, /* >> */ + void **optionsPPV); /* << */ + + SPAPI A_Err (*AEGP_SetOutSpecOptionsHandle)( + AEIO_OutSpecH outH, /* >> */ + void *optionsPV, /* >> */ + void **old_optionsPPVO); /* <> */ + + SPAPI A_Err (*AEGP_GetOutSpecFilePath)( + AEIO_OutSpecH outH, /* >> */ + AEGP_MemHandle *unicode_pathPH, // << handle of A_UTF16Char (contains null terminated UTF16 string); must be disposed with AEGP_FreeMemHandle + A_Boolean *file_reservedPB); /* << If the file is reserved, do not create the file. + Otherwise, multi-machine rendering can fail. + If true, an empty file has already been created. */ + + SPAPI A_Err (*AEGP_GetOutSpecFPS)( + AEIO_OutSpecH outH, /* >> */ + A_Fixed *native_fpsP); /* << */ + + SPAPI A_Err (*AEGP_SetOutSpecNativeFPS)( + AEIO_OutSpecH outH, /* >> */ + A_Fixed native_fpsP); /* >> */ + + SPAPI A_Err (*AEGP_GetOutSpecDepth)( + AEIO_OutSpecH outH, /* >> */ + A_short *depthPS); /* << */ + + SPAPI A_Err (*AEGP_SetOutSpecDepth)( + AEIO_OutSpecH outH, /* >> */ + A_short depthPS); /* >> */ + + SPAPI A_Err (*AEGP_GetOutSpecInterlaceLabel)( + AEIO_OutSpecH outH, /* >> */ + FIEL_Label *interlaceP); /* << */ + + SPAPI A_Err (*AEGP_SetOutSpecInterlaceLabel)( + AEIO_OutSpecH outH, /* >> */ + const FIEL_Label *interlaceP); /* >> */ + + SPAPI A_Err (*AEGP_GetOutSpecAlphaLabel)( + AEIO_OutSpecH outH, /* >> */ + AEIO_AlphaLabel *alphaP); /* << */ + + SPAPI A_Err (*AEGP_SetOutSpecAlphaLabel)( + AEIO_OutSpecH outH, /* >> */ + const AEIO_AlphaLabel *alphaP); /* >> */ + + SPAPI A_Err (*AEGP_GetOutSpecDuration)( + AEIO_OutSpecH outH, /* >> */ + A_Time *durationP); /* << */ + + SPAPI A_Err (*AEGP_SetOutSpecDuration)( + AEIO_OutSpecH outH, /* >> */ + const A_Time *durationP); /* >> */ + + SPAPI A_Err (*AEGP_GetOutSpecDimensions)( + AEIO_OutSpecH outH, /* >> */ + A_long *widthPL, /* << */ + A_long *heightPL); /* << */ + + SPAPI A_Err (*AEGP_GetOutSpecHSF)( + AEIO_OutSpecH outH, /* >> */ + A_Ratio *hsfP); /* << */ + + SPAPI A_Err (*AEGP_SetOutSpecHSF)( + AEIO_OutSpecH outH, /* >> */ + const A_Ratio *hsfP); /* >> */ + + SPAPI A_Err (*AEGP_GetOutSpecSoundRate)( + AEIO_OutSpecH outH, /* >> */ + A_FpLong *ratePF); /* << */ + + SPAPI A_Err (*AEGP_SetOutSpecSoundRate)( + AEIO_OutSpecH outH, /* >> */ + A_FpLong rateF); /* >> */ + + SPAPI A_Err (*AEGP_GetOutSpecSoundEncoding)( + AEIO_OutSpecH outH, /* >> */ + AEIO_SndEncoding *encodingP); /* << */ + + SPAPI A_Err (*AEGP_SetOutSpecSoundEncoding)( + AEIO_OutSpecH outH, /* >> */ + AEIO_SndEncoding encoding); /* >> */ + + SPAPI A_Err (*AEGP_GetOutSpecSoundSampleSize)( + AEIO_OutSpecH outH, /* >> */ + AEIO_SndSampleSize *bytes_per_sampleP);/* << */ + + SPAPI A_Err (*AEGP_SetOutSpecSoundSampleSize)( + AEIO_OutSpecH outH, /* >> */ + AEIO_SndSampleSize bytes_per_sample); /* >> */ + + SPAPI A_Err (*AEGP_GetOutSpecSoundChannels)( + AEIO_OutSpecH outH, /* >> */ + AEIO_SndChannels *num_channelsP); /* << */ + + SPAPI A_Err (*AEGP_SetOutSpecSoundChannels)( + AEIO_OutSpecH outH, /* >> */ + AEIO_SndChannels num_channels); /* >> */ + + SPAPI A_Err (*AEGP_GetOutSpecIsStill)( + AEIO_OutSpecH outH, /* >> */ + A_Boolean *is_stillPB); /* << */ + + SPAPI A_Err (*AEGP_GetOutSpecPosterTime)( + AEIO_OutSpecH outH, /* >> */ + A_Time *poster_timeP); /* << */ + + SPAPI A_Err (*AEGP_GetOutSpecStartFrame)( + AEIO_OutSpecH outH, /* >> */ + A_long *start_frameP); /* << */ + + SPAPI A_Err (*AEGP_GetOutSpecPullDown)( + AEIO_OutSpecH outH, /* >> */ + AEIO_Pulldown *pulldownP); /* << */ + + SPAPI A_Err (*AEGP_GetOutSpecIsMissing)( + AEIO_OutSpecH outH, /* >> */ + A_Boolean *missingPB); /* << */ + + // see if you need to embed outspec's color profile as an icc profile + SPAPI A_Err (*AEGP_GetOutSpecShouldEmbedICCProfile)( + AEIO_OutSpecH outH, // >> + A_Boolean *embedPB); // << + + // query outspec's color profile + SPAPI A_Err (*AEGP_GetNewOutSpecColorProfile)( + AEGP_PluginID aegp_plugin_id, // >> + AEIO_OutSpecH outH, // >> + AEGP_ColorProfileP *color_profilePP); // << output color space; caller must dispose with AEGP_DisposeColorProfile + + // Fails if rq_itemP is not found. + // This API would also fail if the outH is not a confirmed outH and is a copy. + // e.g. if the Output Module settings dialog is Open. + SPAPI A_Err (*AEGP_GetOutSpecOutputModule)( + AEIO_OutSpecH outH, /* >> */ + AEGP_RQItemRefH *rq_itemP, /* << */ + AEGP_OutputModuleRefH *om_refP); /* << */ + + SPAPI A_Err (*AEGP_GetOutSpecStartTime)( + AEIO_OutSpecH outH, /* >> */ + A_Time *outStartTimePT); /* << */ + + SPAPI A_Err (*AEGP_GetOutSpecFrameTime)( // relative to start time + AEIO_OutSpecH outH, /* >> */ + A_Time *outFrameTimePT); /* << */ + + SPAPI A_Err (*AEGP_GetOutSpecIsDropFrame)( + AEIO_OutSpecH outH, /* >> */ + A_Boolean *outIsDropFramePB); /* << */ + + +} AEGP_IOOutSuite5; + + + +/* This suite allows you to take advantage of going through AE Import Dialog + and being treated as a native format type +*/ + +typedef A_long AE_FIM_ImportFlavorRef; + +#define AE_FIM_ImportFlavorRef_NONE AEGP_Index_NONE + +#define AE_FIM_MAX_FLAVOR_NAME_LEN 63 + +enum { + AE_FIM_ImportFlag_NONE = 0x0, + AE_FIM_ImportFlag_COMP = 0x2 +}; +typedef A_long AE_FIM_ImportFlags; + +enum { + AE_FIM_SpecialAction_NONE = -1, + AE_FIM_SpecialAction_DRAG_N_DROP_FILE = 2 +}; +typedef A_long AE_FIM_SpecialAction; + + +typedef struct AE_FIM_RefconTag *AE_FIM_Refcon; + +typedef struct AE_FIM_ImportOptionsTag *AE_FIM_ImportOptions; + +// callbacks +typedef A_Err (*AE_FIM_ImportFileCB)( + const A_UTF16Char *pathZ, // >> null terminated unicode path with platform separators + AE_FIM_ImportOptions imp_options, /* >> opaque structure; in the future could be expanded with query functions*/ + AE_FIM_SpecialAction action, /* >> is it a special kind of import situation? */ + AEGP_ItemH itemH, /* >> meaning varies depending on AE_FIM_SpecialAction */ + // both for no special action and drag'n'drop it is + // a folder where imported item should go + AE_FIM_Refcon refcon); /* >> the client defines this and it is stored with import callbacks */ + + + +typedef A_Err (*AE_FIM_VerifyImportableCB)( + const A_UTF16Char *pathZ, // >> null terminated unicode path with platform separators + AE_FIM_Refcon refcon, /* >> the client defines this and it is stored with import callbacks */ + A_Boolean *importablePB); /* << */ + + +typedef struct { + AE_FIM_Refcon refcon; // points to whatever you want; stored and passed back with the callbacks + AE_FIM_ImportFileCB import_cb; + AE_FIM_VerifyImportableCB verify_cb; +} AE_FIM_ImportCallbacks; + +#define kAEGPFIMSuite "AEGP File Import Manager Suite" +#define kAEGPFIMSuiteVersion4 4 /* frozen in AE 17.0 */ + + +typedef struct { + SPAPI A_Err (*AEGP_RegisterImportFlavor)( + const A_char *nameZ, // format name you'd like to appear + // in AE's Import Dialog Format pop-up + // menu. + // Limited to AE_FIM_MAX_IMPORT_FLAVOR_NAME_LEN. + // Everything after that will be truncated. + AE_FIM_ImportFlavorRef *imp_refP); // On return it is set to a valid opaque ref. + // If error occured, it will be returned to + // the caller and ref will be set to a special + // value - AE_FIM_ImportFlavorRef_NONE. + + SPAPI A_Err (*AEGP_RegisterImportFlavorFileTypes)( + AE_FIM_ImportFlavorRef imp_ref, // Received from AEGP_RegisterImportFlavor + A_long num_filekindsL, // number of supported file types for this format + const AEIO_FileKind *kindsAP, // Array of supported file types for this format + A_long num_fileextsL, // number of supported file exts for this format + const AEIO_FileKind *extsAP); // Array of supported file exts for this format + + + SPAPI A_Err (*AEGP_RegisterImportFlavorImportCallbacks)( + AE_FIM_ImportFlavorRef imp_ref, // Received from AEGP_RegisterImportFlavor + AE_FIM_ImportFlags single_flag, // You can register callbacks only per single flag + // this also registers the flag with the import flavor + const AE_FIM_ImportCallbacks *imp_cbsP); // Callbacks your format installs per each flag + + // optionally call once from AE_FIM_ImportFileCB. This is used by the application when re-importing + // from the render queue and replacing an existing item. + SPAPI A_Err (*AEGP_SetImportedItem)( + AE_FIM_ImportOptions imp_options, /* <> */ + AEGP_ItemH imported_itemH); /* >> */ + + SPAPI A_Err (*AEGP_FileSequenceImportOptionsFromFIMImportOptions)( + const AE_FIM_ImportOptions imp_options, /* >> */ + AEGP_FileSequenceImportOptions *seq_import_optionsP); /* << */ + +} AEGP_FIMSuite4; + + + +/* --------------------------- Persistent Data Suite ------------------------------*/ +/* +The persist data suite allows you to store persistant data with the application. + +The data entries are accessed by SectionKey, ValueKey pairs. It is recommended +that plugins use their matchname as their SectionKey, or the prefix if using multiple +section names. THe available data types are void*, floating point numbers, and strings. + +Void* unstructured data allows you to store any kind of data. You must pass in a size in +bytes along with the data. + +String data supports the full 8 bit space, only 0x00 is reserved for string ending. +This makes them ideal for storing UTF-8 encoded strings, ISO 8859-1, and plain ASCII. +Both Section keys and Value keys are of this type. + +FpLongs are stored with 6 decimal places of precision. There is no provision +for specifying a different precision. + +Right now the only persistent data host is the application. + +*/ + +#define kAEGPPersistentDataSuite "AEGP Persistent Data Suite" +#define kAEGPPersistentDataSuiteVersion4 4 /* frozen in AE 12.0 */ + +typedef struct { + // get a handle of the application blob, + // modifying this will modify the application + SPAPI A_Err (*AEGP_GetApplicationBlob)( + AEGP_PersistentType blob_type, /* >> new in AE 12 */ + AEGP_PersistentBlobH *blobPH); /* << */ + + // section and value key management + SPAPI A_Err (*AEGP_GetNumSections)( + AEGP_PersistentBlobH blobH, /* >> */ + A_long *num_sectionPL); /* << */ + + SPAPI A_Err (*AEGP_GetSectionKeyByIndex)( + AEGP_PersistentBlobH blobH, /* >> */ + A_long section_index, /* >> */ + A_long max_section_size, /* >> */ + A_char *section_keyZ); /* << */ + + SPAPI A_Err (*AEGP_DoesKeyExist)( + AEGP_PersistentBlobH blobH, /* >> */ + const A_char *section_keyZ, /* >> */ + const A_char *value_keyZ, /* >> */ + A_Boolean *existsPB); /* << */ + + SPAPI A_Err (*AEGP_GetNumKeys)( + AEGP_PersistentBlobH blobH, /* >> */ + const A_char *section_keyZ, /* >> */ + A_long *num_keysPL); /* << */ + + SPAPI A_Err (*AEGP_GetValueKeyByIndex)( + AEGP_PersistentBlobH blobH, /* >> */ + const A_char *section_keyZ, /* >> */ + A_long key_index, /* >> */ + A_long max_key_size, /* >> */ + A_char *value_keyZ); /* << */ + + // data access and manipulation + + // For the entry points below, if a given key is not found, + // the default value is both written to the blobH and + // returned as the value; if no default is provided, a blank value will be written + // and returned + + SPAPI A_Err (*AEGP_GetDataHandle)( + AEGP_PluginID plugin_id, + AEGP_PersistentBlobH blobH, /* >> */ + const A_char *section_keyZ, /* >> */ + const A_char *value_keyZ, /* >> */ + AEGP_MemHandle defaultH0, /* >> never adopted, NULL means no default data */ + AEGP_MemHandle *valuePH); /* << newly allocated, owned by caller, NULL if would be zero sized handle */ + + SPAPI A_Err (*AEGP_GetData)( + AEGP_PersistentBlobH blobH, /* >> */ + const A_char *section_keyZ, /* >> */ + const A_char *value_keyZ, /* >> */ + A_u_long data_sizeLu, /* >> bufPV & default must be this big, if pref isn't then the default will be used */ + const void *defaultPV0, /* >> NULL means all zeros for default */ + void *bufPV); /* << */ + + SPAPI A_Err (*AEGP_GetString)( + AEGP_PersistentBlobH blobH, /* >> */ + const A_char *section_keyZ, /* >> */ + const A_char *value_keyZ, /* >> */ + const A_char *defaultZ0, /* >> NULL means '\0' is the default */ + A_u_long buf_sizeLu, /* >> size of buffer. Behavior dependent on actual_buf_sizeLu0 */ + A_char *bufZ, /* << will be "" if buf_size is too small */ + A_u_long *actual_buf_sizeLu0); /* << actual size needed to store the buffer (includes terminating NULL). Pass NULL for error reporting if size mismatch.*/ + + SPAPI A_Err (*AEGP_GetLong)( + AEGP_PersistentBlobH blobH, /* >> */ + const A_char *section_keyZ, /* >> */ + const A_char *value_keyZ, /* >> */ + A_long defaultL, /* >> */ + A_long *valuePL); /* << */ + + SPAPI A_Err (*AEGP_GetFpLong)( + AEGP_PersistentBlobH blobH, /* >> */ + const A_char *section_keyZ, /* >> */ + const A_char *value_keyZ, /* >> */ + A_FpLong defaultF, /* >> */ + A_FpLong *valuePF); /* << */ + + SPAPI A_Err (*AEGP_GetTime)( + AEGP_PersistentBlobH blobH, /* >> */ + const A_char *section_keyZ, /* >> */ + const A_char *value_keyZ, /* >> */ + const A_Time *defaultPT0, /* >> */ + A_Time *valuePT); /* << */ + + SPAPI A_Err (*AEGP_GetARGB)( + AEGP_PersistentBlobH blobH, /* >> */ + const A_char *section_keyZ, /* >> */ + const A_char *value_keyZ, /* >> */ + const PF_PixelFloat *defaultP0, /* >> */ + PF_PixelFloat *valueP); /* << */ + + // setters + SPAPI A_Err (*AEGP_SetDataHandle)( + AEGP_PersistentBlobH blobH, /* >> */ + const A_char *section_keyZ, /* >> */ + const A_char *value_keyZ, /* >> */ + const AEGP_MemHandle valueH); /* >> not adopted */ + + SPAPI A_Err (*AEGP_SetData)( + AEGP_PersistentBlobH blobH, /* >> */ + const A_char *section_keyZ, /* >> */ + const A_char *value_keyZ, /* >> */ + A_u_long data_sizeLu, /* >> */ + const void *dataPV); /* >> */ + + SPAPI A_Err (*AEGP_SetString)( + AEGP_PersistentBlobH blobH, /* >> */ + const A_char *section_keyZ, /* >> */ + const A_char *value_keyZ, /* >> */ + const A_char *strZ); /* >> */ + + SPAPI A_Err (*AEGP_SetLong)( + AEGP_PersistentBlobH blobH, /* >> */ + const A_char *section_keyZ, /* >> */ + const A_char *value_keyZ, /* >> */ + A_long valueL); /* >> */ + + SPAPI A_Err (*AEGP_SetFpLong)( + AEGP_PersistentBlobH blobH, /* >> */ + const A_char *section_keyZ, /* >> */ + const A_char *value_keyZ, /* >> */ + A_FpLong valueF); /* >> */ + + SPAPI A_Err (*AEGP_SetTime)( + AEGP_PersistentBlobH blobH, /* >> */ + const A_char *section_keyZ, /* >> */ + const A_char *value_keyZ, /* >> */ + const A_Time *valuePT); /* >> */ + + SPAPI A_Err (*AEGP_SetARGB)( + AEGP_PersistentBlobH blobH, /* >> */ + const A_char *section_keyZ, /* >> */ + const A_char *value_keyZ, /* >> */ + const PF_PixelFloat *valueP); /* >> */ + + SPAPI A_Err (*AEGP_DeleteEntry)( /* no error if entry not found */ + AEGP_PersistentBlobH blobH, /* >> */ + const A_char *section_keyZ, /* >> */ + const A_char *value_keyZ); /* >> */ + + SPAPI A_Err (*AEGP_GetPrefsDirectory)( + AEGP_MemHandle *unicode_pathPH); // << empty string if no file. handle of A_UTF16Char (contains null terminated UTF16 string); must be disposed with AEGP_FreeMemHandle + +} AEGP_PersistentDataSuite4; + + +// AEGP_CollectionSuite1 + +#define kAEGPCollectionSuite "AEGP Collection Suite" +#define kAEGPCollectionSuiteVersion2 2 /* frozen in AE 6.5 */ + +enum { + AEGP_CollectionItemType_NONE, + + AEGP_CollectionItemType_LAYER, + AEGP_CollectionItemType_MASK, + AEGP_CollectionItemType_EFFECT, + AEGP_CollectionItemType_STREAM, + AEGP_CollectionItemType_KEYFRAME, + AEGP_CollectionItemType_MASK_VERTEX, + AEGP_CollectionItemType_STREAMREF, + + AEGP_CollectionItemType_END, + AEGP_CollectionItemType_BEGIN = AEGP_CollectionItemType_LAYER +}; +typedef A_LegacyEnumType AEGP_CollectionItemType; + +typedef struct { + AEGP_LayerH layerH; /* comp derived from layerH */ +} AEGP_LayerCollectionItem; + +typedef struct { + AEGP_LayerH layerH; /* containing layer */ + AEGP_MaskIndex index; /* index to layer. */ +}AEGP_MaskCollectionItem; + +typedef struct { + AEGP_LayerH layerH; /* containing layer */ + AEGP_EffectIndex index; /* index to the effect */ +}AEGP_EffectCollectionItem; + +enum { + AEGP_StreamCollectionItemType_NONE, + AEGP_StreamCollectionItemType_LAYER, + AEGP_StreamCollectionItemType_MASK, + AEGP_StreamCollectionItemType_EFFECT, + AEGP_StreamCollectionItemType_END, + AEGP_StreamCollectionItemType_BEGIN = AEGP_StreamCollectionItemType_LAYER +}; +typedef A_LegacyEnumType AEGP_StreamCollectionItemType; + +typedef struct { + AEGP_MaskCollectionItem mask; + AEGP_MaskStream mask_stream; +} AEGP_MaskStreamCollectionItem; + +typedef struct { + AEGP_EffectCollectionItem effect; + A_long param_index; +} AEGP_EffectStreamCollectionItem; + +typedef struct { + AEGP_LayerH layerH; + AEGP_LayerStream layer_stream; +} AEGP_LayerStreamCollectionItem; + +typedef struct { + AEGP_StreamCollectionItemType type; + union { + AEGP_LayerStreamCollectionItem layer_stream; + AEGP_MaskStreamCollectionItem mask_stream; + AEGP_EffectStreamCollectionItem effect_stream; + } u; +}AEGP_StreamCollectionItem; + +typedef struct { + AEGP_MaskCollectionItem mask_sel; /* the mask must be selected for a vertex to be selected */ + AEGP_VertexIndex index; +}AEGP_MaskVertexCollectionItem; + +typedef struct { + AEGP_StreamCollectionItem stream_coll; + AEGP_KeyframeIndex index; +}AEGP_KeyframeCollectionItem; + +typedef struct { + AEGP_CollectionItemType type; + // the union is not used for AEGP_CollectionItemType_STREAMREF + union { + AEGP_LayerCollectionItem layer; + AEGP_MaskCollectionItem mask; + AEGP_EffectCollectionItem effect; + AEGP_StreamCollectionItem stream; + AEGP_MaskVertexCollectionItem mask_vertex; + AEGP_KeyframeCollectionItem keyframe; + } u; + + AEGP_StreamRefH stream_refH; // valid for all types +} AEGP_CollectionItemV2; + +typedef struct { + SPAPI A_Err (*AEGP_NewCollection)( /* dispose with dispose collection */ + AEGP_PluginID plugin_id, /* >> */ + AEGP_Collection2H *collectionPH); /* << */ + + SPAPI A_Err (*AEGP_DisposeCollection)( + AEGP_Collection2H collectionH); /* >> */ + + SPAPI A_Err (*AEGP_GetCollectionNumItems)( /* constant time */ + AEGP_Collection2H collectionH, /* >> */ + A_u_long *num_itemsPL); /* << */ + + SPAPI A_Err (*AEGP_GetCollectionItemByIndex)( /* constant time */ + AEGP_Collection2H collectionH, /* >> */ + A_u_long indexL, /* >> */ + AEGP_CollectionItemV2 *collection_itemP); /* << */ + + SPAPI A_Err (*AEGP_CollectionPushBack)( /* constant time */ + AEGP_Collection2H collectionH, /* <> */ + const AEGP_CollectionItemV2 *collection_itemP); /* >> NOTE: The passed AEGP_CollectionItemV2, as well as all the AEGP_StreamRefH's + it references, will be adopted by AE; DO NOT dispose of it! */ + + SPAPI A_Err (*AEGP_CollectionErase)( /* O(n) */ + AEGP_Collection2H collectionH, /* <> */ + A_u_long index_firstL, /* >> */ + A_u_long index_lastL); /* >> */ + +} AEGP_CollectionSuite2; + + +enum +{ + AEGP_WorldType_NONE, + AEGP_WorldType_8, + AEGP_WorldType_16, + AEGP_WorldType_32 +}; + +typedef A_long AEGP_WorldType; + + +#define kAEGPWorldSuite "AEGP World Suite" +#define kAEGPWorldSuiteVersion3 3 /* frozen in AE 7.0 */ + +typedef struct { + SPAPI A_Err (*AEGP_New)( + AEGP_PluginID plugin_id, /* >> */ + AEGP_WorldType type, /* >> */ + A_long widthL, /* >> */ + A_long heightL, /* >> */ + AEGP_WorldH *worldPH); /* << */ + + SPAPI A_Err (*AEGP_Dispose)( + AEGP_WorldH worldH); /* >> */ + + SPAPI A_Err (*AEGP_GetType)( + AEGP_WorldH worldH, /* >> */ + AEGP_WorldType *typeP); /* << */ + + SPAPI A_Err (*AEGP_GetSize)( + AEGP_WorldH worldH, /* >> */ + A_long *widthPL, /* << */ + A_long *heightPL); /* << */ + + SPAPI A_Err (*AEGP_GetRowBytes)( + AEGP_WorldH worldH, /* >> */ + A_u_long *row_bytesPL); /* << */ + + SPAPI A_Err (*AEGP_GetBaseAddr8)( + AEGP_WorldH worldH, /* >> error if the worldH is not AEGP_WorldType_8 */ + PF_Pixel8 **base_addrP); /* << */ + + SPAPI A_Err (*AEGP_GetBaseAddr16)( + AEGP_WorldH worldH, /* >> error if the worldH is not AEGP_WorldType_16 */ + PF_Pixel16 **base_addrP); /* << */ + + SPAPI A_Err (*AEGP_GetBaseAddr32)( + AEGP_WorldH worldH, /* >> error if the worldH is not AEGP_WorldType_32 */ + PF_PixelFloat **base_addrP); /* << */ + + SPAPI A_Err (*AEGP_FillOutPFEffectWorld)( /* Provided so you can use some of the PF routines with an AEGPWorld. Pass NULL as the ProgPtr to the PF routines.*/ + AEGP_WorldH worldH, /* >> */ + PF_EffectWorld *pf_worldP); /* << */ + + SPAPI A_Err (*AEGP_FastBlur)( + A_FpLong radiusF, /* >> */ + PF_ModeFlags mode, /* >> */ + PF_Quality quality, /* >> */ + AEGP_WorldH worldH); /* <> only for user allocated worlds; not for checked-out frames which are read only */ + + SPAPI A_Err (*AEGP_NewPlatformWorld)( + AEGP_PluginID plugin_id, /* >> */ + AEGP_WorldType type, /* >> */ + A_long widthL, /* >> */ + A_long heightL, /* >> */ + AEGP_PlatformWorldH *worldPH); /* << */ + + SPAPI A_Err (*AEGP_DisposePlatformWorld)( + AEGP_PlatformWorldH worldH); /* >> */ + + SPAPI A_Err (*AEGP_NewReferenceFromPlatformWorld)( + AEGP_PluginID plugin_id, /* >> */ + AEGP_PlatformWorldH platform_worldH, // >> + AEGP_WorldH *worldPH); /* << */ + + +} AEGP_WorldSuite3; + + +/* AEGP_RenderOptionsSuite + +*/ + +enum { + AEGP_MatteMode_STRAIGHT = 0, + AEGP_MatteMode_PREMUL_BLACK, + AEGP_MatteMode_PREMUL_BG_COLOR +}; +typedef A_long AEGP_MatteMode; + +enum { + AEGP_ChannelOrder_ARGB = 0, + AEGP_ChannelOrder_BGRA +}; +typedef A_char AEGP_ChannelOrder; + +enum { + AEGP_ItemQuality_DRAFT = 0, /* footage only. perform faster decode at expense of quality and draft-quality deinterlacing. */ + AEGP_ItemQuality_BEST /* footage only. perform full decode and resampled deinterlacing */ +}; +typedef A_char AEGP_ItemQuality; + +#define kAEGPRenderOptionsSuite "AEGP Render Options Suite" +#define kAEGPRenderOptionsSuiteVersion4 4 /* frozen in AE 10.5 */ + +typedef struct { + // fills out + // Time to 0 + // Time step to the frame duration + // field render to none + // depth is best resolution of item + SPAPI A_Err (*AEGP_NewFromItem)( + AEGP_PluginID plugin_id, /* >> */ + AEGP_ItemH itemH, /* >> */ + AEGP_RenderOptionsH *optionsPH); /* << */ + + SPAPI A_Err (*AEGP_Duplicate)( + AEGP_PluginID plugin_id, /* >> */ + AEGP_RenderOptionsH optionsH, /* >> */ + AEGP_RenderOptionsH *copyPH); /* << */ + + SPAPI A_Err (*AEGP_Dispose)( + AEGP_RenderOptionsH optionsH); /* >> */ + + SPAPI A_Err (*AEGP_SetTime)( /* the render time */ + AEGP_RenderOptionsH optionsH, /* <> */ + A_Time time); /* >> */ + + SPAPI A_Err (*AEGP_GetTime)( + AEGP_RenderOptionsH optionsH, /* >> */ + A_Time *timeP); /* << */ + + SPAPI A_Err (*AEGP_SetTimeStep)( /* duration of the frame; important for motion blur. */ + AEGP_RenderOptionsH optionsH, /* <> */ + A_Time time_step); /* >> */ + + SPAPI A_Err (*AEGP_GetTimeStep)( + AEGP_RenderOptionsH optionsH, /* >> */ + A_Time *timePT); /* << */ + + SPAPI A_Err (*AEGP_SetFieldRender)( /* How fields are to be handled. */ + AEGP_RenderOptionsH optionsH, /* <> */ + PF_Field field_render); /* >> */ + + SPAPI A_Err (*AEGP_GetFieldRender)( + AEGP_RenderOptionsH optionsH, /* >> */ + PF_Field *field_renderP); /* << */ + + + SPAPI A_Err (*AEGP_SetWorldType)( + AEGP_RenderOptionsH optionsH, /* <> */ + AEGP_WorldType type); /* >> */ + + SPAPI A_Err (*AEGP_GetWorldType)( + AEGP_RenderOptionsH optionsH, /* >> */ + AEGP_WorldType *typeP); /* << */ + + + // 1 == 100% + // 2 == 50% + // ... + SPAPI A_Err (*AEGP_SetDownsampleFactor)( + AEGP_RenderOptionsH optionsH, /* <> */ + A_short x, /* >> */ + A_short y); /* >> */ + + SPAPI A_Err (*AEGP_GetDownsampleFactor)( + AEGP_RenderOptionsH optionsH, /* >> */ + A_short *xP, /* >> */ + A_short *yP); /* << */ + + SPAPI A_Err (*AEGP_SetRegionOfInterest)( + AEGP_RenderOptionsH optionsH, /* <> */ + const A_LRect *roiP); /* >> {0,0,0,0} for all*/ + + SPAPI A_Err (*AEGP_GetRegionOfInterest)( + AEGP_RenderOptionsH optionsH, /* >> */ + A_LRect *roiP); /* << */ + + SPAPI A_Err (*AEGP_SetMatteMode)( + AEGP_RenderOptionsH optionsH, /* <> */ + AEGP_MatteMode mode); /* >> */ + + SPAPI A_Err (*AEGP_GetMatteMode)( + AEGP_RenderOptionsH optionsH, /* >> */ + AEGP_MatteMode *modeP); /* << */ + + SPAPI A_Err (*AEGP_SetChannelOrder)( + AEGP_RenderOptionsH optionsH, /* <> */ + AEGP_ChannelOrder channel_order); /* >> */ + + SPAPI A_Err (*AEGP_GetChannelOrder)( + AEGP_RenderOptionsH optionsH, /* >> */ + AEGP_ChannelOrder *channelP); /* << */ + + SPAPI A_Err (*AEGP_GetRenderGuideLayers)( + AEGP_RenderOptionsH optionsH, /* >> */ + A_Boolean *will_renderPB); /* << */ + + SPAPI A_Err (*AEGP_SetRenderGuideLayers)( + AEGP_RenderOptionsH optionsH, /* >> */ + A_Boolean render_themB); /* >> */ + + /* AEGP_ItemType_FOOTAGE can be decoded at different with different + quality levels. Ignore for other AEGP_ItemType + */ + + SPAPI A_Err (*AEGP_GetRenderQuality)( + AEGP_RenderOptionsH optionsH, /* >> */ + AEGP_ItemQuality *qualityP); /* << */ + + SPAPI A_Err (*AEGP_SetRenderQuality)( + AEGP_RenderOptionsH optionsH, /* >> */ + AEGP_ItemQuality quality); /* >> */ +} AEGP_RenderOptionsSuite4; + + +#define kAEGPLayerRenderOptionsSuite "AEGP Layer Render Options Suite" +#define kAEGPLayerRenderOptionsSuiteVersion2 2 /* frozen in 13.5 */ + +typedef struct { + // optionsPH must be disposed by calling code + // + // fills out + // Time to the layer's current time + // Time step to layer's frame duration + // ROI to the layer's nominal bounds + // EffectsToRender to "all" + SPAPI A_Err (*AEGP_NewFromLayer)( + AEGP_PluginID plugin_id, /* >> */ + AEGP_LayerH layerH, /* >> */ + AEGP_LayerRenderOptionsH *optionsPH); /* << */ + + // optionsPH must be disposed by calling code + // like AEGP_NewFromLayer, but sets EffectsToRender to be the index fof effectH + SPAPI A_Err (*AEGP_NewFromUpstreamOfEffect)( + AEGP_PluginID plugin_id, /* >> */ + AEGP_EffectRefH effectH, /* >> */ + AEGP_LayerRenderOptionsH *optionsPH); /* << */ + + // optionsPH must be disposed by calling code + // like AEGP_NewFromLayer, but sets EffectsToRender to include the effect output + // THIS MAY ONLY BE CALLED FROM THE UI THREAD + SPAPI A_Err (*AEGP_NewFromDownstreamOfEffect)( + AEGP_PluginID plugin_id, /* >> */ + AEGP_EffectRefH effectH, /* >> */ + AEGP_LayerRenderOptionsH *optionsPH); /* << */ + + // copyPH must be disposed by calling code + SPAPI A_Err (*AEGP_Duplicate)( + AEGP_PluginID plugin_id, /* >> */ + AEGP_LayerRenderOptionsH optionsH, /* >> */ + AEGP_LayerRenderOptionsH *copyPH); /* << */ + + SPAPI A_Err (*AEGP_Dispose)( + AEGP_LayerRenderOptionsH optionsH); /* >> */ + + SPAPI A_Err (*AEGP_SetTime)( /* the render time */ + AEGP_LayerRenderOptionsH optionsH, /* <> */ + A_Time time); /* >> */ + + SPAPI A_Err (*AEGP_GetTime)( + AEGP_LayerRenderOptionsH optionsH, /* >> */ + A_Time *timeP); /* << */ + + SPAPI A_Err (*AEGP_SetTimeStep)( /* duration of the frame; important for motion blur. */ + AEGP_LayerRenderOptionsH optionsH, /* <> */ + A_Time time_step); /* >> */ + + SPAPI A_Err (*AEGP_GetTimeStep)( + AEGP_LayerRenderOptionsH optionsH, /* >> */ + A_Time *timePT); /* << */ + + SPAPI A_Err (*AEGP_SetWorldType)( + AEGP_LayerRenderOptionsH optionsH, /* <> */ + AEGP_WorldType type); /* >> */ + + SPAPI A_Err (*AEGP_GetWorldType)( + AEGP_LayerRenderOptionsH optionsH, /* >> */ + AEGP_WorldType *typeP); /* << */ + + // 1 == 100% + // 2 == 50% + // ... + SPAPI A_Err (*AEGP_SetDownsampleFactor)( + AEGP_LayerRenderOptionsH optionsH, /* <> */ + A_short x, /* >> */ + A_short y); /* >> */ + + SPAPI A_Err (*AEGP_GetDownsampleFactor)( + AEGP_LayerRenderOptionsH optionsH, /* >> */ + A_short *xP, /* >> */ + A_short *yP); /* << */ + + SPAPI A_Err (*AEGP_SetMatteMode)( + AEGP_LayerRenderOptionsH optionsH, /* <> */ + AEGP_MatteMode mode); /* >> */ + + SPAPI A_Err (*AEGP_GetMatteMode)( + AEGP_LayerRenderOptionsH optionsH, /* >> */ + AEGP_MatteMode *modeP); /* << */ +} AEGP_LayerRenderOptionsSuite2; + + +#define kAEGPRenderSuite "AEGP Render Suite" +#define kAEGPRenderSuiteVersion5 8 /* frozen in 13.5 */ + +typedef A_u_longlong AEGP_AsyncRequestId; + +typedef A_Err (*AEGP_RenderSuiteCheckForCancel)( + void *refcon, + A_Boolean *cancelPB); + +typedef A_Err (*AEGP_AsyncFrameReadyCallback)( + AEGP_AsyncRequestId request_id, // this will be the AEGP_AsyncRequestId that was returned from AEGP_RenderAndCheckoutLayerFrame_Async + A_Boolean was_canceled, // will be set to true if this request was canceled via a call to AEGP_CancelAsyncRequest + A_Err error, // will be set to A_Err_NONE (0) if successful + AEGP_FrameReceiptH receiptH, // frame data (only if successful) + AEGP_AsyncFrameRequestRefcon refconP0); // this is the AEGP_AsyncFrameRequestRefcon that was (optionally) passed in to AEGP_RenderAndCheckoutLayerFrame_Async + +typedef struct { + // IMPORTANT: use of this call on the UI thread should be considered DEPRECATED except in a very narrow use case: + // a) the plugin requires this frame to make database change (e.g. an auto color button on an effect) + // b) the user explicitly requested this operation (e.g. this is not a passive redraw of UI because something else changed) + // This is to avoid having poor interactivity while the user is doing other unrelated things. + // Asynchronous APIs should be used on the UI thread except in this specific case + // On the UI thread, if the frame takes longer than 2 seconds, a progress dialog will automatically open to allow the user to cancel + // On a render thread, these calls will work as normal with no progress dialog + + // See IMPORTANT note above about using this synchronous call on the UI thread which is considered DEPRECATED behavior + SPAPI A_Err (*AEGP_RenderAndCheckoutFrame)( + AEGP_RenderOptionsH optionsH, /* >> */ + AEGP_RenderSuiteCheckForCancel cancel_functionP0, /* >> optional*/ + AEGP_CancelRefcon cancel_function_refconP0, /* >> optional */ + AEGP_FrameReceiptH *receiptPH); /* << check in using AEGP_CheckinFrame to release memory */ + + // render_plain_layer_frameB was confusing and is not the design we want going forward + // eventually this will be replaced with new RenderOptions calls. Until that is available, this will behave as if render_plain_layer_frameB is "false" + // (upstream effect render). If the "true" behavior for adjustment layer mask is desired, see kAEGPRenderSuiteVersion4 that still has this flag + + // See IMPORTANT note above about using this synchronous call on the UI thread which is considered DEPRECATED behavior + SPAPI A_Err (*AEGP_RenderAndCheckoutLayerFrame)( + AEGP_LayerRenderOptionsH optionsH, /* >> */ + AEGP_RenderSuiteCheckForCancel cancel_functionP0, /* >> optional*/ + AEGP_CancelRefcon cancel_function_refconP0, /* >> optional */ + AEGP_FrameReceiptH *receiptPH); /* << check in using AEGP_CheckinFrame to release memory */ + + SPAPI A_Err (*AEGP_RenderAndCheckoutLayerFrame_Async)( + AEGP_LayerRenderOptionsH optionsH, /* >> */ + AEGP_AsyncFrameReadyCallback callback, /* >> this will be called when the frame is ready (guaranteed to be called unless AE is shutting down) */ + AEGP_AsyncFrameRequestRefcon request_completion_refconP0, /* >> optional. if included, it will be passed into the above callback */ + AEGP_AsyncRequestId *asyncRequestIdP); /* << Id associated with frame request. Can be used to cancel early */ + + SPAPI A_Err (*AEGP_CancelAsyncRequest)( + AEGP_AsyncRequestId asyncRequestId); /* >> */ + + SPAPI A_Err (*AEGP_CheckinFrame)( + AEGP_FrameReceiptH receiptH); /* >> */ + + /* This returns a read only world that is not-owned by the plugin. + Call CheckinFrame to release the world when you are done reading from it. + */ + + SPAPI A_Err (*AEGP_GetReceiptWorld)( + AEGP_FrameReceiptH receiptH, /* >> */ + AEGP_WorldH *worldPH); /* << */ + + SPAPI A_Err (*AEGP_GetRenderedRegion)( + AEGP_FrameReceiptH receiptH, /* >> */ + A_LRect *rendered_regionP); /* << */ + + SPAPI A_Err (*AEGP_IsRenderedFrameSufficient)( + AEGP_RenderOptionsH rendered_optionsH, /* >> */ + AEGP_RenderOptionsH proposed_optionsH, /* >> */ + A_Boolean *rendered_is_sufficientPB); /* << */ + + // See IMPORTANT note above about using this synchronous call on the UI thread which is considered DEPRECATED behavior + SPAPI A_Err (*AEGP_RenderNewItemSoundData)( /* Works on Compositions and Footage items. */ + AEGP_ItemH itemH, /* >> */ + const A_Time *start_timePT, /* >> */ + const A_Time *durationPT, /* >> */ + const AEGP_SoundDataFormat *sound_formatP, /* >> */ + AEGP_RenderSuiteCheckForCancel cancel_functionP0, /* >> optional*/ + AEGP_CancelRefcon cancel_function_refconP0, /* >> optional */ + AEGP_SoundDataH *new_sound_dataPH); /* << AEGP_SoundDataH must be disposed. Returns NULL if no audio */ + + + // returns the current timestamp of the project.this is increased any time something is touched in the project + // that affects rendering + SPAPI A_Err (*AEGP_GetCurrentTimestamp)( + AEGP_TimeStamp * time_stampP); // out + + // Lets you know if the video of the item has changed since the input time stamp. + // Is not affected by audio. + SPAPI A_Err (*AEGP_HasItemChangedSinceTimestamp)(AEGP_ItemH itemH, // in + const A_Time * start_timeP, // in + const A_Time* durationP, //in + const AEGP_TimeStamp * time_stampP, //in + A_Boolean * item_has_changedPB); //out + + // checks whether this frame would be worth rendering externally and + // checking in to the cache. a speculative renderer should check this twice: + // (1) before sending the frame out to render + // (2) when it is complete, before calling AEGP_NewPlatformWorld and checking in. + // (don't forget to call AEGP_HasItemChangedSinceTimestamp also!) + SPAPI A_Err (*AEGP_IsItemWorthwhileToRender)( AEGP_RenderOptionsH roH, // in + const AEGP_TimeStamp* time_stampP, // in + A_Boolean *worthwhile_to_renderPB); // out + + // ticks_to_render is the approximate amount of time needed to render the frame + // on this machine. it is 60Hz. + SPAPI A_Err (*AEGP_CheckinRenderedFrame)( AEGP_RenderOptionsH roH, // in + const AEGP_TimeStamp* time_stampP, // in + A_u_long ticks_to_renderL, // in + AEGP_PlatformWorldH imageH); // in (adopted) + + SPAPI A_Err (*AEGP_GetReceiptGuid) (AEGP_FrameReceiptH receiptH, // in + AEGP_MemHandle *guidMH); // out, must be disposed +} AEGP_RenderSuite5; + + + +// AsyncManager render suite. For render requests that are managed by AE rather than explicitly by plugin callbacks (as in some cases in AEGP_RenderSuite5+) +// As of 13.5 the only way to get an AsyncManager is via PF_GetContextAsyncManager in PF_EffectCustomUISuite2. (This Async Manager is PF_Event_DRAW specific +// but there may be others in the future) + +#define kAEGPRenderAsyncManagerSuite "AEGP Render Asyc Manager Suite" +#define kAEGPRenderAsyncManagerSuiteVersion1 1 /* frozen in 13.5 */ + + +typedef struct { + + // An AsyncManager automatically handles possibly multiple async render requests + // The first use of this in for async requests in CUSTOM_UI of PF_EventDRAW. See PF_OutFlags2_CUSTOM_UI_ASYNC_MANAGER + // The purpose_id is a unique constant number that helps the manager understand when it can automatically cancel + // old requests (because they have the same purpose id and the RO has changed) + + SPAPI A_Err (*AEGP_CheckoutOrRender_ItemFrame_AsyncManager)( PF_AsyncManagerP async_managerP, // >> the async manager to ask for the render + A_u_long purpose_id, // >> a unique id to identify requests for the same usage (e.g. to hint cancellation of old) + AEGP_RenderOptionsH ro, // >> the description of the item frame to render + AEGP_FrameReceiptH *out_receiptPH ); // << on success, the rendered frame. Can succeed and have no pixels (no world) + + SPAPI A_Err (*AEGP_CheckoutOrRender_LayerFrame_AsyncManager)( PF_AsyncManagerP async_managerP, // >> the async manager to ask for the render + A_u_long purpose_id, // >> a unique id to identify requests for the same usage (e.g. to hint cancellation of old) + AEGP_LayerRenderOptionsH lro, // >> the description of the layer frame to render + AEGP_FrameReceiptH *out_receiptPH ); // << on success, the rendered frame. Can succeed and have no pixels (no world) + + + +} AEGP_RenderAsyncManagerSuite1; + + + + +#define kAEGPTrackerSuite "AEGP Tracker Suite" +#define kAEGPTrackerSuiteVersion1 1 /* frozen in AE 6.0 */ + + +typedef struct { + SPAPI A_Err (*AEGP_GetNumFeatures)( + const PT_TrackingContextPtr contextP, /* >> */ + A_long *num_featuresPL); /* << */ + + SPAPI A_Err (*AEGP_GetFeatureRegionByIndex)( + const PT_TrackingContextPtr contextP, /* >> */ + PT_Index index, /* >> */ + A_FloatRect *rectP); /* << */ + + SPAPI A_Err (*AEGP_GetSearchRegionByIndex)( + const PT_TrackingContextPtr contextP, /* >> */ + PT_Index index, /* >> */ + A_FloatRect *rectP); /* << */ + + SPAPI A_Err (*AEGP_GetFeatureWorldByIndex)( + const PT_TrackingContextPtr contextP, /* >> */ + PT_Index index, /* >> */ + AEGP_WorldH *feature_worldPH); /* << */ + + SPAPI A_Err (*AEGP_GetFrameWorld)( + const PT_TrackingContextPtr contextP, /* >> */ + AEGP_WorldH *frame_worldPH); /* << */ + + SPAPI A_Err (*AEGP_GetTrackerSourceDimensions)( + const PT_TrackingContextPtr contextP, /* >> */ + A_long *widthPL, /* << */ + A_long *heightPL); + + SPAPI A_Err (*AEGP_SetFeatureRegionByIndex)( + const PT_TrackingContextPtr contextP, /* >> */ + PT_Index index, /* >> */ + const A_FloatRect *rectP); /* >> */ + + SPAPI A_Err (*AEGP_SetAccuracyByIndex)( + const PT_TrackingContextPtr contextP, /* >> */ + PT_Index index, /* >> */ + A_FpLong accuracyF); /* >> */ + + SPAPI A_Err (*AEGP_ShouldTrackFeature)( + const PT_TrackingContextPtr contextP, /* >> */ + PT_Index index, /* >> */ + A_Boolean *trackPB); /* << */ + +} AEGP_TrackerSuite1; + + +#define kAEGPTrackerUtilitySuite "AEGP Tracker Utility Suite" +#define kAEGPTrackerUtilitySuiteVersion1 1 /* frozen in AE 6.0 */ + +typedef struct { + SPAPI A_Err (*AEGP_HasUserCancelled)( + const PT_TrackingContextPtr contextP, /* >> */ + A_Boolean *user_cancelledPB); /* << */ + + SPAPI A_Err (*AEGP_GetTrackerFromTrackerInstance)( + const PT_TrackerInstancePtr tracker_instanceP, /* >> */ + PT_TrackerPtr *trackerPP); /* << */ + + SPAPI A_Err (*AEGP_GetTrackerInstanceFromTrackingContext)( + const PT_TrackingContextPtr contextP, /* >> */ + PT_TrackerInstancePtr *tracker_instancePP); /* << */ + + SPAPI A_Err (*AEGP_GetGlobalData)( + const PT_TrackerPtr trackerP, /* >> */ + AEGP_MemHandle *global_dataPH); /* << */ + + SPAPI A_Err (*AEGP_GetInstanceData)( + const PT_TrackerInstancePtr tracker_instanceP, /* >> */ + AEGP_MemHandle *instance_dataPH); /* << */ // currently has to be flat (no handles inside the handle) + + SPAPI A_Err (*AEGP_GetTrackData)( + const PT_TrackingContextPtr contextP, /* >> */ + AEGP_MemHandle *track_dataPH); /* << */ +} AEGP_TrackerUtilitySuite1; + + + +#define kAEGPRenderQueueMonitorSuite "AEGP RenderQueue Monitor Suite" +#define kAEGPRenderQueueMonitorSuiteVersion1 1 /* frozen AE 11.0 */ + +typedef struct _AEGP_RQM_Refcon *AEGP_RQM_Refcon; +typedef A_u_longlong AEGP_RQM_SessionId; +typedef A_u_longlong AEGP_RQM_ItemId; +typedef A_u_longlong AEGP_RQM_FrameId; + +typedef enum +{ + AEGP_RQM_FinishedStatus_UNKNOWN, + AEGP_RQM_FinishedStatus_SUCCEEDED, + AEGP_RQM_FinishedStatus_ABORTED, + AEGP_RQM_FinishedStatus_ERRED +} AEGP_RQM_FinishedStatus; + +typedef struct _AEGP_RQM_BasicData { + const struct SPBasicSuite *pica_basicP; + A_long aegp_plug_id; + AEGP_RQM_Refcon aegp_refconPV; +} AEGP_RQM_BasicData; + +typedef struct _AEGP_RQM_FunctionBlock1 { + A_Err (*AEGP_RQM_RenderJobStarted)(AEGP_RQM_BasicData *basic_dataP, AEGP_RQM_SessionId jobid); + A_Err (*AEGP_RQM_RenderJobEnded)(AEGP_RQM_BasicData *basic_dataP, AEGP_RQM_SessionId jobid); + A_Err (*AEGP_RQM_RenderJobItemStarted)(AEGP_RQM_BasicData *basic_dataP, AEGP_RQM_SessionId jobid, AEGP_RQM_ItemId itemid); + A_Err (*AEGP_RQM_RenderJobItemUpdated)(AEGP_RQM_BasicData *basic_dataP, AEGP_RQM_SessionId jobid, AEGP_RQM_ItemId itemid, AEGP_RQM_FrameId frameid); + A_Err (*AEGP_RQM_RenderJobItemEnded)(AEGP_RQM_BasicData *basic_dataP, AEGP_RQM_SessionId jobid, AEGP_RQM_ItemId itemid, AEGP_RQM_FinishedStatus fstatus); + A_Err (*AEGP_RQM_RenderJobItemReportLog)(AEGP_RQM_BasicData *basic_dataP, AEGP_RQM_SessionId jobid, AEGP_RQM_ItemId itemid, A_Boolean isError, AEGP_MemHandle logbuf); +} AEGP_RQM_FunctionBlock1; + +typedef struct AEGP_RenderQueueMonitorSuite1 { + + SPAPI A_Err (*AEGP_RegisterListener) ( + AEGP_PluginID aegp_plugin_id, /* >> */ + AEGP_RQM_Refcon aegp_refconP, /* >> */ + const AEGP_RQM_FunctionBlock1 * fcn_blockP); /* >> */ + + SPAPI A_Err (*AEGP_DeregisterListener) ( + AEGP_PluginID aegp_plugin_id, /* >> */ + AEGP_RQM_Refcon aegp_refconP); /* >> */ + + SPAPI A_Err (*AEGP_GetProjectName)( + AEGP_RQM_SessionId sessid, // >> + AEGP_MemHandle *utf_project_namePH0); // << handle of A_UTF16Char (contains null terminated UTF16 string); must be disposed with AEGP_FreeMemHandle + + SPAPI A_Err (*AEGP_GetAppVersion)( + AEGP_RQM_SessionId sessid, // >> + AEGP_MemHandle *utf_app_versionPH0); // << handle of A_UTF16Char (contains null terminated UTF16 string); must be disposed with AEGP_FreeMemHandle + + SPAPI A_Err (*AEGP_GetNumJobItems)( + AEGP_RQM_SessionId sessid, // >> + A_long *num_jobitemsPL); // << + + SPAPI A_Err (*AEGP_GetJobItemID)( + AEGP_RQM_SessionId sessid, // >> + A_long jobItemIndex, // >> + AEGP_RQM_ItemId *jobItemID); // << + + SPAPI A_Err (*AEGP_GetNumJobItemRenderSettings)( + AEGP_RQM_SessionId sessid, // >> + AEGP_RQM_ItemId itemid, // >> + A_long *num_settingsPL); // << + + SPAPI A_Err (*AEGP_GetJobItemRenderSetting)( + AEGP_RQM_SessionId sessid, // >> + AEGP_RQM_ItemId itemid, // >> + A_long settingIndex, // >> + AEGP_MemHandle *utf_setting_namePH0, // << handle of A_UTF16Char (contains null terminated UTF16 string); must be disposed with AEGP_FreeMemHandle + AEGP_MemHandle *utf_setting_valuePH0); // << handle of A_UTF16Char (contains null terminated UTF16 string); must be disposed with AEGP_FreeMemHandle + + SPAPI A_Err (*AEGP_GetNumJobItemOutputModules)( + AEGP_RQM_SessionId sessid, // >> + AEGP_RQM_ItemId itemid, // >> + A_long *num_outputmodulesPL); // << + + SPAPI A_Err (*AEGP_GetNumJobItemOutputModuleSettings)( + AEGP_RQM_SessionId sessid, // >> + AEGP_RQM_ItemId itemid, // >> + A_long outputModuleIndex, // >> + A_long *num_settingsPL); // << + + SPAPI A_Err (*AEGP_GetJobItemOutputModuleSetting)( + AEGP_RQM_SessionId sessid, // >> + AEGP_RQM_ItemId itemid, // >> + A_long outputModuleIndex, // >> + A_long settingIndex, // >> + AEGP_MemHandle *utf_setting_namePH0, // << handle of A_UTF16Char (contains null terminated UTF16 string); must be disposed with AEGP_FreeMemHandle + AEGP_MemHandle *utf_setting_valuePH0); // << handle of A_UTF16Char (contains null terminated UTF16 string); must be disposed with AEGP_FreeMemHandle + + SPAPI A_Err (*AEGP_GetNumJobItemOutputModuleWarnings)( + AEGP_RQM_SessionId sessid, // >> + AEGP_RQM_ItemId itemid, // >> + A_long outputModuleIndex, // >> + A_long *num_warningsPL); // << + + SPAPI A_Err (*AEGP_GetJobItemOutputModuleWarning)( + AEGP_RQM_SessionId sessid, // >> + AEGP_RQM_ItemId itemid, // >> + A_long outputModuleIndex, // >> + A_long warningIndex, // >> + AEGP_MemHandle *utf_warning_valuePH0); // << handle of A_UTF16Char (contains null terminated UTF16 string); must be disposed with AEGP_FreeMemHandle + + SPAPI A_Err (*AEGP_GetNumJobItemFrameProperties)( + AEGP_RQM_SessionId sessid, // >> + AEGP_RQM_ItemId itemid, // >> + AEGP_RQM_FrameId frameid, // >> + A_long *num_propertiesPL); // << + + SPAPI A_Err (*AEGP_GetJobItemFrameProperty)( + AEGP_RQM_SessionId sessid, // >> + AEGP_RQM_ItemId itemid, // >> + AEGP_RQM_FrameId frameid, // >> + A_long propertyIndex, // >> + AEGP_MemHandle *utf_property_namePH0, // << handle of A_UTF16Char (contains null terminated UTF16 string); must be disposed with AEGP_FreeMemHandle + AEGP_MemHandle *utf_property_valuePH0);// << handle of A_UTF16Char (contains null terminated UTF16 string); must be disposed with AEGP_FreeMemHandle + + SPAPI A_Err (*AEGP_GetNumJobItemOutputModuleProperties)( + AEGP_RQM_SessionId sessid, // >> + AEGP_RQM_ItemId itemid, // >> + A_long outputModuleIndex, // >> + A_long *num_propertiesPL); // << + + SPAPI A_Err (*AEGP_GetJobItemOutputModuleProperty)( + AEGP_RQM_SessionId sessid, // >> + AEGP_RQM_ItemId itemid, // >> + A_long outputModuleIndex, // >> + A_long propertyIndex, // >> + AEGP_MemHandle *utf_property_namePH0, // << handle of A_UTF16Char (contains null terminated UTF16 string); must be disposed with AEGP_FreeMemHandle + AEGP_MemHandle *utf_property_valuePH0);// << handle of A_UTF16Char (contains null terminated UTF16 string); must be disposed with AEGP_FreeMemHandle + + SPAPI A_Err (*AEGP_GetJobItemFrameThumbnail)( + AEGP_RQM_SessionId sessid, // >> + AEGP_RQM_ItemId itemid, // >> + AEGP_RQM_FrameId frameid, // >> + A_long *widthPL, // <> pass in the maximum width, returns the actual width + A_long *heightPL, // <> pass in the maximum height, returns the actual height + AEGP_MemHandle *thumbnailPH0); // << handle of an image memory block in JPEG format + +} AEGP_RenderQueueMonitorSuite1; + + + +/* -------------------------------------------------------------------- */ + +typedef const void *PF_ConstPtr; +typedef const PF_ConstPtr *PF_ConstHandle; + +#define kPFEffectSequenceDataSuite "PF Effect Sequence Data Suite" +#define kPFEffectSequenceDataSuiteVersion1 1 /* frozen in 18.2 */ + +typedef struct PF_EffectSequenceDataSuite1 { + + SPAPI PF_Err (*PF_GetConstSequenceData)( PF_ProgPtr effect_ref, + PF_ConstHandle *sequence_data); /* >> */ + +} PF_EffectSequenceDataSuite1; + + + + +#include + + +/****************************************************************/ +/* include old versions of the suites */ +/****************************************************************/ +#include + +#endif diff --git a/External/AE SDK/Headers/AE_GeneralPlugOld.h b/External/AE SDK/Headers/AE_GeneralPlugOld.h new file mode 100644 index 00000000..68bb8620 --- /dev/null +++ b/External/AE SDK/Headers/AE_GeneralPlugOld.h @@ -0,0 +1,9125 @@ +/*******************************************************************/ +/* */ +/* ADOBE CONFIDENTIAL */ +/* _ _ _ _ _ _ _ _ _ _ _ _ _ */ +/* */ +/* Copyright 2007 Adobe Systems Incorporated */ +/* All Rights Reserved. */ +/* */ +/* NOTICE: All information contained herein is, and remains the */ +/* property of Adobe Systems Incorporated and its suppliers, if */ +/* any. The intellectual and technical concepts contained */ +/* herein are proprietary to Adobe Systems Incorporated and its */ +/* suppliers and may be covered by U.S. and Foreign Patents, */ +/* patents in process, and are protected by trade secret or */ +/* copyright law. Dissemination of this information or */ +/* reproduction of this material is strictly forbidden unless */ +/* prior written permission is obtained from Adobe Systems */ +/* Incorporated. */ +/* */ +/*******************************************************************/ + +/*******************************************************************/ +/* */ +/* this file contains the old or deprecated versions of the suites */ +/* listed in AE_GeneralPlug.h */ +/*******************************************************************/ + + +#include + +typedef struct { // note: unused values are still stored in settings and used when cycling through + // the 3 types using cmd/ctrl-click on timecode + AEGP_TimeDisplayType time_display_type; + A_char timebaseC; // only used for AEGP_TimeDisplayType_TIMECODE, 1 to 100 + A_Boolean non_drop_30B; // only used for AEGP_TimeDisplayType_TIMECODE, + // when timebaseC == 30 && item framerate == 29.97, use drop frame or non-drop? + A_char frames_per_footC; // only used for AEGP_TimeDisplayType_FEET_AND_FRAMES + A_long starting_frameL; // usually 0 or 1, not used for AEGP_TimeDisplayType_TIMECODE +} AEGP_TimeDisplay; + +/** + ** Canvas Suite + ** Used by artisans to render layers + **/ + +#define kAEGPCanvasSuiteVersion1 4 /* frozen in AE 5.0 */ + +typedef struct AEGP_CanvasSuite1 { + + SPAPI A_Err (*AEGP_GetCompToRender)( + PR_RenderContextH render_contextH, /* >> */ + AEGP_CompH *compPH); /* << */ + + SPAPI A_Err (*AEGP_GetNumLayersToRender)( + const PR_RenderContextH render_contextH, + A_long *num_to_renderPL); + + + SPAPI A_Err (*AEGP_GetNthLayerContextToRender)( + const PR_RenderContextH render_contextH, /* >> */ + A_long n, /* >> */ + AEGP_RenderLayerContextH *layer_contextPH); /* << */ + + SPAPI A_Err (*AEGP_GetLayerFromLayerContext)( + const PR_RenderContextH render_contextH, + AEGP_RenderLayerContextH layer_contextH, + AEGP_LayerH *layerPH); + + SPAPI A_Err (*AEGP_GetCompRenderTime)( + PR_RenderContextH render_contextH, /* >> */ + A_Time *time, /* << */ + A_Time *time_step); + + SPAPI A_Err (*AEGP_GetCompDestinationBuffer)( + PR_RenderContextH render_contextH, /* <> */ + AEGP_CompH compH, /* >> */ + PF_EffectWorld *dst); /* <> */ + + SPAPI A_Err (*AEGP_GetROI)( + PR_RenderContextH render_contextH, /* <> */ + A_LegacyRect *roiPR); /* << */ + + /// for rendering track mattes + SPAPI A_Err (*AEGP_RenderLayer)( + PR_RenderContextH render_contextH, /* <> */ + AEGP_LayerH layerH, /* >> */ + AEGP_RenderHints render_hints, /* >> */ + PF_EffectWorld *render_bufferP); /* >> */ + + // for rendering the texture map of a layer + SPAPI A_Err (*AEGP_RenderTexture)( + PR_RenderContextH render_contextH, /* <> */ + AEGP_RenderLayerContextH layer_contextH, /* >> */ + AEGP_RenderHints render_hints, /* >> */ + A_FloatPoint *suggested_scaleP0, /* >> */ + A_FloatRect *suggested_src_rectP0, /* >> */ + A_Matrix3 *src_matrixP0, /* << */ + PF_EffectWorld *dst); /* <> */ + + + SPAPI A_Err (*AEGP_DisposeTexture)( + PR_RenderContextH render_contextH, /* <> */ + AEGP_RenderLayerContextH layer_contextH, /* >> */ + PF_EffectWorld *dst0); /* <> */ + + SPAPI A_Err (*AEGP_GetFieldRender)( + PR_RenderContextH render_contextH, /* >> */ + PF_Field *field); /* << */ + + // not thread safe on MacOS + // only call when thread ID = 0 + SPAPI A_Err (*AEGP_ReportArtisanProgress)( + PR_RenderContextH render_contextH, /* >> */ + A_long countL, /* >> */ + A_long totalL); /* >> */ + + SPAPI A_Err (*AEGP_GetRenderDownsampleFactor)( + PR_RenderContextH render_contextH, /* >> */ + AEGP_DownsampleFactor *dsfP); /* << */ + + SPAPI A_Err (*AEGP_IsBlankCanvas)( + PR_RenderContextH render_contextH, /* >> */ + A_Boolean *is_blankPB); /* << */ + + SPAPI A_Err (*AEGP_GetRenderLayerToWorldXform)( + PR_RenderContextH render_contextH, /* >> */ + AEGP_RenderLayerContextH layer_contextH, /* >> */ + const A_Time *comp_timeP, /* >> */ + A_Matrix4 *transform); /* << */ + + SPAPI A_Err (*AEGP_GetRenderLayerBounds)( + PR_RenderContextH render_contextH, /* >> */ + AEGP_RenderLayerContextH layer_contextH, /* >> */ + const A_Time *comp_timeP, /* >> */ + A_LegacyRect *boundsP); /* << */ + + SPAPI A_Err (*AEGP_GetRenderOpacity)( + PR_RenderContextH render_contextH, /* >> */ + AEGP_RenderLayerContextH layer_contextH, /* >> */ + const A_Time *comp_timePT, /* >> */ + A_FpLong *opacityPF); /* << */ + + SPAPI A_Err (*AEGP_IsRenderLayerActive)( + PR_RenderContextH render_contextH, /* >> */ + AEGP_RenderLayerContextH layer_contextH, /* >> */ + const A_Time *comp_timePT, /* >> */ + A_Boolean *activePB); /* << */ + + // set the layer index. If total > 0, set it too. + SPAPI A_Err (*AEGP_SetArtisanLayerProgress)( + PR_RenderContextH render_contextH, /* >> */ + A_long countL, /* >> */ + A_long num_layersL); + +} AEGP_CanvasSuite1; + +/********************************************************************/ + +#define kAEGPRQItemSuiteVersion3 4 /* frozen in AE 7.0 */ + +typedef struct AEGP_RQItemSuite3 { + + SPAPI A_Err (*AEGP_GetNumRQItems)( + A_long *num_itemsPL); /* << */ + + /* NOTE: All AEGP_RQItemRefH are invalidated by ANY + re-ordering, addition or removal of render + items. DO NOT CACHE THEM. + */ + + SPAPI A_Err (*AEGP_GetRQItemByIndex)( + A_long rq_item_index, /* >> */ + AEGP_RQItemRefH *rq_item_refPH); /* << */ + + SPAPI A_Err (*AEGP_GetNextRQItem)( /* Pass RQ_ITEM_INDEX_NONE for current_rq_itemH to get first RQItemH. */ + AEGP_RQItemRefH current_rq_itemH, /* >> */ + AEGP_RQItemRefH *next_rq_itemH); /* << */ + + SPAPI A_Err (*AEGP_GetNumOutputModulesForRQItem)( + AEGP_RQItemRefH rq_itemH, /* >> */ + A_long *num_outmodsPL); /* << */ + + SPAPI A_Err (*AEGP_GetRenderState)( + AEGP_RQItemRefH rq_itemH, /* >> */ + AEGP_RenderItemStatusType *statusP); /* << */ + + /* + the following now returns: + Err_PARAMETER if you try to call while AEGP_RenderQueueState != AEGP_RenderQueueState_STOPPED + + if that's okay then: + Err_RANGE if you pass a status that is illegal in any case + Err_PARAMETER if you try to pass a status that doesn't make sense right now (eg: trying to Que something for which you haven't set the output path) + */ + SPAPI A_Err (*AEGP_SetRenderState)( + AEGP_RQItemRefH rq_itemH, /* >> */ + AEGP_RenderItemStatusType status); /* >> */ + + SPAPI A_Err (*AEGP_GetStartedTime)( + AEGP_RQItemRefH rq_itemH, /* >> */ + A_Time *started_timePT); /* << Returns {0,1} if not started. */ + + SPAPI A_Err (*AEGP_GetElapsedTime)( + AEGP_RQItemRefH rq_itemH, /* >> */ + A_Time *render_timePT); /* << Returns {0,1} if not rendered. */ + + SPAPI A_Err (*AEGP_GetLogType)( + AEGP_RQItemRefH rq_itemH, /* >> */ + AEGP_LogType *logtypeP); /* << */ + + SPAPI A_Err (*AEGP_SetLogType)( + AEGP_RQItemRefH rq_itemH, /* >> */ + AEGP_LogType logtype); /* << */ + + SPAPI A_Err (*AEGP_RemoveOutputModule)( + AEGP_RQItemRefH rq_itemH, /* >> */ + AEGP_OutputModuleRefH outmodH); /* >> */ + + SPAPI A_Err (*AEGP_GetComment)( + AEGP_RQItemRefH rq_itemH, /* >> */ + A_char *commentZ); /* << up to A_char[AEGP_MAX_RQITEM_COMMENT_SIZE] */ + + SPAPI A_Err (*AEGP_SetComment)( + AEGP_RQItemRefH rq_itemH, /* >> */ + const A_char *commentZ); /* >> up to A_char[AEGP_MAX_RQITEM_COMMENT_SIZE] */ + + SPAPI A_Err (*AEGP_GetCompFromRQItem)( + AEGP_RQItemRefH rq_itemH, /* >> */ + AEGP_CompH *compPH); /* << */ + + SPAPI A_Err (*AEGP_DeleteRQItem)( + AEGP_RQItemRefH rq_itemH); /* <> UNDOABLE */ + +} AEGP_RQItemSuite3; + +#define kAEGPRQItemSuiteVersion2 3 /* frozen in AE 6.5 */ + +typedef struct AEGP_RQItemSuite2 { + + SPAPI A_Err (*AEGP_GetNumRQItems)( + A_long *num_itemsPL); /* << */ + + /* NOTE: All AEGP_RQItemRefH are invalidated by ANY + re-ordering, addition or removal of render + items. DO NOT CACHE THEM. + */ + + SPAPI A_Err (*AEGP_GetRQItemByIndex)( + A_long rq_item_index, /* >> */ + AEGP_RQItemRefH *rq_item_refPH); /* << */ + + SPAPI A_Err (*AEGP_GetNextRQItem)( /* Pass NULL for current_rq_itemH to get first RQItemH. */ + AEGP_RQItemRefH current_rq_itemH, /* >> */ + AEGP_RQItemRefH *next_rq_itemH); /* << */ + + SPAPI A_Err (*AEGP_GetNumOutputModulesForRQItem)( + AEGP_RQItemRefH rq_itemH, /* >> */ + A_long *num_outmodsPL); /* << */ + + SPAPI A_Err (*AEGP_GetRenderState)( + AEGP_RQItemRefH rq_itemH, /* >> */ + AEGP_RenderItemStatusType *statusP); /* << */ + + /* + the following now returns: + Err_PARAMETER if you try to call while AEGP_RenderQueueState != AEGP_RenderQueueState_STOPPED + + if that's okay then: + Err_RANGE if you pass a status that is illegal in any case + Err_PARAMETER if you try to pass a status that doesn't make sense right now (eg: trying to Que something for which you haven't set the output path) + */ + SPAPI A_Err (*AEGP_SetRenderState)( + AEGP_RQItemRefH rq_itemH, /* >> */ + AEGP_RenderItemStatusType status); /* >> */ + + SPAPI A_Err (*AEGP_GetStartedTime)( + AEGP_RQItemRefH rq_itemH, /* >> */ + A_Time *started_timePT); /* << Returns {0,1} if not started. */ + + SPAPI A_Err (*AEGP_GetElapsedTime)( + AEGP_RQItemRefH rq_itemH, /* >> */ + A_Time *render_timePT); /* << Returns {0,1} if not rendered. */ + + SPAPI A_Err (*AEGP_GetLogType)( + AEGP_RQItemRefH rq_itemH, /* >> */ + AEGP_LogType *logtypeP); /* << */ + + SPAPI A_Err (*AEGP_SetLogType)( + AEGP_RQItemRefH rq_itemH, /* >> */ + AEGP_LogType logtype); /* << */ + + SPAPI A_Err (*AEGP_RemoveOutputModule)( + AEGP_RQItemRefH rq_itemH, /* >> */ + AEGP_OutputModuleRefH outmodH); /* >> */ + + SPAPI A_Err (*AEGP_GetComment)( + AEGP_RQItemRefH rq_itemH, /* >> */ + A_char *commentZ); /* << up to A_char[AEGP_MAX_RQITEM_COMMENT_SIZE] */ + + SPAPI A_Err (*AEGP_SetComment)( + AEGP_RQItemRefH rq_itemH, /* >> */ + const A_char *commentZ); /* >> up to A_char[AEGP_MAX_RQITEM_COMMENT_SIZE] */ + + SPAPI A_Err (*AEGP_GetCompFromRQItem)( + AEGP_RQItemRefH rq_itemH, /* >> */ + AEGP_CompH *compPH); /* << */ + +} AEGP_RQItemSuite2; + +#define kAEGPRQItemSuiteVersion1 1 /* frozen in AE 6.0 */ + +typedef struct AEGP_RQItemSuite1 { + + SPAPI A_Err (*AEGP_GetNumRQItems)( + A_long *num_itemsPL); /* << */ + + /* NOTE: All AEGP_RQItemRefH are invalidated by ANY + re-ordering, addition or removal of render + items. DO NOT CACHE THEM. + */ + + SPAPI A_Err (*AEGP_GetRQItemByIndex)( + A_long rq_item_index, /* >> */ + AEGP_RQItemRefH *rq_item_refPH); /* << */ + + SPAPI A_Err (*AEGP_GetNextRQItem)( /* Pass NULL for current_rq_itemH to get first RQItemH. */ + AEGP_RQItemRefH current_rq_itemH, /* >> */ + AEGP_RQItemRefH *next_rq_itemH); /* << */ + + SPAPI A_Err (*AEGP_GetNumOutputModulesForRQItem)( + AEGP_RQItemRefH rq_itemH, /* >> */ + A_long *num_outmodsPL); /* << */ + + SPAPI A_Err (*AEGP_GetRenderState)( + AEGP_RQItemRefH rq_itemH, /* >> */ + AEGP_RenderItemStatusType *statusP); /* << */ + + SPAPI A_Err (*AEGP_SetRenderState)( /* Will return error if called while (AEGP_RenderQueueState != AEGP_RenderQueueState_STOPPED). */ + AEGP_RQItemRefH rq_itemH, /* >> */ + AEGP_RenderItemStatusType status); /* >> */ + + SPAPI A_Err (*AEGP_GetStartedTime)( + AEGP_RQItemRefH rq_itemH, /* >> */ + A_Time *started_timePT); /* << Returns {0,0} if not started. */ + + SPAPI A_Err (*AEGP_GetElapsedTime)( + AEGP_RQItemRefH rq_itemH, /* >> */ + A_Time *render_timePT); /* << Returns {0,0} if not rendered. */ + + SPAPI A_Err (*AEGP_GetLogType)( + AEGP_RQItemRefH rq_itemH, /* >> */ + AEGP_LogType *logtypeP); /* << */ + + SPAPI A_Err (*AEGP_SetLogType)( + AEGP_RQItemRefH rq_itemH, /* >> */ + AEGP_LogType logtype); /* << */ + + SPAPI A_Err (*AEGP_RemoveOutputModule)( + AEGP_RQItemRefH rq_itemH, /* >> */ + AEGP_OutputModuleRefH outmodH); /* >> */ + + SPAPI A_Err (*AEGP_GetComment)( + AEGP_RQItemRefH rq_itemH, /* >> */ + A_char *commentZ); /* << up to A_char[AEGP_MAX_RQITEM_COMMENT_SIZE] */ + + SPAPI A_Err (*AEGP_SetComment)( + AEGP_RQItemRefH rq_itemH, /* >> */ + const A_char *commentZ); /* >> up to A_char[AEGP_MAX_RQITEM_COMMENT_SIZE] */ + +} AEGP_RQItemSuite1; + + + +#define kAEGPCanvasSuiteVersion2 6 /* frozen in AE 5.5 */ + +typedef struct AEGP_CanvasSuite2 { + + SPAPI A_Err (*AEGP_GetCompToRender)( + PR_RenderContextH render_contextH, /* >> */ + AEGP_CompH *compPH); /* << */ + + SPAPI A_Err (*AEGP_GetNumLayersToRender)( + const PR_RenderContextH render_contextH, + A_long *num_to_renderPL); + + + SPAPI A_Err (*AEGP_GetNthLayerContextToRender)( + const PR_RenderContextH render_contextH, /* >> */ + A_long n, /* >> */ + AEGP_RenderLayerContextH *layer_contextPH); /* << */ + + SPAPI A_Err (*AEGP_GetLayerFromLayerContext)( + const PR_RenderContextH render_contextH, + AEGP_RenderLayerContextH layer_contextH, + AEGP_LayerH *layerPH); + + /** + ** With collapsed geometrics "on" this gives the layer in the root comp + ** contining the layer context. With collapsed geometrics off + ** this is the same as AEGP_GetLayerFromLayerContext. + ** + **/ + SPAPI A_Err (*AEGP_GetTopLayerFromLayerContext)( + const PR_RenderContextH render_contextH, + AEGP_RenderLayerContextH layer_contextH, + AEGP_LayerH *layerPH); + + SPAPI A_Err (*AEGP_GetCompRenderTime)( + PR_RenderContextH render_contextH, /* >> */ + A_Time *time, /* << */ + A_Time *time_step); + + SPAPI A_Err (*AEGP_GetCompDestinationBuffer)( + PR_RenderContextH render_contextH, /* <> */ + AEGP_CompH compH, /* >> */ + PF_EffectWorld *dst); /* <> */ + + SPAPI A_Err (*AEGP_GetROI)( + PR_RenderContextH render_contextH, /* <> */ + A_LegacyRect *roiPR); /* << */ + + /// for rendering track mattes + SPAPI A_Err (*AEGP_RenderLayer)( + PR_RenderContextH render_contextH, /* <> */ + AEGP_LayerH layerH, /* >> */ + AEGP_RenderHints render_hints, /* >> */ + PF_EffectWorld *render_bufferP); /* >> */ + + // for rendering the texture map of a layer + SPAPI A_Err (*AEGP_RenderTexture)( + PR_RenderContextH render_contextH, /* <> */ + AEGP_RenderLayerContextH layer_contextH, /* >> */ + AEGP_RenderHints render_hints, /* >> */ + A_FloatPoint *suggested_scaleP0, /* >> */ + A_FloatRect *suggested_src_rectP0, /* >> */ + A_Matrix3 *src_matrixP0, /* << */ + PF_EffectWorld *dst); /* <> */ + + + SPAPI A_Err (*AEGP_DisposeTexture)( + PR_RenderContextH render_contextH, /* <> */ + AEGP_RenderLayerContextH layer_contextH, /* >> */ + PF_EffectWorld *dst0); /* <> */ + + SPAPI A_Err (*AEGP_GetFieldRender)( + PR_RenderContextH render_contextH, /* >> */ + PF_Field *field); /* << */ + + // not thread safe on MacOS + // only call when thread ID = 0 + SPAPI A_Err (*AEGP_ReportArtisanProgress)( + PR_RenderContextH render_contextH, /* >> */ + A_long countL, /* >> */ + A_long totalL); /* >> */ + + SPAPI A_Err (*AEGP_GetRenderDownsampleFactor)( + PR_RenderContextH render_contextH, /* >> */ + AEGP_DownsampleFactor *dsfP); /* << */ + + SPAPI A_Err (*AEGP_IsBlankCanvas)( + PR_RenderContextH render_contextH, /* >> */ + A_Boolean *is_blankPB); /* << */ + + SPAPI A_Err (*AEGP_GetRenderLayerToWorldXform)( + PR_RenderContextH render_contextH, /* >> */ + AEGP_RenderLayerContextH layer_contextH, /* >> */ + const A_Time *comp_timeP, /* >> */ + A_Matrix4 *transform); /* << */ + + SPAPI A_Err (*AEGP_GetRenderLayerBounds)( + PR_RenderContextH render_contextH, /* >> */ + AEGP_RenderLayerContextH layer_contextH, /* >> */ + const A_Time *comp_timeP, /* >> */ + A_LegacyRect *boundsP); /* << */ + + SPAPI A_Err (*AEGP_GetRenderOpacity)( + PR_RenderContextH render_contextH, /* >> */ + AEGP_RenderLayerContextH layer_contextH, /* >> */ + const A_Time *comp_timePT, /* >> */ + A_FpLong *opacityPF); /* << */ + + SPAPI A_Err (*AEGP_IsRenderLayerActive)( + PR_RenderContextH render_contextH, /* >> */ + AEGP_RenderLayerContextH layer_contextH, /* >> */ + const A_Time *comp_timePT, /* >> */ + A_Boolean *activePB); /* << */ + + // set the layer index. If total > 0, set it too. + SPAPI A_Err (*AEGP_SetArtisanLayerProgress)( + PR_RenderContextH render_contextH, /* >> */ + A_long countL, /* >> */ + A_long num_layersL); + + SPAPI A_Err (*AEGP_RenderLayerPlus)( + PR_RenderContextH render_contextH, /* <> */ + AEGP_LayerH layerH, /* >> */ + AEGP_RenderLayerContextH layer_contextH, /* >> */ + AEGP_RenderHints render_hints, /* >> */ + PF_EffectWorld *render_bufferP); /* << */ + + + SPAPI A_Err (*AEGP_GetTrackMatteContext)( + PR_RenderContextH render_contextH, /* <> */ + AEGP_RenderLayerContextH fill_contextH, /* << */ + AEGP_RenderLayerContextH *matte_contextPH); /* >> */ + +} AEGP_CanvasSuite2; + + + +#define kAEGPCanvasSuiteVersion4 9 /* frozen AE 6.0 */ + +typedef struct AEGP_CanvasSuite4 { + + SPAPI A_Err (*AEGP_GetCompToRender)( + PR_RenderContextH render_contextH, /* >> */ + AEGP_CompH *compPH); /* << */ + + SPAPI A_Err (*AEGP_GetNumLayersToRender)( + const PR_RenderContextH render_contextH, /* >> */ + A_long *num_to_renderPL); /* << */ + + + SPAPI A_Err (*AEGP_GetNthLayerContextToRender)( + const PR_RenderContextH render_contextH, /* >> */ + A_long n, /* >> */ + AEGP_RenderLayerContextH *layer_contextPH); /* << */ + + SPAPI A_Err (*AEGP_GetLayerFromLayerContext)( + const PR_RenderContextH render_contextH, /* >> */ + AEGP_RenderLayerContextH layer_contextH, /* >> */ + AEGP_LayerH *layerPH); /* << */ + + /** + ** With collapsed geometrics "on" this gives the layer in the root comp + ** contining the layer context. With collapsed geometrics off + ** this is the same as AEGP_GetLayerFromLayerContext. + ** + **/ + SPAPI A_Err (*AEGP_GetTopLayerFromLayerContext)( + const PR_RenderContextH render_contextH, + AEGP_RenderLayerContextH layer_contextH, + AEGP_LayerH *layerPH); + + SPAPI A_Err (*AEGP_GetCompRenderTime)( + PR_RenderContextH render_contextH, /* >> */ + A_Time *time, /* << */ + A_Time *time_step); + + SPAPI A_Err (*AEGP_GetCompDestinationBuffer)( + PR_RenderContextH render_contextH, /* <> */ + AEGP_CompH compH, /* >> */ + AEGP_WorldH *dst); /* << */ + + SPAPI A_Err (*AEGP_GetROI)( + PR_RenderContextH render_contextH, /* <> */ + A_LegacyRect *roiPR); /* << */ + + // for rendering the texture map of a layer + SPAPI A_Err (*AEGP_RenderTexture)( + PR_RenderContextH render_contextH, /* <> */ + AEGP_RenderLayerContextH layer_contextH, /* >> */ + AEGP_RenderHints render_hints, /* >> */ + A_FloatPoint *suggested_scaleP0, /* >> */ + A_FloatRect *suggested_src_rectP0, /* >> */ + A_Matrix3 *src_matrixP0, /* << */ + AEGP_WorldH *dstPH); /* <> */ + + + SPAPI A_Err (*AEGP_DisposeTexture)( + PR_RenderContextH render_contextH, /* <> */ + AEGP_RenderLayerContextH layer_contextH, /* >> */ + AEGP_WorldH dstH0); /* <> */ + + SPAPI A_Err (*AEGP_GetFieldRender)( + PR_RenderContextH render_contextH, /* >> */ + PF_Field *field); /* << */ + + // not thread safe on MacOS + // only call when thread ID = 0 + SPAPI A_Err (*AEGP_ReportArtisanProgress)( + PR_RenderContextH render_contextH, /* >> */ + A_long countL, /* >> */ + A_long totalL); /* >> */ + + SPAPI A_Err (*AEGP_GetRenderDownsampleFactor)( + PR_RenderContextH render_contextH, /* >> */ + AEGP_DownsampleFactor *dsfP); /* << */ + + SPAPI A_Err (*AEGP_SetRenderDownsampleFactor)( + PR_RenderContextH render_contextH, /* >> */ + AEGP_DownsampleFactor *dsfP); /* >> */ + + SPAPI A_Err (*AEGP_IsBlankCanvas)( + PR_RenderContextH render_contextH, /* >> */ + A_Boolean *is_blankPB); /* << */ + + SPAPI A_Err (*AEGP_GetRenderLayerToWorldXform)( + PR_RenderContextH render_contextH, /* >> */ + AEGP_RenderLayerContextH layer_contextH, /* >> */ + const A_Time *comp_timeP, /* >> */ + A_Matrix4 *transform); /* << */ + + SPAPI A_Err (*AEGP_GetRenderLayerBounds)( + PR_RenderContextH render_contextH, /* >> */ + AEGP_RenderLayerContextH layer_contextH, /* >> */ + const A_Time *comp_timeP, /* >> */ + A_LegacyRect *boundsP); /* << */ + + SPAPI A_Err (*AEGP_GetRenderOpacity)( + PR_RenderContextH render_contextH, /* >> */ + AEGP_RenderLayerContextH layer_contextH, /* >> */ + const A_Time *comp_timePT, /* >> */ + A_FpLong *opacityPF); /* << */ + + SPAPI A_Err (*AEGP_IsRenderLayerActive)( + PR_RenderContextH render_contextH, /* >> */ + AEGP_RenderLayerContextH layer_contextH, /* >> */ + const A_Time *comp_timePT, /* >> */ + A_Boolean *activePB); /* << */ + + // set the layer index. If total > 0, set it too. + SPAPI A_Err (*AEGP_SetArtisanLayerProgress)( + PR_RenderContextH render_contextH, /* >> */ + A_long countL, /* >> */ + A_long num_layersL); + + // for track mattes. + // Returns a comp-size buffer, which must be disposed thru AEGP_Dispose in World suite + SPAPI A_Err (*AEGP_RenderLayerPlus)( + PR_RenderContextH render_contextH, /* <> */ + AEGP_LayerH layerH, /* >> */ + AEGP_RenderLayerContextH layer_contextH, /* >> */ + AEGP_RenderHints render_hints, /* >> */ + AEGP_WorldH *render_bufferPH); /* << must be disposed with AEGP_DisposeWorld */ + + + SPAPI A_Err (*AEGP_GetTrackMatteContext)( + PR_RenderContextH render_contextH, /* <> */ + AEGP_RenderLayerContextH fill_contextH, /* << */ + AEGP_RenderLayerContextH *matte_contextPH); /* >> */ + + // new for 6.0 --get receipt with the returned texture + // use receipt to determine if a subsequent call to render + // this layer can be skipped (because the artisan cached it) + SPAPI A_Err (*AEGP_RenderTextureWithReceipt)( + PR_RenderContextH render_contextH, /* <> */ + AEGP_RenderLayerContextH layer_contextH, /* >> */ + AEGP_RenderHints render_hints, /* >> */ + A_FloatPoint *suggested_scaleP0, /* >> */ + A_FloatRect *suggested_src_rectP0, /* >> */ + A_Matrix3 *src_matrixP0, /* << */ + AEGP_RenderReceiptH *render_receiptPH, /* << must be disposed with AEGP_DisposeRenderReceipt */ + AEGP_WorldH *dstPH); /* << */ + + SPAPI A_Err (*AEGP_RenderLayerPlusWithReceipt)( + PR_RenderContextH render_contextH, /* <> */ + AEGP_LayerH layerH, /* >> */ + AEGP_RenderLayerContextH layer_contextH, /* >> */ + AEGP_RenderHints render_hints, /* >> */ + AEGP_RenderReceiptH *render_receiptPH, /* << must be disposed with AEGP_DisposeRenderReceipt */ + AEGP_WorldH *render_bufferPH); /* << */ + + SPAPI A_Err (*AEGP_DisposeRenderReceipt)( + AEGP_RenderReceiptH render_receiptH); /* >> */ + + + SPAPI A_Err (*AEGP_CheckRenderReceipt)( + PR_RenderContextH current_render_contextH, /* >> */ + AEGP_RenderLayerContextH current_layer_contextH, /* >> */ + AEGP_RenderReceiptH old_render_receiptH, /* >> */ + A_Boolean check_aceB, /* >> */ + AEGP_RenderReceiptStatus *receipt_statusP); /* << */ + + + SPAPI A_Err (*AEGP_GetNumBinsToRender)( + const PR_RenderContextH render_contextH, /* >> */ + A_long *num_bins_to_renderPL); /* << */ + + + SPAPI A_Err (*AEGP_SetNthBin)( + const PR_RenderContextH render_contextH, /* >> */ + A_long n); /* >> */ + + SPAPI A_Err (*AEGP_GetBinType)( + const PR_RenderContextH render_contextH, /* >> */ + AEGP_BinType *bin_typeP); /* << */ + + SPAPI A_Err (*AEGP_GetRenderLayerToWorldXform2D3D)( + PR_RenderContextH render_contextH, /* >> */ + AEGP_RenderLayerContextH layer_contextH, /* >> */ + const A_Time *comp_timeP, /* >> */ + A_Boolean only_2dB, /* >> */ + A_Matrix4 *transform); /* << */ + + + // interactive artisan information + // handle to the on-screen window + SPAPI A_Err (*AEGP_GetPlatformWindowRef)( + const PR_RenderContextH render_contextH, /* >> */ + AEGP_PlatformWindowRef *window_refP); /* << */ + + + // the dsf src to frame scale factors + SPAPI A_Err (*AEGP_GetViewportScale)( + const PR_RenderContextH render_contextH, /* >> */ + A_FpLong *scale_xPF, /* << */ + A_FpLong *scale_yPF); /* << */ + + + // the dsf src to frame translate + SPAPI A_Err (*AEGP_GetViewportOrigin)( + const PR_RenderContextH render_contextH, /* >> */ + A_long *origin_xPL, /* << */ + A_long *origin_yPL); /* << */ + + + SPAPI A_Err (*AEGP_GetViewportRect)( + const PR_RenderContextH render_contextH, /* >> */ + A_LegacyRect *viewport_rectPR); /* << */ + + + SPAPI A_Err (*AEGP_GetFallowColor)( + const PR_RenderContextH render_contextH, /* >> */ + PF_Pixel8 *fallow_colorP); /* << */ + + SPAPI A_Err (*AEGP_GetInteractiveBuffer)( + const PR_RenderContextH render_contextH, /* >> */ + AEGP_WorldH *buffer); /* << */ + + SPAPI A_Err (*AEGP_GetInteractiveCheckerboard)( + const PR_RenderContextH render_contextH, /* in */ + A_Boolean *checkerboard_onPB);/* out */ + + SPAPI A_Err (*AEGP_GetInteractiveCheckerboardColors)( + const PR_RenderContextH render_contextH, /* in */ + PF_Pixel *checkerboard_color1P, /* out */ + PF_Pixel *checkerboard_color2P); /* out */ + + SPAPI A_Err (*AEGP_GetInteractiveCheckerboardSize)( + const PR_RenderContextH render_contextH, /* in */ + A_u_long *checkerboard_widthPLu, /* out - width of square*/ + A_u_long *checkerboard_heightPLu); /* out - height of square*/ + + SPAPI A_Err (*AEGP_GetInteractiveCachedBuffer)( + const PR_RenderContextH render_contextH, /* >> */ + AEGP_WorldH *buffer); /* << */ + + + // should we call AEGP_RenderLayer or AEGP_RenderTexture + SPAPI A_Err (*AEGP_ArtisanMustRenderAsLayer)( + const PR_RenderContextH render_contextH, /* >> */ + AEGP_RenderLayerContextH layer_contextH, + A_Boolean *use_render_texturePB); + +} AEGP_CanvasSuite4; + + + +#define kAEGPCanvasSuiteVersion5 10 /* frozen in AE 6.5 */ + +typedef struct AEGP_CanvasSuite5 { + + SPAPI A_Err (*AEGP_GetCompToRender)( + PR_RenderContextH render_contextH, /* >> */ + AEGP_CompH *compPH); /* << */ + + SPAPI A_Err (*AEGP_GetNumLayersToRender)( + const PR_RenderContextH render_contextH, /* >> */ + A_long *num_to_renderPL); /* << */ + + + SPAPI A_Err (*AEGP_GetNthLayerContextToRender)( + const PR_RenderContextH render_contextH, /* >> */ + A_long n, /* >> */ + AEGP_RenderLayerContextH *layer_contextPH); /* << */ + + SPAPI A_Err (*AEGP_GetLayerFromLayerContext)( + const PR_RenderContextH render_contextH, /* >> */ + AEGP_RenderLayerContextH layer_contextH, /* >> */ + AEGP_LayerH *layerPH); /* << */ + + /** + ** With collapsed geometrics "on" this gives the layer in the root comp + ** contining the layer context. With collapsed geometrics off + ** this is the same as AEGP_GetLayerFromLayerContext. + ** + **/ + SPAPI A_Err (*AEGP_GetTopLayerFromLayerContext)( + const PR_RenderContextH render_contextH, + AEGP_RenderLayerContextH layer_contextH, + AEGP_LayerH *layerPH); + + SPAPI A_Err (*AEGP_GetCompRenderTime)( + PR_RenderContextH render_contextH, /* >> */ + A_Time *time, /* << */ + A_Time *time_step); + + SPAPI A_Err (*AEGP_GetCompDestinationBuffer)( + PR_RenderContextH render_contextH, /* <> */ + AEGP_CompH compH, /* >> */ + AEGP_WorldH *dst); /* << */ + + SPAPI A_Err (*AEGP_GetROI)( + PR_RenderContextH render_contextH, /* <> */ + A_LegacyRect *roiPR); /* << */ + + // for rendering the texture map of a layer + SPAPI A_Err (*AEGP_RenderTexture)( + PR_RenderContextH render_contextH, /* <> */ + AEGP_RenderLayerContextH layer_contextH, /* >> */ + AEGP_RenderHints render_hints, /* >> */ + A_FloatPoint *suggested_scaleP0, /* >> */ + A_FloatRect *suggested_src_rectP0, /* >> */ + A_Matrix3 *src_matrixP0, /* << */ + AEGP_WorldH *dstPH); /* <> */ + + + SPAPI A_Err (*AEGP_DisposeTexture)( + PR_RenderContextH render_contextH, /* <> */ + AEGP_RenderLayerContextH layer_contextH, /* >> */ + AEGP_WorldH dstH0); /* <> */ + + SPAPI A_Err (*AEGP_GetFieldRender)( + PR_RenderContextH render_contextH, /* >> */ + PF_Field *field); /* << */ + + // not thread safe on MacOS + // only call when thread ID = 0 + SPAPI A_Err (*AEGP_ReportArtisanProgress)( + PR_RenderContextH render_contextH, /* >> */ + A_long countL, /* >> */ + A_long totalL); /* >> */ + + SPAPI A_Err (*AEGP_GetRenderDownsampleFactor)( + PR_RenderContextH render_contextH, /* >> */ + AEGP_DownsampleFactor *dsfP); /* << */ + + SPAPI A_Err (*AEGP_SetRenderDownsampleFactor)( + PR_RenderContextH render_contextH, /* >> */ + AEGP_DownsampleFactor *dsfP); /* >> */ + + SPAPI A_Err (*AEGP_IsBlankCanvas)( + PR_RenderContextH render_contextH, /* >> */ + A_Boolean *is_blankPB); /* << */ + + SPAPI A_Err (*AEGP_GetRenderLayerToWorldXform)( + PR_RenderContextH render_contextH, /* >> */ + AEGP_RenderLayerContextH layer_contextH, /* >> */ + const A_Time *comp_timeP, /* >> */ + A_Matrix4 *transform); /* << */ + + SPAPI A_Err (*AEGP_GetRenderLayerBounds)( + PR_RenderContextH render_contextH, /* >> */ + AEGP_RenderLayerContextH layer_contextH, /* >> */ + const A_Time *comp_timeP, /* >> */ + A_LegacyRect *boundsP); /* << */ + + SPAPI A_Err (*AEGP_GetRenderOpacity)( + PR_RenderContextH render_contextH, /* >> */ + AEGP_RenderLayerContextH layer_contextH, /* >> */ + const A_Time *comp_timePT, /* >> */ + A_FpLong *opacityPF); /* << */ + + SPAPI A_Err (*AEGP_IsRenderLayerActive)( + PR_RenderContextH render_contextH, /* >> */ + AEGP_RenderLayerContextH layer_contextH, /* >> */ + const A_Time *comp_timePT, /* >> */ + A_Boolean *activePB); /* << */ + + // set the layer index. If total > 0, set it too. + SPAPI A_Err (*AEGP_SetArtisanLayerProgress)( + PR_RenderContextH render_contextH, /* >> */ + A_long countL, /* >> */ + A_long num_layersL); + + // for track mattes. + // Returns a comp-size buffer, which must be disposed thru AEGP_Dispose in World suite + SPAPI A_Err (*AEGP_RenderLayerPlus)( + PR_RenderContextH render_contextH, /* <> */ + AEGP_LayerH layerH, /* >> */ + AEGP_RenderLayerContextH layer_contextH, /* >> */ + AEGP_RenderHints render_hints, /* >> */ + AEGP_WorldH *render_bufferPH); /* << must be disposed with AEGP_DisposeWorld */ + + + SPAPI A_Err (*AEGP_GetTrackMatteContext)( + PR_RenderContextH render_contextH, /* <> */ + AEGP_RenderLayerContextH fill_contextH, /* << */ + AEGP_RenderLayerContextH *matte_contextPH); /* >> */ + + // new for 6.0 --get receipt with the returned texture + // use receipt to determine if a subsequent call to render + // this layer can be skipped (because the artisan cached it) + SPAPI A_Err (*AEGP_RenderTextureWithReceipt)( + PR_RenderContextH render_contextH, /* <> */ + AEGP_RenderLayerContextH layer_contextH, /* >> */ + AEGP_RenderHints render_hints, /* >> */ + A_FloatPoint *suggested_scaleP0, /* >> */ + A_FloatRect *suggested_src_rectP0, /* >> */ + A_Matrix3 *src_matrixP0, /* << */ + AEGP_RenderReceiptH *render_receiptPH, /* << must be disposed with AEGP_DisposeRenderReceipt */ + AEGP_WorldH *dstPH); /* << */ + + SPAPI A_Err (*AEGP_RenderLayerPlusWithReceipt)( + PR_RenderContextH render_contextH, /* <> */ + AEGP_LayerH layerH, /* >> */ + AEGP_RenderLayerContextH layer_contextH, /* >> */ + AEGP_RenderHints render_hints, /* >> */ + AEGP_RenderReceiptH *render_receiptPH, /* << must be disposed with AEGP_DisposeRenderReceipt */ + AEGP_WorldH *render_bufferPH); /* << */ + + SPAPI A_Err (*AEGP_DisposeRenderReceipt)( + AEGP_RenderReceiptH render_receiptH); /* >> */ + + + SPAPI A_Err (*AEGP_CheckRenderReceipt)( + PR_RenderContextH current_render_contextH, /* >> */ + AEGP_RenderLayerContextH current_layer_contextH, /* >> */ + AEGP_RenderReceiptH old_render_receiptH, /* >> */ + A_Boolean check_geometricsB, /* >> */ + AEGP_RenderReceiptStatus *receipt_statusP); /* << */ + + + SPAPI A_Err (*AEGP_GetNumBinsToRender)( + const PR_RenderContextH render_contextH, /* >> */ + A_long *num_bins_to_renderPL); /* << */ + + + SPAPI A_Err (*AEGP_SetNthBin)( + const PR_RenderContextH render_contextH, /* >> */ + A_long n); /* >> */ + + SPAPI A_Err (*AEGP_GetBinType)( + const PR_RenderContextH render_contextH, /* >> */ + AEGP_BinType *bin_typeP); /* << */ + + SPAPI A_Err (*AEGP_GetRenderLayerToWorldXform2D3D)( + PR_RenderContextH render_contextH, /* >> */ + AEGP_RenderLayerContextH layer_contextH, /* >> */ + const A_Time *comp_timeP, /* >> */ + A_Boolean only_2dB, /* >> */ + A_Matrix4 *transform); /* << */ + + + // interactive artisan information + // handle to the on-screen window + SPAPI A_Err (*AEGP_GetPlatformWindowRef)( + const PR_RenderContextH render_contextH, /* >> */ + AEGP_PlatformWindowRef *window_refP); /* << */ + + + // the dsf src to frame scale factors + SPAPI A_Err (*AEGP_GetViewportScale)( + const PR_RenderContextH render_contextH, /* >> */ + A_FpLong *scale_xPF, /* << */ + A_FpLong *scale_yPF); /* << */ + + + // the dsf src to frame translate + SPAPI A_Err (*AEGP_GetViewportOrigin)( + const PR_RenderContextH render_contextH, /* >> */ + A_long *origin_xPL, /* << */ + A_long *origin_yPL); /* << */ + + + SPAPI A_Err (*AEGP_GetViewportRect)( + const PR_RenderContextH render_contextH, /* >> */ + A_LegacyRect *viewport_rectPR); /* << */ + + + SPAPI A_Err (*AEGP_GetFallowColor)( + const PR_RenderContextH render_contextH, /* >> */ + PF_Pixel8 *fallow_colorP); /* << */ + + SPAPI A_Err (*AEGP_GetInteractiveBuffer)( + const PR_RenderContextH render_contextH, /* >> */ + AEGP_WorldH *buffer); /* << */ + + SPAPI A_Err (*AEGP_GetInteractiveCheckerboard)( + const PR_RenderContextH render_contextH, /* in */ + A_Boolean *checkerboard_onPB);/* out */ + + SPAPI A_Err (*AEGP_GetInteractiveCheckerboardColors)( + const PR_RenderContextH render_contextH, /* in */ + PF_Pixel *checkerboard_color1P, /* out */ + PF_Pixel *checkerboard_color2P); /* out */ + + SPAPI A_Err (*AEGP_GetInteractiveCheckerboardSize)( + const PR_RenderContextH render_contextH, /* in */ + A_u_long *checkerboard_widthPLu, /* out - width of square*/ + A_u_long *checkerboard_heightPLu); /* out - height of square*/ + + SPAPI A_Err (*AEGP_GetInteractiveCachedBuffer)( + const PR_RenderContextH render_contextH, /* >> */ + AEGP_WorldH *buffer); /* << */ + + + // should we call AEGP_RenderLayer or AEGP_RenderTexture + SPAPI A_Err (*AEGP_ArtisanMustRenderAsLayer)( + const PR_RenderContextH render_contextH, /* >> */ + AEGP_RenderLayerContextH layer_contextH, + A_Boolean *use_render_texturePB); + + + SPAPI A_Err (*AEGP_GetInteractiveDisplayChannel)( + const PR_RenderContextH render_contextH, /* >> */ + AEGP_DisplayChannelType *display_channelP); /* << */ + +} AEGP_CanvasSuite5; + + +#define kAEGPCanvasSuiteVersion6 11 /* frozen in AE 7.0 */ + +typedef struct AEGP_CanvasSuite6 { + + SPAPI A_Err (*AEGP_GetCompToRender)( + PR_RenderContextH render_contextH, /* >> */ + AEGP_CompH *compPH); /* << */ + + SPAPI A_Err (*AEGP_GetNumLayersToRender)( + const PR_RenderContextH render_contextH, /* >> */ + A_long *num_to_renderPL); /* << */ + + + SPAPI A_Err (*AEGP_GetNthLayerContextToRender)( + const PR_RenderContextH render_contextH, /* >> */ + A_long n, /* >> */ + AEGP_RenderLayerContextH *layer_contextPH); /* << */ + + SPAPI A_Err (*AEGP_GetLayerFromLayerContext)( + const PR_RenderContextH render_contextH, /* >> */ + AEGP_RenderLayerContextH layer_contextH, /* >> */ + AEGP_LayerH *layerPH); /* << */ + + /** + ** With collapsed geometrics "on" this gives the layer in the root comp + ** contining the layer context. With collapsed geometrics off + ** this is the same as AEGP_GetLayerFromLayerContext. + ** + **/ + SPAPI A_Err (*AEGP_GetTopLayerFromLayerContext)( + const PR_RenderContextH render_contextH, + AEGP_RenderLayerContextH layer_contextH, + AEGP_LayerH *layerPH); + + SPAPI A_Err (*AEGP_GetCompRenderTime)( + PR_RenderContextH render_contextH, /* >> */ + A_Time *time, /* << */ + A_Time *time_step); + + SPAPI A_Err (*AEGP_GetCompDestinationBuffer)( + PR_RenderContextH render_contextH, /* <> */ + AEGP_CompH compH, /* >> */ + AEGP_WorldH *dst); /* << */ + + SPAPI A_Err (*AEGP_GetROI)( + PR_RenderContextH render_contextH, /* <> */ + A_LegacyRect *roiPR); /* << */ + + // for rendering the texture map of a layer + SPAPI A_Err (*AEGP_RenderTexture)( + PR_RenderContextH render_contextH, /* <> */ + AEGP_RenderLayerContextH layer_contextH, /* >> */ + AEGP_RenderHints render_hints, /* >> */ + A_FloatPoint *suggested_scaleP0, /* >> */ + A_FloatRect *suggested_src_rectP0, /* >> */ + A_Matrix3 *src_matrixP0, /* << */ + AEGP_WorldH *dstPH); /* <> */ + + + SPAPI A_Err (*AEGP_DisposeTexture)( + PR_RenderContextH render_contextH, /* <> */ + AEGP_RenderLayerContextH layer_contextH, /* >> */ + AEGP_WorldH dstH0); /* <> */ + + SPAPI A_Err (*AEGP_GetFieldRender)( + PR_RenderContextH render_contextH, /* >> */ + PF_Field *field); /* << */ + + // not thread safe on MacOS + // only call when thread ID = 0 + SPAPI A_Err (*AEGP_ReportArtisanProgress)( + PR_RenderContextH render_contextH, /* >> */ + A_long countL, /* >> */ + A_long totalL); /* >> */ + + SPAPI A_Err (*AEGP_GetRenderDownsampleFactor)( + PR_RenderContextH render_contextH, /* >> */ + AEGP_DownsampleFactor *dsfP); /* << */ + + SPAPI A_Err (*AEGP_SetRenderDownsampleFactor)( + PR_RenderContextH render_contextH, /* >> */ + AEGP_DownsampleFactor *dsfP); /* >> */ + + SPAPI A_Err (*AEGP_IsBlankCanvas)( + PR_RenderContextH render_contextH, /* >> */ + A_Boolean *is_blankPB); /* << */ + + SPAPI A_Err (*AEGP_GetRenderLayerToWorldXform)( + PR_RenderContextH render_contextH, /* >> */ + AEGP_RenderLayerContextH layer_contextH, /* >> */ + const A_Time *comp_timeP, /* >> */ + A_Matrix4 *transform); /* << */ + + SPAPI A_Err (*AEGP_GetRenderLayerBounds)( + PR_RenderContextH render_contextH, /* >> */ + AEGP_RenderLayerContextH layer_contextH, /* >> */ + const A_Time *comp_timeP, /* >> */ + A_LegacyRect *boundsP); /* << */ + + SPAPI A_Err (*AEGP_GetRenderOpacity)( + PR_RenderContextH render_contextH, /* >> */ + AEGP_RenderLayerContextH layer_contextH, /* >> */ + const A_Time *comp_timePT, /* >> */ + A_FpLong *opacityPF); /* << */ + + SPAPI A_Err (*AEGP_IsRenderLayerActive)( + PR_RenderContextH render_contextH, /* >> */ + AEGP_RenderLayerContextH layer_contextH, /* >> */ + const A_Time *comp_timePT, /* >> */ + A_Boolean *activePB); /* << */ + + // set the layer index. If total > 0, set it too. + SPAPI A_Err (*AEGP_SetArtisanLayerProgress)( + PR_RenderContextH render_contextH, /* >> */ + A_long countL, /* >> */ + A_long num_layersL); + + // for track mattes. + // Returns a comp-size buffer, which must be disposed thru AEGP_Dispose in World suite + SPAPI A_Err (*AEGP_RenderLayerPlus)( + PR_RenderContextH render_contextH, /* <> */ + AEGP_LayerH layerH, /* >> */ + AEGP_RenderLayerContextH layer_contextH, /* >> */ + AEGP_RenderHints render_hints, /* >> */ + AEGP_WorldH *render_bufferPH); /* << must be disposed with AEGP_DisposeWorld */ + + + SPAPI A_Err (*AEGP_GetTrackMatteContext)( + PR_RenderContextH render_contextH, /* <> */ + AEGP_RenderLayerContextH fill_contextH, /* << */ + AEGP_RenderLayerContextH *matte_contextPH); /* >> */ + + // new for 6.0 --get receipt with the returned texture + // use receipt to determine if a subsequent call to render + // this layer can be skipped (because the artisan cached it) + SPAPI A_Err (*AEGP_RenderTextureWithReceipt)( + PR_RenderContextH render_contextH, /* <> */ + AEGP_RenderLayerContextH layer_contextH, /* >> */ + AEGP_RenderHints render_hints, /* >> */ + AEGP_NumEffectsToRenderType num_effectsS, /* >> number of effect to render, -1 for all */ + A_FloatPoint *suggested_scaleP0, /* >> */ + A_FloatRect *suggested_src_rectP0, /* >> */ + A_Matrix3 *src_matrixP0, /* << */ + AEGP_RenderReceiptH *render_receiptPH, /* << must be disposed with AEGP_DisposeRenderReceipt */ + AEGP_WorldH *dstPH); /* << */ + + + + SPAPI A_Err (*AEGP_GetNumberOfSoftwareEffects)( + PR_RenderContextH render_contextH, /* <> */ + AEGP_RenderLayerContextH layer_contextH, /* >> */ + A_short *num_software_effectsPS); + + SPAPI A_Err (*AEGP_RenderLayerPlusWithReceipt)( + PR_RenderContextH render_contextH, /* <> */ + AEGP_LayerH layerH, /* >> */ + AEGP_RenderLayerContextH layer_contextH, /* >> */ + AEGP_RenderHints render_hints, /* >> */ + AEGP_RenderReceiptH *render_receiptPH, /* << must be disposed with AEGP_DisposeRenderReceipt */ + AEGP_WorldH *render_bufferPH); /* << */ + + SPAPI A_Err (*AEGP_DisposeRenderReceipt)( + AEGP_RenderReceiptH render_receiptH); /* >> */ + + + /* modified for 7.0 - added num_effects to check against */ + SPAPI A_Err (*AEGP_CheckRenderReceipt)( + PR_RenderContextH current_render_contextH, /* in */ + AEGP_RenderLayerContextH current_layer_contextH, /* in */ + AEGP_RenderReceiptH old_render_receiptH, /* in */ + A_Boolean check_geometricsB, /* in */ + AEGP_NumEffectsToRenderType num_effectsS, /* in */ + AEGP_RenderReceiptStatus *receipt_statusP); /* out */ + + + /* new in 7.0 generate a receipt for a layer as asd if the first num_effectsS have been rendered */ + SPAPI A_Err (*AEGP_GenerateRenderReceipt)( + PR_RenderContextH current_render_contextH, /* >> */ + AEGP_RenderLayerContextH current_layer_contextH, /* >> */ + AEGP_NumEffectsToRenderType num_effectsS, /* in */ + AEGP_RenderReceiptH *render_receiptPH); /* << */ + + SPAPI A_Err (*AEGP_GetNumBinsToRender)( + const PR_RenderContextH render_contextH, /* >> */ + A_long *num_bins_to_renderPL); /* << */ + + + SPAPI A_Err (*AEGP_SetNthBin)( + const PR_RenderContextH render_contextH, /* >> */ + A_long n); /* >> */ + + SPAPI A_Err (*AEGP_GetBinType)( + const PR_RenderContextH render_contextH, /* >> */ + AEGP_BinType *bin_typeP); /* << */ + + SPAPI A_Err (*AEGP_GetRenderLayerToWorldXform2D3D)( + PR_RenderContextH render_contextH, /* >> */ + AEGP_RenderLayerContextH layer_contextH, /* >> */ + const A_Time *comp_timeP, /* >> */ + A_Boolean only_2dB, /* >> */ + A_Matrix4 *transform); /* << */ + + + // interactive artisan information + // handle to the on-screen window + SPAPI A_Err (*AEGP_GetPlatformWindowRef)( + const PR_RenderContextH render_contextH, /* >> */ + AEGP_PlatformWindowRef *window_refP); /* << */ + + + // the dsf src to frame scale factors + SPAPI A_Err (*AEGP_GetViewportScale)( + const PR_RenderContextH render_contextH, /* >> */ + A_FpLong *scale_xPF, /* << */ + A_FpLong *scale_yPF); /* << */ + + + // the dsf src to frame translate + SPAPI A_Err (*AEGP_GetViewportOrigin)( + const PR_RenderContextH render_contextH, /* >> */ + A_long *origin_xPL, /* << */ + A_long *origin_yPL); /* << */ + + + SPAPI A_Err (*AEGP_GetViewportRect)( + const PR_RenderContextH render_contextH, /* >> */ + A_LegacyRect *viewport_rectPR); /* << */ + + + SPAPI A_Err (*AEGP_GetFallowColor)( + const PR_RenderContextH render_contextH, /* >> */ + PF_Pixel8 *fallow_colorP); /* << */ + + SPAPI A_Err (*AEGP_GetInteractiveBuffer)( + const PR_RenderContextH render_contextH, /* >> */ + AEGP_WorldH *buffer); /* << */ + + SPAPI A_Err (*AEGP_GetInteractiveCheckerboard)( + const PR_RenderContextH render_contextH, /* in */ + A_Boolean *checkerboard_onPB);/* out */ + + SPAPI A_Err (*AEGP_GetInteractiveCheckerboardColors)( + const PR_RenderContextH render_contextH, /* in */ + PF_Pixel *checkerboard_color1P, /* out */ + PF_Pixel *checkerboard_color2P); /* out */ + + SPAPI A_Err (*AEGP_GetInteractiveCheckerboardSize)( + const PR_RenderContextH render_contextH, /* in */ + A_u_long *checkerboard_widthPLu, /* out - width of square*/ + A_u_long *checkerboard_heightPLu); /* out - height of square*/ + + SPAPI A_Err (*AEGP_GetInteractiveCachedBuffer)( + const PR_RenderContextH render_contextH, /* >> */ + AEGP_WorldH *buffer); /* << */ + + + // should we call AEGP_RenderLayer or AEGP_RenderTexture + SPAPI A_Err (*AEGP_ArtisanMustRenderAsLayer)( + const PR_RenderContextH render_contextH, /* >> */ + AEGP_RenderLayerContextH layer_contextH, + A_Boolean *use_render_texturePB); + + + SPAPI A_Err (*AEGP_GetInteractiveDisplayChannel)( + const PR_RenderContextH render_contextH, /* >> */ + AEGP_DisplayChannelType *display_channelP); /* << */ + + +} AEGP_CanvasSuite6; + + + +#define kAEGPCanvasSuiteVersion7 13 /* frozen in AE 8.0, source code-compatible additions in 64-bit AE 10.0*/ + +typedef struct AEGP_CanvasSuite7 { + + SPAPI A_Err (*AEGP_GetCompToRender)( + PR_RenderContextH render_contextH, /* >> */ + AEGP_CompH *compPH); /* << */ + + SPAPI A_Err (*AEGP_GetNumLayersToRender)( + const PR_RenderContextH render_contextH, /* >> */ + A_long *num_to_renderPL); /* << */ + + + SPAPI A_Err (*AEGP_GetNthLayerContextToRender)( + const PR_RenderContextH render_contextH, /* >> */ + A_long n, /* >> */ + AEGP_RenderLayerContextH *layer_contextPH); /* << */ + + SPAPI A_Err (*AEGP_GetLayerFromLayerContext)( + const PR_RenderContextH render_contextH, /* >> */ + AEGP_RenderLayerContextH layer_contextH, /* >> */ + AEGP_LayerH *layerPH); /* << */ + + SPAPI A_Err (*AEGP_GetLayerAndSubLayerFromLayerContext)( + const PR_RenderContextH render_contextH, /* >> */ + AEGP_RenderLayerContextH layer_contextH, /* >> */ + AEGP_LayerH *layerPH, /* << */ + AEGP_SubLayerIndex *sublayerP); /* << */ + + /** + ** With collapsed geometrics "on" this gives the layer in the root comp + ** contining the layer context. With collapsed geometrics off + ** this is the same as AEGP_GetLayerFromLayerContext. + ** + **/ + SPAPI A_Err (*AEGP_GetTopLayerFromLayerContext)( + const PR_RenderContextH render_contextH, + AEGP_RenderLayerContextH layer_contextH, + AEGP_LayerH *layerPH); + + SPAPI A_Err (*AEGP_GetCompRenderTime)( + PR_RenderContextH render_contextH, /* >> */ + A_Time *time, /* << */ + A_Time *time_step); + + SPAPI A_Err (*AEGP_GetCompDestinationBuffer)( + PR_RenderContextH render_contextH, /* <> */ + AEGP_CompH compH, /* >> */ + AEGP_WorldH *dst); /* << */ + + SPAPI A_Err (*AEGP_GetROI)( + PR_RenderContextH render_contextH, /* <> */ + A_LegacyRect *roiPR); /* << */ + + // for rendering the texture map of a layer + SPAPI A_Err (*AEGP_RenderTexture)( + PR_RenderContextH render_contextH, /* <> */ + AEGP_RenderLayerContextH layer_contextH, /* >> */ + AEGP_RenderHints render_hints, /* >> */ + A_FloatPoint *suggested_scaleP0, /* >> */ + A_FloatRect *suggested_src_rectP0, /* >> */ + A_Matrix3 *src_matrixP0, /* << */ + AEGP_WorldH *dstPH); /* <> */ + + + SPAPI A_Err (*AEGP_DisposeTexture)( + PR_RenderContextH render_contextH, /* <> */ + AEGP_RenderLayerContextH layer_contextH, /* >> */ + AEGP_WorldH dstH0); /* <> */ + + SPAPI A_Err (*AEGP_GetFieldRender)( + PR_RenderContextH render_contextH, /* >> */ + PF_Field *field); /* << */ + + // not thread safe on MacOS + // only call when thread ID = 0 + SPAPI A_Err (*AEGP_ReportArtisanProgress)( + PR_RenderContextH render_contextH, /* >> */ + A_long countL, /* >> */ + A_long totalL); /* >> */ + + SPAPI A_Err (*AEGP_GetRenderDownsampleFactor)( + PR_RenderContextH render_contextH, /* >> */ + AEGP_DownsampleFactor *dsfP); /* << */ + + SPAPI A_Err (*AEGP_SetRenderDownsampleFactor)( + PR_RenderContextH render_contextH, /* >> */ + AEGP_DownsampleFactor *dsfP); /* >> */ + + SPAPI A_Err (*AEGP_IsBlankCanvas)( + PR_RenderContextH render_contextH, /* >> */ + A_Boolean *is_blankPB); /* << */ + + SPAPI A_Err (*AEGP_GetRenderLayerToWorldXform)( + PR_RenderContextH render_contextH, /* >> */ + AEGP_RenderLayerContextH layer_contextH, /* >> */ + const A_Time *comp_timeP, /* >> */ + A_Matrix4 *transform); /* << */ + + SPAPI A_Err (*AEGP_GetRenderLayerBounds)( + PR_RenderContextH render_contextH, /* >> */ + AEGP_RenderLayerContextH layer_contextH, /* >> */ + const A_Time *comp_timeP, /* >> */ + A_LegacyRect *boundsP); /* << */ + + SPAPI A_Err (*AEGP_GetRenderOpacity)( + PR_RenderContextH render_contextH, /* >> */ + AEGP_RenderLayerContextH layer_contextH, /* >> */ + const A_Time *comp_timePT, /* >> */ + A_FpLong *opacityPF); /* << */ + + SPAPI A_Err (*AEGP_IsRenderLayerActive)( + PR_RenderContextH render_contextH, /* >> */ + AEGP_RenderLayerContextH layer_contextH, /* >> */ + const A_Time *comp_timePT, /* >> */ + A_Boolean *activePB); /* << */ + + // set the layer index. If total > 0, set it too. + SPAPI A_Err (*AEGP_SetArtisanLayerProgress)( + PR_RenderContextH render_contextH, /* >> */ + A_long countL, /* >> */ + A_long num_layersL); + + // for track mattes. + // Returns a comp-size buffer, which must be disposed thru AEGP_Dispose in World suite + SPAPI A_Err (*AEGP_RenderLayerPlus)( + PR_RenderContextH render_contextH, /* <> */ + AEGP_LayerH layerH, /* >> */ + AEGP_RenderLayerContextH layer_contextH, /* >> */ + AEGP_RenderHints render_hints, /* >> */ + AEGP_WorldH *render_bufferPH); /* << must be disposed with AEGP_DisposeWorld */ + + + SPAPI A_Err (*AEGP_GetTrackMatteContext)( + PR_RenderContextH render_contextH, /* <> */ + AEGP_RenderLayerContextH fill_contextH, /* << */ + AEGP_RenderLayerContextH *matte_contextPH); /* >> */ + + // new for 6.0 --get receipt with the returned texture + // use receipt to determine if a subsequent call to render + // this layer can be skipped (because the artisan cached it) + SPAPI A_Err (*AEGP_RenderTextureWithReceipt)( + PR_RenderContextH render_contextH, /* <> */ + AEGP_RenderLayerContextH layer_contextH, /* >> */ + AEGP_RenderHints render_hints, /* >> */ + AEGP_NumEffectsToRenderType num_effectsS, /* >> number of effect to render, -1 for all */ + A_FloatPoint *suggested_scaleP0, /* >> */ + A_FloatRect *suggested_src_rectP0, /* >> */ + A_Matrix3 *src_matrixP0, /* << */ + AEGP_RenderReceiptH *render_receiptPH, /* << must be disposed with AEGP_DisposeRenderReceipt */ + AEGP_WorldH *dstPH); /* << */ + + + + SPAPI A_Err (*AEGP_GetNumberOfSoftwareEffects)( + PR_RenderContextH render_contextH, /* <> */ + AEGP_RenderLayerContextH layer_contextH, /* >> */ + A_short *num_software_effectsPS); + + SPAPI A_Err (*AEGP_RenderLayerPlusWithReceipt)( + PR_RenderContextH render_contextH, /* <> */ + AEGP_LayerH layerH, /* >> */ + AEGP_RenderLayerContextH layer_contextH, /* >> */ + AEGP_RenderHints render_hints, /* >> */ + AEGP_RenderReceiptH *render_receiptPH, /* << must be disposed with AEGP_DisposeRenderReceipt */ + AEGP_WorldH *render_bufferPH); /* << */ + + SPAPI A_Err (*AEGP_DisposeRenderReceipt)( + AEGP_RenderReceiptH render_receiptH); /* >> */ + + + /* modified for 7.0 - added num_effects to check against */ + SPAPI A_Err (*AEGP_CheckRenderReceipt)( + PR_RenderContextH current_render_contextH, /* in */ + AEGP_RenderLayerContextH current_layer_contextH, /* in */ + AEGP_RenderReceiptH old_render_receiptH, /* in */ + A_Boolean check_geometricsB, /* in */ + AEGP_NumEffectsToRenderType num_effectsS, /* in */ + AEGP_RenderReceiptStatus *receipt_statusP); /* out */ + + + /* new in 7.0 generate a receipt for a layer as asd if the first num_effectsS have been rendered */ + SPAPI A_Err (*AEGP_GenerateRenderReceipt)( + PR_RenderContextH current_render_contextH, /* >> */ + AEGP_RenderLayerContextH current_layer_contextH, /* >> */ + AEGP_NumEffectsToRenderType num_effectsS, /* in */ + AEGP_RenderReceiptH *render_receiptPH); /* << */ + + SPAPI A_Err (*AEGP_GetNumBinsToRender)( + const PR_RenderContextH render_contextH, /* >> */ + A_long *num_bins_to_renderPL); /* << */ + + + SPAPI A_Err (*AEGP_SetNthBin)( + const PR_RenderContextH render_contextH, /* >> */ + A_long n); /* >> */ + + SPAPI A_Err (*AEGP_GetBinType)( + const PR_RenderContextH render_contextH, /* >> */ + AEGP_BinType *bin_typeP); /* << */ + + SPAPI A_Err (*AEGP_GetRenderLayerToWorldXform2D3D)( + PR_RenderContextH render_contextH, /* >> */ + AEGP_RenderLayerContextH layer_contextH, /* >> */ + const A_Time *comp_timeP, /* >> */ + A_Boolean only_2dB, /* >> */ + A_Matrix4 *transform); /* << */ + + + // interactive artisan information + // handle to the on-screen window + SPAPI A_Err (*AEGP_GetPlatformWindowRef)( + const PR_RenderContextH render_contextH, /* >> */ + AEGP_PlatformWindowRef *window_refP); /* << */ + + + // the dsf src to frame scale factors + SPAPI A_Err (*AEGP_GetViewportScale)( + const PR_RenderContextH render_contextH, /* >> */ + A_FpLong *scale_xPF, /* << */ + A_FpLong *scale_yPF); /* << */ + + + // the dsf src to frame translate + SPAPI A_Err (*AEGP_GetViewportOrigin)( + const PR_RenderContextH render_contextH, /* >> */ + A_long *origin_xPL, /* << */ + A_long *origin_yPL); /* << */ + + + SPAPI A_Err (*AEGP_GetViewportRect)( + const PR_RenderContextH render_contextH, /* >> */ + A_LegacyRect *viewport_rectPR); /* << */ + + + SPAPI A_Err (*AEGP_GetFallowColor)( + const PR_RenderContextH render_contextH, /* >> */ + PF_Pixel8 *fallow_colorP); /* << */ + + SPAPI A_Err (*AEGP_GetInteractiveBuffer)( + const PR_RenderContextH render_contextH, /* >> */ + AEGP_WorldH *buffer); /* << */ + + SPAPI A_Err (*AEGP_GetInteractiveCheckerboard)( + const PR_RenderContextH render_contextH, /* in */ + A_Boolean *checkerboard_onPB);/* out */ + + SPAPI A_Err (*AEGP_GetInteractiveCheckerboardColors)( + const PR_RenderContextH render_contextH, /* in */ + PF_Pixel *checkerboard_color1P, /* out */ + PF_Pixel *checkerboard_color2P); /* out */ + + SPAPI A_Err (*AEGP_GetInteractiveCheckerboardSize)( + const PR_RenderContextH render_contextH, /* in */ + A_u_long *checkerboard_widthPLu, /* out - width of square*/ + A_u_long *checkerboard_heightPLu); /* out - height of square*/ + + SPAPI A_Err (*AEGP_GetInteractiveCachedBuffer)( + const PR_RenderContextH render_contextH, /* >> */ + AEGP_WorldH *buffer); /* << */ + + + // should we call AEGP_RenderLayer or AEGP_RenderTexture + SPAPI A_Err (*AEGP_ArtisanMustRenderAsLayer)( + const PR_RenderContextH render_contextH, /* >> */ + AEGP_RenderLayerContextH layer_contextH, + A_Boolean *use_render_texturePB); + + + SPAPI A_Err (*AEGP_GetInteractiveDisplayChannel)( + const PR_RenderContextH render_contextH, /* >> */ + AEGP_DisplayChannelType *display_channelP); /* << */ + + SPAPI A_Err (*AEGP_GetInteractiveExposure)( + const PR_RenderContextH render_contextH, /* >> */ + A_FpLong *exposurePF); /* << */ + + + SPAPI A_Err (*AEGP_GetColorTransform)( + const PR_RenderContextH render_contextH, /* >> */ + A_Boolean *cms_onB, + A_u_long *xform_keyLu, + void *xformP); + + + SPAPI A_Err (*AEGP_GetCompShutterTime)( + PR_RenderContextH render_contextH, /* >> */ + A_Time *shutter_time, /* << */ + A_Time *shutter_dur); + +} AEGP_CanvasSuite7; + + + + +#define kAEGPMaskOutlineSuite "AEGP Mask Outline Suite" +#define kAEGPMaskOutlineSuiteVersion2 3 /* frozen in AE 5.5 */ + +typedef struct AEGP_MaskOutlineSuite2 { + + SPAPI A_Err (*AEGP_IsMaskOutlineOpen)( + AEGP_MaskOutlineValH mask_outlineH, /* >> */ + A_Boolean *openPB); /* << */ + + SPAPI A_Err (*AEGP_SetMaskOutlineOpen)( + AEGP_MaskOutlineValH mask_outlineH, /* >> */ + A_Boolean openB); /* >> */ + + // N segments means there are segments [0..N-1]; segment J is defined by vertex J & J+1 + SPAPI A_Err (*AEGP_GetMaskOutlineNumSegments)( + AEGP_MaskOutlineValH mask_outlineH, /* >> */ + A_long *num_segmentsPL); /* << */ + + // which_pointL range: [0..num_segments]; for closed masks vertex[0] == vertex[num_segments] + SPAPI A_Err (*AEGP_GetMaskOutlineVertexInfo)( + AEGP_MaskOutlineValH mask_outlineH, /* >> */ + AEGP_VertexIndex which_pointL, /* >> */ + AEGP_MaskVertex *vertexP); /* << tangents are relative to position */ + + // Setting vertex 0 is special. Its in tangent will actually set the out tangent + // of the last vertex in the outline. + SPAPI A_Err (*AEGP_SetMaskOutlineVertexInfo)( + AEGP_MaskOutlineValH mask_outlineH, /* >> */ + AEGP_VertexIndex which_pointL, /* >> must already exists (use Create) */ + const AEGP_MaskVertex *vertexP); /* >> tangents are relative to position */ + + SPAPI A_Err (*AEGP_CreateVertex)( + AEGP_MaskOutlineValH mask_outlineH, /* >> */ + AEGP_VertexIndex insert_position); /* >> will insert at this index. moving other verticies index++*/ + + SPAPI A_Err (*AEGP_DeleteVertex)( + AEGP_MaskOutlineValH mask_outlineH, /* >> */ + AEGP_VertexIndex index); /* >> */ + +} AEGP_MaskOutlineSuite2; + +#define kAEGPMaskOutlineSuiteVersion1 2 /* frozen in AE 5.0 */ + +typedef struct AEGP_MaskOutlineSuite1 { + + SPAPI A_Err (*AEGP_IsMaskOutlineOpen)( + AEGP_MaskOutlineValH mask_outlineH, /* >> */ + A_Boolean *openPB); /* << */ + + // N segments means there are segments [0..N-1]; segment J is defined by vertex J & J+1 + SPAPI A_Err (*AEGP_GetMaskOutlineNumSegments)( + AEGP_MaskOutlineValH mask_outlineH, /* >> */ + A_long *num_segmentsPL); /* << */ + + // which_pointL range: [0..num_segments]; for closed masks vertex[0] == vertex[num_segments] + SPAPI A_Err (*AEGP_GetMaskOutlineVertexInfo)( + AEGP_MaskOutlineValH mask_outlineH, /* >> */ + AEGP_VertexIndex which_pointL, /* >> */ + AEGP_MaskVertex *vertexP); /* << tangents are relative to position */ + + // Setting vertex 0 is special. Its in tangent will actually set the out tangent + // of the last vertex in the outline. + SPAPI A_Err (*AEGP_SetMaskOutlineVertexInfo)( + AEGP_MaskOutlineValH mask_outlineH, /* >> */ + AEGP_VertexIndex which_pointL, /* >> must already exists (use Create) */ + const AEGP_MaskVertex *vertexP); /* >> tangents are relative to position */ + + SPAPI A_Err (*AEGP_CreateVertex)( + AEGP_MaskOutlineValH mask_outlineH, /* >> */ + AEGP_VertexIndex insert_position); /* >> will insert at this index. moving other verticies index++*/ + + SPAPI A_Err (*AEGP_DeleteVertex)( + AEGP_MaskOutlineValH mask_outlineH, /* >> */ + AEGP_VertexIndex index); /* >> */ + +} AEGP_MaskOutlineSuite1; + + +#define kAEGPCompSuite "AEGP Comp Suite" +#define kAEGPCompSuiteVersion10 21 /* frozen in AE 12 */ + +typedef struct AEGP_CompSuite10 { + + SPAPI A_Err (*AEGP_GetCompFromItem)( // error if item isn't AEGP_ItemType_COMP! + AEGP_ItemH itemH, /* >> */ + AEGP_CompH *compPH); /* << */ + + SPAPI A_Err (*AEGP_GetItemFromComp)( + AEGP_CompH compH, /* >> */ + AEGP_ItemH *itemPH); /* << */ + + SPAPI A_Err (*AEGP_GetCompDownsampleFactor)( + AEGP_CompH compH, /* >> */ + AEGP_DownsampleFactor *dsfP); /* << */ + + SPAPI A_Err (*AEGP_SetCompDownsampleFactor)( + AEGP_CompH compH, /* <> */ + const AEGP_DownsampleFactor *dsfP); /* >> */ + + SPAPI A_Err (*AEGP_GetCompBGColor)( + AEGP_CompH compH, /* >> */ + AEGP_ColorVal *bg_colorP); /* << */ + + SPAPI A_Err (*AEGP_SetCompBGColor)( + AEGP_CompH compH, /* >> */ + const AEGP_ColorVal *bg_colorP); /* >> */ + + SPAPI A_Err (*AEGP_GetCompFlags)( + AEGP_CompH compH, /* >> */ + AEGP_CompFlags *comp_flagsP); /* << */ + + /*Opens the comp*/ + SPAPI A_Err (*AEGP_GetShowLayerNameOrSourceName)( + AEGP_CompH compH, /* >> */ + A_Boolean *layer_names_shownPB); /* << true if layer names, false if source names */ + + /*Opens the comp*/ + SPAPI A_Err (*AEGP_SetShowLayerNameOrSourceName)( + AEGP_CompH compH, /* >> */ + A_Boolean show_layer_namesB); /* >> true to show layer names, false to show source names */ + + /*Opens the comp*/ + SPAPI A_Err (*AEGP_GetShowBlendModes)( + AEGP_CompH compH, /* >> */ + A_Boolean *blend_modes_shownPB); /* << */ + + /*Opens the comp*/ + SPAPI A_Err (*AEGP_SetShowBlendModes)( + AEGP_CompH compH, /* >> */ + A_Boolean show_blend_modesB); /* << */ + + SPAPI A_Err (*AEGP_GetCompFramerate)( + AEGP_CompH compH, /* >> */ + A_FpLong *fpsPF); /* << */ + + SPAPI A_Err (*AEGP_SetCompFrameRate)( + AEGP_CompH compH, /* >> */ + const A_FpLong *fpsPF); /* >> */ + + SPAPI A_Err (*AEGP_GetCompShutterAnglePhase)( + AEGP_CompH compH, /* >> */ + A_Ratio *angle, /* << */ + A_Ratio *phase); /* << */ + + SPAPI A_Err (*AEGP_GetCompShutterFrameRange)( + AEGP_CompH compH, /* >> */ + const A_Time *comp_timeP, /* >> */ + A_Time *start, /* << */ + A_Time *duration); /* << */ + + SPAPI A_Err (*AEGP_GetCompSuggestedMotionBlurSamples)( + AEGP_CompH compH, /* >> */ + A_long *samplesPL); /* << */ + + SPAPI A_Err (*AEGP_SetCompSuggestedMotionBlurSamples)( /* UNDOABLE */ + AEGP_CompH compH, /* >> */ + A_long samplesL); /* >> */ + + SPAPI A_Err (*AEGP_GetCompMotionBlurAdaptiveSampleLimit)( + AEGP_CompH compH, /* >> */ + A_long *samplesPL); /* << */ + + SPAPI A_Err (*AEGP_SetCompMotionBlurAdaptiveSampleLimit)( /* UNDOABLE */ + AEGP_CompH compH, /* >> */ + A_long samplesL); /* >> */ + + SPAPI A_Err (*AEGP_GetCompWorkAreaStart)( + AEGP_CompH compH, /* >> */ + A_Time *work_area_startPT); /* << */ + + SPAPI A_Err (*AEGP_GetCompWorkAreaDuration)( + AEGP_CompH compH, /* >> */ + A_Time *work_area_durationPT); /* << */ + + SPAPI A_Err (*AEGP_SetCompWorkAreaStartAndDuration)( /* UNDOABLE */ + AEGP_CompH compH, /* >> */ + const A_Time *work_area_startPT, /* >> */ + const A_Time *work_area_durationPT); /* >> */ + + SPAPI A_Err (*AEGP_CreateSolidInComp)( + const A_UTF16Char *utf_nameZ, /* >> */ + A_long width, /* >> */ + A_long height, /* >> */ + const AEGP_ColorVal *color, /* >> */ + AEGP_CompH parent_compH, /* >> */ + const A_Time *durationPT0, /* >> */ + AEGP_LayerH *new_solidPH); /* << */ + + SPAPI A_Err (*AEGP_CreateCameraInComp)( + const A_UTF16Char *utf_nameZ, /* >> */ + A_FloatPoint center_point, /* >> */ + AEGP_CompH parent_compH, /* >> */ + AEGP_LayerH *new_cameraPH); /* << */ + + SPAPI A_Err (*AEGP_CreateLightInComp)( + const A_UTF16Char *utf_nameZ, /* >> */ + A_FloatPoint center_point, /* >> */ + AEGP_CompH parent_compH, /* >> */ + AEGP_LayerH *new_lightPH); /* << */ + + SPAPI A_Err (*AEGP_CreateComp)( + AEGP_ItemH parent_folderH0, /* >> */ + const A_UTF16Char *utf_nameZ, /* >> */ + A_long widthL, /* >> */ + A_long heightL, /* >> */ + const A_Ratio *pixel_aspect_ratioPRt, /* >> */ + const A_Time *durationPT, /* >> */ + const A_Ratio *frameratePRt, /* >> */ + AEGP_CompH *new_compPH); /* << */ + + SPAPI A_Err (*AEGP_GetNewCollectionFromCompSelection)( + AEGP_PluginID plugin_id, /* >> */ + AEGP_CompH compH, /* >> */ + AEGP_Collection2H *collectionPH); /* << */ + + SPAPI A_Err (*AEGP_SetSelection)( + AEGP_CompH compH, /* >> */ + AEGP_Collection2H collectionH); /* >> not adopted */ + + SPAPI A_Err (*AEGP_GetCompDisplayStartTime)( + AEGP_CompH compH, /* >> */ + A_Time *start_timePT); /* << */ + + SPAPI A_Err (*AEGP_SetCompDisplayStartTime)( /* NOT Undoable! */ + AEGP_CompH compH, /* >> */ + const A_Time *start_timePT); /* >> */ + + SPAPI A_Err (*AEGP_SetCompDuration)( + AEGP_CompH compH, /* >> */ + const A_Time *durationPT); /* >> */ + + SPAPI A_Err (*AEGP_CreateNullInComp)( + const A_UTF16Char *utf_nameZ, /* >> */ + AEGP_CompH parent_compH, /* >> */ + const A_Time *durationPT0, /* >> */ + AEGP_LayerH *new_null_solidPH); /* << */ + + SPAPI A_Err (*AEGP_SetCompPixelAspectRatio)( + AEGP_CompH compH, /* >> */ + const A_Ratio *pix_aspectratioPRt); /* >> */ + + SPAPI A_Err (*AEGP_CreateTextLayerInComp)( + AEGP_CompH parent_compH, /* >> */ + A_Boolean select_new_layerB, /* >> */ + AEGP_LayerH *new_text_layerPH); /* << */ + + SPAPI A_Err (*AEGP_CreateBoxTextLayerInComp)( + AEGP_CompH parent_compH, /* >> */ + A_Boolean select_new_layerB, /* >> */ + A_FloatPoint box_dimensions, /* >> */ // (width and height) + AEGP_LayerH *new_text_layerPH); /* << */ + + SPAPI A_Err (*AEGP_SetCompDimensions)( + AEGP_CompH compH, /* >> */ + A_long widthL, /* >> */ + A_long heightL); /* >> */ + + SPAPI A_Err (*AEGP_DuplicateComp)( + AEGP_CompH compH, /* >> */ + AEGP_CompH *new_compPH); /* << */ + + SPAPI A_Err (*AEGP_GetCompFrameDuration)( + AEGP_CompH compH, /* >> */ + A_Time *timeP); /* << */ + + SPAPI A_Err (*AEGP_GetMostRecentlyUsedComp)( + AEGP_CompH *compPH); /* << If compPH returns NULL, there's no available comp */ + + SPAPI A_Err (*AEGP_CreateVectorLayerInComp)( + AEGP_CompH parent_compH, /* >> */ + AEGP_LayerH *new_vector_layerPH); /* << */ + + SPAPI A_Err (*AEGP_GetNewCompMarkerStream)( + AEGP_PluginID aegp_plugin_id, /* >> */ + AEGP_CompH parent_compH, /* >> */ + AEGP_StreamRefH *streamPH); /* << must be disposed by caller */ + + SPAPI A_Err (*AEGP_GetCompDisplayDropFrame)( + AEGP_CompH compH, /* >> */ + A_Boolean *dropFramePB); /* << */ + + SPAPI A_Err (*AEGP_SetCompDisplayDropFrame)( + AEGP_CompH compH, /* >> */ + A_Boolean dropFrameB); /* << */ + +} AEGP_CompSuite10; + + +#define kAEGPCompSuiteVersion9 19 /* frozen in AE 11 */ + +typedef struct AEGP_CompSuite9 { + + SPAPI A_Err (*AEGP_GetCompFromItem)( // error if item isn't AEGP_ItemType_COMP! + AEGP_ItemH itemH, /* >> */ + AEGP_CompH *compPH); /* << */ + + SPAPI A_Err (*AEGP_GetItemFromComp)( + AEGP_CompH compH, /* >> */ + AEGP_ItemH *itemPH); /* << */ + + SPAPI A_Err (*AEGP_GetCompDownsampleFactor)( + AEGP_CompH compH, /* >> */ + AEGP_DownsampleFactor *dsfP); /* << */ + + SPAPI A_Err (*AEGP_SetCompDownsampleFactor)( + AEGP_CompH compH, /* <> */ + const AEGP_DownsampleFactor *dsfP); /* >> */ + + SPAPI A_Err (*AEGP_GetCompBGColor)( + AEGP_CompH compH, /* >> */ + AEGP_ColorVal *bg_colorP); /* << */ + + SPAPI A_Err (*AEGP_SetCompBGColor)( + AEGP_CompH compH, /* >> */ + const AEGP_ColorVal *bg_colorP); /* >> */ + + SPAPI A_Err (*AEGP_GetCompFlags)( + AEGP_CompH compH, /* >> */ + AEGP_CompFlags *comp_flagsP); /* << */ + + SPAPI A_Err (*AEGP_GetCompFramerate)( + AEGP_CompH compH, /* >> */ + A_FpLong *fpsPF); /* << */ + + SPAPI A_Err (*AEGP_SetCompFrameRate)( + AEGP_CompH compH, /* >> */ + const A_FpLong *fpsPF); /* >> */ + + SPAPI A_Err (*AEGP_GetCompShutterAnglePhase)( + AEGP_CompH compH, /* >> */ + A_Ratio *angle, /* << */ + A_Ratio *phase); /* << */ + + SPAPI A_Err (*AEGP_GetCompShutterFrameRange)( + AEGP_CompH compH, /* >> */ + const A_Time *comp_timeP, /* >> */ + A_Time *start, /* << */ + A_Time *duration); /* << */ + + SPAPI A_Err (*AEGP_GetCompSuggestedMotionBlurSamples)( + AEGP_CompH compH, /* >> */ + A_long *samplesPL); /* << */ + + SPAPI A_Err (*AEGP_SetCompSuggestedMotionBlurSamples)( /* UNDOABLE */ + AEGP_CompH compH, /* >> */ + A_long samplesL); /* >> */ + + SPAPI A_Err (*AEGP_GetCompWorkAreaStart)( + AEGP_CompH compH, /* >> */ + A_Time *work_area_startPT); /* << */ + + SPAPI A_Err (*AEGP_GetCompWorkAreaDuration)( + AEGP_CompH compH, /* >> */ + A_Time *work_area_durationPT); /* << */ + + SPAPI A_Err (*AEGP_SetCompWorkAreaStartAndDuration)( /* UNDOABLE */ + AEGP_CompH compH, /* >> */ + const A_Time *work_area_startPT, /* >> */ + const A_Time *work_area_durationPT); /* >> */ + + SPAPI A_Err (*AEGP_CreateSolidInComp)( + const A_UTF16Char *utf_nameZ, /* >> */ + A_long width, /* >> */ + A_long height, /* >> */ + const AEGP_ColorVal *color, /* >> */ + AEGP_CompH parent_compH, /* >> */ + const A_Time *durationPT0, /* >> */ + AEGP_LayerH *new_solidPH); /* << */ + + SPAPI A_Err (*AEGP_CreateCameraInComp)( + const A_UTF16Char *utf_nameZ, /* >> */ + A_FloatPoint center_point, /* >> */ + AEGP_CompH parent_compH, /* >> */ + AEGP_LayerH *new_cameraPH); /* << */ + + SPAPI A_Err (*AEGP_CreateLightInComp)( + const A_UTF16Char *utf_nameZ, /* >> */ + A_FloatPoint center_point, /* >> */ + AEGP_CompH parent_compH, /* >> */ + AEGP_LayerH *new_lightPH); /* << */ + + SPAPI A_Err (*AEGP_CreateComp)( + AEGP_ItemH parent_folderH0, /* >> */ + const A_UTF16Char *utf_nameZ, /* >> */ + A_long widthL, /* >> */ + A_long heightL, /* >> */ + const A_Ratio *pixel_aspect_ratioPRt, /* >> */ + const A_Time *durationPT, /* >> */ + const A_Ratio *frameratePRt, /* >> */ + AEGP_CompH *new_compPH); /* << */ + + SPAPI A_Err (*AEGP_GetNewCollectionFromCompSelection)( + AEGP_PluginID plugin_id, /* >> */ + AEGP_CompH compH, /* >> */ + AEGP_Collection2H *collectionPH); /* << */ + + SPAPI A_Err (*AEGP_SetSelection)( + AEGP_CompH compH, /* >> */ + AEGP_Collection2H collectionH); /* >> not adopted */ + + SPAPI A_Err (*AEGP_GetCompDisplayStartTime)( + AEGP_CompH compH, /* >> */ + A_Time *start_timePT); /* << */ + + SPAPI A_Err (*AEGP_SetCompDisplayStartTime)( /* NOT Undoable! */ + AEGP_CompH compH, /* >> */ + const A_Time *start_timePT); /* >> */ + + SPAPI A_Err (*AEGP_SetCompDuration)( + AEGP_CompH compH, /* >> */ + const A_Time *durationPT); /* >> */ + + SPAPI A_Err (*AEGP_CreateNullInComp)( + const A_UTF16Char *utf_nameZ, /* >> */ + AEGP_CompH parent_compH, /* >> */ + const A_Time *durationPT0, /* >> */ + AEGP_LayerH *new_null_solidPH); /* << */ + + SPAPI A_Err (*AEGP_SetCompPixelAspectRatio)( + AEGP_CompH compH, /* >> */ + const A_Ratio *pix_aspectratioPRt); /* >> */ + + SPAPI A_Err (*AEGP_CreateTextLayerInComp)( + AEGP_CompH parent_compH, /* >> */ + A_Boolean select_new_layerB, /* >> */ + AEGP_LayerH *new_text_layerPH); /* << */ + + SPAPI A_Err (*AEGP_CreateBoxTextLayerInComp)( + AEGP_CompH parent_compH, /* >> */ + A_Boolean select_new_layerB, /* >> */ + A_FloatPoint box_dimensions, /* >> */ // (width and height) + AEGP_LayerH *new_text_layerPH); /* << */ + + SPAPI A_Err (*AEGP_SetCompDimensions)( + AEGP_CompH compH, /* >> */ + A_long widthL, /* >> */ + A_long heightL); /* >> */ + + SPAPI A_Err (*AEGP_DuplicateComp)( + AEGP_CompH compH, /* >> */ + AEGP_CompH *new_compPH); /* << */ + + SPAPI A_Err (*AEGP_GetCompFrameDuration)( + AEGP_CompH compH, /* >> */ + A_Time *timeP); /* << */ + + SPAPI A_Err (*AEGP_GetMostRecentlyUsedComp)( + AEGP_CompH *compPH); /* << If compPH returns NULL, there's no available comp */ + + SPAPI A_Err (*AEGP_CreateVectorLayerInComp)( + AEGP_CompH parent_compH, /* >> */ + AEGP_LayerH *new_vector_layerPH); /* << */ + + SPAPI A_Err (*AEGP_GetNewCompMarkerStream)( + AEGP_PluginID aegp_plugin_id, /* >> */ + AEGP_CompH parent_compH, /* >> */ + AEGP_StreamRefH *streamPH); /* << must be disposed by caller */ + + SPAPI A_Err (*AEGP_GetCompDisplayDropFrame)( + AEGP_CompH compH, /* >> */ + A_Boolean *dropFramePB); /* << */ + + SPAPI A_Err (*AEGP_SetCompDisplayDropFrame)( + AEGP_CompH compH, /* >> */ + A_Boolean dropFrameB); /* << */ + + +} AEGP_CompSuite9; + + +#define kAEGPCompSuiteVersion8 18 /* frozen in AE 10.5 */ + +typedef struct AEGP_CompSuite8 { + + SPAPI A_Err (*AEGP_GetCompFromItem)( // error if item isn't AEGP_ItemType_COMP! + AEGP_ItemH itemH, /* >> */ + AEGP_CompH *compPH); /* << */ + + SPAPI A_Err (*AEGP_GetItemFromComp)( + AEGP_CompH compH, /* >> */ + AEGP_ItemH *itemPH); /* << */ + + SPAPI A_Err (*AEGP_GetCompDownsampleFactor)( + AEGP_CompH compH, /* >> */ + AEGP_DownsampleFactor *dsfP); /* << */ + + SPAPI A_Err (*AEGP_SetCompDownsampleFactor)( + AEGP_CompH compH, /* <> */ + const AEGP_DownsampleFactor *dsfP); /* >> */ + + SPAPI A_Err (*AEGP_GetCompBGColor)( + AEGP_CompH compH, /* >> */ + AEGP_ColorVal *bg_colorP); /* << */ + + SPAPI A_Err (*AEGP_SetCompBGColor)( + AEGP_CompH compH, /* >> */ + const AEGP_ColorVal *bg_colorP); /* >> */ + + SPAPI A_Err (*AEGP_GetCompFlags)( + AEGP_CompH compH, /* >> */ + AEGP_CompFlags *comp_flagsP); /* << */ + + SPAPI A_Err (*AEGP_GetCompFramerate)( + AEGP_CompH compH, /* >> */ + A_FpLong *fpsPF); /* << */ + + SPAPI A_Err (*AEGP_SetCompFrameRate)( + AEGP_CompH compH, /* >> */ + const A_FpLong *fpsPF); /* >> */ + + SPAPI A_Err (*AEGP_GetCompShutterAnglePhase)( + AEGP_CompH compH, /* >> */ + A_Ratio *angle, /* << */ + A_Ratio *phase); /* << */ + + SPAPI A_Err (*AEGP_GetCompShutterFrameRange)( + AEGP_CompH compH, /* >> */ + const A_Time *comp_timeP, /* >> */ + A_Time *start, /* << */ + A_Time *duration); /* << */ + + SPAPI A_Err (*AEGP_GetCompSuggestedMotionBlurSamples)( + AEGP_CompH compH, /* >> */ + A_long *samplesPL); /* << */ + + SPAPI A_Err (*AEGP_SetCompSuggestedMotionBlurSamples)( /* UNDOABLE */ + AEGP_CompH compH, /* >> */ + A_long samplesL); /* >> */ + + SPAPI A_Err (*AEGP_GetCompWorkAreaStart)( + AEGP_CompH compH, /* >> */ + A_Time *work_area_startPT); /* << */ + + SPAPI A_Err (*AEGP_GetCompWorkAreaDuration)( + AEGP_CompH compH, /* >> */ + A_Time *work_area_durationPT); /* << */ + + SPAPI A_Err (*AEGP_SetCompWorkAreaStartAndDuration)( /* UNDOABLE */ + AEGP_CompH compH, /* >> */ + const A_Time *work_area_startPT, /* >> */ + const A_Time *work_area_durationPT); /* >> */ + + SPAPI A_Err (*AEGP_CreateSolidInComp)( + const A_UTF16Char *utf_nameZ, /* >> */ + A_long width, /* >> */ + A_long height, /* >> */ + const AEGP_ColorVal *color, /* >> */ + AEGP_CompH parent_compH, /* >> */ + const A_Time *durationPT0, /* >> */ + AEGP_LayerH *new_solidPH); /* << */ + + SPAPI A_Err (*AEGP_CreateCameraInComp)( + const A_UTF16Char *utf_nameZ, /* >> */ + A_FloatPoint center_point, /* >> */ + AEGP_CompH parent_compH, /* >> */ + AEGP_LayerH *new_cameraPH); /* << */ + + SPAPI A_Err (*AEGP_CreateLightInComp)( + const A_UTF16Char *utf_nameZ, /* >> */ + A_FloatPoint center_point, /* >> */ + AEGP_CompH parent_compH, /* >> */ + AEGP_LayerH *new_lightPH); /* << */ + + SPAPI A_Err (*AEGP_CreateComp)( + AEGP_ItemH parent_folderH0, /* >> */ + const A_UTF16Char *utf_nameZ, /* >> */ + A_long widthL, /* >> */ + A_long heightL, /* >> */ + const A_Ratio *pixel_aspect_ratioPRt, /* >> */ + const A_Time *durationPT, /* >> */ + const A_Ratio *frameratePRt, /* >> */ + AEGP_CompH *new_compPH); /* << */ + + SPAPI A_Err (*AEGP_GetNewCollectionFromCompSelection)( + AEGP_PluginID plugin_id, /* >> */ + AEGP_CompH compH, /* >> */ + AEGP_Collection2H *collectionPH); /* << */ + + SPAPI A_Err (*AEGP_SetSelection)( + AEGP_CompH compH, /* >> */ + AEGP_Collection2H collectionH); /* >> not adopted */ + + SPAPI A_Err (*AEGP_GetCompDisplayStartTime)( + AEGP_CompH compH, /* >> */ + A_Time *start_timePT); /* << */ + + SPAPI A_Err (*AEGP_SetCompDisplayStartTime)( /* NOT Undoable! */ + AEGP_CompH compH, /* >> */ + const A_Time *start_timePT); /* >> */ + + SPAPI A_Err (*AEGP_SetCompDuration)( + AEGP_CompH compH, /* >> */ + const A_Time *durationPT); /* >> */ + + SPAPI A_Err (*AEGP_CreateNullInComp)( + const A_UTF16Char *utf_nameZ, /* >> */ + AEGP_CompH parent_compH, /* >> */ + const A_Time *durationPT0, /* >> */ + AEGP_LayerH *new_null_solidPH); /* << */ + + SPAPI A_Err (*AEGP_SetCompPixelAspectRatio)( + AEGP_CompH compH, /* >> */ + const A_Ratio *pix_aspectratioPRt); /* >> */ + + SPAPI A_Err (*AEGP_CreateTextLayerInComp)( + AEGP_CompH parent_compH, /* >> */ + AEGP_LayerH *new_text_layerPH); /* << */ + + SPAPI A_Err (*AEGP_CreateBoxTextLayerInComp)( + AEGP_CompH parent_compH, /* >> */ + A_FloatPoint box_dimensions, /* >> */ // (width and height) + AEGP_LayerH *new_text_layerPH); /* << */ + + SPAPI A_Err (*AEGP_SetCompDimensions)( + AEGP_CompH compH, /* >> */ + A_long widthL, /* >> */ + A_long heightL); /* >> */ + + SPAPI A_Err (*AEGP_DuplicateComp)( + AEGP_CompH compH, /* >> */ + AEGP_CompH *new_compPH); /* << */ + + SPAPI A_Err (*AEGP_GetCompFrameDuration)( + AEGP_CompH compH, /* >> */ + A_Time *timeP); /* << */ + + SPAPI A_Err (*AEGP_GetMostRecentlyUsedComp)( + AEGP_CompH *compPH); /* << If compPH returns NULL, there's no available comp */ + + SPAPI A_Err (*AEGP_CreateVectorLayerInComp)( + AEGP_CompH parent_compH, /* >> */ + AEGP_LayerH *new_vector_layerPH); /* << */ + + SPAPI A_Err (*AEGP_GetNewCompMarkerStream)( + AEGP_PluginID aegp_plugin_id, /* >> */ + AEGP_CompH parent_compH, /* >> */ + AEGP_StreamRefH *streamPH); /* << must be disposed by caller */ + + SPAPI A_Err (*AEGP_GetCompDisplayDropFrame)( + AEGP_CompH compH, /* >> */ + A_Boolean *dropFramePB); /* << */ + + SPAPI A_Err (*AEGP_SetCompDisplayDropFrame)( + AEGP_CompH compH, /* >> */ + A_Boolean dropFrameB); /* << */ + + +} AEGP_CompSuite8; + + + +#define kAEGPCompSuiteVersion7 15 /* frozen in AE 9.0 */ + +typedef struct AEGP_CompSuite7 { + + SPAPI A_Err (*AEGP_GetCompFromItem)( // error if item isn't AEGP_ItemType_COMP! + AEGP_ItemH itemH, /* >> */ + AEGP_CompH *compPH); /* << */ + + SPAPI A_Err (*AEGP_GetItemFromComp)( + AEGP_CompH compH, /* >> */ + AEGP_ItemH *itemPH); /* << */ + + SPAPI A_Err (*AEGP_GetCompDownsampleFactor)( + AEGP_CompH compH, /* >> */ + AEGP_DownsampleFactor *dsfP); /* << */ + + SPAPI A_Err (*AEGP_SetCompDownsampleFactor)( + AEGP_CompH compH, /* <> */ + const AEGP_DownsampleFactor *dsfP); /* >> */ + + SPAPI A_Err (*AEGP_GetCompBGColor)( + AEGP_CompH compH, /* >> */ + AEGP_ColorVal *bg_colorP); /* << */ + + SPAPI A_Err (*AEGP_SetCompBGColor)( + AEGP_CompH compH, /* >> */ + const AEGP_ColorVal *bg_colorP); /* >> */ + + SPAPI A_Err (*AEGP_GetCompFlags)( + AEGP_CompH compH, /* >> */ + AEGP_CompFlags *comp_flagsP); /* << */ + + SPAPI A_Err (*AEGP_GetCompFramerate)( + AEGP_CompH compH, /* >> */ + A_FpLong *fpsPF); /* << */ + + SPAPI A_Err (*AEGP_SetCompFrameRate)( + AEGP_CompH compH, /* >> */ + const A_FpLong *fpsPF); /* >> */ + + SPAPI A_Err (*AEGP_GetCompShutterAnglePhase)( + AEGP_CompH compH, /* >> */ + A_Ratio *angle, /* << */ + A_Ratio *phase); /* << */ + + SPAPI A_Err (*AEGP_GetCompShutterFrameRange)( + AEGP_CompH compH, /* >> */ + const A_Time *comp_timeP, /* >> */ + A_Time *start, /* << */ + A_Time *duration); /* << */ + + SPAPI A_Err (*AEGP_GetCompSuggestedMotionBlurSamples)( + AEGP_CompH compH, /* >> */ + A_long *samplesPL); /* << */ + + SPAPI A_Err (*AEGP_SetCompSuggestedMotionBlurSamples)( /* UNDOABLE */ + AEGP_CompH compH, /* >> */ + A_long samplesL); /* >> */ + + SPAPI A_Err (*AEGP_GetCompWorkAreaStart)( + AEGP_CompH compH, /* >> */ + A_Time *work_area_startPT); /* << */ + + SPAPI A_Err (*AEGP_GetCompWorkAreaDuration)( + AEGP_CompH compH, /* >> */ + A_Time *work_area_durationPT); /* << */ + + SPAPI A_Err (*AEGP_SetCompWorkAreaStartAndDuration)( /* UNDOABLE */ + AEGP_CompH compH, /* >> */ + const A_Time *work_area_startPT, /* >> */ + const A_Time *work_area_durationPT); /* >> */ + + SPAPI A_Err (*AEGP_CreateSolidInComp)( + const A_UTF16Char *utf_nameZ, /* >> */ + A_long width, /* >> */ + A_long height, /* >> */ + const AEGP_ColorVal *color, /* >> */ + AEGP_CompH parent_compH, /* >> */ + const A_Time *durationPT0, /* >> */ + AEGP_LayerH *new_solidPH); /* << */ + + SPAPI A_Err (*AEGP_CreateCameraInComp)( + const A_UTF16Char *utf_nameZ, /* >> */ + A_FloatPoint center_point, /* >> */ + AEGP_CompH parent_compH, /* >> */ + AEGP_LayerH *new_cameraPH); /* << */ + + SPAPI A_Err (*AEGP_CreateLightInComp)( + const A_UTF16Char *utf_nameZ, /* >> */ + A_FloatPoint center_point, /* >> */ + AEGP_CompH parent_compH, /* >> */ + AEGP_LayerH *new_lightPH); /* << */ + + SPAPI A_Err (*AEGP_CreateComp)( + AEGP_ItemH parent_folderH0, /* >> */ + const A_UTF16Char *utf_nameZ, /* >> */ + A_long widthL, /* >> */ + A_long heightL, /* >> */ + const A_Ratio *pixel_aspect_ratioPRt, /* >> */ + const A_Time *durationPT, /* >> */ + const A_Ratio *frameratePRt, /* >> */ + AEGP_CompH *new_compPH); /* << */ + + SPAPI A_Err (*AEGP_GetNewCollectionFromCompSelection)( + AEGP_PluginID plugin_id, /* >> */ + AEGP_CompH compH, /* >> */ + AEGP_Collection2H *collectionPH); /* << */ + + SPAPI A_Err (*AEGP_SetSelection)( + AEGP_CompH compH, /* >> */ + AEGP_Collection2H collectionH); /* >> not adopted */ + + SPAPI A_Err (*AEGP_GetCompDisplayStartTime)( + AEGP_CompH compH, /* >> */ + A_Time *start_timePT); /* << */ + + SPAPI A_Err (*AEGP_SetCompDisplayStartTime)( /* NOT Undoable! */ + AEGP_CompH compH, /* >> */ + const A_Time *start_timePT); /* >> */ + + SPAPI A_Err (*AEGP_SetCompDuration)( + AEGP_CompH compH, /* >> */ + const A_Time *durationPT); /* >> */ + + SPAPI A_Err (*AEGP_CreateNullInComp)( + const A_UTF16Char *utf_nameZ, /* >> */ + AEGP_CompH parent_compH, /* >> */ + const A_Time *durationPT0, /* >> */ + AEGP_LayerH *new_null_solidPH); /* << */ + + SPAPI A_Err (*AEGP_SetCompPixelAspectRatio)( + AEGP_CompH compH, /* >> */ + const A_Ratio *pix_aspectratioPRt); /* >> */ + + SPAPI A_Err (*AEGP_CreateTextLayerInComp)( + AEGP_CompH parent_compH, /* >> */ + AEGP_LayerH *new_text_layerPH); /* << */ + + SPAPI A_Err (*AEGP_SetCompDimensions)( + AEGP_CompH compH, /* >> */ + A_long widthL, /* >> */ + A_long heightL); /* >> */ + + SPAPI A_Err (*AEGP_DuplicateComp)( + AEGP_CompH compH, /* >> */ + AEGP_CompH *new_compPH); /* << */ + + SPAPI A_Err (*AEGP_GetCompFrameDuration)( + AEGP_CompH compH, /* >> */ + A_Time *timeP); /* << */ + + SPAPI A_Err (*AEGP_GetMostRecentlyUsedComp)( + AEGP_CompH *compPH); /* << If compPH returns NULL, there's no available comp */ + + SPAPI A_Err (*AEGP_CreateVectorLayerInComp)( + AEGP_CompH parent_compH, /* >> */ + AEGP_LayerH *new_vector_layerPH); /* << */ + + SPAPI A_Err (*AEGP_GetNewCompMarkerStream)( + AEGP_PluginID aegp_plugin_id, /* >> */ + AEGP_CompH parent_compH, /* >> */ + AEGP_StreamRefH *streamPH); /* << must be disposed by caller */ + +} AEGP_CompSuite7; + + +#define kAEGPCompSuiteVersion6 14 /* frozen in AE 8.0 */ + +typedef struct AEGP_CompSuite6 { + + SPAPI A_Err (*AEGP_GetCompFromItem)( // error if item isn't AEGP_ItemType_COMP! + AEGP_ItemH itemH, /* >> */ + AEGP_CompH *compPH); /* << */ + + SPAPI A_Err (*AEGP_GetItemFromComp)( + AEGP_CompH compH, /* >> */ + AEGP_ItemH *itemPH); /* << */ + + SPAPI A_Err (*AEGP_GetCompDownsampleFactor)( + AEGP_CompH compH, /* >> */ + AEGP_DownsampleFactor *dsfP); /* << */ + + SPAPI A_Err (*AEGP_SetCompDownsampleFactor)( + AEGP_CompH compH, /* <> */ + const AEGP_DownsampleFactor *dsfP); /* >> */ + + SPAPI A_Err (*AEGP_GetCompBGColor)( + AEGP_CompH compH, /* >> */ + AEGP_ColorVal *bg_colorP); /* << */ + + SPAPI A_Err (*AEGP_SetCompBGColor)( + AEGP_CompH compH, /* >> */ + const AEGP_ColorVal *bg_colorP); /* >> */ + + SPAPI A_Err (*AEGP_GetCompFlags)( + AEGP_CompH compH, /* >> */ + AEGP_CompFlags *comp_flagsP); /* << */ + + SPAPI A_Err (*AEGP_GetCompFramerate)( + AEGP_CompH compH, /* >> */ + A_FpLong *fpsPF); /* << */ + + SPAPI A_Err (*AEGP_SetCompFrameRate)( + AEGP_CompH compH, /* >> */ + const A_FpLong *fpsPF); /* >> */ + + SPAPI A_Err (*AEGP_GetCompShutterAnglePhase)( + AEGP_CompH compH, /* >> */ + A_Ratio *angle, /* << */ + A_Ratio *phase); /* << */ + + SPAPI A_Err (*AEGP_GetCompShutterFrameRange)( + AEGP_CompH compH, /* >> */ + const A_Time *comp_timeP, /* >> */ + A_Time *start, /* << */ + A_Time *duration); /* << */ + + SPAPI A_Err (*AEGP_GetCompSuggestedMotionBlurSamples)( + AEGP_CompH compH, /* >> */ + A_long *samplesPL); /* << */ + + SPAPI A_Err (*AEGP_SetCompSuggestedMotionBlurSamples)( /* UNDOABLE */ + AEGP_CompH compH, /* >> */ + A_long samplesL); /* >> */ + + SPAPI A_Err (*AEGP_GetCompWorkAreaStart)( + AEGP_CompH compH, /* >> */ + A_Time *work_area_startPT); /* << */ + + SPAPI A_Err (*AEGP_GetCompWorkAreaDuration)( + AEGP_CompH compH, /* >> */ + A_Time *work_area_durationPT); /* << */ + + SPAPI A_Err (*AEGP_SetCompWorkAreaStartAndDuration)( /* UNDOABLE */ + AEGP_CompH compH, /* >> */ + const A_Time *work_area_startPT, /* >> */ + const A_Time *work_area_durationPT); /* >> */ + + SPAPI A_Err (*AEGP_CreateSolidInComp)( + const A_char *nameZ, /* >> */ + A_long width, /* >> */ + A_long height, /* >> */ + const AEGP_ColorVal *color, /* >> */ + AEGP_CompH parent_compH, /* >> */ + const A_Time *durationPT0, /* >> */ + AEGP_LayerH *new_solidPH); /* << */ + + SPAPI A_Err (*AEGP_CreateCameraInComp)( + const A_char *nameZ, /* >> */ + A_FloatPoint center_point, /* >> */ + AEGP_CompH parent_compH, /* >> */ + AEGP_LayerH *new_cameraPH); /* << */ + + SPAPI A_Err (*AEGP_CreateLightInComp)( + const A_char *nameZ, /* >> */ + A_FloatPoint center_point, /* >> */ + AEGP_CompH parent_compH, /* >> */ + AEGP_LayerH *new_lightPH); /* << */ + + SPAPI A_Err (*AEGP_CreateComp)( + AEGP_ItemH parent_folderH0, /* >> */ + const A_char *nameZ, /* >> */ + A_long widthL, /* >> */ + A_long heightL, /* >> */ + const A_Ratio *pixel_aspect_ratioPRt, /* >> */ + const A_Time *durationPT, /* >> */ + const A_Ratio *frameratePRt, /* >> */ + AEGP_CompH *new_compPH); /* << */ + + SPAPI A_Err (*AEGP_GetNewCollectionFromCompSelection)( + AEGP_PluginID plugin_id, /* >> */ + AEGP_CompH compH, /* >> */ + AEGP_Collection2H *collectionPH); /* << */ + + SPAPI A_Err (*AEGP_SetSelection)( + AEGP_CompH compH, /* >> */ + AEGP_Collection2H collectionH); /* >> not adopted */ + + SPAPI A_Err (*AEGP_GetCompDisplayStartTime)( + AEGP_CompH compH, /* >> */ + A_Time *start_timePT); /* << */ + + SPAPI A_Err (*AEGP_SetCompDisplayStartTime)( /* NOT Undoable! */ + AEGP_CompH compH, /* >> */ + const A_Time *start_timePT); /* >> */ + + SPAPI A_Err (*AEGP_SetCompDuration)( + AEGP_CompH compH, /* >> */ + const A_Time *durationPT); /* >> */ + + SPAPI A_Err (*AEGP_CreateNullInComp)( + const A_char *nameZ, /* >> */ + AEGP_CompH parent_compH, /* >> */ + const A_Time *durationPT0, /* >> */ + AEGP_LayerH *new_null_solidPH); /* << */ + + SPAPI A_Err (*AEGP_SetCompPixelAspectRatio)( + AEGP_CompH compH, /* >> */ + const A_Ratio *pix_aspectratioPRt); /* >> */ + + SPAPI A_Err (*AEGP_CreateTextLayerInComp)( + AEGP_CompH parent_compH, /* >> */ + AEGP_LayerH *new_text_layerPH); /* << */ + + SPAPI A_Err (*AEGP_SetCompDimensions)( + AEGP_CompH compH, /* >> */ + A_long widthL, /* >> */ + A_long heightL); /* >> */ + + SPAPI A_Err (*AEGP_DuplicateComp)( + AEGP_CompH compH, /* >> */ + AEGP_CompH *new_compPH); /* << */ + + SPAPI A_Err (*AEGP_GetCompFrameDuration)( + AEGP_CompH compH, /* >> */ + A_Time *timeP); /* << */ + + SPAPI A_Err (*AEGP_GetMostRecentlyUsedComp)( + AEGP_CompH *compPH); /* << If compPH returns NULL, there's no available comp */ + + SPAPI A_Err (*AEGP_CreateVectorLayerInComp)( + AEGP_CompH parent_compH, /* >> */ + AEGP_LayerH *new_vector_layerPH); /* << */ + + SPAPI A_Err (*AEGP_GetNewCompMarkerStream)( + AEGP_PluginID aegp_plugin_id, /* >> */ + AEGP_CompH parent_compH, /* >> */ + AEGP_StreamRefH *streamPH); /* << must be disposed by caller */ + +} AEGP_CompSuite6; + + +#define kAEGPCompSuiteVersion5 11 /* frozen AE 7.0 */ + +typedef struct AEGP_CompSuite5 { + + SPAPI A_Err (*AEGP_GetCompFromItem)( // error if item isn't AEGP_ItemType_COMP! + AEGP_ItemH itemH, /* >> */ + AEGP_CompH *compPH); /* << */ + + SPAPI A_Err (*AEGP_GetItemFromComp)( + AEGP_CompH compH, /* >> */ + AEGP_ItemH *itemPH); /* << */ + + SPAPI A_Err (*AEGP_GetCompDownsampleFactor)( + AEGP_CompH compH, /* >> */ + AEGP_DownsampleFactor *dsfP); /* << */ + + SPAPI A_Err (*AEGP_SetCompDownsampleFactor)( + AEGP_CompH compH, /* <> */ + const AEGP_DownsampleFactor *dsfP); /* >> */ + + SPAPI A_Err (*AEGP_GetCompBGColor)( + AEGP_CompH compH, /* >> */ + AEGP_ColorVal *bg_colorP); /* << */ + + SPAPI A_Err (*AEGP_SetCompBGColor)( + AEGP_CompH compH, /* >> */ + const AEGP_ColorVal *bg_colorP); /* >> */ + + SPAPI A_Err (*AEGP_GetCompFlags)( + AEGP_CompH compH, /* >> */ + AEGP_CompFlags *comp_flagsP); /* << */ + + SPAPI A_Err (*AEGP_GetCompFramerate)( + AEGP_CompH compH, /* >> */ + A_FpLong *fpsPF); /* << */ + + SPAPI A_Err (*AEGP_SetCompFrameRate)( + AEGP_CompH compH, /* >> */ + const A_FpLong *fpsPF); /* >> */ + + SPAPI A_Err (*AEGP_GetCompShutterAnglePhase)( + AEGP_CompH compH, /* >> */ + A_Ratio *angle, /* << */ + A_Ratio *phase); /* << */ + + SPAPI A_Err (*AEGP_GetCompShutterFrameRange)( + AEGP_CompH compH, /* >> */ + const A_Time *comp_timeP, /* >> */ + A_Time *start, /* << */ + A_Time *duration); /* << */ + + SPAPI A_Err (*AEGP_GetCompWorkAreaStart)( + AEGP_CompH compH, /* >> */ + A_Time *work_area_startPT); /* << */ + + SPAPI A_Err (*AEGP_GetCompWorkAreaDuration)( + AEGP_CompH compH, /* >> */ + A_Time *work_area_durationPT); /* << */ + + SPAPI A_Err (*AEGP_SetCompWorkAreaStartAndDuration)( /* UNDOABLE */ + AEGP_CompH compH, /* >> */ + A_Time *work_area_startPT, /* >> */ + A_Time *work_area_durationPT); /* >> */ + + SPAPI A_Err (*AEGP_CreateSolidInComp)( + const A_char *nameZ, /* >> */ + A_long width, /* >> */ + A_long height, /* >> */ + const AEGP_ColorVal *color, /* >> */ + AEGP_CompH parent_compH, /* >> */ + const A_Time *durationPT0, /* >> */ + AEGP_LayerH *new_solidPH); /* << */ + + SPAPI A_Err (*AEGP_CreateCameraInComp)( + const A_char *nameZ, /* >> */ + A_FloatPoint center_point, /* >> */ + AEGP_CompH parent_compH, /* >> */ + AEGP_LayerH *new_cameraPH); /* << */ + + SPAPI A_Err (*AEGP_CreateLightInComp)( + const A_char *nameZ, /* >> */ + A_FloatPoint center_point, /* >> */ + AEGP_CompH parent_compH, /* >> */ + AEGP_LayerH *new_lightPH); /* << */ + + SPAPI A_Err (*AEGP_CreateComp)( + AEGP_ItemH parent_folderH0, /* >> */ + const A_char *nameZ, /* >> */ + A_long widthL, /* >> */ + A_long heightL, /* >> */ + const A_Ratio *pixel_aspect_ratioPRt, /* >> */ + const A_Time *durationPT, /* >> */ + const A_Ratio *frameratePRt, /* >> */ + AEGP_CompH *new_compPH); /* << */ + + SPAPI A_Err (*AEGP_GetNewCollectionFromCompSelection)( + AEGP_PluginID plugin_id, /* >> */ + AEGP_CompH compH, /* >> */ + AEGP_Collection2H *collectionPH); /* << */ + + SPAPI A_Err (*AEGP_SetSelection)( + AEGP_CompH compH, /* >> */ + AEGP_Collection2H collectionH); /* >> not adopted */ + + SPAPI A_Err (*AEGP_GetCompDisplayStartTime)( + AEGP_CompH compH, /* >> */ + A_Time *start_timePT); /* << */ + + SPAPI A_Err (*AEGP_SetCompDisplayStartTime)( /* NOT Undoable! */ + AEGP_CompH compH, /* >> */ + const A_Time *start_timePT); /* >> */ + + SPAPI A_Err (*AEGP_SetCompDuration)( + AEGP_CompH compH, /* >> */ + const A_Time *durationPT); /* >> */ + + SPAPI A_Err (*AEGP_CreateNullInComp)( + const A_char *nameZ, /* >> */ + AEGP_CompH parent_compH, /* >> */ + const A_Time *durationPT0, /* >> */ + AEGP_LayerH *new_null_solidPH); /* << */ + + SPAPI A_Err (*AEGP_SetCompPixelAspectRatio)( + AEGP_CompH compH, /* >> */ + const A_Ratio *pix_aspectratioPRt); /* >> */ + + SPAPI A_Err (*AEGP_CreateTextLayerInComp)( + AEGP_CompH parent_compH, /* >> */ + AEGP_LayerH *new_text_layerPH); /* << */ + + SPAPI A_Err (*AEGP_SetCompDimensions)( + AEGP_CompH compH, /* >> */ + A_long widthL, /* >> */ + A_long heightL); /* >> */ + + SPAPI A_Err (*AEGP_DuplicateComp)( + AEGP_CompH compH, /* >> */ + AEGP_CompH *new_compPH); /* << */ + + SPAPI A_Err (*AEGP_GetCompFrameDuration)(AEGP_CompH compH, /* >> */ + A_Time* timeP); /* << */ + + SPAPI A_Err (*AEGP_GetMostRecentlyUsedComp)( + AEGP_CompH *compPH); /* << If compPH returns NULL, there's no available comp */ +} AEGP_CompSuite5; + + +#define kAEGPCompSuiteVersion4 9 /* frozen AE 6.5 */ + +typedef struct AEGP_CompSuite4 { + + SPAPI A_Err (*AEGP_GetCompFromItem)( // error if item isn't AEGP_ItemType_COMP! + AEGP_ItemH itemH, /* >> */ + AEGP_CompH *compPH); /* << */ + + SPAPI A_Err (*AEGP_GetItemFromComp)( + AEGP_CompH compH, /* >> */ + AEGP_ItemH *itemPH); /* << */ + + SPAPI A_Err (*AEGP_GetCompDownsampleFactor)( + AEGP_CompH compH, /* >> */ + AEGP_DownsampleFactor *dsfP); /* << */ + + SPAPI A_Err (*AEGP_SetCompDownsampleFactor)( + AEGP_CompH compH, /* <> */ + const AEGP_DownsampleFactor *dsfP); /* >> */ + + SPAPI A_Err (*AEGP_GetCompBGColor)( + AEGP_CompH compH, /* >> */ + AEGP_ColorVal *bg_colorP); /* << */ + + SPAPI A_Err (*AEGP_GetCompFlags)( + AEGP_CompH compH, /* >> */ + AEGP_CompFlags *comp_flagsP); /* << */ + + SPAPI A_Err (*AEGP_GetCompFramerate)( + AEGP_CompH compH, /* >> */ + A_FpLong *fpsPF); /* << */ + + SPAPI A_Err (*AEGP_SetCompFrameRate)( + AEGP_CompH compH, /* >> */ + const A_FpLong *fpsPF); /* >> */ + + SPAPI A_Err (*AEGP_GetCompShutterAnglePhase)( + AEGP_CompH compH, /* >> */ + A_Ratio *angle, /* << */ + A_Ratio *phase); /* << */ + + SPAPI A_Err (*AEGP_GetCompShutterFrameRange)( + AEGP_CompH compH, /* >> */ + const A_Time *comp_timeP, /* >> */ + A_Time *start, /* << */ + A_Time *duration); /* << */ + + SPAPI A_Err (*AEGP_GetCompWorkAreaStart)( + AEGP_CompH compH, /* >> */ + A_Time *work_area_startPT); /* << */ + + SPAPI A_Err (*AEGP_GetCompWorkAreaDuration)( + AEGP_CompH compH, /* >> */ + A_Time *work_area_durationPT); /* << */ + + SPAPI A_Err (*AEGP_SetCompWorkAreaStartAndDuration)( /* UNDOABLE */ + AEGP_CompH compH, /* >> */ + A_Time *work_area_startPT, /* >> */ + A_Time *work_area_durationPT); /* >> */ + + SPAPI A_Err (*AEGP_CreateSolidInComp)( + const A_char *nameZ, /* >> */ + A_long width, /* >> */ + A_long height, /* >> */ + const AEGP_ColorVal *color, /* >> */ + AEGP_CompH parent_compH, /* >> */ + const A_Time *durationPT0, /* >> */ + AEGP_LayerH *new_solidPH); /* << */ + + SPAPI A_Err (*AEGP_CreateCameraInComp)( + const A_char *nameZ, /* >> */ + A_FloatPoint center_point, /* >> */ + AEGP_CompH parent_compH, /* >> */ + AEGP_LayerH *new_cameraPH); /* << */ + + SPAPI A_Err (*AEGP_CreateLightInComp)( + const A_char *nameZ, /* >> */ + A_FloatPoint center_point, /* >> */ + AEGP_CompH parent_compH, /* >> */ + AEGP_LayerH *new_lightPH); /* << */ + + SPAPI A_Err (*AEGP_CreateComp)( + AEGP_ItemH parent_folderH0, /* >> */ + const A_char *nameZ, /* >> */ + A_long widthL, /* >> */ + A_long heightL, /* >> */ + const A_Ratio *pixel_aspect_ratioPRt, /* >> */ + const A_Time *durationPT, /* >> */ + const A_Ratio *frameratePRt, /* >> */ + AEGP_CompH *new_compPH); /* << */ + + SPAPI A_Err (*AEGP_GetNewCollectionFromCompSelection)( + AEGP_PluginID plugin_id, /* >> */ + AEGP_CompH compH, /* >> */ + AEGP_Collection2H *collectionPH); /* << */ + + SPAPI A_Err (*AEGP_SetSelection)( + AEGP_CompH compH, /* >> */ + AEGP_Collection2H collectionH); /* >> not adopted */ + + SPAPI A_Err (*AEGP_GetCompDisplayStartTime)( + AEGP_CompH compH, /* >> */ + A_Time *start_timePT); /* << */ + + SPAPI A_Err (*AEGP_SetCompDisplayStartTime)( /* NOT Undoable! */ + AEGP_CompH compH, /* >> */ + const A_Time *start_timePT); /* >> */ + + SPAPI A_Err (*AEGP_SetCompDuration)( + AEGP_CompH compH, /* >> */ + const A_Time *durationPT); /* >> */ + + SPAPI A_Err (*AEGP_CreateNullInComp)( + const A_char *nameZ, /* >> */ + AEGP_CompH parent_compH, /* >> */ + const A_Time *durationPT0, /* >> */ + AEGP_LayerH *new_null_solidPH); /* << */ + + SPAPI A_Err (*AEGP_SetCompPixelAspectRatio)( + AEGP_CompH compH, /* >> */ + const A_Ratio *pix_aspectratioPRt); /* >> */ + + SPAPI A_Err (*AEGP_CreateTextLayerInComp)( + AEGP_CompH parent_compH, /* >> */ + AEGP_LayerH *new_text_layerPH); /* << */ + + SPAPI A_Err (*AEGP_SetCompDimensions)( + AEGP_CompH compH, /* >> */ + A_long widthL, /* >> */ + A_long heightL); /* >> */ + + SPAPI A_Err (*AEGP_DuplicateComp)( + AEGP_CompH compH, /* >> */ + AEGP_CompH *new_compPH); /* << */ + + SPAPI A_Err (*AEGP_GetCompFrameDuration)(AEGP_CompH compH, // in + A_Time* timeP); // out + +} AEGP_CompSuite4; + + +#define kAEGPCompSuiteVersion3 7 /* frozen AE 6.0 */ + +typedef struct AEGP_CompSuite3 { + + SPAPI A_Err (*AEGP_GetCompFromItem)( // error if item isn't AEGP_ItemType_COMP! + AEGP_ItemH itemH, /* >> */ + AEGP_CompH *compPH); /* << */ + + SPAPI A_Err (*AEGP_GetItemFromComp)( + AEGP_CompH compH, /* >> */ + AEGP_ItemH *itemPH); /* << */ + + SPAPI A_Err (*AEGP_GetCompDownsampleFactor)( + AEGP_CompH compH, /* >> */ + AEGP_DownsampleFactor *dsfP); /* << */ + + SPAPI A_Err (*AEGP_SetCompDownsampleFactor)( + AEGP_CompH compH, /* <> */ + const AEGP_DownsampleFactor *dsfP); /* >> */ + + SPAPI A_Err (*AEGP_GetCompBGColor)( + AEGP_CompH compH, /* >> */ + AEGP_ColorVal *bg_colorP); /* << */ + + SPAPI A_Err (*AEGP_GetCompFlags)( + AEGP_CompH compH, /* >> */ + AEGP_CompFlags *comp_flagsP); /* << */ + + SPAPI A_Err (*AEGP_GetCompFramerate)( + AEGP_CompH compH, /* >> */ + A_FpLong *fpsPF); /* << */ + + SPAPI A_Err (*AEGP_SetCompFrameRate)( + AEGP_CompH compH, /* >> */ + const A_FpLong *fpsPF); /* >> */ + + SPAPI A_Err (*AEGP_GetCompShutterAnglePhase)( + AEGP_CompH compH, /* >> */ + A_Ratio *angle, /* << */ + A_Ratio *phase); /* << */ + + SPAPI A_Err (*AEGP_GetCompShutterFrameRange)( + AEGP_CompH compH, /* >> */ + const A_Time *comp_timeP, /* >> */ + A_Time *start, /* << */ + A_Time *duration); /* << */ + + SPAPI A_Err (*AEGP_GetCompWorkAreaStart)( + AEGP_CompH compH, /* >> */ + A_Time *work_area_startPT); /* << */ + + SPAPI A_Err (*AEGP_GetCompWorkAreaDuration)( + AEGP_CompH compH, /* >> */ + A_Time *work_area_durationPT); /* << */ + + SPAPI A_Err (*AEGP_SetCompWorkAreaStartAndDuration)( /* UNDOABLE */ + AEGP_CompH compH, /* >> */ + A_Time *work_area_startPT, /* >> */ + A_Time *work_area_durationPT); /* >> */ + + SPAPI A_Err (*AEGP_CreateSolidInComp)( + const A_char *nameZ, /* >> */ + A_long width, /* >> */ + A_long height, /* >> */ + const AEGP_ColorVal *color, /* >> */ + AEGP_CompH parent_compH, /* >> */ + const A_Time *durationPT0, /* >> */ + AEGP_LayerH *new_solidPH); /* << */ + + SPAPI A_Err (*AEGP_CreateCameraInComp)( + const A_char *nameZ, /* >> */ + A_FloatPoint center_point, /* >> */ + AEGP_CompH parent_compH, /* >> */ + AEGP_LayerH *new_cameraPH); /* << */ + + SPAPI A_Err (*AEGP_CreateLightInComp)( + const A_char *nameZ, /* >> */ + A_FloatPoint center_point, /* >> */ + AEGP_CompH parent_compH, /* >> */ + AEGP_LayerH *new_lightPH); /* << */ + + SPAPI A_Err (*AEGP_CreateComp)( + AEGP_ItemH parent_folderH0, /* >> */ + const A_char *nameZ, /* >> */ + A_long widthL, /* >> */ + A_long heightL, /* >> */ + const A_Ratio *pixel_aspect_ratioPRt, /* >> */ + const A_Time *durationPT, /* >> */ + const A_Ratio *frameratePRt, /* >> */ + AEGP_CompH *new_compPH); /* << */ + + SPAPI A_Err (*AEGP_GetNewCollectionFromCompSelection)( + AEGP_PluginID plugin_id, /* >> */ + AEGP_CompH compH, /* >> */ + AEGP_CollectionH *collectionPH); /* << */ + + SPAPI A_Err (*AEGP_SetSelection)( + AEGP_CompH compH, /* >> */ + AEGP_CollectionH collectionH); /* >> not adopted */ + + SPAPI A_Err (*AEGP_GetCompDisplayStartTime)( + AEGP_CompH compH, /* >> */ + A_Time *start_timePT); /* << */ + + SPAPI A_Err (*AEGP_SetCompDisplayStartTime)( /* NOT Undoable! */ + AEGP_CompH compH, /* >> */ + const A_Time *start_timePT); /* >> */ + + SPAPI A_Err (*AEGP_SetCompDuration)( + AEGP_CompH compH, /* >> */ + const A_Time *durationPT); /* >> */ + + SPAPI A_Err (*AEGP_CreateNullInComp)( + const A_char *nameZ, /* >> */ + AEGP_CompH parent_compH, /* >> */ + const A_Time *durationPT0, /* >> */ + AEGP_LayerH *new_null_solidPH); /* << */ + + SPAPI A_Err (*AEGP_SetCompPixelAspectRatio)( + AEGP_CompH compH, /* >> */ + const A_Ratio *pix_aspectratioPRt); /* >> */ + + SPAPI A_Err (*AEGP_CreateTextLayerInComp)( + AEGP_CompH parent_compH, /* >> */ + AEGP_LayerH *new_text_layerPH); /* << */ + +} AEGP_CompSuite3; + + +#define kAEGPCompSuiteVersion2 6 /* frozen in AE 5.5 */ + +typedef struct AEGP_CompSuite2 { + + SPAPI A_Err (*AEGP_GetCompFromItem)( // error if item isn't AEGP_ItemType_COMP! + AEGP_ItemH itemH, /* >> */ + AEGP_CompH *compPH); /* << */ + + SPAPI A_Err (*AEGP_GetItemFromComp)( + AEGP_CompH compH, /* >> */ + AEGP_ItemH *itemPH); /* << */ + + SPAPI A_Err (*AEGP_GetCompDownsampleFactor)( + AEGP_CompH compH, /* >> */ + AEGP_DownsampleFactor *dsfP); /* << */ + + SPAPI A_Err (*AEGP_SetCompDownsampleFactor)( + AEGP_CompH compH, /* <> */ + const AEGP_DownsampleFactor *dsfP); /* >> */ + + SPAPI A_Err (*AEGP_GetCompBGColor)( + AEGP_CompH compH, /* >> */ + AEGP_ColorVal *bg_colorP); /* << */ + + SPAPI A_Err (*AEGP_GetCompFlags)( + AEGP_CompH compH, /* >> */ + AEGP_CompFlags *comp_flagsP); /* << */ + + SPAPI A_Err (*AEGP_GetCompFramerate)( + AEGP_CompH compH, /* >> */ + A_FpLong *fpsPF); /* << */ + + SPAPI A_Err (*AEGP_GetCompShutterAnglePhase)( + AEGP_CompH compH, /* >> */ + A_Ratio *angle, /* << */ + A_Ratio *phase); /* << */ + + SPAPI A_Err (*AEGP_GetCompShutterFrameRange)( + AEGP_CompH compH, /* >> */ + const A_Time *comp_timeP, /* >> */ + A_Time *start, /* << */ + A_Time *duration); /* << */ + + SPAPI A_Err (*AEGP_GetCompWorkAreaStart)( + AEGP_CompH compH, /* >> */ + A_Time *work_area_startPT); /* << */ + + SPAPI A_Err (*AEGP_GetCompWorkAreaDuration)( + AEGP_CompH compH, /* >> */ + A_Time *work_area_durationPT); /* << */ + + SPAPI A_Err (*AEGP_SetCompWorkAreaStartAndDuration)( /* UNDOABLE */ + AEGP_CompH compH, /* >> */ + A_Time *work_area_startPT, /* >> */ + A_Time *work_area_durationPT); /* >> */ + + SPAPI A_Err (*AEGP_CreateSolidInComp)( + const A_char *nameZ, /* >> */ + A_long width, /* >> */ + A_long height, /* >> */ + const AEGP_ColorVal *color, /* >> */ + AEGP_ItemH parent_compH, /* >> */ + const A_Time *durationPT0, /* >> */ + AEGP_LayerH *new_solidPH); /* << */ + + SPAPI A_Err (*AEGP_CreateCameraInComp)( + const A_char *nameZ, /* >> */ + A_FloatPoint center_point, /* >> */ + AEGP_ItemH parent_compH, /* >> */ + AEGP_LayerH *new_cameraPH); /* << */ + + SPAPI A_Err (*AEGP_CreateLightInComp)( + const A_char *nameZ, /* >> */ + A_FloatPoint center_point, /* >> */ + AEGP_ItemH parent_compH, /* >> */ + AEGP_LayerH *new_lightPH); /* << */ + + SPAPI A_Err (*AEGP_CreateComp)( + AEGP_ItemH parent_folderH0, /* >> */ + const A_char *nameZ, /* >> */ + A_long widthL, /* >> */ + A_long heightL, /* >> */ + const A_Ratio *pixel_aspect_ratioPRt, /* >> */ + const A_Time *durationPT, /* >> */ + const A_Ratio *frameratePRt, /* >> */ + AEGP_CompH *new_compPH); /* << */ + + SPAPI A_Err (*AEGP_GetNewCollectionFromCompSelection)( + AEGP_PluginID plugin_id, /* >> */ + AEGP_CompH compH, /* >> */ + AEGP_CollectionH *collectionPH); /* << */ + + SPAPI A_Err (*AEGP_SetSelection)( + AEGP_CompH compH, /* >> */ + AEGP_CollectionH collectionH); /* >> not adopted */ + + SPAPI A_Err (*AEGP_SetCompDisplayStartTime)( /* NOT Undoable! */ + AEGP_CompH compH, /* >> */ + const A_Time *start_timePT); /* >> */ + + SPAPI A_Err (*AEGP_SetCompDuration)( + AEGP_CompH compH, /* >> */ + const A_Time *durationPT); /* >> */ + + + SPAPI A_Err (*AEGP_CreateNullInComp)( + const A_char *nameZ, /* >> */ + AEGP_CompH parent_compH, /* >> */ + const A_Time *durationPT0, /* >> */ + AEGP_LayerH *new_null_solidPH); /* << */ + +} AEGP_CompSuite2; + + +#define kAEGPCompSuiteVersion1 4 /* frozen in AE 5.0 */ + +typedef struct AEGP_CompSuite1 { + + SPAPI A_Err (*AEGP_GetCompFromItem)( // error if item isn't AEGP_ItemType_COMP! + AEGP_ItemH itemH, /* >> */ + AEGP_CompH *compPH); /* << */ + + SPAPI A_Err (*AEGP_GetItemFromComp)( + AEGP_CompH compH, /* >> */ + AEGP_ItemH *itemPH); /* << */ + + SPAPI A_Err (*AEGP_GetCompDownsampleFactor)( + AEGP_CompH compH, /* >> */ + AEGP_DownsampleFactor *dsfP); /* << */ + + SPAPI A_Err (*AEGP_GetCompBGColor)( + AEGP_CompH compH, /* >> */ + AEGP_ColorVal *bg_colorP); /* << */ + + SPAPI A_Err (*AEGP_GetCompFlags)( + AEGP_CompH compH, /* >> */ + AEGP_CompFlags *comp_flagsP); /* << */ + + SPAPI A_Err (*AEGP_GetCompFramerate)( + AEGP_CompH compH, /* >> */ + A_FpLong *fpsPF); /* << */ + + SPAPI A_Err (*AEGP_GetCompShutterAnglePhase)( + AEGP_CompH compH, /* >> */ + A_Ratio *angle, /* << */ + A_Ratio *phase); /* << */ + + SPAPI A_Err (*AEGP_GetCompShutterFrameRange)( + AEGP_CompH compH, /* >> */ + const A_Time *comp_timeP, /* >> */ + A_Time *start, /* << */ + A_Time *duration); /* << */ + + SPAPI A_Err (*AEGP_GetCompWorkAreaStart)( + AEGP_CompH compH, /* >> */ + A_Time *work_area_startPT); /* << */ + + SPAPI A_Err (*AEGP_GetCompWorkAreaDuration)( + AEGP_CompH compH, /* >> */ + A_Time *work_area_durationPT); /* << */ + + SPAPI A_Err (*AEGP_SetCompWorkAreaStartAndDuration)( /* UNDOABLE */ + AEGP_CompH compH, /* >> */ + A_Time *work_area_startPT, /* >> */ + A_Time *work_area_durationPT); /* >> */ + + SPAPI A_Err (*AEGP_CreateSolidInComp)( + const A_char *nameZ, /* >> */ + A_long width, /* >> */ + A_long height, /* >> */ + const AEGP_ColorVal *color, /* >> */ + AEGP_ItemH parent_compH, /* >> */ + AEGP_LayerH *new_solidPH); /* << */ + + SPAPI A_Err (*AEGP_CreateComp)( + AEGP_ItemH parent_folderH0, /* >> */ + const A_char *nameZ, /* >> */ + A_long widthL, /* >> */ + A_long heightL, /* >> */ + const A_Ratio *pixel_aspect_ratioPRt, /* >> */ + const A_Time *durationPT, /* >> */ + const A_Ratio *frameratePRt, /* >> */ + AEGP_ItemH *new_compPH); /* << */ + + SPAPI A_Err (*AEGP_GetNewCollectionFromCompSelection)( + AEGP_PluginID plugin_id, /* >> */ + AEGP_CompH compH, /* >> */ + AEGP_CollectionH *collectionPH); /* << */ + + SPAPI A_Err (*AEGP_SetSelection)( + AEGP_CompH compH, /* >> */ + AEGP_CollectionH collectionH); /* >> not adopted */ + + SPAPI A_Err (*AEGP_SetCompDisplayStartTime)( /* NOT Undoable! */ + AEGP_CompH compH, /* >> */ + const A_Time *start_timePT); /* >> */ + + SPAPI A_Err (*AEGP_SetCompDuration)( + AEGP_CompH compH, /* >> */ + const A_Time *durationPT); /* >> */ +} AEGP_CompSuite1; + + + +#define kAEGPLayerSuite "AEGP Layer Suite" + +#define kAEGPLayerSuiteVersion6 12 /* frozen AE 9.0 */ + +typedef struct AEGP_LayerSuite6 { + + SPAPI A_Err (*AEGP_GetCompNumLayers)( + AEGP_CompH compH, /* >> */ + A_long *num_layersPL); /* << */ + + SPAPI A_Err (*AEGP_GetCompLayerByIndex)( + AEGP_CompH compH, /* >> */ + A_long layer_indexL, /* >> */ + AEGP_LayerH *layerPH); /* << */ + + SPAPI A_Err (*AEGP_GetActiveLayer)( + AEGP_LayerH *layerPH); /* << returns non null only if one layer is selected */ + + SPAPI A_Err (*AEGP_GetLayerIndex)( + AEGP_LayerH layerH, /* >> */ + A_long *layer_indexPL); /* << */ + + SPAPI A_Err (*AEGP_GetLayerSourceItem)( + AEGP_LayerH layerH, /* >> */ + AEGP_ItemH *source_itemPH); /* << */ + + SPAPI A_Err (*AEGP_GetLayerSourceItemID)( + AEGP_LayerH layerH, /* >> */ + A_long *source_item_idPL); /* << */ + + SPAPI A_Err (*AEGP_GetLayerParentComp)( + AEGP_LayerH layerH, /* >> */ + AEGP_CompH *compPH); /* << */ + + SPAPI A_Err (*AEGP_GetLayerName)( + AEGP_PluginID pluginID, // in + AEGP_LayerH layerH, /* >> */ + AEGP_MemHandle *utf_layer_namePH0, // << handle of A_UTF16Char (contains null terminated UTF16 string); must be disposed with AEGP_FreeMemHandle + AEGP_MemHandle *utf_source_namePH0); // << handle of A_UTF16Char (contains null terminated UTF16 string); must be disposed with AEGP_FreeMemHandle + + SPAPI A_Err (*AEGP_GetLayerQuality)( + AEGP_LayerH layerH, /* >> */ + AEGP_LayerQuality *qualityP); /* << */ + + SPAPI A_Err (*AEGP_SetLayerQuality)( /* UNDOABLE */ + AEGP_LayerH layerH, /* >> */ + AEGP_LayerQuality quality); /* >> */ + + SPAPI A_Err (*AEGP_GetLayerFlags)( + AEGP_LayerH layerH, /* >> */ + AEGP_LayerFlags *layer_flagsP); /* << */ + + SPAPI A_Err (*AEGP_SetLayerFlag)( + AEGP_LayerH layerH, /* >> */ + AEGP_LayerFlags single_flag, /* >> */ + A_Boolean valueB); /* >> */ + + SPAPI A_Err (*AEGP_IsLayerVideoReallyOn)( // accounts for solo status of other layers in comp + AEGP_LayerH layerH, /* >> */ + A_Boolean *onPB); /* << */ + + SPAPI A_Err (*AEGP_IsLayerAudioReallyOn)( // accounts for solo status of other layers in comp + AEGP_LayerH layerH, /* >> */ + A_Boolean *onPB); /* << */ + + SPAPI A_Err (*AEGP_GetLayerCurrentTime)( // not updated while rendering + AEGP_LayerH layerH, /* >> */ + AEGP_LTimeMode time_mode, /* >> */ + A_Time *curr_timePT); /* << */ + + SPAPI A_Err (*AEGP_GetLayerInPoint)( + AEGP_LayerH layerH, /* >> */ + AEGP_LTimeMode time_mode, /* >> */ + A_Time *in_pointPT); /* << */ + + SPAPI A_Err (*AEGP_GetLayerDuration)( + AEGP_LayerH layerH, /* >> */ + AEGP_LTimeMode time_mode, /* >> */ + A_Time *durationPT); /* << */ + + SPAPI A_Err (*AEGP_SetLayerInPointAndDuration)( /* UNDOABLE */ + AEGP_LayerH layerH, /* >> */ + AEGP_LTimeMode time_mode, /* >> */ + const A_Time *in_pointPT, /* >> */ + const A_Time *durationPT); /* >> */ + + SPAPI A_Err (*AEGP_GetLayerOffset)( + AEGP_LayerH layerH, /* >> */ + A_Time *offsetPT); /* << always in comp time */ + + SPAPI A_Err (*AEGP_SetLayerOffset)( /* UNDOABLE */ + AEGP_LayerH layerH, /* >> */ + const A_Time *offsetPT); /* >> always in comp time */ + + SPAPI A_Err (*AEGP_GetLayerStretch)( + AEGP_LayerH layerH, /* >> */ + A_Ratio *stretchPRt); /* << */ + + SPAPI A_Err (*AEGP_SetLayerStretch)( /* UNDOABLE */ + AEGP_LayerH layerH, /* >> */ + const A_Ratio *stretchPRt); /* >> */ + + SPAPI A_Err (*AEGP_GetLayerTransferMode)( + AEGP_LayerH layerH, /* >> */ + AEGP_LayerTransferMode *transfer_modeP); /* << */ + + SPAPI A_Err (*AEGP_SetLayerTransferMode)( /* UNDOABLE */ + AEGP_LayerH layerH, /* >> */ + const AEGP_LayerTransferMode *transfer_modeP); /* >> */ + + SPAPI A_Err (*AEGP_IsAddLayerValid)( + AEGP_ItemH item_to_addH, /* >> */ + AEGP_CompH into_compH, /* >> */ + A_Boolean *validPB); /* << */ + + SPAPI A_Err (*AEGP_AddLayer)( /* UNDOABLE */ + AEGP_ItemH item_to_addH, /* >> check AEGP_IsAddLayerValid() before using */ + AEGP_CompH into_compH, /* >> */ + AEGP_LayerH *added_layerPH0); /* << */ + + SPAPI A_Err (*AEGP_ReorderLayer)( /* UNDOABLE */ + AEGP_LayerH layerH, /* >> */ + A_long layer_indexL); /* >> */ + + SPAPI A_Err (*AEGP_GetLayerMaskedBounds)( + AEGP_LayerH layerH, /* >> */ + AEGP_LTimeMode time_mode, /* >> */ + const A_Time *timePT, /* >> */ + A_FloatRect *boundsPR); /* << */ + + SPAPI A_Err (*AEGP_GetLayerObjectType)( + AEGP_LayerH layerH, /* >> */ + AEGP_ObjectType *object_type); /* << */ + + SPAPI A_Err (*AEGP_IsLayer3D)( + AEGP_LayerH layerH, /* >> */ + A_Boolean *is_3DPB); /* << */ + + SPAPI A_Err (*AEGP_IsLayer2D)( + AEGP_LayerH layerH, /* >> */ + A_Boolean *is_2DPB); /* << */ + + SPAPI A_Err (*AEGP_IsVideoActive)( + AEGP_LayerH layerH, /* >> */ + AEGP_LTimeMode time_mode, /* >> */ + const A_Time *timePT, /* >> */ + A_Boolean *is_activePB); /* << */ + + SPAPI A_Err (*AEGP_IsLayerUsedAsTrackMatte)( + AEGP_LayerH layerH, /* >> */ + A_Boolean fill_must_be_activeB, /* >> */ + A_Boolean *is_track_mattePB); /* << */ + + SPAPI A_Err (*AEGP_DoesLayerHaveTrackMatte)( + AEGP_LayerH layerH, /* >> */ + A_Boolean *has_track_mattePB); /* << */ + + SPAPI A_Err (*AEGP_ConvertCompToLayerTime)( + AEGP_LayerH layerH, /* >> */ + const A_Time *comp_timePT, /* >> */ + A_Time *layer_timePT); /* << */ + + SPAPI A_Err (*AEGP_ConvertLayerToCompTime)( + AEGP_LayerH layerH, /* >> */ + const A_Time *layer_timePT, /* >> */ + A_Time *comp_timePT) ; /* << */ + + SPAPI A_Err (*AEGP_GetLayerDancingRandValue)( + AEGP_LayerH layerH, /* >> */ + const A_Time *comp_timePT, /* >> */ + A_long *rand_valuePL); /* << */ + + SPAPI A_Err (*AEGP_GetLayerID)( + AEGP_LayerH layerH, /* >> */ + AEGP_LayerIDVal *id_valP); /* << */ + + SPAPI A_Err (*AEGP_GetLayerToWorldXform)( + AEGP_LayerH aegp_layerH, /* >> */ + const A_Time *comp_timeP, /* >> */ + A_Matrix4 *transform); /* << */ + + SPAPI A_Err (*AEGP_GetLayerToWorldXformFromView)( + AEGP_LayerH aegp_layerH, /* >> */ + const A_Time *view_timeP, /* >> */ + const A_Time *comp_timeP, /* >> */ + A_Matrix4 *transform); /* << */ + + SPAPI A_Err (*AEGP_SetLayerName)( + AEGP_LayerH aegp_layerH, /* >> */ + const A_UTF16Char *new_nameZ); /* >> null terminated UTF16 */ + + SPAPI A_Err (*AEGP_GetLayerParent)( + const AEGP_LayerH layerH, /* >> */ + AEGP_LayerH *parent_layerPH); /* << NULL if no parent */ + + SPAPI A_Err (*AEGP_SetLayerParent)( + AEGP_LayerH layerH, /* >> */ + const AEGP_LayerH parent_layerH0); /* >> */ + + SPAPI A_Err (*AEGP_DeleteLayer)( + AEGP_LayerH layerH); /* >> UNDOABLE */ + + SPAPI A_Err (*AEGP_DuplicateLayer)( + AEGP_LayerH orig_layerH, /* >> */ + AEGP_LayerH *duplicate_layerPH); /* << */ + + SPAPI A_Err (*AEGP_GetLayerFromLayerID)( + AEGP_CompH parent_compH, /* >> */ + AEGP_LayerIDVal id, /* >> */ + AEGP_LayerH *layerPH); /* << */ + +} AEGP_LayerSuite6; + + +#define kAEGPLayerSuiteVersion5 11 /* frozen AE 7.0 */ + +typedef struct AEGP_LayerSuite5 { + + SPAPI A_Err (*AEGP_GetCompNumLayers)( + AEGP_CompH compH, /* >> */ + A_long *num_layersPL); /* << */ + + SPAPI A_Err (*AEGP_GetCompLayerByIndex)( + AEGP_CompH compH, /* >> */ + A_long layer_indexL, /* >> */ + AEGP_LayerH *layerPH); /* << */ + + SPAPI A_Err (*AEGP_GetActiveLayer)( + AEGP_LayerH *layerPH); /* << returns non null only if one layer is selected */ + + SPAPI A_Err (*AEGP_GetLayerIndex)( + AEGP_LayerH layerH, /* >> */ + A_long *layer_indexPL); /* << */ + + SPAPI A_Err (*AEGP_GetLayerSourceItem)( + AEGP_LayerH layerH, /* >> */ + AEGP_ItemH *source_itemPH); /* << */ + + SPAPI A_Err (*AEGP_GetLayerSourceItemID)( + AEGP_LayerH layerH, /* >> */ + A_long *source_item_idPL); /* << */ + + SPAPI A_Err (*AEGP_GetLayerParentComp)( + AEGP_LayerH layerH, /* >> */ + AEGP_CompH *compPH); /* << */ + + SPAPI A_Err (*AEGP_GetLayerName)( + AEGP_LayerH layerH, /* >> */ + A_char *layer_nameZ0, /* << space for A_char[AEGP_MAX_LAYER_NAME_MB_SIZE] */ + A_char *source_nameZ0); /* << space for A_char[AEGP_MAX_LAYER_NAME_MB_SIZE] */ + + SPAPI A_Err (*AEGP_GetLayerQuality)( + AEGP_LayerH layerH, /* >> */ + AEGP_LayerQuality *qualityP); /* << */ + + SPAPI A_Err (*AEGP_SetLayerQuality)( /* UNDOABLE */ + AEGP_LayerH layerH, /* >> */ + AEGP_LayerQuality quality); /* >> */ + + SPAPI A_Err (*AEGP_GetLayerFlags)( + AEGP_LayerH layerH, /* >> */ + AEGP_LayerFlags *layer_flagsP); /* << */ + + SPAPI A_Err (*AEGP_SetLayerFlag)( + AEGP_LayerH layerH, /* >> */ + AEGP_LayerFlags single_flag, /* >> */ + A_Boolean valueB); /* >> */ + + SPAPI A_Err (*AEGP_IsLayerVideoReallyOn)( // accounts for solo status of other layers in comp + AEGP_LayerH layerH, /* >> */ + A_Boolean *onPB); /* << */ + + SPAPI A_Err (*AEGP_IsLayerAudioReallyOn)( // accounts for solo status of other layers in comp + AEGP_LayerH layerH, /* >> */ + A_Boolean *onPB); /* << */ + + SPAPI A_Err (*AEGP_GetLayerCurrentTime)( // not updated while rendering + AEGP_LayerH layerH, /* >> */ + AEGP_LTimeMode time_mode, /* >> */ + A_Time *curr_timePT); /* << */ + + SPAPI A_Err (*AEGP_GetLayerInPoint)( + AEGP_LayerH layerH, /* >> */ + AEGP_LTimeMode time_mode, /* >> */ + A_Time *in_pointPT); /* << */ + + SPAPI A_Err (*AEGP_GetLayerDuration)( + AEGP_LayerH layerH, /* >> */ + AEGP_LTimeMode time_mode, /* >> */ + A_Time *durationPT); /* << */ + + SPAPI A_Err (*AEGP_SetLayerInPointAndDuration)( /* UNDOABLE */ + AEGP_LayerH layerH, /* >> */ + AEGP_LTimeMode time_mode, /* >> */ + const A_Time *in_pointPT, /* >> */ + const A_Time *durationPT); /* >> */ + + SPAPI A_Err (*AEGP_GetLayerOffset)( + AEGP_LayerH layerH, /* >> */ + A_Time *offsetPT); /* << always in comp time */ + + SPAPI A_Err (*AEGP_SetLayerOffset)( /* UNDOABLE */ + AEGP_LayerH layerH, /* >> */ + const A_Time *offsetPT); /* >> always in comp time */ + + SPAPI A_Err (*AEGP_GetLayerStretch)( + AEGP_LayerH layerH, /* >> */ + A_Ratio *stretchPRt); /* << */ + + SPAPI A_Err (*AEGP_SetLayerStretch)( /* UNDOABLE */ + AEGP_LayerH layerH, /* >> */ + const A_Ratio *stretchPRt); /* >> */ + + SPAPI A_Err (*AEGP_GetLayerTransferMode)( + AEGP_LayerH layerH, /* >> */ + AEGP_LayerTransferMode *transfer_modeP); /* << */ + + SPAPI A_Err (*AEGP_SetLayerTransferMode)( /* UNDOABLE */ + AEGP_LayerH layerH, /* >> */ + const AEGP_LayerTransferMode *transfer_modeP); /* >> */ + + SPAPI A_Err (*AEGP_IsAddLayerValid)( + AEGP_ItemH item_to_addH, /* >> */ + AEGP_CompH into_compH, /* >> */ + A_Boolean *validPB); /* << */ + + SPAPI A_Err (*AEGP_AddLayer)( /* UNDOABLE */ + AEGP_ItemH item_to_addH, /* >> check AEGP_IsAddLayerValid() before using */ + AEGP_CompH into_compH, /* >> */ + AEGP_LayerH *added_layerPH0); /* << */ + + SPAPI A_Err (*AEGP_ReorderLayer)( /* UNDOABLE */ + AEGP_LayerH layerH, /* >> */ + A_long layer_indexL); /* >> */ + + SPAPI A_Err (*AEGP_GetLayerMaskedBounds)( + AEGP_LayerH layerH, /* >> */ + AEGP_LTimeMode time_mode, /* >> */ + const A_Time *timePT, /* >> */ + A_FloatRect *boundsPR); /* << */ + + SPAPI A_Err (*AEGP_GetLayerObjectType)( + AEGP_LayerH layerH, /* >> */ + AEGP_ObjectType *object_type); /* << */ + + SPAPI A_Err (*AEGP_IsLayer3D)( + AEGP_LayerH layerH, /* >> */ + A_Boolean *is_3DPB); /* << */ + + SPAPI A_Err (*AEGP_IsLayer2D)( + AEGP_LayerH layerH, /* >> */ + A_Boolean *is_2DPB); /* << */ + + SPAPI A_Err (*AEGP_IsVideoActive)( + AEGP_LayerH layerH, /* >> */ + AEGP_LTimeMode time_mode, /* >> */ + const A_Time *timePT, /* >> */ + A_Boolean *is_activePB); /* << */ + + SPAPI A_Err (*AEGP_IsLayerUsedAsTrackMatte)( + AEGP_LayerH layerH, /* >> */ + A_Boolean fill_must_be_activeB, /* >> */ + A_Boolean *is_track_mattePB); /* << */ + + SPAPI A_Err (*AEGP_DoesLayerHaveTrackMatte)( + AEGP_LayerH layerH, /* >> */ + A_Boolean *has_track_mattePB); /* << */ + + SPAPI A_Err (*AEGP_ConvertCompToLayerTime)( + AEGP_LayerH layerH, /* >> */ + const A_Time *comp_timePT, /* >> */ + A_Time *layer_timePT); /* << */ + + SPAPI A_Err (*AEGP_ConvertLayerToCompTime)( + AEGP_LayerH layerH, /* >> */ + const A_Time *layer_timePT, /* >> */ + A_Time *comp_timePT) ; /* << */ + + SPAPI A_Err (*AEGP_GetLayerDancingRandValue)( + AEGP_LayerH layerH, /* >> */ + const A_Time *comp_timePT, /* >> */ + A_long *rand_valuePL); /* << */ + + SPAPI A_Err (*AEGP_GetLayerID)( + AEGP_LayerH layerH, /* >> */ + AEGP_LayerIDVal *id_valP); /* << */ + + SPAPI A_Err (*AEGP_GetLayerToWorldXform)( + AEGP_LayerH aegp_layerH, /* >> */ + const A_Time *comp_timeP, /* >> */ + A_Matrix4 *transform); /* << */ + + SPAPI A_Err (*AEGP_GetLayerToWorldXformFromView)( + AEGP_LayerH aegp_layerH, /* >> */ + const A_Time *view_timeP, /* >> */ + const A_Time *comp_timeP, /* >> */ + A_Matrix4 *transform); /* << */ + + SPAPI A_Err (*AEGP_SetLayerName)( + AEGP_LayerH aegp_layerH, /* >> */ + const A_char *new_nameZ); /* >> */ + + SPAPI A_Err (*AEGP_GetLayerParent)( + const AEGP_LayerH layerH, /* >> */ + AEGP_LayerH *parent_layerPH); /* << NULL if no parent */ + + SPAPI A_Err (*AEGP_SetLayerParent)( + AEGP_LayerH layerH, /* >> */ + const AEGP_LayerH parent_layerH0); /* >> */ + + SPAPI A_Err (*AEGP_DeleteLayer)( + AEGP_LayerH layerH); /* >> UNDOABLE */ + + SPAPI A_Err (*AEGP_DuplicateLayer)( + AEGP_LayerH orig_layerH, /* >> */ + AEGP_LayerH *duplicate_layerPH); /* << */ + + SPAPI A_Err (*AEGP_GetLayerFromLayerID)( + AEGP_CompH parent_compH, /* >> */ + AEGP_LayerIDVal id, /* >> */ + AEGP_LayerH *layerPH); /* << */ + +} AEGP_LayerSuite5; + + + +#define kAEGPLayerSuiteVersion4 10 /* frozen AE 6.5 */ + +typedef struct AEGP_LayerSuite4 { + + SPAPI A_Err (*AEGP_GetCompNumLayers)( + AEGP_CompH compH, /* >> */ + A_long *num_layersPL); /* << */ + + SPAPI A_Err (*AEGP_GetCompLayerByIndex)( + AEGP_CompH compH, /* >> */ + A_long layer_indexL, /* >> */ + AEGP_LayerH *layerPH); /* << */ + + SPAPI A_Err (*AEGP_GetActiveLayer)( + AEGP_LayerH *layerPH); /* << returns non null only if one layer is selected */ + + SPAPI A_Err (*AEGP_GetLayerIndex)( + AEGP_LayerH layerH, /* >> */ + A_long *layer_indexPL); /* << */ + + SPAPI A_Err (*AEGP_GetLayerSourceItem)( + AEGP_LayerH layerH, /* >> */ + AEGP_ItemH *source_itemPH); /* << */ + + SPAPI A_Err (*AEGP_GetLayerSourceItemID)( + AEGP_LayerH layerH, /* >> */ + A_long *source_item_idPL); /* << */ + + SPAPI A_Err (*AEGP_GetLayerParentComp)( + AEGP_LayerH layerH, /* >> */ + AEGP_CompH *compPH); /* << */ + + SPAPI A_Err (*AEGP_GetLayerName)( + AEGP_LayerH layerH, /* >> */ + A_char *layer_nameZ0, /* << space for A_char[AEGP_MAX_LAYER_NAME_SIZE] */ + A_char *source_nameZ0); /* << space for A_char[AEGP_MAX_LAYER_NAME_SIZE] */ + + SPAPI A_Err (*AEGP_GetLayerQuality)( + AEGP_LayerH layerH, /* >> */ + AEGP_LayerQuality *qualityP); /* << */ + + SPAPI A_Err (*AEGP_SetLayerQuality)( /* UNDOABLE */ + AEGP_LayerH layerH, /* >> */ + AEGP_LayerQuality quality); /* >> */ + + SPAPI A_Err (*AEGP_GetLayerFlags)( + AEGP_LayerH layerH, /* >> */ + AEGP_LayerFlags *layer_flagsP); /* << */ + + SPAPI A_Err (*AEGP_SetLayerFlag)( + AEGP_LayerH layerH, /* >> */ + AEGP_LayerFlags single_flag, /* >> */ + A_Boolean valueB); /* >> */ + + SPAPI A_Err (*AEGP_IsLayerVideoReallyOn)( // accounts for solo status of other layers in comp + AEGP_LayerH layerH, /* >> */ + A_Boolean *onPB); /* << */ + + SPAPI A_Err (*AEGP_IsLayerAudioReallyOn)( // accounts for solo status of other layers in comp + AEGP_LayerH layerH, /* >> */ + A_Boolean *onPB); /* << */ + + SPAPI A_Err (*AEGP_GetLayerCurrentTime)( // not updated while rendering + AEGP_LayerH layerH, /* >> */ + AEGP_LTimeMode time_mode, /* >> */ + A_Time *curr_timePT); /* << */ + + SPAPI A_Err (*AEGP_GetLayerInPoint)( + AEGP_LayerH layerH, /* >> */ + AEGP_LTimeMode time_mode, /* >> */ + A_Time *in_pointPT); /* << */ + + SPAPI A_Err (*AEGP_GetLayerDuration)( + AEGP_LayerH layerH, /* >> */ + AEGP_LTimeMode time_mode, /* >> */ + A_Time *durationPT); /* << */ + + SPAPI A_Err (*AEGP_SetLayerInPointAndDuration)( /* UNDOABLE */ + AEGP_LayerH layerH, /* >> */ + AEGP_LTimeMode time_mode, /* >> */ + const A_Time *in_pointPT, /* >> */ + const A_Time *durationPT); /* >> */ + + SPAPI A_Err (*AEGP_GetLayerOffset)( + AEGP_LayerH layerH, /* >> */ + A_Time *offsetPT); /* << always in comp time */ + + SPAPI A_Err (*AEGP_SetLayerOffset)( /* UNDOABLE */ + AEGP_LayerH layerH, /* >> */ + const A_Time *offsetPT); /* >> always in comp time */ + + SPAPI A_Err (*AEGP_GetLayerStretch)( + AEGP_LayerH layerH, /* >> */ + A_Ratio *stretchPRt); /* << */ + + SPAPI A_Err (*AEGP_SetLayerStretch)( /* UNDOABLE */ + AEGP_LayerH layerH, /* >> */ + const A_Ratio *stretchPRt); /* >> */ + + SPAPI A_Err (*AEGP_GetLayerTransferMode)( + AEGP_LayerH layerH, /* >> */ + AEGP_LayerTransferMode *transfer_modeP); /* << */ + + SPAPI A_Err (*AEGP_SetLayerTransferMode)( /* UNDOABLE */ + AEGP_LayerH layerH, /* >> */ + const AEGP_LayerTransferMode *transfer_modeP); /* >> */ + + SPAPI A_Err (*AEGP_IsAddLayerValid)( + AEGP_ItemH item_to_addH, /* >> */ + AEGP_CompH into_compH, /* >> */ + A_Boolean *validPB); /* << */ + + SPAPI A_Err (*AEGP_AddLayer)( /* UNDOABLE */ + AEGP_ItemH item_to_addH, /* >> check AEGP_IsAddLayerValid() before using */ + AEGP_CompH into_compH, /* >> */ + AEGP_LayerH *added_layerPH0); /* << */ + + SPAPI A_Err (*AEGP_ReorderLayer)( /* UNDOABLE */ + AEGP_LayerH layerH, /* >> */ + A_long layer_indexL); /* >> */ + + SPAPI A_Err (*AEGP_GetLayerMaskedBounds)( + AEGP_LayerH layerH, /* >> */ + AEGP_LTimeMode time_mode, /* >> */ + const A_Time *timePT, /* >> */ + A_FloatRect *boundsPR); /* << */ + + SPAPI A_Err (*AEGP_GetLayerObjectType)( + AEGP_LayerH layerH, /* >> */ + AEGP_ObjectType *object_type); /* << */ + + SPAPI A_Err (*AEGP_IsLayer3D)( + AEGP_LayerH layerH, /* >> */ + A_Boolean *is_3DPB); /* << */ + + SPAPI A_Err (*AEGP_IsLayer2D)( + AEGP_LayerH layerH, /* >> */ + A_Boolean *is_2DPB); /* << */ + + SPAPI A_Err (*AEGP_IsVideoActive)( + AEGP_LayerH layerH, /* >> */ + AEGP_LTimeMode time_mode, /* >> */ + const A_Time *timePT, /* >> */ + A_Boolean *is_activePB); /* << */ + + SPAPI A_Err (*AEGP_IsLayerUsedAsTrackMatte)( + AEGP_LayerH layerH, /* >> */ + A_Boolean fill_must_be_activeB, /* >> */ + A_Boolean *is_track_mattePB); /* << */ + + SPAPI A_Err (*AEGP_DoesLayerHaveTrackMatte)( + AEGP_LayerH layerH, /* >> */ + A_Boolean *has_track_mattePB); /* << */ + + SPAPI A_Err (*AEGP_ConvertCompToLayerTime)( + AEGP_LayerH layerH, /* >> */ + const A_Time *comp_timePT, /* >> */ + A_Time *layer_timePT); /* << */ + + SPAPI A_Err (*AEGP_ConvertLayerToCompTime)( + AEGP_LayerH layerH, /* >> */ + const A_Time *layer_timePT, /* >> */ + A_Time *comp_timePT) ; /* << */ + + SPAPI A_Err (*AEGP_GetLayerDancingRandValue)( + AEGP_LayerH layerH, /* >> */ + const A_Time *comp_timePT, /* >> */ + A_long *rand_valuePL); /* << */ + + SPAPI A_Err (*AEGP_GetLayerID)( + AEGP_LayerH layerH, /* >> */ + AEGP_LayerIDVal *id_valP); /* << */ + + SPAPI A_Err (*AEGP_GetLayerToWorldXform)( + AEGP_LayerH aegp_layerH, /* >> */ + const A_Time *comp_timeP, /* >> */ + A_Matrix4 *transform); /* << */ + + SPAPI A_Err (*AEGP_GetLayerToWorldXformFromView)( + AEGP_LayerH aegp_layerH, /* >> */ + const A_Time *view_timeP, /* >> */ + const A_Time *comp_timeP, /* >> */ + A_Matrix4 *transform); /* << */ + + SPAPI A_Err (*AEGP_SetLayerName)( + AEGP_LayerH aegp_layerH, /* >> */ + const A_char *new_nameZ); /* >> */ + + SPAPI A_Err (*AEGP_GetLayerParent)( + const AEGP_LayerH layerH, /* >> */ + AEGP_LayerH *parent_layerPH); /* << NULL if no parent */ + + SPAPI A_Err (*AEGP_SetLayerParent)( + AEGP_LayerH layerH, /* >> */ + const AEGP_LayerH parent_layerH0); /* >> */ + + SPAPI A_Err (*AEGP_DeleteLayer)( + AEGP_LayerH layerH); /* >> UNDOABLE */ + + SPAPI A_Err (*AEGP_DuplicateLayer)( + AEGP_LayerH orig_layerH, /* >> */ + AEGP_LayerH *duplicate_layerPH); /* << */ + +} AEGP_LayerSuite4; + +#define kAEGPLayerSuiteVersion3 8 /* frozen AE 6.0 */ + +typedef struct AEGP_LayerSuite3 { + + SPAPI A_Err (*AEGP_GetCompNumLayers)( + AEGP_CompH compH, /* >> */ + A_long *num_layersPL); /* << */ + + SPAPI A_Err (*AEGP_GetCompLayerByIndex)( + AEGP_CompH compH, /* >> */ + A_long layer_indexL, /* >> */ + AEGP_LayerH *layerPH); /* << */ + + SPAPI A_Err (*AEGP_GetActiveLayer)( + AEGP_LayerH *layerPH); /* << only if one layer is selected */ + + SPAPI A_Err (*AEGP_GetLayerIndex)( + AEGP_LayerH layerH, /* >> */ + A_long *layer_indexPL); /* << */ + + SPAPI A_Err (*AEGP_GetLayerSourceItem)( + AEGP_LayerH layerH, /* >> */ + AEGP_ItemH *source_itemPH); /* << */ + + SPAPI A_Err (*AEGP_GetLayerParentComp)( + AEGP_LayerH layerH, /* >> */ + AEGP_CompH *compPH); /* << */ + + SPAPI A_Err (*AEGP_GetLayerName)( + AEGP_LayerH layerH, /* >> */ + A_char *layer_nameZ0, /* << space for A_char[AEGP_MAX_LAYER_NAME_SIZE] */ + A_char *source_nameZ0); /* << space for A_char[AEGP_MAX_LAYER_NAME_SIZE] */ + + SPAPI A_Err (*AEGP_GetLayerQuality)( + AEGP_LayerH layerH, /* >> */ + AEGP_LayerQuality *qualityP); /* << */ + + SPAPI A_Err (*AEGP_SetLayerQuality)( /* UNDOABLE */ + AEGP_LayerH layerH, /* >> */ + AEGP_LayerQuality quality); /* >> */ + + SPAPI A_Err (*AEGP_GetLayerFlags)( + AEGP_LayerH layerH, /* >> */ + AEGP_LayerFlags *layer_flagsP); /* << */ + + SPAPI A_Err (*AEGP_SetLayerFlag)( + AEGP_LayerH layerH, /* >> */ + AEGP_LayerFlags single_flag, /* >> */ + A_Boolean valueB); /* >> */ + + SPAPI A_Err (*AEGP_IsLayerVideoReallyOn)( // accounts for solo status of other layers in comp + AEGP_LayerH layerH, /* >> */ + A_Boolean *onPB); /* << */ + + SPAPI A_Err (*AEGP_IsLayerAudioReallyOn)( // accounts for solo status of other layers in comp + AEGP_LayerH layerH, /* >> */ + A_Boolean *onPB); /* << */ + + SPAPI A_Err (*AEGP_GetLayerCurrentTime)( // not updated while rendering + AEGP_LayerH layerH, /* >> */ + AEGP_LTimeMode time_mode, /* >> */ + A_Time *curr_timePT); /* << */ + + SPAPI A_Err (*AEGP_GetLayerInPoint)( + AEGP_LayerH layerH, /* >> */ + AEGP_LTimeMode time_mode, /* >> */ + A_Time *in_pointPT); /* << */ + + SPAPI A_Err (*AEGP_GetLayerDuration)( + AEGP_LayerH layerH, /* >> */ + AEGP_LTimeMode time_mode, /* >> */ + A_Time *durationPT); /* << */ + + SPAPI A_Err (*AEGP_SetLayerInPointAndDuration)( /* UNDOABLE */ + AEGP_LayerH layerH, /* >> */ + AEGP_LTimeMode time_mode, /* >> */ + const A_Time *in_pointPT, /* >> */ + const A_Time *durationPT); /* >> */ + + SPAPI A_Err (*AEGP_GetLayerOffset)( + AEGP_LayerH layerH, /* >> */ + A_Time *offsetPT); /* << always in comp time */ + + SPAPI A_Err (*AEGP_SetLayerOffset)( /* UNDOABLE */ + AEGP_LayerH layerH, /* >> */ + const A_Time *offsetPT); /* >> always in comp time */ + + SPAPI A_Err (*AEGP_GetLayerStretch)( + AEGP_LayerH layerH, /* >> */ + A_Ratio *stretchPRt); /* << */ + + SPAPI A_Err (*AEGP_SetLayerStretch)( /* UNDOABLE */ + AEGP_LayerH layerH, /* >> */ + const A_Ratio *stretchPRt); /* >> */ + + SPAPI A_Err (*AEGP_GetLayerTransferMode)( + AEGP_LayerH layerH, /* >> */ + AEGP_LayerTransferMode *transfer_modeP); /* << */ + + SPAPI A_Err (*AEGP_SetLayerTransferMode)( /* UNDOABLE */ + AEGP_LayerH layerH, /* >> */ + const AEGP_LayerTransferMode *transfer_modeP); /* >> */ + + SPAPI A_Err (*AEGP_IsAddLayerValid)( + AEGP_ItemH item_to_addH, /* >> */ + AEGP_CompH into_compH, /* >> */ + A_Boolean *validPB); /* << */ + + SPAPI A_Err (*AEGP_AddLayer)( /* UNDOABLE */ + AEGP_ItemH item_to_addH, /* >> check AEGP_IsAddLayerValid() before using */ + AEGP_CompH into_compH, /* >> */ + AEGP_LayerH *added_layerPH0); /* << */ + + SPAPI A_Err (*AEGP_ReorderLayer)( /* UNDOABLE */ + AEGP_LayerH layerH, /* >> */ + A_long layer_indexL); /* >> */ + + SPAPI A_Err (*AEGP_GetLayerMaskedBounds)( + AEGP_LayerH layerH, /* >> */ + AEGP_LTimeMode time_mode, /* >> */ + const A_Time *timePT, /* >> */ + A_FloatRect *boundsPR); /* << */ + + SPAPI A_Err (*AEGP_GetLayerObjectType)( + AEGP_LayerH layerH, /* >> */ + AEGP_ObjectType *object_type); /* << */ + + SPAPI A_Err (*AEGP_IsLayer3D)( + AEGP_LayerH layerH, /* >> */ + A_Boolean *is_3DPB); /* << */ + + SPAPI A_Err (*AEGP_IsLayer2D)( + AEGP_LayerH layerH, /* >> */ + A_Boolean *is_2DPB); /* << */ + + SPAPI A_Err (*AEGP_IsVideoActive)( + AEGP_LayerH layerH, /* >> */ + AEGP_LTimeMode time_mode, /* >> */ + const A_Time *timePT, /* >> */ + A_Boolean *is_activePB); /* << */ + + SPAPI A_Err (*AEGP_IsLayerUsedAsTrackMatte)( + AEGP_LayerH layerH, /* >> */ + A_Boolean fill_must_be_activeB, /* >> */ + A_Boolean *is_track_mattePB); /* << */ + + SPAPI A_Err (*AEGP_DoesLayerHaveTrackMatte)( + AEGP_LayerH layerH, /* >> */ + A_Boolean *has_track_mattePB); /* << */ + + SPAPI A_Err (*AEGP_ConvertCompToLayerTime)( + AEGP_LayerH layerH, /* >> */ + const A_Time *comp_timePT, /* >> */ + A_Time *layer_timePT); /* << */ + + SPAPI A_Err (*AEGP_ConvertLayerToCompTime)( + AEGP_LayerH layerH, /* >> */ + const A_Time *layer_timePT, /* >> */ + A_Time *comp_timePT) ; /* << */ + + SPAPI A_Err (*AEGP_GetLayerDancingRandValue)( + AEGP_LayerH layerH, /* >> */ + const A_Time *comp_timePT, /* >> */ + A_long *rand_valuePL); /* << */ + + SPAPI A_Err (*AEGP_GetLayerID)( + AEGP_LayerH layerH, /* >> */ + AEGP_LayerIDVal *id_valP); /* << */ + + SPAPI A_Err (*AEGP_GetLayerToWorldXform)( + AEGP_LayerH aegp_layerH, /* >> */ + const A_Time *comp_timeP, /* >> */ + A_Matrix4 *tranform); /* >> */ + + SPAPI A_Err (*AEGP_GetLayerToWorldXformFromView)( + AEGP_LayerH aegp_layerH, /* >> */ + const A_Time *view_timeP, /* >> */ + const A_Time *comp_timeP, /* >> */ + A_Matrix4 *tranform); /* >> */ + + SPAPI A_Err (*AEGP_SetLayerName)( + AEGP_LayerH aegp_layerH, /* >> */ + const A_char *new_nameZ); /* >> */ + + SPAPI A_Err (*AEGP_GetLayerParent)( + const AEGP_LayerH layerH, /* >> */ + AEGP_LayerH *parent_layerPH); /* << NULL if no parent */ + + SPAPI A_Err (*AEGP_SetLayerParent)( + AEGP_LayerH layerH, /* >> */ + const AEGP_LayerH parent_layerH0); /* >> */ + + SPAPI A_Err (*AEGP_DeleteLayer)( + AEGP_LayerH layerH); /* >> UNDOABLE */ + + +} AEGP_LayerSuite3; + +/*******************************************************************************/ + +typedef struct { + A_char nameAC [AEGP_MAX_MARKER_NAME_SIZE]; + A_char urlAC [AEGP_MAX_MARKER_URL_SIZE]; + A_char targetAC [AEGP_MAX_MARKER_TARGET_SIZE]; + A_char chapterAC [AEGP_MAX_MARKER_CHAPTER_SIZE]; +} AEGP_MarkerVal; + +typedef AEGP_MarkerVal** AEGP_MarkerValH; + +typedef union { + AEGP_FourDVal four_d; + AEGP_ThreeDVal three_d; + AEGP_TwoDVal two_d; + AEGP_OneDVal one_d; + AEGP_ColorVal color; + AEGP_ArbBlockVal arbH; + AEGP_MarkerValH markerH; + AEGP_LayerIDVal layer_id; + AEGP_MaskIDVal mask_id; + AEGP_MaskOutlineValH mask; + AEGP_TextDocumentH text_documentH; +} AEGP_StreamVal; + +/* Metrowerks 2.4.6, a.k.a. Codewarrior Pro 7.1, changed PowerPC struct + alignment. The pragma ensures the same alignment as with 2.4.5 and + previous since plug-ins are built against this structure. See Codewarrior + release notes for for details. Bug# WB1-27922. +*/ + +#if (__MWERKS__ >= 0x2406) +#pragma options align=mac68k4byte +#endif + +typedef struct { + + AEGP_StreamRefH streamH; + /* CW 7.1 was adding 4 padding bytes here. See pragma above for comments. */ + AEGP_StreamVal val; +} AEGP_StreamValue; + +#define kAEGPStreamSuite "AEGP Stream Suite" + +#define kAEGPStreamSuiteVersion4 9 /* frozen in AE 9 */ +typedef struct AEGP_StreamSuite4 { + // the only diff from this vs. last rev is that routines that pass AEGP_StreamValue2, when referring to a marker, + // (comp or layer) the struct now contains the NEW markerP type, which is compatible with the new Marker Suite + + SPAPI A_Err(*AEGP_IsStreamLegal)( + AEGP_LayerH layerH, /* >> */ + AEGP_LayerStream which_stream, /* >> */ + A_Boolean* is_legalP); /* << */ + + + SPAPI A_Err(*AEGP_CanVaryOverTime)( + AEGP_StreamRefH streamH, /* >> */ + A_Boolean* can_varyPB); /* << */ + + SPAPI A_Err(*AEGP_GetValidInterpolations)( + AEGP_StreamRefH streamH, /* >> */ + AEGP_KeyInterpolationMask* valid_interpolationsP); /* << */ + + SPAPI A_Err(*AEGP_GetNewLayerStream)( + AEGP_PluginID aegp_plugin_id, /* >> */ + AEGP_LayerH layerH, /* >> */ + AEGP_LayerStream which_stream, /* >> */ + AEGP_StreamRefH *streamPH); /* << must be disposed by caller! */ + + SPAPI A_Err(*AEGP_GetEffectNumParamStreams)( + AEGP_EffectRefH effect_refH, /* >> */ + A_long *num_paramsPL); /* << */ + + SPAPI A_Err(*AEGP_GetNewEffectStreamByIndex)( + AEGP_PluginID aegp_plugin_id, /* >> */ + AEGP_EffectRefH effect_refH, /* >> */ + PF_ParamIndex param_index, /* >> valid in range [0 to AEGP_GetEffectNumParamStreams - 1], where 0 is the effect's input layer */ + AEGP_StreamRefH *streamPH); /* << must be disposed by caller! */ + + SPAPI A_Err(*AEGP_GetNewMaskStream)( + AEGP_PluginID aegp_plugin_id, /* >> */ + AEGP_MaskRefH mask_refH, /* >> */ + AEGP_MaskStream which_stream, /* >> */ + AEGP_StreamRefH *mask_streamPH); /* << must be disposed by caller! */ + + SPAPI A_Err(*AEGP_DisposeStream)( + AEGP_StreamRefH streamH); /* >> */ + + SPAPI A_Err(*AEGP_GetStreamName)( + AEGP_PluginID pluginID, // in + AEGP_StreamRefH streamH, /* >> */ + A_Boolean force_englishB, /* >> */ + AEGP_MemHandle *utf_stream_namePH); // << handle of A_UTF16Char (contains null terminated UTF16 string); must be disposed with AEGP_FreeMemHandle + + SPAPI A_Err(*AEGP_GetStreamUnitsText)( + AEGP_StreamRefH streamH, /* >> */ + A_Boolean force_englishB, /* >> */ + A_char *unitsZ); /* << space for A_char[AEGP_MAX_STREAM_UNITS_SIZE] */ + + SPAPI A_Err(*AEGP_GetStreamProperties)( + AEGP_StreamRefH streamH, /* >> */ + AEGP_StreamFlags *flagsP, /* << */ + A_FpLong *minP0, /* << */ + A_FpLong *maxP0); /* << */ + + SPAPI A_Err(*AEGP_IsStreamTimevarying)( /* takes expressions into account */ + AEGP_StreamRefH streamH, /* >> */ + A_Boolean *is_timevaryingPB); /* << */ + + SPAPI A_Err(*AEGP_GetStreamType)( + AEGP_StreamRefH streamH, /* >> */ + AEGP_StreamType *stream_typeP); /* << */ + + SPAPI A_Err(*AEGP_GetNewStreamValue)( + AEGP_PluginID aegp_plugin_id, /* >> */ + AEGP_StreamRefH streamH, /* >> */ + AEGP_LTimeMode time_mode, /* >> */ + const A_Time *timePT, /* >> */ + A_Boolean pre_expressionB, /* >> sample the stream before evaluating the expression */ + AEGP_StreamValue2 *valueP); /* << must be disposed */ + + SPAPI A_Err(*AEGP_DisposeStreamValue)( + AEGP_StreamValue2 *valueP); /* <> */ + + + SPAPI A_Err(*AEGP_SetStreamValue)( // only legal to call when AEGP_GetStreamNumKFs==0 or NO_DATA + AEGP_PluginID aegp_plugin_id, /* >> */ + AEGP_StreamRefH streamH, /* >> */ + AEGP_StreamValue2 *valueP); /* << */ + + // this is only valid on streams with primitive types. It is illegal on + // AEGP_ArbBlockVal || AEGP_MarkerValP || AEGP_MaskOutlineValH + + SPAPI A_Err(*AEGP_GetLayerStreamValue)( + AEGP_LayerH layerH, /* >> */ + AEGP_LayerStream which_stream, /* >> */ + AEGP_LTimeMode time_mode, /* >> */ + const A_Time *timePT, /* >> */ + A_Boolean pre_expressionB, /* >> sample the stream before evaluating the expression */ + AEGP_StreamVal2 *stream_valP, /* << */ + AEGP_StreamType *stream_typeP0); /* << */ + + SPAPI A_Err(*AEGP_GetExpressionState)( /* expressions can be disabled automatically by the parser on playback */ + AEGP_PluginID aegp_plugin_id, /* >> */ + AEGP_StreamRefH streamH, /* >> */ + A_Boolean *enabledPB); /* >> */ + + SPAPI A_Err(*AEGP_SetExpressionState)( /* expressions can be disabled automatically by the parser on playback */ + AEGP_PluginID aegp_plugin_id, /* >> */ + AEGP_StreamRefH streamH, /* >> */ + A_Boolean enabledB); /* >> */ + + SPAPI A_Err(*AEGP_GetExpression)( + AEGP_PluginID aegp_plugin_id, /* >> */ + AEGP_StreamRefH streamH, /* >> */ + AEGP_MemHandle *expressionHZ); /* << must be disposed with AEGP_FreeMemHandle */ + + SPAPI A_Err(*AEGP_SetExpression)( + AEGP_PluginID aegp_plugin_id, /* >> */ + AEGP_StreamRefH streamH, /* >> */ + const A_char* expressionP); /* >> not adopted */ + + SPAPI A_Err(*AEGP_DuplicateStreamRef)( // must dispose yourself + AEGP_PluginID aegp_plugin_id, // in + AEGP_StreamRefH streamH, // in + AEGP_StreamRefH *dup_streamPH); // out +} AEGP_StreamSuite4; + + + +#define kAEGPStreamSuiteVersion3 8 /* frozen in AE 8 */ +typedef struct AEGP_StreamSuite3 { + // the only diff from this vs. last rev is that routines that pass AEGP_StreamValue2, when referring to a marker, + // (comp or layer) the struct now contains the NEW markerP type, which is compatible with the new Marker Suite + + SPAPI A_Err (*AEGP_IsStreamLegal)( + AEGP_LayerH layerH, /* >> */ + AEGP_LayerStream which_stream, /* >> */ + A_Boolean* is_legalP); /* << */ + + + SPAPI A_Err (*AEGP_CanVaryOverTime)( + AEGP_StreamRefH streamH, /* >> */ + A_Boolean* can_varyPB); /* << */ + + SPAPI A_Err (*AEGP_GetValidInterpolations)( + AEGP_StreamRefH streamH, /* >> */ + AEGP_KeyInterpolationMask* valid_interpolationsP); /* << */ + + SPAPI A_Err (*AEGP_GetNewLayerStream)( + AEGP_PluginID aegp_plugin_id, /* >> */ + AEGP_LayerH layerH, /* >> */ + AEGP_LayerStream which_stream, /* >> */ + AEGP_StreamRefH *streamPH); /* << must be disposed by caller! */ + + SPAPI A_Err (*AEGP_GetEffectNumParamStreams)( + AEGP_EffectRefH effect_refH, /* >> */ + A_long *num_paramsPL); /* << */ + + SPAPI A_Err (*AEGP_GetNewEffectStreamByIndex)( + AEGP_PluginID aegp_plugin_id, /* >> */ + AEGP_EffectRefH effect_refH, /* >> */ + PF_ParamIndex param_index, /* >> valid in range [0 to AEGP_GetEffectNumParamStreams - 1], where 0 is the effect's input layer */ + AEGP_StreamRefH *streamPH); /* << must be disposed by caller! */ + + SPAPI A_Err (*AEGP_GetNewMaskStream)( + AEGP_PluginID aegp_plugin_id, /* >> */ + AEGP_MaskRefH mask_refH, /* >> */ + AEGP_MaskStream which_stream, /* >> */ + AEGP_StreamRefH *mask_streamPH); /* << must be disposed by caller! */ + + SPAPI A_Err (*AEGP_DisposeStream)( + AEGP_StreamRefH streamH); /* >> */ + + SPAPI A_Err (*AEGP_GetStreamName)( + AEGP_StreamRefH streamH, /* >> */ + A_Boolean force_englishB, /* >> */ + A_char *nameZ); /* << space for A_char[AEGP_MAX_STREAM_NAME_SIZE] */ + + SPAPI A_Err (*AEGP_GetStreamUnitsText)( + AEGP_StreamRefH streamH, /* >> */ + A_Boolean force_englishB, /* >> */ + A_char *unitsZ); /* << space for A_char[AEGP_MAX_STREAM_UNITS_SIZE] */ + + SPAPI A_Err (*AEGP_GetStreamProperties)( + AEGP_StreamRefH streamH, /* >> */ + AEGP_StreamFlags *flagsP, /* << */ + A_FpLong *minP0, /* << */ + A_FpLong *maxP0); /* << */ + + SPAPI A_Err (*AEGP_IsStreamTimevarying)( /* takes expressions into account */ + AEGP_StreamRefH streamH, /* >> */ + A_Boolean *is_timevaryingPB); /* << */ + + SPAPI A_Err (*AEGP_GetStreamType)( + AEGP_StreamRefH streamH, /* >> */ + AEGP_StreamType *stream_typeP); /* << */ + + SPAPI A_Err (*AEGP_GetNewStreamValue)( + AEGP_PluginID aegp_plugin_id, /* >> */ + AEGP_StreamRefH streamH, /* >> */ + AEGP_LTimeMode time_mode, /* >> */ + const A_Time *timePT, /* >> */ + A_Boolean pre_expressionB, /* >> sample the stream before evaluating the expression */ + AEGP_StreamValue2 *valueP); /* << must be disposed */ + + SPAPI A_Err (*AEGP_DisposeStreamValue)( + AEGP_StreamValue2 *valueP); /* <> */ + + + SPAPI A_Err (*AEGP_SetStreamValue)( // only legal to call when AEGP_GetStreamNumKFs==0 or NO_DATA + AEGP_PluginID aegp_plugin_id, /* >> */ + AEGP_StreamRefH streamH, /* >> */ + AEGP_StreamValue2 *valueP); /* << */ + + // this is only valid on streams with primitive types. It is illegal on + // AEGP_ArbBlockVal || AEGP_MarkerValP || AEGP_MaskOutlineValH + + SPAPI A_Err (*AEGP_GetLayerStreamValue)( + AEGP_LayerH layerH, /* >> */ + AEGP_LayerStream which_stream, /* >> */ + AEGP_LTimeMode time_mode, /* >> */ + const A_Time *timePT, /* >> */ + A_Boolean pre_expressionB, /* >> sample the stream before evaluating the expression */ + AEGP_StreamVal2 *stream_valP, /* << */ + AEGP_StreamType *stream_typeP0); /* << */ + + SPAPI A_Err (*AEGP_GetExpressionState)( /* expressions can be disabled automatically by the parser on playback */ + AEGP_PluginID aegp_plugin_id, /* >> */ + AEGP_StreamRefH streamH, /* >> */ + A_Boolean *enabledPB); /* >> */ + + SPAPI A_Err (*AEGP_SetExpressionState)( /* expressions can be disabled automatically by the parser on playback */ + AEGP_PluginID aegp_plugin_id, /* >> */ + AEGP_StreamRefH streamH, /* >> */ + A_Boolean enabledB); /* >> */ + + SPAPI A_Err (*AEGP_GetExpression)( + AEGP_PluginID aegp_plugin_id, /* >> */ + AEGP_StreamRefH streamH, /* >> */ + AEGP_MemHandle *expressionHZ); /* << must be disposed with AEGP_FreeMemHandle */ + + SPAPI A_Err (*AEGP_SetExpression)( + AEGP_PluginID aegp_plugin_id, /* >> */ + AEGP_StreamRefH streamH, /* >> */ + const A_char* expressionP); /* >> not adopted */ + + SPAPI A_Err (*AEGP_DuplicateStreamRef)( // must dispose yourself + AEGP_PluginID aegp_plugin_id, // in + AEGP_StreamRefH streamH, // in + AEGP_StreamRefH *dup_streamPH); // out +} AEGP_StreamSuite3; + + +#define kAEGPStreamSuiteVersion2 7 /* frozen in AE 6.5 */ + +typedef struct AEGP_StreamSuite2 { + + SPAPI A_Err (*AEGP_IsStreamLegal)( + AEGP_LayerH layerH, /* >> */ + AEGP_LayerStream which_stream, /* >> */ + A_Boolean* is_legalP); /* << */ + + + SPAPI A_Err (*AEGP_CanVaryOverTime)( + AEGP_StreamRefH streamH, /* >> */ + A_Boolean* can_varyPB); /* << */ + + SPAPI A_Err (*AEGP_GetValidInterpolations)( + AEGP_StreamRefH streamH, /* >> */ + AEGP_KeyInterpolationMask* valid_interpolationsP); /* << */ + + SPAPI A_Err (*AEGP_GetNewLayerStream)( + AEGP_PluginID aegp_plugin_id, /* >> */ + AEGP_LayerH layerH, /* >> */ + AEGP_LayerStream which_stream, /* >> */ + AEGP_StreamRefH *streamPH); /* << must be disposed by caller! */ + + SPAPI A_Err (*AEGP_GetEffectNumParamStreams)( + AEGP_EffectRefH effect_refH, /* >> */ + A_long *num_paramsPL); /* << */ + + SPAPI A_Err (*AEGP_GetNewEffectStreamByIndex)( + AEGP_PluginID aegp_plugin_id, /* >> */ + AEGP_EffectRefH effect_refH, /* >> */ + PF_ParamIndex param_index, /* >> valid in range [0 to AEGP_GetEffectNumParamStreams - 1], where 0 is the effect's input layer */ + AEGP_StreamRefH *streamPH); /* << must be disposed by caller! */ + + SPAPI A_Err (*AEGP_GetNewMaskStream)( + AEGP_PluginID aegp_plugin_id, /* >> */ + AEGP_MaskRefH mask_refH, /* >> */ + AEGP_MaskStream which_stream, /* >> */ + AEGP_StreamRefH *mask_streamPH); /* << must be disposed by caller! */ + + SPAPI A_Err (*AEGP_DisposeStream)( + AEGP_StreamRefH streamH); /* >> */ + + SPAPI A_Err (*AEGP_GetStreamName)( + AEGP_StreamRefH streamH, /* >> */ + A_Boolean force_englishB, /* >> */ + A_char *nameZ); /* << space for A_char[AEGP_MAX_STREAM_NAME_SIZE] */ + + SPAPI A_Err (*AEGP_GetStreamUnitsText)( + AEGP_StreamRefH streamH, /* >> */ + A_Boolean force_englishB, /* >> */ + A_char *unitsZ); /* << space for A_char[AEGP_MAX_STREAM_UNITS_SIZE] */ + + SPAPI A_Err (*AEGP_GetStreamProperties)( + AEGP_StreamRefH streamH, /* >> */ + AEGP_StreamFlags *flagsP, /* << */ + A_FpLong *minP0, /* << */ + A_FpLong *maxP0); /* << */ + + SPAPI A_Err (*AEGP_IsStreamTimevarying)( /* takes expressions into account */ + AEGP_StreamRefH streamH, /* >> */ + A_Boolean *is_timevaryingPB); /* << */ + + SPAPI A_Err (*AEGP_GetStreamType)( + AEGP_StreamRefH streamH, /* >> */ + AEGP_StreamType *stream_typeP); /* << */ + + SPAPI A_Err (*AEGP_GetNewStreamValue)( + AEGP_PluginID aegp_plugin_id, /* >> */ + AEGP_StreamRefH streamH, /* >> */ + AEGP_LTimeMode time_mode, /* >> */ + const A_Time *timePT, /* >> */ + A_Boolean pre_expressionB, /* >> sample the stream before evaluating the expression */ + AEGP_StreamValue *valueP); /* << must be disposed */ + + SPAPI A_Err (*AEGP_DisposeStreamValue)( + AEGP_StreamValue *valueP); /* <> */ + + + SPAPI A_Err (*AEGP_SetStreamValue)( // only legal to call when AEGP_GetStreamNumKFs==0 or NO_DATA + AEGP_PluginID aegp_plugin_id, /* >> */ + AEGP_StreamRefH streamH, /* >> */ + AEGP_StreamValue *valueP); /* << */ + + // this is only valid on streams with primitive types. It is illegal on + // AEGP_ArbBlockVal || AEGP_MarkerValP || AEGP_MaskOutlineValH + + SPAPI A_Err (*AEGP_GetLayerStreamValue)( + AEGP_LayerH layerH, /* >> */ + AEGP_LayerStream which_stream, /* >> */ + AEGP_LTimeMode time_mode, /* >> */ + const A_Time *timePT, /* >> */ + A_Boolean pre_expressionB, /* >> sample the stream before evaluating the expression */ + AEGP_StreamVal *stream_valP, /* << */ + AEGP_StreamType *stream_typeP0); /* << */ + + SPAPI A_Err (*AEGP_GetExpressionState)( /* expressions can be disabled automatically by the parser on playback */ + AEGP_PluginID aegp_plugin_id, /* >> */ + AEGP_StreamRefH streamH, /* >> */ + A_Boolean *enabledPB); /* >> */ + + SPAPI A_Err (*AEGP_SetExpressionState)( /* expressions can be disabled automatically by the parser on playback */ + AEGP_PluginID aegp_plugin_id, /* >> */ + AEGP_StreamRefH streamH, /* >> */ + A_Boolean enabledB); /* >> */ + + SPAPI A_Err (*AEGP_GetExpression)( + AEGP_PluginID aegp_plugin_id, /* >> */ + AEGP_StreamRefH streamH, /* >> */ + AEGP_MemHandle *expressionHZ); /* << must be disposed with AEGP_FreeMemHandle */ + + SPAPI A_Err (*AEGP_SetExpression)( + AEGP_PluginID aegp_plugin_id, /* >> */ + AEGP_StreamRefH streamH, /* >> */ + const A_char* expressionP); /* >> not adopted */ + + SPAPI A_Err (*AEGP_DuplicateStreamRef)( // must dispose yourself + AEGP_PluginID aegp_plugin_id, // in + AEGP_StreamRefH streamH, // in + AEGP_StreamRefH *dup_streamPH); // out +} AEGP_StreamSuite2; + +#define kAEGPStreamSuite "AEGP Stream Suite" +#define kAEGPStreamSuiteVersion1 4 /* frozen in AE 5.0 */ + +typedef struct AEGP_StreamSuite1 { + + SPAPI A_Err (*AEGP_IsStreamLegal)( + AEGP_LayerH layerH, /* >> */ + AEGP_LayerStream which_stream, /* >> */ + A_Boolean* is_legalP); /* << */ + + + SPAPI A_Err (*AEGP_CanVaryOverTime)( + AEGP_StreamRefH streamH, /* >> */ + A_Boolean* can_varyPB); /* << */ + + + SPAPI A_Err (*AEGP_GetNewLayerStream)( + AEGP_PluginID aegp_plugin_id, /* >> */ + AEGP_LayerH layerH, /* >> */ + AEGP_LayerStream which_stream, /* >> */ + AEGP_StreamRefH *streamPH); /* << must be disposed by caller! */ + + SPAPI A_Err (*AEGP_GetEffectNumParamStreams)( + AEGP_EffectRefH effect_refH, /* >> */ + A_long *num_paramsPL); /* << */ + + SPAPI A_Err (*AEGP_GetNewEffectStreamByIndex)( + AEGP_PluginID aegp_plugin_id, /* >> */ + AEGP_EffectRefH effect_refH, /* >> */ + PF_ParamIndex param_index, /* >> valid in range [0 to AEGP_GetEffectNumParamStreams - 1], where 0 is the effect's input layer */ + AEGP_StreamRefH *streamPH); /* << must be disposed by caller! */ + + SPAPI A_Err (*AEGP_GetNewMaskStream)( + AEGP_PluginID aegp_plugin_id, /* >> */ + AEGP_MaskRefH mask_refH, /* >> */ + AEGP_MaskStream which_stream, /* >> */ + AEGP_StreamRefH *mask_streamPH); /* << must be disposed by caller! */ + + SPAPI A_Err (*AEGP_DisposeStream)( + AEGP_StreamRefH streamH); /* >> */ + + SPAPI A_Err (*AEGP_GetStreamName)( + AEGP_StreamRefH streamH, /* >> */ + A_Boolean force_englishB, /* >> */ + A_char *nameZ); /* << space for A_char[AEGP_MAX_STREAM_NAME_SIZE] */ + + SPAPI A_Err (*AEGP_GetStreamUnitsText)( + AEGP_StreamRefH streamH, /* >> */ + A_Boolean force_englishB, /* >> */ + A_char *unitsZ); /* << space for A_char[AEGP_MAX_STREAM_UNITS_SIZE] */ + + SPAPI A_Err (*AEGP_GetStreamProperties)( + AEGP_StreamRefH streamH, /* >> */ + AEGP_StreamFlags *flagsP, /* << */ + A_FpLong *minP0, /* << */ + A_FpLong *maxP0); /* << */ + + SPAPI A_Err (*AEGP_IsStreamTimevarying)( /* takes expressions into account */ + AEGP_StreamRefH streamH, /* >> */ + A_Boolean *is_timevaryingPB); /* << */ + + SPAPI A_Err (*AEGP_GetStreamType)( + AEGP_StreamRefH streamH, /* >> */ + AEGP_StreamType *stream_typeP); /* << */ + + SPAPI A_Err (*AEGP_GetNewStreamValue)( + AEGP_PluginID aegp_plugin_id, /* >> */ + AEGP_StreamRefH streamH, /* >> */ + AEGP_LTimeMode time_mode, /* >> */ + const A_Time *timePT, /* >> */ + A_Boolean pre_expressionB, /* >> sample the stream before evaluating the expression */ + AEGP_StreamValue *valueP); /* << must be disposed */ + + SPAPI A_Err (*AEGP_DisposeStreamValue)( + AEGP_StreamValue *valueP); /* <> */ + + + SPAPI A_Err (*AEGP_SetStreamValue)( // only legal to call when AEGP_GetStreamNumKFs==0 or NO_DATA + AEGP_PluginID aegp_plugin_id, /* >> */ + AEGP_StreamRefH streamH, /* >> */ + AEGP_StreamValue *valueP); /* << */ + + // this is only valid on streams with primitive types. It is illegal on + // AEGP_ArbBlockVal || AEGP_MarkerValH || AEGP_MaskOutlineValH + + SPAPI A_Err (*AEGP_GetLayerStreamValue)( + AEGP_LayerH layerH, /* >> */ + AEGP_LayerStream which_stream, /* >> */ + AEGP_LTimeMode time_mode, /* >> */ + const A_Time *timePT, /* >> */ + A_Boolean pre_expressionB, /* >> sample the stream before evaluating the expression */ + AEGP_StreamVal *stream_valP, /* << */ + AEGP_StreamType *stream_typeP0); /* << */ + + SPAPI A_Err (*AEGP_GetExpressionState)( /* expressions can be disabled automatically by the parser on playback */ + AEGP_PluginID aegp_plugin_id, /* >> */ + AEGP_StreamRefH streamH, /* >> */ + A_Boolean *enabledPB); /* >> */ + + SPAPI A_Err (*AEGP_SetExpressionState)( /* expressions can be disabled automatically by the parser on playback */ + AEGP_PluginID aegp_plugin_id, /* >> */ + AEGP_StreamRefH streamH, /* >> */ + A_Boolean enabledB); /* >> */ + + SPAPI A_Err (*AEGP_GetExpression)( + AEGP_PluginID aegp_plugin_id, /* >> */ + AEGP_StreamRefH streamH, /* >> */ + AEGP_MemHandle *expressionHZ); /* << must be disposed with AEGP_FreeMemHandle */ + + SPAPI A_Err (*AEGP_SetExpression)( + AEGP_PluginID aegp_plugin_id, /* >> */ + AEGP_StreamRefH streamH, /* >> */ + const A_char* expressionP); /* >> not adopted */ + + +} AEGP_StreamSuite1; + + +#define kAEGPLayerSuiteVersion1 5 /* frozen in AE 5.0 */ + +typedef struct AEGP_LayerSuite1 { + + SPAPI A_Err (*AEGP_GetCompNumLayers)( + AEGP_CompH compH, /* >> */ + A_long *num_layersPL); /* << */ + + SPAPI A_Err (*AEGP_GetCompLayerByIndex)( + AEGP_CompH compH, /* >> */ + A_long layer_indexL, /* >> */ + AEGP_LayerH *layerPH); /* << */ + + SPAPI A_Err (*AEGP_GetActiveLayer)( + AEGP_LayerH *layerPH); /* << only if one layer is selected */ + + SPAPI A_Err (*AEGP_GetLayerIndex)( + AEGP_LayerH layerH, /* >> */ + A_long *layer_indexPL); /* << */ + + SPAPI A_Err (*AEGP_GetLayerSourceItem)( + AEGP_LayerH layerH, /* >> */ + AEGP_ItemH *source_itemPH); /* << */ + + SPAPI A_Err (*AEGP_GetLayerParentComp)( + AEGP_LayerH layerH, /* >> */ + AEGP_CompH *compPH); /* << */ + + SPAPI A_Err (*AEGP_GetLayerName)( + AEGP_LayerH layerH, /* >> */ + A_char *layer_nameZ0, /* << space for A_char[AEGP_MAX_LAYER_NAME_SIZE] */ + A_char *source_nameZ0); /* << space for A_char[AEGP_MAX_LAYER_NAME_SIZE] */ + + SPAPI A_Err (*AEGP_GetLayerQuality)( + AEGP_LayerH layerH, /* >> */ + AEGP_LayerQuality *qualityP); /* << */ + + SPAPI A_Err (*AEGP_SetLayerQuality)( /* UNDOABLE */ + AEGP_LayerH layerH, /* >> */ + AEGP_LayerQuality quality); /* >> */ + + SPAPI A_Err (*AEGP_GetLayerFlags)( + AEGP_LayerH layerH, /* >> */ + AEGP_LayerFlags *layer_flagsP); /* << */ + + SPAPI A_Err (*AEGP_SetLayerFlag)( + AEGP_LayerH layerH, // >> + AEGP_LayerFlags single_flag, // >> + A_Boolean valueB); // >> + + SPAPI A_Err (*AEGP_IsLayerVideoReallyOn)( // accounts for solo status of other layers in comp + AEGP_LayerH layerH, /* >> */ + A_Boolean *onPB); /* << */ + + SPAPI A_Err (*AEGP_IsLayerAudioReallyOn)( // accounts for solo status of other layers in comp + AEGP_LayerH layerH, /* >> */ + A_Boolean *onPB); /* << */ + + SPAPI A_Err (*AEGP_GetLayerCurrentTime)( // not updated while rendering + AEGP_LayerH layerH, /* >> */ + AEGP_LTimeMode time_mode, /* >> */ + A_Time *curr_timePT); /* << */ + + SPAPI A_Err (*AEGP_GetLayerInPoint)( + AEGP_LayerH layerH, /* >> */ + AEGP_LTimeMode time_mode, /* >> */ + A_Time *in_pointPT); /* << */ + + SPAPI A_Err (*AEGP_GetLayerDuration)( + AEGP_LayerH layerH, /* >> */ + AEGP_LTimeMode time_mode, /* >> */ + A_Time *durationPT); /* << */ + + SPAPI A_Err (*AEGP_SetLayerInPointAndDuration)( /* UNDOABLE */ + AEGP_LayerH layerH, /* >> */ + AEGP_LTimeMode time_mode, /* >> */ + const A_Time *in_pointPT, /* >> */ + const A_Time *durationPT); /* >> */ + + SPAPI A_Err (*AEGP_GetLayerOffset)( + AEGP_LayerH layerH, /* >> */ + A_Time *offsetPT); /* << always in comp time */ + + SPAPI A_Err (*AEGP_SetLayerOffset)( /* UNDOABLE */ + AEGP_LayerH layerH, /* >> */ + const A_Time *offsetPT); /* >> always in comp time */ + + SPAPI A_Err (*AEGP_GetLayerStretch)( + AEGP_LayerH layerH, /* >> */ + A_Ratio *stretchPRt); /* << */ + + SPAPI A_Err (*AEGP_SetLayerStretch)( /* UNDOABLE */ + AEGP_LayerH layerH, /* >> */ + const A_Ratio *stretchPRt); /* >> */ + + SPAPI A_Err (*AEGP_GetLayerTransferMode)( + AEGP_LayerH layerH, /* >> */ + AEGP_LayerTransferMode *transfer_modeP); /* << */ + + SPAPI A_Err (*AEGP_SetLayerTransferMode)( /* UNDOABLE */ + AEGP_LayerH layerH, /* >> */ + const AEGP_LayerTransferMode *transfer_modeP); /* >> */ + + SPAPI A_Err (*AEGP_IsAddLayerValid)( + AEGP_ItemH item_to_addH, /* >> */ + AEGP_CompH into_compH, /* >> */ + A_Boolean *validPB); /* << */ + + SPAPI A_Err (*AEGP_AddLayer)( /* UNDOABLE */ + AEGP_ItemH item_to_addH, /* >> check AEGP_IsAddLayerValid() before using */ + AEGP_CompH into_compH, /* >> */ + AEGP_LayerH *added_layerPH0); /* << */ + + SPAPI A_Err (*AEGP_ReorderLayer)( /* UNDOABLE */ + AEGP_LayerH layerH, /* >> */ + A_long layer_indexL); /* >> */ + + SPAPI A_Err (*AEGP_GetLayerMaskedBounds)( + AEGP_LayerH layerH, /* >> */ + AEGP_LTimeMode time_mode, /* >> */ + const A_Time *timePT, /* >> */ + A_FloatRect *boundsPR); /* << */ + + SPAPI A_Err (*AEGP_GetLayerObjectType)( + AEGP_LayerH layerH, /* >> */ + AEGP_ObjectType *object_type); /* << */ + + SPAPI A_Err (*AEGP_IsLayer3D)( + AEGP_LayerH layerH, /* >> */ + A_Boolean *is_3DPB); /* << */ + + SPAPI A_Err (*AEGP_IsLayer2D)( + AEGP_LayerH layerH, /* >> */ + A_Boolean *is_2DPB); /* << */ + + SPAPI A_Err (*AEGP_IsVideoActive)( + AEGP_LayerH layerH, /* >> */ + AEGP_LTimeMode time_mode, /* >> */ + const A_Time *timePT, /* >> */ + A_Boolean *is_activePB); /* << */ + + SPAPI A_Err (*AEGP_IsLayerUsedAsTrackMatte)( + AEGP_LayerH layerH, /* >> */ + A_Boolean fill_must_be_activeB, /* >> */ + A_Boolean *is_track_mattePB); /* << */ + + SPAPI A_Err (*AEGP_DoesLayerHaveTrackMatte)( + AEGP_LayerH layerH, /* >> */ + A_Boolean *has_track_mattePB); /* << */ + + SPAPI A_Err (*AEGP_ConvertCompToLayerTime)( + AEGP_LayerH layerH, /* >> */ + const A_Time *comp_timeP, /* >> */ + A_Time *layer_timeP); /* << */ + + SPAPI A_Err (*AEGP_GetLayerDancingRandValue)( + AEGP_LayerH layerH, /* >> */ + const A_Time *comp_timePT, /* >> */ + A_long *rand_valuePL); /* << */ + + SPAPI A_Err (*AEGP_GetLayerID)( + AEGP_LayerH layerH, /* >> */ + AEGP_LayerIDVal *id_valP); /* << */ + + SPAPI A_Err (*AEGP_GetLayerToWorldXform)( + AEGP_LayerH aegp_layerH, /* >> */ + const A_Time *comp_timeP, /* >> */ + A_Matrix4 *tranform); /* >> */ + + SPAPI A_Err (*AEGP_GetLayerToWorldXformFromView)( + AEGP_LayerH aegp_layerH, /* >> */ + const A_Time *view_timeP, /* >> */ + const A_Time *comp_timeP, /* >> */ + A_Matrix4 *tranform); /* >> */ + + SPAPI A_Err (*AEGP_SetLayerName)( + AEGP_LayerH aegp_layerH, /* >> */ + const A_char *new_nameZ); /* >> */ + +} AEGP_LayerSuite1; + +#define kAEGPLayerSuiteVersion2 7 /* frozen in AE 5.5 */ + +typedef struct AEGP_LayerSuite2 { + + SPAPI A_Err (*AEGP_GetCompNumLayers)( + AEGP_CompH compH, /* >> */ + A_long *num_layersPL); /* << */ + + SPAPI A_Err (*AEGP_GetCompLayerByIndex)( + AEGP_CompH compH, /* >> */ + A_long layer_indexL, /* >> */ + AEGP_LayerH *layerPH); /* << */ + + SPAPI A_Err (*AEGP_GetActiveLayer)( + AEGP_LayerH *layerPH); /* << only if one layer is selected */ + + SPAPI A_Err (*AEGP_GetLayerIndex)( + AEGP_LayerH layerH, /* >> */ + A_long *layer_indexPL); /* << */ + + SPAPI A_Err (*AEGP_GetLayerSourceItem)( + AEGP_LayerH layerH, /* >> */ + AEGP_ItemH *source_itemPH); /* << */ + + SPAPI A_Err (*AEGP_GetLayerParentComp)( + AEGP_LayerH layerH, /* >> */ + AEGP_CompH *compPH); /* << */ + + SPAPI A_Err (*AEGP_GetLayerName)( + AEGP_LayerH layerH, /* >> */ + A_char *layer_nameZ0, /* << space for A_char[AEGP_MAX_LAYER_NAME_SIZE] */ + A_char *source_nameZ0); /* << space for A_char[AEGP_MAX_LAYER_NAME_SIZE] */ + + SPAPI A_Err (*AEGP_GetLayerQuality)( + AEGP_LayerH layerH, /* >> */ + AEGP_LayerQuality *qualityP); /* << */ + + SPAPI A_Err (*AEGP_SetLayerQuality)( /* UNDOABLE */ + AEGP_LayerH layerH, /* >> */ + AEGP_LayerQuality quality); /* >> */ + + SPAPI A_Err (*AEGP_GetLayerFlags)( + AEGP_LayerH layerH, /* >> */ + AEGP_LayerFlags *layer_flagsP); /* << */ + + SPAPI A_Err (*AEGP_SetLayerFlag)( + AEGP_LayerH layerH, /* >> */ + AEGP_LayerFlags single_flag, /* >> */ + A_Boolean valueB); /* >> */ + + SPAPI A_Err (*AEGP_IsLayerVideoReallyOn)( // accounts for solo status of other layers in comp + AEGP_LayerH layerH, /* >> */ + A_Boolean *onPB); /* << */ + + SPAPI A_Err (*AEGP_IsLayerAudioReallyOn)( // accounts for solo status of other layers in comp + AEGP_LayerH layerH, /* >> */ + A_Boolean *onPB); /* << */ + + SPAPI A_Err (*AEGP_GetLayerCurrentTime)( // not updated while rendering + AEGP_LayerH layerH, /* >> */ + AEGP_LTimeMode time_mode, /* >> */ + A_Time *curr_timePT); /* << */ + + SPAPI A_Err (*AEGP_GetLayerInPoint)( + AEGP_LayerH layerH, /* >> */ + AEGP_LTimeMode time_mode, /* >> */ + A_Time *in_pointPT); /* << */ + + SPAPI A_Err (*AEGP_GetLayerDuration)( + AEGP_LayerH layerH, /* >> */ + AEGP_LTimeMode time_mode, /* >> */ + A_Time *durationPT); /* << */ + + SPAPI A_Err (*AEGP_SetLayerInPointAndDuration)( /* UNDOABLE */ + AEGP_LayerH layerH, /* >> */ + AEGP_LTimeMode time_mode, /* >> */ + const A_Time *in_pointPT, /* >> */ + const A_Time *durationPT); /* >> */ + + SPAPI A_Err (*AEGP_GetLayerOffset)( + AEGP_LayerH layerH, /* >> */ + A_Time *offsetPT); /* << always in comp time */ + + SPAPI A_Err (*AEGP_SetLayerOffset)( /* UNDOABLE */ + AEGP_LayerH layerH, /* >> */ + const A_Time *offsetPT); /* >> always in comp time */ + + SPAPI A_Err (*AEGP_GetLayerStretch)( + AEGP_LayerH layerH, /* >> */ + A_Ratio *stretchPRt); /* << */ + + SPAPI A_Err (*AEGP_SetLayerStretch)( /* UNDOABLE */ + AEGP_LayerH layerH, /* >> */ + const A_Ratio *stretchPRt); /* >> */ + + SPAPI A_Err (*AEGP_GetLayerTransferMode)( + AEGP_LayerH layerH, /* >> */ + AEGP_LayerTransferMode *transfer_modeP); /* << */ + + SPAPI A_Err (*AEGP_SetLayerTransferMode)( /* UNDOABLE */ + AEGP_LayerH layerH, /* >> */ + const AEGP_LayerTransferMode *transfer_modeP); /* >> */ + + SPAPI A_Err (*AEGP_IsAddLayerValid)( + AEGP_ItemH item_to_addH, /* >> */ + AEGP_CompH into_compH, /* >> */ + A_Boolean *validPB); /* << */ + + SPAPI A_Err (*AEGP_AddLayer)( /* UNDOABLE */ + AEGP_ItemH item_to_addH, /* >> check AEGP_IsAddLayerValid() before using */ + AEGP_CompH into_compH, /* >> */ + AEGP_LayerH *added_layerPH0); /* << */ + + SPAPI A_Err (*AEGP_ReorderLayer)( /* UNDOABLE */ + AEGP_LayerH layerH, /* >> */ + A_long layer_indexL); /* >> */ + + SPAPI A_Err (*AEGP_GetLayerMaskedBounds)( + AEGP_LayerH layerH, /* >> */ + AEGP_LTimeMode time_mode, /* >> */ + const A_Time *timePT, /* >> */ + A_FloatRect *boundsPR); /* << */ + + SPAPI A_Err (*AEGP_GetLayerObjectType)( + AEGP_LayerH layerH, /* >> */ + AEGP_ObjectType *object_type); /* << */ + + SPAPI A_Err (*AEGP_IsLayer3D)( + AEGP_LayerH layerH, /* >> */ + A_Boolean *is_3DPB); /* << */ + + SPAPI A_Err (*AEGP_IsLayer2D)( + AEGP_LayerH layerH, /* >> */ + A_Boolean *is_2DPB); /* << */ + + SPAPI A_Err (*AEGP_IsVideoActive)( + AEGP_LayerH layerH, /* >> */ + AEGP_LTimeMode time_mode, /* >> */ + const A_Time *timePT, /* >> */ + A_Boolean *is_activePB); /* << */ + + SPAPI A_Err (*AEGP_IsLayerUsedAsTrackMatte)( + AEGP_LayerH layerH, /* >> */ + A_Boolean fill_must_be_activeB, /* >> */ + A_Boolean *is_track_mattePB); /* << */ + + SPAPI A_Err (*AEGP_DoesLayerHaveTrackMatte)( + AEGP_LayerH layerH, /* >> */ + A_Boolean *has_track_mattePB); /* << */ + + SPAPI A_Err (*AEGP_ConvertCompToLayerTime)( + AEGP_LayerH layerH, /* >> */ + const A_Time *comp_timePT, /* >> */ + A_Time *layer_timePT); /* << */ + + SPAPI A_Err (*AEGP_ConvertLayerToCompTime)( + AEGP_LayerH layerH, /* >> */ + const A_Time *layer_timePT, /* >> */ + A_Time *comp_timePT) ; /* << */ + + SPAPI A_Err (*AEGP_GetLayerDancingRandValue)( + AEGP_LayerH layerH, /* >> */ + const A_Time *comp_timePT, /* >> */ + A_long *rand_valuePL); /* << */ + + SPAPI A_Err (*AEGP_GetLayerID)( + AEGP_LayerH layerH, /* >> */ + AEGP_LayerIDVal *id_valP); /* << */ + + SPAPI A_Err (*AEGP_GetLayerToWorldXform)( + AEGP_LayerH aegp_layerH, /* >> */ + const A_Time *comp_timeP, /* >> */ + A_Matrix4 *tranform); /* >> */ + + SPAPI A_Err (*AEGP_GetLayerToWorldXformFromView)( + AEGP_LayerH aegp_layerH, /* >> */ + const A_Time *view_timeP, /* >> */ + const A_Time *comp_timeP, /* >> */ + A_Matrix4 *tranform); /* >> */ + + SPAPI A_Err (*AEGP_SetLayerName)( + AEGP_LayerH aegp_layerH, /* >> */ + const A_char *new_nameZ); /* >> */ + + SPAPI A_Err (*AEGP_GetLayerParent)( + const AEGP_LayerH layerH, /* >> */ + AEGP_LayerH *parent_layerPH); /* << NULL if no parent */ + + SPAPI A_Err (*AEGP_SetLayerParent)( + AEGP_LayerH layerH, /* >> */ + const AEGP_LayerH parent_layerH); /* >> */ + + +} AEGP_LayerSuite2; + + + + +#define kAEGPEffectSuite "AEGP Effect Suite" +#define kAEGPEffectSuiteVersion1 1 /* frozen in AE 5.5 */ + +typedef struct AEGP_EffectSuite1 { + + SPAPI A_Err (*AEGP_GetLayerNumEffects)( + AEGP_LayerH layerH, /* >> */ + A_long *num_effectsPL); /* << */ + + SPAPI A_Err (*AEGP_GetLayerEffectByIndex)( + AEGP_PluginID aegp_plugin_id, /* >> */ + AEGP_LayerH layerH, /* >> */ + AEGP_EffectIndex layer_effect_indexL, /* >> */ + AEGP_EffectRefH *effectPH); /* << MUST dispose with DisposeEffect*/ + + SPAPI A_Err (*AEGP_GetInstalledKeyFromLayerEffect)( + AEGP_EffectRefH effect_refH, /* >> */ + AEGP_InstalledEffectKey *installed_effect_keyP); /* << */ + + SPAPI A_Err (*AEGP_GetEffectParamUnionByIndex)( + AEGP_PluginID aegp_plugin_id, /* >> */ + AEGP_EffectRefH effect_refH, /* >> */ + PF_ParamIndex param_index, /* >> valid in range [0 to AEGP_GetEffectNumParamStreams - 1], where 0 is the effect's input layer */ + PF_ParamType *param_typeP, /* << */ + PF_ParamDefUnion *uP0); /* << DO NOT USE THE VALUE FROM THIS PARAMDEF! */ + + SPAPI A_Err (*AEGP_GetEffectFlags)( + AEGP_EffectRefH effect_refH, /* >> */ + AEGP_EffectFlags *effect_flagsP); /* << */ + + SPAPI A_Err (*AEGP_SetEffectFlags)( + AEGP_EffectRefH effect_refH, /* >> */ + AEGP_EffectFlags effect_flags_set_mask, /* >> */ + AEGP_EffectFlags effect_flags); /* >> */ + + SPAPI A_Err (*AEGP_ReorderEffect)( /* UNDOABLE */ + AEGP_EffectRefH effect_refH, /* >> */ + A_long effect_indexL); /* >> */ + + SPAPI A_Err (*AEGP_EffectCallGeneric)( + AEGP_PluginID aegp_plugin_id, /* >> */ + AEGP_EffectRefH effect_refH, /* >> */ + const A_Time *timePT, /* >> Use the timebase of the layer to which effect is applied. */ + void *effect_extraPV); /* <> */ + + SPAPI A_Err (*AEGP_DisposeEffect)( + AEGP_EffectRefH effect_refH ); /* >> */ + + SPAPI A_Err (*AEGP_ApplyEffect)( + AEGP_PluginID aegp_plugin_id, /* >> */ + AEGP_LayerH layerH, /* >> */ + AEGP_InstalledEffectKey installed_effect_key, /* >> */ + AEGP_EffectRefH *effect_refPH); /* << MUST BE DISPOSED with AEGP_DisposeEffect */ + + SPAPI A_Err (*AEGP_DeleteLayerEffect)( + AEGP_EffectRefH effect_refH); /* >> undoable */ + + SPAPI A_Err (*AEGP_GetNumInstalledEffects)( + A_long *num_installed_effectsPL); /* << */ + + // pass in AEGP_InstalledEffectKey_NONE for installed_effect_key to get first effect key + + SPAPI A_Err (*AEGP_GetNextInstalledEffect)( + AEGP_InstalledEffectKey installed_effect_key, /* >> */ + AEGP_InstalledEffectKey *next_effectPH); /* << */ + + SPAPI A_Err (*AEGP_GetEffectName)( + AEGP_InstalledEffectKey installed_effect_key, /* >> */ + A_char *nameZ); /* << space for A_char[AEGP_MAX_EFFECT_NAME_SIZE] */ + + SPAPI A_Err (*AEGP_GetEffectMatchName)( + AEGP_InstalledEffectKey installed_effect_key, /* >> */ + A_char *match_nameZ); /* << space for A_char[AEGP_MAX_EFFECT_MATCH_NAME_SIZE] */ + + SPAPI A_Err (*AEGP_GetEffectCategory)( + AEGP_InstalledEffectKey installed_effect_key, /* >> */ + A_char *categoryZ); /* << space for A_char[AEGP_MAX_EFFECT_CATEGORY_NAME_SIZE] */ + + +} AEGP_EffectSuite1; + + + + +#define kAEGPEffectSuiteVersion2 2 /* frozen in AE 6.5 */ + +typedef struct AEGP_EffectSuite2 { + + SPAPI A_Err (*AEGP_GetLayerNumEffects)( + AEGP_LayerH layerH, /* >> */ + A_long *num_effectsPL); /* << */ + + SPAPI A_Err (*AEGP_GetLayerEffectByIndex)( + AEGP_PluginID aegp_plugin_id, /* >> */ + AEGP_LayerH layerH, /* >> */ + AEGP_EffectIndex layer_effect_indexL, /* >> */ + AEGP_EffectRefH *effectPH); /* << MUST dispose with DisposeEffect*/ + + SPAPI A_Err (*AEGP_GetInstalledKeyFromLayerEffect)( + AEGP_EffectRefH effect_refH, /* >> */ + AEGP_InstalledEffectKey *installed_effect_keyP); /* << */ + + SPAPI A_Err (*AEGP_GetEffectParamUnionByIndex)( + AEGP_PluginID aegp_plugin_id, /* >> */ + AEGP_EffectRefH effect_refH, /* >> */ + PF_ParamIndex param_index, /* >> valid in range [0 to AEGP_GetEffectNumParamStreams - 1], where 0 is the effect's input layer */ + PF_ParamType *param_typeP, /* << */ + PF_ParamDefUnion *uP0); /* << DO NOT USE THE VALUE FROM THIS PARAMDEF! */ + + SPAPI A_Err (*AEGP_GetEffectFlags)( + AEGP_EffectRefH effect_refH, /* >> */ + AEGP_EffectFlags *effect_flagsP); /* << */ + + SPAPI A_Err (*AEGP_SetEffectFlags)( + AEGP_EffectRefH effect_refH, /* >> */ + AEGP_EffectFlags effect_flags_set_mask, /* >> */ + AEGP_EffectFlags effect_flags); /* >> */ + + SPAPI A_Err (*AEGP_ReorderEffect)( /* UNDOABLE */ + AEGP_EffectRefH effect_refH, /* >> */ + A_long effect_indexL); /* >> */ + + SPAPI A_Err (*AEGP_EffectCallGeneric)( + AEGP_PluginID aegp_plugin_id, /* >> */ + AEGP_EffectRefH effect_refH, /* >> */ + const A_Time *timePT, /* >> Use the timebase of the layer to which effect is applied. */ + void *effect_extraPV); /* <> */ + + SPAPI A_Err (*AEGP_DisposeEffect)( + AEGP_EffectRefH effect_refH ); /* >> */ + + SPAPI A_Err (*AEGP_ApplyEffect)( + AEGP_PluginID aegp_plugin_id, /* >> */ + AEGP_LayerH layerH, /* >> */ + AEGP_InstalledEffectKey installed_effect_key, /* >> */ + AEGP_EffectRefH *effect_refPH); /* << MUST BE DISPOSED with AEGP_DisposeEffect */ + + SPAPI A_Err (*AEGP_DeleteLayerEffect)( + AEGP_EffectRefH effect_refH); /* >> undoable */ + + SPAPI A_Err (*AEGP_GetNumInstalledEffects)( + A_long *num_installed_effectsPL); /* << */ + + // pass in AEGP_InstalledEffectKey_NONE for installed_effect_key to get first effect key + + SPAPI A_Err (*AEGP_GetNextInstalledEffect)( + AEGP_InstalledEffectKey installed_effect_key, /* >> */ + AEGP_InstalledEffectKey *next_effectPH); /* << */ + + SPAPI A_Err (*AEGP_GetEffectName)( + AEGP_InstalledEffectKey installed_effect_key, /* >> */ + A_char *nameZ); /* << space for A_char[AEGP_MAX_EFFECT_NAME_SIZE] */ + + SPAPI A_Err (*AEGP_GetEffectMatchName)( + AEGP_InstalledEffectKey installed_effect_key, /* >> */ + A_char *match_nameZ); /* << space for A_char[AEGP_MAX_EFFECT_MATCH_NAME_SIZE] */ + + SPAPI A_Err (*AEGP_GetEffectCategory)( + AEGP_InstalledEffectKey installed_effect_key, /* >> */ + A_char *categoryZ); /* << space for A_char[AEGP_MAX_EFFECT_CATEGORY_NAME_SIZE] */ + + SPAPI A_Err (*AEGP_DuplicateEffect)( + AEGP_EffectRefH original_effect_refH, /* >> */ + AEGP_EffectRefH *duplicate_effect_refPH); /* << */ + +} AEGP_EffectSuite2; + + +#define kAEGPEffectSuiteVersion3 3 /* frozen in AE 7.0 */ + +typedef struct AEGP_EffectSuite3 { + + SPAPI A_Err (*AEGP_GetLayerNumEffects)( + AEGP_LayerH layerH, /* >> */ + A_long *num_effectsPL); /* << */ + + SPAPI A_Err (*AEGP_GetLayerEffectByIndex)( + AEGP_PluginID aegp_plugin_id, /* >> */ + AEGP_LayerH layerH, /* >> */ + AEGP_EffectIndex layer_effect_indexL, /* >> */ + AEGP_EffectRefH *effectPH); /* << MUST dispose with DisposeEffect*/ + + SPAPI A_Err (*AEGP_GetInstalledKeyFromLayerEffect)( + AEGP_EffectRefH effect_refH, /* >> */ + AEGP_InstalledEffectKey *installed_effect_keyP); /* << */ + + SPAPI A_Err (*AEGP_GetEffectParamUnionByIndex)( + AEGP_PluginID aegp_plugin_id, /* >> */ + AEGP_EffectRefH effect_refH, /* >> */ + PF_ParamIndex param_index, /* >> valid in range [0 to AEGP_GetEffectNumParamStreams - 1], where 0 is the effect's input layer */ + PF_ParamType *param_typeP, /* << */ + PF_ParamDefUnion *uP0); /* << DO NOT USE THE VALUE FROM THIS PARAMDEF! */ + + SPAPI A_Err (*AEGP_GetEffectFlags)( + AEGP_EffectRefH effect_refH, /* >> */ + AEGP_EffectFlags *effect_flagsP); /* << */ + + SPAPI A_Err (*AEGP_SetEffectFlags)( + AEGP_EffectRefH effect_refH, /* >> */ + AEGP_EffectFlags effect_flags_set_mask, /* >> */ + AEGP_EffectFlags effect_flags); /* >> */ + + SPAPI A_Err (*AEGP_ReorderEffect)( /* UNDOABLE */ + AEGP_EffectRefH effect_refH, /* >> */ + A_long effect_indexL); /* >> */ + + /** new command parameter addded. To get old behaviour pass in PF_Cmd_COMPLETELY_GENERAL for effect_command **/ + SPAPI A_Err (*AEGP_EffectCallGeneric)( + AEGP_PluginID aegp_plugin_id, /* >> */ + AEGP_EffectRefH effect_refH, /* >> */ + const A_Time *timePT, /* >> Use the timebase of the layer to which effect is applied. */ + PF_Cmd effect_cmd, /* >> new parameter from version 2 */ + void *effect_extraPV); /* <> */ + + SPAPI A_Err (*AEGP_DisposeEffect)( + AEGP_EffectRefH effect_refH ); /* >> */ + + SPAPI A_Err (*AEGP_ApplyEffect)( + AEGP_PluginID aegp_plugin_id, /* >> */ + AEGP_LayerH layerH, /* >> */ + AEGP_InstalledEffectKey installed_effect_key, /* >> */ + AEGP_EffectRefH *effect_refPH); /* << MUST BE DISPOSED with AEGP_DisposeEffect */ + + SPAPI A_Err (*AEGP_DeleteLayerEffect)( + AEGP_EffectRefH effect_refH); /* >> undoable */ + + SPAPI A_Err (*AEGP_GetNumInstalledEffects)( + A_long *num_installed_effectsPL); /* << */ + + // pass in AEGP_InstalledEffectKey_NONE for installed_effect_key to get first effect key + + SPAPI A_Err (*AEGP_GetNextInstalledEffect)( + AEGP_InstalledEffectKey installed_effect_key, /* >> */ + AEGP_InstalledEffectKey *next_effectPH); /* << */ + + SPAPI A_Err (*AEGP_GetEffectName)( + AEGP_InstalledEffectKey installed_effect_key, /* >> */ + A_char *nameZ); /* << space for A_char[AEGP_MAX_EFFECT_NAME_SIZE] */ + + SPAPI A_Err (*AEGP_GetEffectMatchName)( + AEGP_InstalledEffectKey installed_effect_key, /* >> */ + A_char *match_nameZ); /* << space for A_char[AEGP_MAX_EFFECT_MATCH_NAME_SIZE] */ + + SPAPI A_Err (*AEGP_GetEffectCategory)( + AEGP_InstalledEffectKey installed_effect_key, /* >> */ + A_char *categoryZ); /* << space for A_char[AEGP_MAX_EFFECT_CATEGORY_NAME_SIZE] */ + + SPAPI A_Err (*AEGP_DuplicateEffect)( + AEGP_EffectRefH original_effect_refH, /* >> */ + AEGP_EffectRefH *duplicate_effect_refPH); /* << */ +} AEGP_EffectSuite3; + +#define kAEGPLightSuite "AEGP Light Suite" +#define kAEGPLightSuiteVersion1 1 /* frozen in AE 5.0 */ + + + +typedef struct AEGP_LightSuite1 { + + SPAPI A_Err (*AEGP_GetLightType)( + AEGP_LayerH light_layerH, /* >> */ + AEGP_LightType *light_typeP); /* << */ + + +} AEGP_LightSuite1; + + + +#define kAEGPMaskSuite "AEGP Layer Mask Suite" +#define kAEGPMaskSuiteVersion5 6 /* frozen AE 10 */ + +typedef struct AEGP_MaskSuite5 { + + SPAPI A_Err (*AEGP_GetLayerNumMasks)( + AEGP_LayerH aegp_layerH, /* >> */ + A_long *num_masksPL); /* << */ + + SPAPI A_Err (*AEGP_GetLayerMaskByIndex)( + AEGP_LayerH aegp_layerH, /* >> */ + AEGP_MaskIndex mask_indexL, /* >> */ + AEGP_MaskRefH *maskPH); /* << must be disposed by calling AEGP_DisposeMask() */ + + SPAPI A_Err (*AEGP_DisposeMask)( + AEGP_MaskRefH mask_refH); /* >> */ + + SPAPI A_Err (*AEGP_GetMaskInvert)( + AEGP_MaskRefH mask_refH, /* >> */ + A_Boolean *invertPB); /* << */ + + SPAPI A_Err (*AEGP_SetMaskInvert)( + AEGP_MaskRefH mask_refH, /* >> */ + A_Boolean invertB); /* << */ + + SPAPI A_Err (*AEGP_GetMaskMode)( + AEGP_MaskRefH mask_refH, /* >> */ + PF_MaskMode *modeP); /* << */ + + SPAPI A_Err (*AEGP_SetMaskMode)( + AEGP_MaskRefH maskH, /* >> */ + PF_MaskMode mode); /* >> */ + + SPAPI A_Err (*AEGP_GetMaskMotionBlurState)( + AEGP_MaskRefH mask_refH, /* >> */ + AEGP_MaskMBlur *blur_stateP); /* << */ + + SPAPI A_Err (*AEGP_SetMaskMotionBlurState)( + AEGP_MaskRefH mask_refH, /* >> */ + AEGP_MaskMBlur blur_state); /* >> */ + + // AEGP_GetMaskName/SetMaskName are obsoleted. Use AEGP_GetNewDynamicStreamForMask + // and the name functions there + + SPAPI A_Err (*AEGP_GetMaskID)( + AEGP_MaskRefH mask_refH, /* >> */ + AEGP_MaskIDVal *id_valP); /* << */ + + SPAPI A_Err (*AEGP_CreateNewMask)( /* UNDOABLE */ + AEGP_LayerH layerH, /* >> */ + AEGP_MaskRefH *mask_refPH, /* << */ + A_long *mask_indexPL0); /* << */ + + SPAPI A_Err (*AEGP_DeleteMaskFromLayer)( /* UNDOABLE */ + AEGP_MaskRefH mask_refH); /* >> still need to Dispose MaskRefH */ + + SPAPI A_Err (*AEGP_GetMaskColor)( + AEGP_MaskRefH mask_refH, /* >> */ + AEGP_ColorVal *colorP); /* << */ + + SPAPI A_Err (*AEGP_SetMaskColor)( + AEGP_MaskRefH mask_refH, /* >> */ + const AEGP_ColorVal *colorP); /* >> */ + + SPAPI A_Err (*AEGP_GetMaskLockState)( + AEGP_MaskRefH mask_refH, /* <> */ + A_Boolean *is_lockedPB); /* >> */ + + SPAPI A_Err (*AEGP_SetMaskLockState)( + AEGP_MaskRefH mask_refH, /* <> */ + A_Boolean lockB); /* >> */ + + SPAPI A_Err (*AEGP_GetMaskIsRotoBezier)( + AEGP_MaskRefH mask_refH, /* <> */ + A_Boolean *is_roto_bezierPB); /* << */ + + SPAPI A_Err (*AEGP_SetMaskIsRotoBezier)( + AEGP_MaskRefH mask_refH, /* <> */ + A_Boolean is_roto_bezierB); /* >> */ + + SPAPI A_Err (*AEGP_DuplicateMask)( + AEGP_MaskRefH orig_mask_refH, /* >> */ + AEGP_MaskRefH *duplicate_mask_refPH); /* << */ + +} AEGP_MaskSuite5; + +#define kAEGPMaskSuiteVersion4 5 /* frozen AE 6.5 */ + +typedef struct AEGP_MaskSuite4 { + + SPAPI A_Err (*AEGP_GetLayerNumMasks)( + AEGP_LayerH aegp_layerH, /* >> */ + A_long *num_masksPL); /* << */ + + SPAPI A_Err (*AEGP_GetLayerMaskByIndex)( + AEGP_LayerH aegp_layerH, /* >> */ + AEGP_MaskIndex mask_indexL, /* >> */ + AEGP_MaskRefH *maskPH); /* << must be disposed by calling AEGP_DisposeMask() */ + + SPAPI A_Err (*AEGP_DisposeMask)( + AEGP_MaskRefH mask_refH); /* >> */ + + SPAPI A_Err (*AEGP_GetMaskInvert)( + AEGP_MaskRefH mask_refH, /* >> */ + A_Boolean *invertPB); /* << */ + + SPAPI A_Err (*AEGP_SetMaskInvert)( + AEGP_MaskRefH mask_refH, /* >> */ + A_Boolean invertB); /* << */ + + SPAPI A_Err (*AEGP_GetMaskMode)( + AEGP_MaskRefH mask_refH, /* >> */ + PF_MaskMode *modeP); /* << */ + + SPAPI A_Err (*AEGP_SetMaskMode)( + AEGP_MaskRefH maskH, /* >> */ + PF_MaskMode mode); /* >> */ + + SPAPI A_Err (*AEGP_GetMaskMotionBlurState)( + AEGP_MaskRefH mask_refH, /* >> */ + AEGP_MaskMBlur *blur_stateP); /* << */ + + SPAPI A_Err (*AEGP_SetMaskMotionBlurState)( + AEGP_MaskRefH mask_refH, /* >> */ + AEGP_MaskMBlur blur_state); /* >> */ + + SPAPI A_Err (*AEGP_GetMaskName)( + AEGP_MaskRefH mask_refH, /* >> */ + A_char *nameZ); /* << space for A_char[AEGP_MAX_MASK_NAME_SIZE] */ + + SPAPI A_Err (*AEGP_SetMaskName)( + AEGP_MaskRefH mask_refH, /* >> */ + A_char *nameZ); /* >> space for A_char[AEGP_MAX_MASK_NAME_SIZE] */ + + SPAPI A_Err (*AEGP_GetMaskID)( + AEGP_MaskRefH mask_refH, /* >> */ + AEGP_MaskIDVal *id_valP); /* << */ + + SPAPI A_Err (*AEGP_CreateNewMask)( /* UNDOABLE */ + AEGP_LayerH layerH, /* >> */ + AEGP_MaskRefH *mask_refPH, /* << */ + A_long *mask_indexPL0); /* << */ + + SPAPI A_Err (*AEGP_DeleteMaskFromLayer)( /* UNDOABLE */ + AEGP_MaskRefH mask_refH); /* >> still need to Dispose MaskRefH */ + + SPAPI A_Err (*AEGP_GetMaskColor)( + AEGP_MaskRefH mask_refH, /* >> */ + AEGP_ColorVal *colorP); /* << */ + + SPAPI A_Err (*AEGP_SetMaskColor)( + AEGP_MaskRefH mask_refH, /* >> */ + const AEGP_ColorVal *colorP); /* >> */ + + SPAPI A_Err (*AEGP_GetMaskLockState)( + AEGP_MaskRefH mask_refH, /* <> */ + A_Boolean *is_lockedPB); /* >> */ + + SPAPI A_Err (*AEGP_SetMaskLockState)( + AEGP_MaskRefH mask_refH, /* <> */ + A_Boolean lockB); /* >> */ + + SPAPI A_Err (*AEGP_GetMaskIsRotoBezier)( + AEGP_MaskRefH mask_refH, /* <> */ + A_Boolean *is_roto_bezierPB); /* << */ + + SPAPI A_Err (*AEGP_SetMaskIsRotoBezier)( + AEGP_MaskRefH mask_refH, /* <> */ + A_Boolean is_roto_bezierB); /* >> */ + + SPAPI A_Err (*AEGP_DuplicateMask)( + AEGP_MaskRefH orig_mask_refH, /* >> */ + AEGP_MaskRefH *duplicate_mask_refPH); /* << */ + +} AEGP_MaskSuite4; + +#define kAEGPMaskSuiteVersion3 4 /* frozen AE 6.0 */ + +typedef struct AEGP_MaskSuite3 { + + SPAPI A_Err (*AEGP_GetLayerNumMasks)( + AEGP_LayerH aegp_layerH, /* >> */ + A_long *num_masksPL); /* << */ + + SPAPI A_Err (*AEGP_GetLayerMaskByIndex)( + AEGP_LayerH aegp_layerH, /* >> */ + AEGP_MaskIndex mask_indexL, /* >> */ + AEGP_MaskRefH *maskPH); /* << must be disposed by calling AEGP_DisposeMask() */ + + SPAPI A_Err (*AEGP_DisposeMask)( + AEGP_MaskRefH mask_refH); /* >> */ + + SPAPI A_Err (*AEGP_GetMaskInvert)( + AEGP_MaskRefH mask_refH, /* >> */ + A_Boolean *invertPB); /* << */ + + SPAPI A_Err (*AEGP_SetMaskInvert)( + AEGP_MaskRefH mask_refH, /* >> */ + A_Boolean invertB); /* << */ + + SPAPI A_Err (*AEGP_GetMaskMode)( + AEGP_MaskRefH mask_refH, /* >> */ + PF_MaskMode *modeP); /* << */ + + SPAPI A_Err (*AEGP_SetMaskMode)( + AEGP_MaskRefH maskH, /* >> */ + PF_MaskMode mode); /* >> */ + + SPAPI A_Err (*AEGP_GetMaskMotionBlurState)( + AEGP_MaskRefH mask_refH, /* >> */ + AEGP_MaskMBlur *blur_stateP); /* << */ + + SPAPI A_Err (*AEGP_SetMaskMotionBlurState)( + AEGP_MaskRefH mask_refH, /* >> */ + AEGP_MaskMBlur blur_state); /* >> */ + + SPAPI A_Err (*AEGP_GetMaskName)( + AEGP_MaskRefH mask_refH, /* >> */ + A_char *nameZ); /* << space for A_char[AEGP_MAX_MASK_NAME_SIZE] */ + + SPAPI A_Err (*AEGP_SetMaskName)( + AEGP_MaskRefH mask_refH, /* >> */ + A_char *nameZ); /* >> space for A_char[AEGP_MAX_MASK_NAME_SIZE] */ + + SPAPI A_Err (*AEGP_GetMaskID)( + AEGP_MaskRefH mask_refH, /* >> */ + AEGP_MaskIDVal *id_valP); /* << */ + + SPAPI A_Err (*AEGP_CreateNewMask)( /* UNDOABLE */ + AEGP_LayerH layerH, /* >> */ + AEGP_MaskRefH *mask_refPH, /* << */ + A_long *mask_indexPL0); /* << */ + + SPAPI A_Err (*AEGP_DeleteMaskFromLayer)( /* UNDOABLE */ + AEGP_MaskRefH mask_refH); /* >> still need to Dispose MaskRefH */ + + SPAPI A_Err (*AEGP_GetMaskColor)( + AEGP_MaskRefH mask_refH, /* >> */ + AEGP_ColorVal *colorP); /* << */ + + SPAPI A_Err (*AEGP_SetMaskColor)( + AEGP_MaskRefH mask_refH, /* >> */ + const AEGP_ColorVal *colorP); /* >> */ + + SPAPI A_Err (*AEGP_GetMaskLockState)( + AEGP_MaskRefH mask_refH, /* <> */ + A_Boolean *is_lockedPB); /* >> */ + + SPAPI A_Err (*AEGP_SetMaskLockState)( + AEGP_MaskRefH mask_refH, /* <> */ + A_Boolean lockB); /* >> */ + + SPAPI A_Err (*AEGP_GetMaskIsRotoBezier)( + AEGP_MaskRefH mask_refH, /* <> */ + A_Boolean *is_roto_bezierPB); /* << */ + + SPAPI A_Err (*AEGP_SetMaskIsRotoBezier)( + AEGP_MaskRefH mask_refH, /* <> */ + A_Boolean is_roto_bezierB); /* >> */ + +} AEGP_MaskSuite3; + +#define kAEGPMaskSuiteVersion1 2 /* frozen in AE 5.0 */ + +typedef struct AEGP_MaskSuite1 { + + SPAPI A_Err (*AEGP_GetLayerNumMasks)( + AEGP_LayerH aegp_layerH, /* >> */ + A_long *num_masksPL); /* << */ + + SPAPI A_Err (*AEGP_GetLayerMaskByIndex)( + AEGP_LayerH aegp_layerH, /* >> */ + AEGP_MaskIndex mask_indexL, /* >> */ + AEGP_MaskRefH *maskPH); /* << must be disposed by calling AEGP_DisposeMask() */ + + SPAPI A_Err (*AEGP_DisposeMask)( + AEGP_MaskRefH mask_refH); /* >> */ + + SPAPI A_Err (*AEGP_GetMaskInvert)( + AEGP_MaskRefH mask_refH, /* >> */ + A_Boolean *invertPB); /* << */ + + SPAPI A_Err (*AEGP_GetMaskMode)( + AEGP_MaskRefH mask_refH, /* >> */ + PF_MaskMode *modeP); /* << */ + + SPAPI A_Err (*AEGP_GetMaskName)( + AEGP_MaskRefH mask_refH, /* >> */ + A_char *nameZ); /* << space for A_char[AEGP_MAX_MASK_NAME_SIZE] */ + + SPAPI A_Err (*AEGP_GetMaskID)( + AEGP_MaskRefH mask_refH, /* >> */ + AEGP_MaskIDVal *id_valP); /* << */ + + SPAPI A_Err (*AEGP_CreateNewMask)( //undoable + AEGP_LayerH layerH, /* >> */ + AEGP_MaskRefH *mask_refPH, /* << */ + A_long *mask_indexPL0);/* << */ + + SPAPI A_Err (*AEGP_DeleteMaskFromLayer)( //undoable + AEGP_MaskRefH mask_refH); /* >> still need to Dispose MaskRefH */ + +} AEGP_MaskSuite1; + +#define kAEGPMaskSuiteVersion2 3 /* frozen in AE 5.5 */ + +typedef struct AEGP_MaskSuite2 { + + SPAPI A_Err (*AEGP_GetLayerNumMasks)( + AEGP_LayerH aegp_layerH, /* >> */ + A_long *num_masksPL); /* << */ + + SPAPI A_Err (*AEGP_GetLayerMaskByIndex)( + AEGP_LayerH aegp_layerH, /* >> */ + AEGP_MaskIndex mask_indexL, /* >> */ + AEGP_MaskRefH *maskPH); /* << must be disposed by calling AEGP_DisposeMask() */ + + SPAPI A_Err (*AEGP_DisposeMask)( + AEGP_MaskRefH mask_refH); /* >> */ + + SPAPI A_Err (*AEGP_GetMaskInvert)( + AEGP_MaskRefH mask_refH, /* >> */ + A_Boolean *invertPB); /* << */ + + SPAPI A_Err (*AEGP_SetMaskInvert)( + AEGP_MaskRefH mask_refH, /* >> */ + A_Boolean invertB); /* << */ + + SPAPI A_Err (*AEGP_GetMaskMode)( + AEGP_MaskRefH mask_refH, /* >> */ + PF_MaskMode *modeP); /* << */ + + SPAPI A_Err (*AEGP_SetMaskMode)( + AEGP_MaskRefH maskH, /* >> */ + PF_MaskMode mode); /* >> */ + + SPAPI A_Err (*AEGP_GetMaskMotionBlurState)( + AEGP_MaskRefH mask_refH, /* >> */ + AEGP_MaskMBlur *blur_stateP); /* << */ + + SPAPI A_Err (*AEGP_SetMaskMotionBlurState)( + AEGP_MaskRefH mask_refH, /* >> */ + AEGP_MaskMBlur blur_state); /* >> */ + + SPAPI A_Err (*AEGP_GetMaskName)( + AEGP_MaskRefH mask_refH, /* >> */ + A_char *nameZ); /* << space for A_char[AEGP_MAX_MASK_NAME_SIZE] */ + + SPAPI A_Err (*AEGP_GetMaskID)( + AEGP_MaskRefH mask_refH, /* >> */ + AEGP_MaskIDVal *id_valP); /* << */ + + SPAPI A_Err (*AEGP_CreateNewMask)( //undoable + AEGP_LayerH layerH, /* >> */ + AEGP_MaskRefH *mask_refPH, /* << */ + A_long *mask_indexPL0); /* << */ + + SPAPI A_Err (*AEGP_DeleteMaskFromLayer)( //undoable + AEGP_MaskRefH mask_refH); /* >> still need to Dispose MaskRefH */ + +} AEGP_MaskSuite2; +/** + ** Camera Suite + ** + **/ +#define kAEGPCameraSuite "AEGP Camera Suite" +#define kAEGPCameraSuiteVersion1 1 /* frozen in AE 5.0 */ + + + +typedef struct AEGP_CameraSuite1 { + + SPAPI A_Err (*AEGP_GetCamera)( + PR_RenderContextH render_contextH, /* >> */ + const A_Time *comp_timeP, /* >> */ + AEGP_LayerH *camera_layerPH); /* << */ + + SPAPI A_Err (*AEGP_GetCameraType)( + AEGP_LayerH camera_layerH, /* >> */ + AEGP_CameraType *camera_typeP); /* << */ + + + SPAPI A_Err (*AEGP_GetDefaultCameraDistanceToImagePlane)( + AEGP_CompH compH, /* >> */ + A_FpLong *dist_to_planePF); /* << */ + +} AEGP_CameraSuite1; + + +#define kAEGPItemSuite "AEGP Item Suite" + +#define kAEGPItemSuiteVersion8 13 /* frozen in AE 9.0 */ + +typedef struct AEGP_ItemSuite8 { + + SPAPI A_Err (*AEGP_GetFirstProjItem)( + AEGP_ProjectH projectH, /* >> */ + AEGP_ItemH *itemPH); /* << */ + + SPAPI A_Err (*AEGP_GetNextProjItem)( + AEGP_ProjectH projectH, /* >> */ + AEGP_ItemH itemH, /* >> */ + AEGP_ItemH *next_itemPH); /* << NULL after last item */ + + SPAPI A_Err (*AEGP_GetActiveItem)( + AEGP_ItemH *itemPH); /* << NULL if none is active */ + + SPAPI A_Err (*AEGP_IsItemSelected)( + AEGP_ItemH itemH, /* >> */ + A_Boolean *selectedPB); /* << */ + + SPAPI A_Err (*AEGP_SelectItem)( + AEGP_ItemH itemH, /* >> */ + A_Boolean selectB, /* >> allows to select or deselect the item */ + A_Boolean deselect_othersB); /* >> */ + + SPAPI A_Err (*AEGP_GetItemType)( + AEGP_ItemH itemH, /* >> */ + AEGP_ItemType *item_typeP); /* << */ + + SPAPI A_Err (*AEGP_GetTypeName)( + AEGP_ItemType item_type, /* << */ + A_char *nameZ); /* << space for A_char[AEGP_MAX_TYPE_NAME_SIZE] */ + + SPAPI A_Err (*AEGP_GetItemName)( + AEGP_PluginID pluginID, // in + AEGP_ItemH itemH, /* >> */ + AEGP_MemHandle *unicode_namePH); // << handle of A_UTF16Char (contains null terminated UTF16 string); must be disposed with AEGP_FreeMemHandle + + SPAPI A_Err (*AEGP_SetItemName)( /* UNDOABLE */ + AEGP_ItemH itemH, /* >> */ + const A_UTF16Char *nameZ); /* >> null terminated UTF16 */ + + SPAPI A_Err (*AEGP_GetItemID)( + AEGP_ItemH itemH, /* >> */ + A_long *item_idPL); /* << */ + + SPAPI A_Err (*AEGP_GetItemFlags)( + AEGP_ItemH itemH, /* >> */ + AEGP_ItemFlags *item_flagsP); /* << */ + + SPAPI A_Err (*AEGP_SetItemUseProxy)( /* UNDOABLE */ + AEGP_ItemH itemH, /* >> error if has_proxy is FALSE! */ + A_Boolean use_proxyB); /* >> */ + + SPAPI A_Err (*AEGP_GetItemParentFolder)( + AEGP_ItemH itemH, /* >> */ + AEGP_ItemH *parent_folder_itemPH); /* << */ + + SPAPI A_Err (*AEGP_SetItemParentFolder)( + AEGP_ItemH itemH, /* <> */ + AEGP_ItemH parent_folder_itemH); /* >> */ + + SPAPI A_Err (*AEGP_GetItemDuration)( /* Returns the result in the item's native timespace: */ + AEGP_ItemH itemH, /* >> Comp -> comp time, */ + A_Time *durationPT); /* << Footage -> footage time, */ + /* Folder -> 0 (no duration) */ + + SPAPI A_Err (*AEGP_GetItemCurrentTime)( /* Returns the result in the item's native timespace (not updated while rendering)*/ + AEGP_ItemH itemH, /* >> */ + A_Time *curr_timePT); /* << */ + + SPAPI A_Err (*AEGP_GetItemDimensions)( + AEGP_ItemH itemH, /* >> */ + A_long *widthPL, /* << */ + A_long *heightPL); /* << */ + + SPAPI A_Err (*AEGP_GetItemPixelAspectRatio)( + AEGP_ItemH itemH, /* >> */ + A_Ratio *pix_aspect_ratioPRt); /* << */ + + SPAPI A_Err (*AEGP_DeleteItem)( /* UNDOABLE */ + AEGP_ItemH itemH); /* >> removes item from all comps */ + + SPAPI A_Err (*AEGP_CreateNewFolder)( + const A_UTF16Char *nameZ, /* >> null terminated UTF16 */ + AEGP_ItemH parent_folderH0, /* >> */ + AEGP_ItemH *new_folderPH); /* << allocated and owned by AE */ + + SPAPI A_Err (*AEGP_SetItemCurrentTime)( /* UNDOABLE. Use the item's native timespace */ + AEGP_ItemH itemH, /* >> */ + const A_Time *new_timePT); /* >> */ + + SPAPI A_Err (*AEGP_GetItemCommentLength)( + AEGP_ItemH itemH, /* >> */ + A_u_long *buf_sizePLu); /* << */ + + SPAPI A_Err (*AEGP_GetItemComment)( + AEGP_ItemH itemH, /* >> */ + A_u_long buf_sizeLu, /* >> */ + A_char *commentZ); /* << */ + + SPAPI A_Err (*AEGP_SetItemComment)( + AEGP_ItemH itemH, /* >> UNDOABLE */ + const A_char *commentZ); /* >> */ + + SPAPI A_Err (*AEGP_GetItemLabel)( + AEGP_ItemH itemH, /* >> */ + AEGP_LabelID *labelP); /* << */ + + SPAPI A_Err (*AEGP_SetItemLabel)( + AEGP_ItemH itemH, /* >> UNDOABLE */ + AEGP_LabelID label); /* >> */ + + SPAPI A_Err (*AEGP_GetItemMRUView)( + AEGP_ItemH itemH, // >> + AEGP_ItemViewP *mru_viewP); // << + +} AEGP_ItemSuite8; + +#define kAEGPItemSuiteVersion7 11 /* frozen in AE 8.0 */ + +typedef struct AEGP_ItemSuite7 { + + SPAPI A_Err (*AEGP_GetFirstProjItem)( + AEGP_ProjectH projectH, /* >> */ + AEGP_ItemH *itemPH); /* << */ + + SPAPI A_Err (*AEGP_GetNextProjItem)( + AEGP_ProjectH projectH, /* >> */ + AEGP_ItemH itemH, /* >> */ + AEGP_ItemH *next_itemPH); /* << NULL after last item */ + + SPAPI A_Err (*AEGP_GetActiveItem)( + AEGP_ItemH *itemPH); /* << NULL if none is active */ + + SPAPI A_Err (*AEGP_IsItemSelected)( + AEGP_ItemH itemH, /* >> */ + A_Boolean *selectedPB); /* << */ + + SPAPI A_Err (*AEGP_SelectItem)( + AEGP_ItemH itemH, /* >> */ + A_Boolean selectB, /* >> allows to select or deselect the item */ + A_Boolean deselect_othersB); /* >> */ + + SPAPI A_Err (*AEGP_GetItemType)( + AEGP_ItemH itemH, /* >> */ + AEGP_ItemType *item_typeP); /* << */ + + SPAPI A_Err (*AEGP_GetTypeName)( + AEGP_ItemType item_type, /* << */ + A_char *nameZ); /* << space for A_char[AEGP_MAX_TYPE_NAME_SIZE] */ + + SPAPI A_Err (*AEGP_GetItemName)( + AEGP_ItemH itemH, /* >> */ + A_char *nameZ); /* << space for A_char[AEGP_MAX_ITEM_NAME_SIZE] */ + + SPAPI A_Err (*AEGP_SetItemName)( /* UNDOABLE */ + AEGP_ItemH itemH, /* >> */ + const A_char *nameZ); /* >> up to A_char[AEGP_MAX_ITEM_NAME_SIZE] */ + + SPAPI A_Err (*AEGP_GetItemID)( + AEGP_ItemH itemH, /* >> */ + A_long *item_idPL); /* << */ + + SPAPI A_Err (*AEGP_GetItemFlags)( + AEGP_ItemH itemH, /* >> */ + AEGP_ItemFlags *item_flagsP); /* << */ + + SPAPI A_Err (*AEGP_SetItemUseProxy)( /* UNDOABLE */ + AEGP_ItemH itemH, /* >> error if has_proxy is FALSE! */ + A_Boolean use_proxyB); /* >> */ + + SPAPI A_Err (*AEGP_GetItemParentFolder)( + AEGP_ItemH itemH, /* >> */ + AEGP_ItemH *parent_folder_itemPH); /* << */ + + SPAPI A_Err (*AEGP_SetItemParentFolder)( + AEGP_ItemH itemH, /* <> */ + AEGP_ItemH parent_folder_itemH); /* >> */ + + SPAPI A_Err (*AEGP_GetItemDuration)( /* Returns the result in the item's native timespace: */ + AEGP_ItemH itemH, /* >> Comp -> comp time, */ + A_Time *durationPT); /* << Footage -> footage time, */ + /* Folder -> 0 (no duration) */ + + SPAPI A_Err (*AEGP_GetItemCurrentTime)( /* Returns the result in the item's native timespace (not updated while rendering)*/ + AEGP_ItemH itemH, /* >> */ + A_Time *curr_timePT); /* << */ + + SPAPI A_Err (*AEGP_GetItemDimensions)( + AEGP_ItemH itemH, /* >> */ + A_long *widthPL, /* << */ + A_long *heightPL); /* << */ + + SPAPI A_Err (*AEGP_GetItemPixelAspectRatio)( + AEGP_ItemH itemH, /* >> */ + A_Ratio *pix_aspect_ratioPRt); /* << */ + + SPAPI A_Err (*AEGP_DeleteItem)( /* UNDOABLE */ + AEGP_ItemH itemH); /* >> removes item from all comps */ + + SPAPI A_Err (*AEGP_CreateNewFolder)( + const A_char *nameZ, /* >> */ + AEGP_ItemH parent_folderH0, /* >> */ + AEGP_ItemH *new_folderPH); /* << allocated and owned by AE */ + + SPAPI A_Err (*AEGP_SetItemCurrentTime)( /* UNDOABLE. Use the item's native timespace */ + AEGP_ItemH itemH, /* >> */ + const A_Time *new_timePT); /* >> */ + + SPAPI A_Err (*AEGP_GetItemCommentLength)( + AEGP_ItemH itemH, /* >> */ + A_u_long *buf_sizePLu); /* << */ + + SPAPI A_Err (*AEGP_GetItemComment)( + AEGP_ItemH itemH, /* >> */ + A_u_long buf_sizeLu, /* >> */ + A_char *commentZ); /* << */ + + SPAPI A_Err (*AEGP_SetItemComment)( + AEGP_ItemH itemH, /* >> UNDOABLE */ + const A_char *commentZ); /* >> */ + + SPAPI A_Err (*AEGP_GetItemLabel)( + AEGP_ItemH itemH, /* >> */ + AEGP_LabelID *labelP); /* << */ + + SPAPI A_Err (*AEGP_SetItemLabel)( + AEGP_ItemH itemH, /* >> UNDOABLE */ + AEGP_LabelID label); /* >> */ + + SPAPI A_Err (*AEGP_GetItemMRUView)( + AEGP_ItemH itemH, // >> + AEGP_ItemViewP *mru_viewP); // << + +} AEGP_ItemSuite7; + + +#define kAEGPItemSuiteVersion6 10 /* frozen in AE 7.0 */ + +typedef struct AEGP_ItemSuite6 { + + SPAPI A_Err (*AEGP_GetFirstProjItem)( + AEGP_ProjectH projectH, /* >> */ + AEGP_ItemH *itemPH); /* << */ + + SPAPI A_Err (*AEGP_GetNextProjItem)( + AEGP_ProjectH projectH, /* >> */ + AEGP_ItemH itemH, /* >> */ + AEGP_ItemH *next_itemPH); /* << NULL after last item */ + + SPAPI A_Err (*AEGP_GetActiveItem)( + AEGP_ItemH *itemPH); /* << NULL if none is active */ + + SPAPI A_Err (*AEGP_IsItemSelected)( + AEGP_ItemH itemH, /* >> */ + A_Boolean *selectedPB); /* << */ + + SPAPI A_Err (*AEGP_SelectItem)( + AEGP_ItemH itemH, /* >> */ + A_Boolean selectB, /* >> allows to select or deselect the item */ + A_Boolean deselect_othersB); /* >> */ + + SPAPI A_Err (*AEGP_GetItemType)( + AEGP_ItemH itemH, /* >> */ + AEGP_ItemType *item_typeP); /* << */ + + SPAPI A_Err (*AEGP_GetTypeName)( + AEGP_ItemType item_type, /* << */ + A_char *nameZ); /* << space for A_char[AEGP_MAX_TYPE_NAME_SIZE] */ + + SPAPI A_Err (*AEGP_GetItemName)( + AEGP_ItemH itemH, /* >> */ + A_char *nameZ); /* << space for A_char[AEGP_MAX_ITEM_NAME_SIZE] */ + + SPAPI A_Err (*AEGP_SetItemName)( /* UNDOABLE */ + AEGP_ItemH itemH, /* >> */ + const A_char *nameZ); /* >> up to A_char[AEGP_MAX_ITEM_NAME_SIZE] */ + + SPAPI A_Err (*AEGP_GetItemID)( + AEGP_ItemH itemH, /* >> */ + A_long *item_idPL); /* << */ + + SPAPI A_Err (*AEGP_GetItemFlags)( + AEGP_ItemH itemH, /* >> */ + AEGP_ItemFlags *item_flagsP); /* << */ + + SPAPI A_Err (*AEGP_SetItemUseProxy)( /* UNDOABLE */ + AEGP_ItemH itemH, /* >> error if has_proxy is FALSE! */ + A_Boolean use_proxyB); /* >> */ + + SPAPI A_Err (*AEGP_GetItemParentFolder)( + AEGP_ItemH itemH, /* >> */ + AEGP_ItemH *parent_folder_itemPH); /* << */ + + SPAPI A_Err (*AEGP_SetItemParentFolder)( + AEGP_ItemH itemH, /* <> */ + AEGP_ItemH parent_folder_itemH); /* >> */ + + SPAPI A_Err (*AEGP_GetItemDuration)( /* Returns the result in the item's native timespace: */ + AEGP_ItemH itemH, /* >> Comp -> comp time, */ + A_Time *durationPT); /* << Footage -> footage time, */ + /* Folder -> 0 (no duration) */ + + SPAPI A_Err (*AEGP_GetItemCurrentTime)( /* Returns the result in the item's native timespace (not updated while rendering)*/ + AEGP_ItemH itemH, /* >> */ + A_Time *curr_timePT); /* << */ + + SPAPI A_Err (*AEGP_GetItemDimensions)( + AEGP_ItemH itemH, /* >> */ + A_long *widthPL, /* << */ + A_long *heightPL); /* << */ + + SPAPI A_Err (*AEGP_GetItemPixelAspectRatio)( + AEGP_ItemH itemH, /* >> */ + A_Ratio *pix_aspect_ratioPRt); /* << */ + + SPAPI A_Err (*AEGP_DeleteItem)( /* UNDOABLE */ + AEGP_ItemH itemH); /* >> removes item from all comps */ + + SPAPI A_Err (*AEGP_CreateNewFolder)( + const A_char *nameZ, /* >> */ + AEGP_ItemH parent_folderH0, /* >> */ + AEGP_ItemH *new_folderPH); /* << allocated and owned by AE */ + + SPAPI A_Err (*AEGP_SetItemCurrentTime)( /* UNDOABLE. Use the item's native timespace */ + AEGP_ItemH itemH, /* >> */ + const A_Time *new_timePT); /* >> */ + + SPAPI A_Err (*AEGP_GetItemCommentLength)( + AEGP_ItemH itemH, /* >> */ + A_u_long *buf_sizePLu); /* << */ + + SPAPI A_Err (*AEGP_GetItemComment)( + AEGP_ItemH itemH, /* >> */ + A_u_long buf_sizeLu, /* >> */ + A_char *commentZ); /* << */ + + SPAPI A_Err (*AEGP_SetItemComment)( + AEGP_ItemH itemH, /* >> UNDOABLE */ + const A_char *commentZ); /* >> */ + + SPAPI A_Err (*AEGP_GetItemLabel)( + AEGP_ItemH itemH, /* >> */ + AEGP_LabelID *labelP); /* << */ + + SPAPI A_Err (*AEGP_SetItemLabel)( + AEGP_ItemH itemH, /* >> UNDOABLE */ + AEGP_LabelID label); /* >> */ + +} AEGP_ItemSuite6; + + +#define kAEGPItemSuiteVersion5 7 /* frozen in AE 6.5 */ + +typedef struct AEGP_ItemSuite5 { + + SPAPI A_Err (*AEGP_GetNextItem)( + AEGP_ItemH itemH, /* >> */ + AEGP_ItemH *next_itemPH); /* << NULL after last item */ + + SPAPI A_Err (*AEGP_GetActiveItem)( + AEGP_ItemH *itemPH); /* << NULL if none is active */ + + SPAPI A_Err (*AEGP_IsItemSelected)( + AEGP_ItemH itemH, /* >> */ + A_Boolean *selectedPB); /* << */ + + SPAPI A_Err (*AEGP_SelectItem)( + AEGP_ItemH itemH, /* >> */ + A_Boolean selectB, /* >> allows to select or deselect the item */ + A_Boolean deselect_othersB); /* >> */ + + SPAPI A_Err (*AEGP_GetItemType)( + AEGP_ItemH itemH, /* >> */ + AEGP_ItemType *item_typeP); /* << */ + + SPAPI A_Err (*AEGP_GetTypeName)( + AEGP_ItemType item_type, /* << */ + A_char *nameZ); /* << space for A_char[AEGP_MAX_TYPE_NAME_SIZE] */ + + SPAPI A_Err (*AEGP_GetItemName)( + AEGP_ItemH itemH, /* >> */ + A_char *nameZ); /* << space for A_char[AEGP_MAX_ITEM_NAME_SIZE] */ + + SPAPI A_Err (*AEGP_GetItemID)( + AEGP_ItemH itemH, /* >> */ + A_long *item_idPL); /* << */ + + SPAPI A_Err (*AEGP_GetItemFlags)( + AEGP_ItemH itemH, /* >> */ + AEGP_ItemFlags *item_flagsP); /* << */ + + SPAPI A_Err (*AEGP_SetItemUseProxy)( /* UNDOABLE */ + AEGP_ItemH itemH, /* >> error if has_proxy is FALSE! */ + A_Boolean use_proxyB); /* >> */ + + SPAPI A_Err (*AEGP_GetItemParentFolder)( + AEGP_ItemH itemH, /* >> */ + AEGP_ItemH *parent_folder_itemPH); /* << */ + + SPAPI A_Err (*AEGP_SetItemParentFolder)( + AEGP_ItemH itemH, /* <> */ + AEGP_ItemH parent_folder_itemH); /* >> */ + + SPAPI A_Err (*AEGP_GetItemDuration)( /* Returns the result in the item's native timespace: */ + AEGP_ItemH itemH, /* >> Comp -> comp time, */ + A_Time *durationPT); /* << Footage -> footage time, */ + /* Folder -> 0 (no duration) */ + + SPAPI A_Err (*AEGP_GetItemCurrentTime)( /* Returns the result in the item's native timespace (not updated while rendering)*/ + AEGP_ItemH itemH, /* >> */ + A_Time *curr_timePT); /* << */ + + SPAPI A_Err (*AEGP_GetItemDimensions)( + AEGP_ItemH itemH, /* >> */ + A_long *widthPL, /* << */ + A_long *heightPL); /* << */ + + SPAPI A_Err (*AEGP_GetItemPixelAspectRatio)( + AEGP_ItemH itemH, /* >> */ + A_Ratio *pix_aspect_ratioPRt); /* << */ + + SPAPI A_Err (*AEGP_DeleteItem)( /* UNDOABLE */ + AEGP_ItemH itemH); /* >> removes item from all comps */ + + SPAPI A_Err (*AEGP_CreateNewFolder)( + const A_char *nameZ, /* >> */ + AEGP_ItemH parent_folderH0, /* >> */ + AEGP_ItemH *new_folderPH); /* << allocated and owned by AE */ + + SPAPI A_Err (*AEGP_SetItemCurrentTime)( /* UNDOABLE. Use the item's native timespace */ + AEGP_ItemH itemH, /* >> */ + const A_Time *new_timePT); /* >> */ + + SPAPI A_Err (*AEGP_GetItemCommentLength)( + AEGP_ItemH itemH, /* >> */ + A_u_long *buf_sizePLu); /* << */ + + SPAPI A_Err (*AEGP_GetItemComment)( + AEGP_ItemH itemH, /* >> */ + A_u_long buf_sizeLu, /* >> */ + char *commentZ); /* << */ + + SPAPI A_Err (*AEGP_SetItemComment)( + AEGP_ItemH itemH, /* >> UNDOABLE */ + const char *commentZ); /* >> */ + +} AEGP_ItemSuite5; + + +#define kAEGPItemSuiteVersion4 6 /* frozen in AE 6.0 */ + +typedef struct AEGP_ItemSuite4 { + + SPAPI A_Err (*AEGP_GetNextItem)( + AEGP_ItemH itemH, /* >> */ + AEGP_ItemH *next_itemPH); /* << NULL after last item */ + + SPAPI A_Err (*AEGP_GetActiveItem)( + AEGP_ItemH *itemPH); /* << NULL if none is active */ + + SPAPI A_Err (*AEGP_IsItemSelected)( + AEGP_ItemH itemH, /* >> */ + A_Boolean *selectedPB); /* << */ + + SPAPI A_Err (*AEGP_SelectItem)( + AEGP_ItemH itemH, /* >> */ + A_Boolean selectB, /* >> allows to select or deselect the item */ + A_Boolean deselect_othersB); /* >> */ + + SPAPI A_Err (*AEGP_GetItemType)( + AEGP_ItemH itemH, /* >> */ + AEGP_ItemType *item_typeP); /* << */ + + SPAPI A_Err (*AEGP_GetTypeName)( + AEGP_ItemType item_type, /* << */ + A_char *nameZ); /* << space for A_char[AEGP_MAX_TYPE_NAME_SIZE] */ + + SPAPI A_Err (*AEGP_GetItemName)( + AEGP_ItemH itemH, /* >> */ + A_char *nameZ); /* << space for A_char[AEGP_MAX_ITEM_NAME_SIZE] */ + + SPAPI A_Err (*AEGP_GetItemID)( + AEGP_ItemH itemH, /* >> */ + A_long *item_idPL); /* << */ + + SPAPI A_Err (*AEGP_GetItemFlags)( + AEGP_ItemH itemH, /* >> */ + AEGP_ItemFlags *item_flagsP); /* << */ + + SPAPI A_Err (*AEGP_SetItemUseProxy)( /* UNDOABLE */ + AEGP_ItemH itemH, /* >> error if has_proxy is FALSE! */ + A_Boolean use_proxyB); /* >> */ + + SPAPI A_Err (*AEGP_GetItemParentFolder)( + AEGP_ItemH itemH, /* >> */ + AEGP_ItemH *parent_folder_itemPH); /* << */ + + SPAPI A_Err (*AEGP_GetItemDuration)( /* Returns the result in the item's native timespace: */ + AEGP_ItemH itemH, /* >> Comp -> comp time, */ + A_Time *durationPT); /* << Footage -> footage time, */ + /* Folder -> 0 (no duration) */ + + SPAPI A_Err (*AEGP_GetItemCurrentTime)( /* Returns the result in the item's native timespace (not updated while rendering)*/ + AEGP_ItemH itemH, /* >> */ + A_Time *curr_timePT); /* << */ + + SPAPI A_Err (*AEGP_GetItemDimensions)( + AEGP_ItemH itemH, /* >> */ + A_long *widthPL, /* << */ + A_long *heightPL); /* << */ + + SPAPI A_Err (*AEGP_GetItemPixelAspectRatio)( + AEGP_ItemH itemH, /* >> */ + A_Ratio *pix_aspect_ratioPRt); /* << */ + + SPAPI A_Err (*AEGP_DeleteItem)( /* UNDOABLE */ + AEGP_ItemH itemH); /* >> removes item from all comps */ + + SPAPI A_Err (*AEGP_CreateNewFolder)( + const A_char *nameZ, /* >> */ + AEGP_ItemH parent_folderH0, /* >> */ + AEGP_ItemH *new_folderPH); /* << allocated and owned by AE */ + + SPAPI A_Err (*AEGP_SetItemCurrentTime)( /* UNDOABLE. Use the item's native timespace */ + AEGP_ItemH itemH, /* >> */ + const A_Time *new_timePT); /* >> */ + + SPAPI A_Err (*AEGP_GetItemCommentLength)( + AEGP_ItemH itemH, /* >> */ + A_u_long *buf_sizePLu); /* << */ + + SPAPI A_Err (*AEGP_GetItemComment)( + AEGP_ItemH itemH, /* >> */ + A_u_long buf_sizeLu, /* >> */ + char *commentZ); /* << */ + + SPAPI A_Err (*AEGP_SetItemComment)( + AEGP_ItemH itemH, /* >> UNDOABLE */ + const char *commentZ); /* >> */ + +} AEGP_ItemSuite4; + + +#define kAEGPItemSuite "AEGP Item Suite" +#define kAEGPItemSuiteVersion3 5 /* frozen in 5.5.1 */ + +typedef struct AEGP_ItemSuite3 { + + SPAPI A_Err (*AEGP_GetNextItem)( + AEGP_ItemH itemH, /* >> */ + AEGP_ItemH *next_itemPH); /* << NULL after last item */ + + SPAPI A_Err (*AEGP_GetActiveItem)( + AEGP_ItemH *itemPH); /* << could be NULL if none is active */ + + SPAPI A_Err (*AEGP_IsItemSelected)( + AEGP_ItemH itemH, /* >> */ + A_Boolean *selectedPB); /* << */ + + SPAPI A_Err (*AEGP_SelectItem)( + AEGP_ItemH itemH, /* >> */ + A_Boolean selectB, /* >> allows to select or deselect the item */ + A_Boolean deselect_othersB); /* >> */ + + SPAPI A_Err (*AEGP_GetItemType)( + AEGP_ItemH itemH, /* >> */ + AEGP_ItemType *item_typeP); /* << */ + + SPAPI A_Err (*AEGP_GetTypeName)( + AEGP_ItemType item_type, /* << */ + A_char *nameZ); /* << space for A_char[AEGP_MAX_TYPE_NAME_SIZE] */ + + SPAPI A_Err (*AEGP_GetItemName)( + AEGP_ItemH itemH, /* >> */ + A_char *nameZ); /* << space for A_char[AEGP_MAX_ITEM_NAME_SIZE] */ + + SPAPI A_Err (*AEGP_GetItemID)( + AEGP_ItemH itemH, /* >> */ + A_long *item_idPL); /* << */ + + SPAPI A_Err (*AEGP_GetItemFlags)( + AEGP_ItemH itemH, /* >> */ + AEGP_ItemFlags *item_flagsP); /* << */ + + SPAPI A_Err (*AEGP_SetItemUseProxy)( /* UNDOABLE */ + AEGP_ItemH itemH, /* >> error if has_proxy is FALSE! */ + A_Boolean use_proxyB); /* >> */ + + SPAPI A_Err (*AEGP_GetItemParentFolder)( + AEGP_ItemH itemH, /* >> */ + AEGP_ItemH *parent_folder_itemPH); /* << */ + + SPAPI A_Err (*AEGP_GetItemDuration)( /* Returns the result in the item's native timespace: */ + AEGP_ItemH itemH, /* >> Comp -> comp time, */ + A_Time *durationPT); /* << Footage -> footage time, */ + /* Solid/Folder -> 0 (no duration) */ + + SPAPI A_Err (*AEGP_GetItemCurrentTime)( /* Returns the result in the item's native timespace (not updated while rendering)*/ + AEGP_ItemH itemH, /* >> */ + A_Time *curr_timePT); /* << */ + + SPAPI A_Err (*AEGP_GetItemDimensions)( + AEGP_ItemH itemH, /* >> */ + A_long *widthPL, /* << */ + A_long *heightPL); /* << */ + + SPAPI A_Err (*AEGP_GetItemPixelAspectRatio)( + AEGP_ItemH itemH, /* >> */ + A_Ratio *pix_aspect_ratioPRt); /* << */ + + SPAPI A_Err (*AEGP_DeleteItem)( /* UNDOABLE */ + AEGP_ItemH itemH); /* >> removes item from all comps */ + + SPAPI A_Err (*AEGP_GetItemSolidColor)( /* error if item isn't AEGP_ItemType_SOLID! */ + AEGP_ItemH itemH, /* >> */ + AEGP_ColorVal *colorP); /* << */ + + SPAPI A_Err (*AEGP_SetSolidColor)( /* error if item isn't AEGP_ItemType_SOLID! */ + AEGP_ItemH itemH, /* <> */ + AEGP_ColorVal color); /* >> */ + + SPAPI A_Err (*AEGP_SetSolidDimensions)( /* error if item isn't AEGP_ItemType_SOLID! */ + AEGP_ItemH itemH, /* <> */ + A_short widthS, /* >> */ + A_short heightS); /* >> */ + + SPAPI A_Err (*AEGP_CreateNewFolder)( + const A_char *nameZ, /* >> */ + AEGP_ItemH parent_folderH0, /* >> */ + AEGP_ItemH *new_folderPH); /* << */ /* allocated and owned by project (AE) */ + + SPAPI A_Err (*AEGP_SetItemCurrentTime)( /* Undoable. Use the item's native timespace */ + AEGP_ItemH itemH, /* >> */ + const A_Time *new_timePT); /* >> */ + + +} AEGP_ItemSuite3; + +/**************************************************************************************************/ +#define kAEGPKeyframeSuite "AEGP Keyframe Suite" +#define kAEGPKeyframeSuiteVersion3 3 /* frozen in 6.5 */ + +typedef struct AEGP_KeyframeSuite3 { + + // returns AEGP_NumKF_NO_DATA if it's a AEGP_StreamType_NO_DATA, and you can't retrieve any values + // returns zero if no keyframes (but might have an expression, so not necessarily constant) + + + SPAPI A_Err (*AEGP_GetStreamNumKFs)( + AEGP_StreamRefH streamH, /* >> */ + A_long *num_kfsPL); /* << */ + + + SPAPI A_Err (*AEGP_GetKeyframeTime)( + AEGP_StreamRefH streamH, /* >> */ + AEGP_KeyframeIndex key_index, /* >> */ + AEGP_LTimeMode time_mode, /* >> */ + A_Time *timePT); /* << */ + + // leaves stream unchanged if a keyframe already exists at specified time + SPAPI A_Err (*AEGP_InsertKeyframe)( /* UNDOABLE */ + AEGP_StreamRefH streamH, /* <> */ + AEGP_LTimeMode time_mode, /* >> */ + const A_Time *timePT, /* >> */ + AEGP_KeyframeIndex *key_indexP); /* << */ + + SPAPI A_Err (*AEGP_DeleteKeyframe)( /* UNDOABLE */ + AEGP_StreamRefH streamH, /* <> */ + AEGP_KeyframeIndex key_index); /* >> */ + + SPAPI A_Err (*AEGP_GetNewKeyframeValue)( // dispose using AEGP_DisposeStreamValue() + AEGP_PluginID aegp_plugin_id, /* >> */ + AEGP_StreamRefH streamH, /* >> */ + AEGP_KeyframeIndex key_index, /* >> */ + AEGP_StreamValue *valueP); /* << */ + + SPAPI A_Err (*AEGP_SetKeyframeValue)( /* UNDOABLE */ + AEGP_StreamRefH streamH, /* >> */ + AEGP_KeyframeIndex key_index, /* >> */ + const AEGP_StreamValue *valueP); /* >> not adopted */ + + SPAPI A_Err (*AEGP_GetStreamValueDimensionality)( + AEGP_StreamRefH streamH, /* >> */ + A_short *value_dimPS); /* << */ + + SPAPI A_Err (*AEGP_GetStreamTemporalDimensionality)( + AEGP_StreamRefH streamH, /* >> */ + A_short *temporal_dimPS); /* << */ + + SPAPI A_Err (*AEGP_GetNewKeyframeSpatialTangents)( // dispose using AEGP_DisposeStreamValue() + AEGP_PluginID aegp_plugin_id, /* >> */ + AEGP_StreamRefH streamH, /* >> */ + AEGP_KeyframeIndex key_index, /* >> */ + AEGP_StreamValue *in_tanP0, /* << */ + AEGP_StreamValue *out_tanP0); /* << */ + + // In AEGP_KeyframeSuite2 and prior versions, the values returned from + // this function were wrong when called on an effect point control stream or + // anchor point. They were not multiplied by the layer size. Now they are. + SPAPI A_Err (*AEGP_SetKeyframeSpatialTangents)( /* UNDOABLE */ + AEGP_StreamRefH streamH, /* >> */ + AEGP_KeyframeIndex key_index, /* >> */ + const AEGP_StreamValue *in_tanP0, /* >> not adopted */ + const AEGP_StreamValue *out_tanP0); /* >> not adopted */ + + SPAPI A_Err (*AEGP_GetKeyframeTemporalEase)( + AEGP_StreamRefH streamH, /* >> */ + AEGP_KeyframeIndex key_index, /* >> */ + A_long dimensionL, /* >> ranges from 0..TemporalDimensionality-1 */ + AEGP_KeyframeEase *in_easeP0, /* << */ + AEGP_KeyframeEase *out_easeP0); /* << */ + + SPAPI A_Err (*AEGP_SetKeyframeTemporalEase)( /* UNDOABLE */ + AEGP_StreamRefH streamH, /* >> */ + AEGP_KeyframeIndex key_index, /* >> */ + A_long dimensionL, /* >> ranges from 0..TemporalDimensionality-1 */ + const AEGP_KeyframeEase *in_easeP0, /* >> not adopted */ + const AEGP_KeyframeEase *out_easeP0); /* >> not adopted */ + + SPAPI A_Err (*AEGP_GetKeyframeFlags)( + AEGP_StreamRefH streamH, /* >> */ + AEGP_KeyframeIndex key_index, /* >> */ + AEGP_KeyframeFlags *flagsP); /* << */ + + SPAPI A_Err (*AEGP_SetKeyframeFlag)( /* UNDOABLE */ + AEGP_StreamRefH streamH, /* >> */ + AEGP_KeyframeIndex key_index, /* >> */ + AEGP_KeyframeFlags flag, /* >> set one flag at a time */ + A_Boolean true_falseB); /* >> */ + + SPAPI A_Err (*AEGP_GetKeyframeInterpolation)( + AEGP_StreamRefH streamH, /* >> */ + AEGP_KeyframeIndex key_index, /* >> */ + AEGP_KeyframeInterpolationType *in_interpP0, /* << */ + AEGP_KeyframeInterpolationType *out_interpP0); /* << */ + + SPAPI A_Err (*AEGP_SetKeyframeInterpolation)( /* UNDOABLE */ + AEGP_StreamRefH streamH, /* >> */ + AEGP_KeyframeIndex key_index, /* >> */ + AEGP_KeyframeInterpolationType in_interp, /* >> */ + AEGP_KeyframeInterpolationType out_interp); /* >> */ + + SPAPI A_Err (*AEGP_StartAddKeyframes)( + AEGP_StreamRefH streamH, + AEGP_AddKeyframesInfoH *akPH); /* << */ + + + SPAPI A_Err (*AEGP_AddKeyframes)( + AEGP_AddKeyframesInfoH akH, /* <> */ + AEGP_LTimeMode time_mode, /* >> */ + const A_Time *timePT, /* >> */ + A_long *key_indexPL); /* >> */ + + SPAPI A_Err (*AEGP_SetAddKeyframe)( + AEGP_AddKeyframesInfoH akH, /* <> */ + A_long key_indexL, /* >> */ + const AEGP_StreamValue *valueP); /* >> */ + + SPAPI A_Err (*AEGP_EndAddKeyframes)( /* UNDOABLE */ + A_Boolean addB, + AEGP_AddKeyframesInfoH akH); /* >> */ + +} AEGP_KeyframeSuite3; + +#define kAEGPKeyframeSuiteVersion2 2 /* frozen in 5.5 */ + +typedef struct AEGP_KeyframeSuite2 { + + // returns AEGP_NumKF_NO_DATA if it's a AEGP_StreamType_NO_DATA, and you can't retrieve any values + // returns zero if no keyframes (but might have an expression, so not necessarily constant) + + + SPAPI A_Err (*AEGP_GetStreamNumKFs)( + AEGP_StreamRefH streamH, /* >> */ + A_long *num_kfsPL); /* << */ + + + SPAPI A_Err (*AEGP_GetKeyframeTime)( + AEGP_StreamRefH streamH, /* >> */ + AEGP_KeyframeIndex key_index, /* >> */ + AEGP_LTimeMode time_mode, /* >> */ + A_Time *timePT); /* << */ + + // leaves stream unchanged if a keyframe already exists at specified time + SPAPI A_Err (*AEGP_InsertKeyframe)( /* UNDOABLE */ + AEGP_StreamRefH streamH, /* <> */ + AEGP_LTimeMode time_mode, /* >> */ + const A_Time *timePT, /* >> */ + AEGP_KeyframeIndex *key_indexP); /* << */ + + SPAPI A_Err (*AEGP_DeleteKeyframe)( /* UNDOABLE */ + AEGP_StreamRefH streamH, /* <> */ + AEGP_KeyframeIndex key_index); /* >> */ + + SPAPI A_Err (*AEGP_GetNewKeyframeValue)( // dispose using AEGP_DisposeStreamValue() + AEGP_PluginID aegp_plugin_id, /* >> */ + AEGP_StreamRefH streamH, /* >> */ + AEGP_KeyframeIndex key_index, /* >> */ + AEGP_StreamValue *valueP); /* << */ + + SPAPI A_Err (*AEGP_SetKeyframeValue)( /* UNDOABLE */ + AEGP_StreamRefH streamH, /* >> */ + AEGP_KeyframeIndex key_index, /* >> */ + const AEGP_StreamValue *valueP); /* >> not adopted */ + + SPAPI A_Err (*AEGP_GetStreamValueDimensionality)( + AEGP_StreamRefH streamH, /* >> */ + A_short *value_dimPS); /* << */ + + SPAPI A_Err (*AEGP_GetStreamTemporalDimensionality)( + AEGP_StreamRefH streamH, /* >> */ + A_short *temporal_dimPS); /* << */ + + SPAPI A_Err (*AEGP_GetNewKeyframeSpatialTangents)( // dispose using AEGP_DisposeStreamValue() + AEGP_PluginID aegp_plugin_id, /* >> */ + AEGP_StreamRefH streamH, /* >> */ + AEGP_KeyframeIndex key_index, /* >> */ + AEGP_StreamValue *in_tanP0, /* << */ + AEGP_StreamValue *out_tanP0); /* << */ + + SPAPI A_Err (*AEGP_SetKeyframeSpatialTangents)( /* UNDOABLE */ + AEGP_StreamRefH streamH, /* >> */ + AEGP_KeyframeIndex key_index, /* >> */ + const AEGP_StreamValue *in_tanP0, /* >> not adopted */ + const AEGP_StreamValue *out_tanP0); /* >> not adopted */ + + SPAPI A_Err (*AEGP_GetKeyframeTemporalEase)( + AEGP_StreamRefH streamH, /* >> */ + AEGP_KeyframeIndex key_index, /* >> */ + A_long dimensionL, /* >> ranges from 0..TemporalDimensionality-1 */ + AEGP_KeyframeEase *in_easeP0, /* << */ + AEGP_KeyframeEase *out_easeP0); /* << */ + + SPAPI A_Err (*AEGP_SetKeyframeTemporalEase)( /* UNDOABLE */ + AEGP_StreamRefH streamH, /* >> */ + AEGP_KeyframeIndex key_index, /* >> */ + A_long dimensionL, /* >> ranges from 0..TemporalDimensionality-1 */ + const AEGP_KeyframeEase *in_easeP0, /* >> not adopted */ + const AEGP_KeyframeEase *out_easeP0); /* >> not adopted */ + + SPAPI A_Err (*AEGP_GetKeyframeFlags)( + AEGP_StreamRefH streamH, /* >> */ + AEGP_KeyframeIndex key_index, /* >> */ + AEGP_KeyframeFlags *flagsP); /* << */ + + SPAPI A_Err (*AEGP_SetKeyframeFlag)( /* UNDOABLE */ + AEGP_StreamRefH streamH, /* >> */ + AEGP_KeyframeIndex key_index, /* >> */ + AEGP_KeyframeFlags flag, /* >> set one flag at a time */ + A_Boolean true_falseB); /* >> */ + + SPAPI A_Err (*AEGP_GetKeyframeInterpolation)( + AEGP_StreamRefH streamH, /* >> */ + AEGP_KeyframeIndex key_index, /* >> */ + AEGP_KeyframeInterpolationType *in_interpP0, /* << */ + AEGP_KeyframeInterpolationType *out_interpP0); /* << */ + + SPAPI A_Err (*AEGP_SetKeyframeInterpolation)( /* UNDOABLE */ + AEGP_StreamRefH streamH, /* >> */ + AEGP_KeyframeIndex key_index, /* >> */ + AEGP_KeyframeInterpolationType in_interp, /* >> */ + AEGP_KeyframeInterpolationType out_interp); /* >> */ + + SPAPI A_Err (*AEGP_StartAddKeyframes)( + AEGP_StreamRefH streamH, + AEGP_AddKeyframesInfoH *akPH); /* << */ + + + SPAPI A_Err (*AEGP_AddKeyframes)( + AEGP_AddKeyframesInfoH akH, /* <> */ + AEGP_LTimeMode time_mode, /* >> */ + const A_Time *timePT, /* >> */ + A_long *key_indexPL); /* >> */ + + SPAPI A_Err (*AEGP_SetAddKeyframe)( + AEGP_AddKeyframesInfoH akH, /* <> */ + A_long key_indexL, /* >> */ + const AEGP_StreamValue *valueP); /* >> */ + + SPAPI A_Err (*AEGP_EndAddKeyframes)( /* UNDOABLE */ + A_Boolean addB, + AEGP_AddKeyframesInfoH akH); /* >> */ + +} AEGP_KeyframeSuite2; + +#define kAEGPKeyframeSuiteVersion1 1 /* frozen in AE 5.0 */ + +typedef struct AEGP_KeyframeSuite1 { + + // returns AEGP_NumKF_NO_DATA if it's a AEGP_StreamType_NO_DATA, and you can't retrieve any values + // returns zero if no keyframes (but might have an expression, so not necessarily constant) + + + SPAPI A_Err (*AEGP_GetStreamNumKFs)( + AEGP_StreamRefH streamH, /* >> */ + A_long *num_kfsPL); /* << */ + + + SPAPI A_Err (*AEGP_GetKeyframeTime)( + AEGP_StreamRefH streamH, /* >> */ + AEGP_KeyframeIndex key_index, /* >> */ + AEGP_LTimeMode time_mode, /* >> */ + A_Time *timePT); /* << */ + + // leaves stream unchanged if a keyframe already exists at specified time + SPAPI A_Err (*AEGP_InsertKeyframe)( /* UNDOABLE */ + AEGP_StreamRefH streamH, /* <> */ + AEGP_LTimeMode time_mode, /* >> */ + const A_Time *timePT, /* >> */ + AEGP_KeyframeIndex *key_indexP); /* << */ + + SPAPI A_Err (*AEGP_DeleteKeyframe)( /* UNDOABLE */ + AEGP_StreamRefH streamH, /* <> */ + AEGP_KeyframeIndex key_index); /* >> */ + + SPAPI A_Err (*AEGP_GetNewKeyframeValue)( // dispose using AEGP_DisposeStreamValue() + AEGP_PluginID aegp_plugin_id, /* >> */ + AEGP_StreamRefH streamH, /* >> */ + AEGP_KeyframeIndex key_index, /* >> */ + AEGP_StreamValue *valueP); /* << */ + + SPAPI A_Err (*AEGP_SetKeyframeValue)( /* UNDOABLE */ + AEGP_StreamRefH streamH, /* >> */ + AEGP_KeyframeIndex key_index, /* >> */ + const AEGP_StreamValue *valueP); /* >> */ // not adopted + + SPAPI A_Err (*AEGP_GetStreamValueDimensionality)( + AEGP_StreamRefH streamH, /* >> */ + short *value_dimPS); /* << */ + + SPAPI A_Err (*AEGP_GetStreamTemporalDimensionality)( + AEGP_StreamRefH streamH, /* >> */ + short *temporal_dimPS); /* << */ + + SPAPI A_Err (*AEGP_GetNewKeyframeSpatialTangents)( // dispose using AEGP_DisposeStreamValue() + AEGP_PluginID aegp_plugin_id, /* >> */ + AEGP_StreamRefH streamH, /* >> */ + AEGP_KeyframeIndex key_index, /* >> */ + AEGP_StreamValue *in_tanP0, /* << */ + AEGP_StreamValue *out_tanP0); /* << */ + + SPAPI A_Err (*AEGP_SetKeyframeSpatialTangents)( /* UNDOABLE */ + AEGP_StreamRefH streamH, /* >> */ + AEGP_KeyframeIndex key_index, /* >> */ + const AEGP_StreamValue *in_tanP0, /* >> */ // not adopted + const AEGP_StreamValue *out_tanP0); /* >> */ // not adopted + + SPAPI A_Err (*AEGP_GetKeyframeTemporalEase)( + AEGP_StreamRefH streamH, /* >> */ + AEGP_KeyframeIndex key_index, /* >> */ + A_long dimensionL, /* >> */ // ranges from 0..TemporalDimensionality-1 + AEGP_KeyframeEase *in_easeP0, /* << */ + AEGP_KeyframeEase *out_easeP0); /* << */ + + SPAPI A_Err (*AEGP_SetKeyframeTemporalEase)( /* UNDOABLE */ + AEGP_StreamRefH streamH, /* >> */ + AEGP_KeyframeIndex key_index, /* >> */ + A_long dimensionL, /* >> */ // ranges from 0..TemporalDimensionality-1 + const AEGP_KeyframeEase *in_easeP0, /* >> */ // not adopted + const AEGP_KeyframeEase *out_easeP0); /* >> */ // not adopted + + SPAPI A_Err (*AEGP_GetKeyframeFlags)( + AEGP_StreamRefH streamH, /* >> */ + AEGP_KeyframeIndex key_index, /* >> */ + AEGP_KeyframeFlags *flagsP); /* << */ + + SPAPI A_Err (*AEGP_SetKeyframeFlag)( /* UNDOABLE */ + AEGP_StreamRefH streamH, /* >> */ + AEGP_KeyframeIndex key_index, /* >> */ + AEGP_KeyframeFlags flag, /* >> */ // set one at a time + A_Boolean true_falseB); /* >> */ + + SPAPI A_Err (*AEGP_GetKeyframeInterpolation)( + AEGP_StreamRefH streamH, /* >> */ + AEGP_KeyframeIndex key_index, /* >> */ + AEGP_KeyframeInterpolationType *in_interpP0, /* << */ + AEGP_KeyframeInterpolationType *out_interpP0); /* << */ + + SPAPI A_Err (*AEGP_SetKeyframeInterpolation)( /* UNDOABLE */ + AEGP_StreamRefH streamH, /* >> */ + AEGP_KeyframeIndex key_index, /* >> */ + AEGP_KeyframeInterpolationType in_interp, /* >> */ + AEGP_KeyframeInterpolationType out_interp); /* >> */ + +} AEGP_KeyframeSuite1; + +/* frozen AE 5.5 */ +#define kAEGPItemSuiteVersion2 4 + +typedef struct AEGP_ItemSuite2 { + + SPAPI A_Err (*AEGP_GetNextItem)( + AEGP_ItemH itemH, /* >> */ + AEGP_ItemH *next_itemPH); /* << NULL after last item */ + + SPAPI A_Err (*AEGP_GetActiveItem)( + AEGP_ItemH *itemPH); /* << could be NULL if none is active */ + + SPAPI A_Err (*AEGP_IsItemSelected)( + AEGP_ItemH itemH, /* >> */ + A_Boolean *selectedPB); /* << */ + + SPAPI A_Err (*AEGP_SelectItem)( + AEGP_ItemH itemH, /* >> */ + A_Boolean selectB, /* >> allows to select or deselect the item */ + A_Boolean deselect_othersB); /* >> */ + + SPAPI A_Err (*AEGP_GetItemType)( + AEGP_ItemH itemH, /* >> */ + AEGP_ItemType *item_typeP); /* << */ + + SPAPI A_Err (*AEGP_GetTypeName)( + AEGP_ItemType item_type, /* << */ + A_char *nameZ); /* << space for A_char[AEGP_MAX_TYPE_NAME_SIZE] */ + + SPAPI A_Err (*AEGP_GetItemName)( + AEGP_ItemH itemH, /* >> */ + A_char *nameZ); /* << space for A_char[AEGP_MAX_ITEM_NAME_SIZE] */ + + SPAPI A_Err (*AEGP_GetItemID)( + AEGP_ItemH itemH, /* >> */ + A_long *item_idPL); /* << */ + + SPAPI A_Err (*AEGP_GetItemFlags)( + AEGP_ItemH itemH, /* >> */ + AEGP_ItemFlags *item_flagsP); /* << */ + + SPAPI A_Err (*AEGP_SetItemUseProxy)( /* UNDOABLE */ + AEGP_ItemH itemH, /* >> error if has_proxy is FALSE! */ + A_Boolean use_proxyB); /* >> */ + + SPAPI A_Err (*AEGP_GetItemParentFolder)( + AEGP_ItemH itemH, /* >> */ + AEGP_ItemH *parent_folder_itemPH); /* << */ + + SPAPI A_Err (*AEGP_GetItemDuration)( /* Returns the result in the item's native timespace: */ + AEGP_ItemH itemH, /* >> Comp -> comp time, */ + A_Time *durationPT); /* << Footage -> footage time, */ + /* Solid/Folder -> 0 (no duration) */ + + SPAPI A_Err (*AEGP_GetItemCurrentTime)( /* Returns the result in the item's native timespace (not updated while rendering)*/ + AEGP_ItemH itemH, /* >> */ + A_Time *curr_timePT); /* << */ + + SPAPI A_Err (*AEGP_GetItemDimensions)( + AEGP_ItemH itemH, /* >> */ + A_long *widthPL, /* << */ + A_long *heightPL); /* << */ + + SPAPI A_Err (*AEGP_GetItemPixelAspectRatio)( + AEGP_ItemH itemH, /* >> */ + A_Ratio *pix_aspect_ratioPRt); /* << */ + + SPAPI A_Err (*AEGP_DeleteItem)( /* UNDOABLE */ + AEGP_ItemH itemH); /* >> removes item from all comps */ + + SPAPI A_Err (*AEGP_GetItemSolidColor)( /* error if item isn't AEGP_ItemType_SOLID! */ + AEGP_ItemH itemH, /* >> */ + AEGP_ColorVal *colorP); /* << */ + + SPAPI A_Err (*AEGP_SetSolidColor)( /* error if item isn't AEGP_ItemType_SOLID! */ + AEGP_ItemH itemH, /* <> */ + AEGP_ColorVal color); /* >> */ + + SPAPI A_Err (*AEGP_SetSolidDimensions)( /* error if item isn't AEGP_ItemType_SOLID! */ + AEGP_ItemH itemH, /* <> */ + A_short widthS, /* >> */ + A_short heightS); /* >> */ + + SPAPI A_Err (*AEGP_CreateNewFolder)( + const A_char *nameZ, /* >> */ + AEGP_ItemH parent_folderH0, /* >> */ + AEGP_ItemH *new_folderPH); /* << */ /* allocated and owned by project (AE) */ + + SPAPI A_Err (*AEGP_SetItemCurrentTime)( /* Undoable. Use the item's native timespace */ + AEGP_ItemH itemH, /* >> */ + const A_Time *new_timePT); /* >> */ + + + // work on Comps and Footage items. + SPAPI A_Err (*AEGP_RenderNewItemSoundData)( // AEGP_SoundDataH must be disposed. + AEGP_ItemH itemH, // >> + const A_Time *start_timePT, // >> + const A_Time *durationPT, // >> + const AEGP_SoundDataFormat* sound_formatP, // >> + AEGP_SoundDataH *new_sound_dataPH); // << can return NULL if no audio + +} AEGP_ItemSuite2; + + +#define kAEGPItemSuiteVersion1 3 /* frozen in AE 5.0 */ + +typedef struct AEGP_ItemSuite1 { + + SPAPI A_Err (*AEGP_GetNextItem)( + AEGP_ItemH itemH, /* >> */ + AEGP_ItemH *next_itemPH); /* << NULL after last item */ + + SPAPI A_Err (*AEGP_GetActiveItem)( + AEGP_ItemH *itemPH); /* << could be NULL if none is active */ + + SPAPI A_Err (*AEGP_IsItemSelected)( + AEGP_ItemH itemH, /* >> */ + A_Boolean *selectedPB); /* << */ + + SPAPI A_Err (*AEGP_SelectItem)( + AEGP_ItemH itemH, /* >> */ + A_Boolean selectB, /* >> allows to select or deselect the item */ + A_Boolean deselect_othersB); /* >> */ + + SPAPI A_Err (*AEGP_GetItemType)( + AEGP_ItemH itemH, /* >> */ + AEGP_ItemType *item_typeP); /* << */ + + SPAPI A_Err (*AEGP_GetTypeName)( + AEGP_ItemType item_type, /* << */ + A_char *nameZ); /* << space for A_char[AEGP_MAX_TYPE_NAME_SIZE] */ + + SPAPI A_Err (*AEGP_GetItemName)( + AEGP_ItemH itemH, /* >> */ + A_char *nameZ); /* << space for A_char[AEGP_MAX_ITEM_NAME_SIZE] */ + + SPAPI A_Err (*AEGP_GetItemID)( + AEGP_ItemH itemH, /* >> */ + A_long *item_idPL); /* << */ + + SPAPI A_Err (*AEGP_GetItemFlags)( + AEGP_ItemH itemH, /* >> */ + AEGP_ItemFlags *item_flagsP); /* << */ + + SPAPI A_Err (*AEGP_SetItemUseProxy)( /* UNDOABLE */ + AEGP_ItemH itemH, /* >> error if has_proxy is FALSE! */ + A_Boolean use_proxyB); /* >> */ + + SPAPI A_Err (*AEGP_GetItemParentFolder)( + AEGP_ItemH itemH, /* >> */ + AEGP_ItemH *parent_folder_itemPH); /* << */ + + SPAPI A_Err (*AEGP_GetItemDuration)( /* Returns the result in the item's native timespace: */ + AEGP_ItemH itemH, /* >> Comp -> comp time, */ + A_Time *durationPT); /* << Footage -> footage time, */ + /* Solid/Folder -> 0 (no duration) */ + + SPAPI A_Err (*AEGP_GetItemCurrentTime)( /* Returns the result in the item's native timespace (not updated while rendering)*/ + AEGP_ItemH itemH, /* >> */ + A_Time *curr_timePT); /* << */ + + SPAPI A_Err (*AEGP_GetItemDimensions)( + AEGP_ItemH itemH, /* >> */ + A_long *widthPL, /* << */ + A_long *heightPL); /* << */ + + SPAPI A_Err (*AEGP_GetItemPixelAspectRatio)( + AEGP_ItemH itemH, /* >> */ + A_Ratio *pix_aspect_ratioPRt); /* << */ + + SPAPI A_Err (*AEGP_DeleteItem)( /* UNDOABLE */ + AEGP_ItemH itemH); /* >> removes item from all comps */ + + SPAPI A_Err (*AEGP_GetItemSolidColor)( /* error if item isn't AEGP_ItemType_SOLID! */ + AEGP_ItemH itemH, /* >> */ + AEGP_ColorVal *colorP); /* << */ + + SPAPI A_Err (*AEGP_CreateNewFolder)( + const A_char *nameZ, /* >> */ + AEGP_ItemH parent_folderH0, /* >> */ + AEGP_ItemH *new_folderPH); /* << */ /* allocated and owned by project (AE) */ + + SPAPI A_Err (*AEGP_SetItemCurrentTime)( /* Undoable. Use the item's native timespace */ + AEGP_ItemH itemH, /* >> */ + const A_Time *new_timePT); /* >> */ + + + // work on Comps and Footage items. + SPAPI A_Err (*AEGP_RenderNewItemSoundData)( // AEGP_SoundDataH must be disposed. + AEGP_ItemH itemH, // >> + const A_Time *start_timePT, // >> + const A_Time *durationPT, // >> + const AEGP_SoundDataFormat* sound_formatP, // >> + AEGP_SoundDataH *new_sound_dataPH); // << can return NULL if no audio + +} AEGP_ItemSuite1; + +/*********************************************************/ + +#define kAEGPUtilitySuiteVersion5 11 /* frozen in AE 8.0 */ + +typedef struct AEGP_UtilitySuite5 { + + SPAPI A_Err (*AEGP_ReportInfo)( /* displays dialog with name of plugin followed by info string */ + AEGP_PluginID aegp_plugin_id, /* >> */ + const A_char *info_stringZ); /* >> */ + + + SPAPI A_Err (*AEGP_GetDriverPluginInitFuncVersion)( + A_short *major_versionPS, /* << */ + A_short *minor_versionPS); /* << */ + + SPAPI A_Err (*AEGP_GetDriverImplementationVersion)( + A_short *major_versionPS, /* << */ + A_short *minor_versionPS); /* << */ + + SPAPI A_Err (*AEGP_StartQuietErrors)( + AEGP_ErrReportState *err_stateP); /* << */ + + SPAPI A_Err (*AEGP_EndQuietErrors)( + A_Boolean report_quieted_errorsB, /* >> currently reports last quieted error */ + AEGP_ErrReportState *err_stateP); /* >> */ + + SPAPI A_Err (*AEGP_GetLastErrorMessage)( + A_long buffer_size, /* >> size of character buffer */ + A_char *error_string, /* << */ + A_Err *error_num); /* << */ + + SPAPI A_Err (*AEGP_StartUndoGroup)( /* MUST be balanced with call to AEGP_EndUndoGroup() */ + const A_char *undo_nameZ); /* >> */ + + SPAPI A_Err (*AEGP_EndUndoGroup)(void); + + SPAPI A_Err (*AEGP_RegisterWithAEGP)( + AEGP_GlobalRefcon global_refcon, /* >> global refcon passed in command handlers */ + const A_char *plugin_nameZ, /* >> name of this plugin. AEGP_MAX_PLUGIN_NAME_SIZE */ + AEGP_PluginID *plugin_id); /* << id for plugin to use in other AEGP calls */ + + SPAPI A_Err (*AEGP_GetMainHWND)( + void *main_hwnd); /* << */ + + SPAPI A_Err (*AEGP_ShowHideAllFloaters)( + A_Boolean include_tool_palB); /* >> */ + + SPAPI A_Err (*AEGP_PaintPalGetForeColor)( + AEGP_ColorVal *fore_colorP); /* << */ + + SPAPI A_Err (*AEGP_PaintPalGetBackColor)( + AEGP_ColorVal *back_colorP); /* << */ + + SPAPI A_Err (*AEGP_PaintPalSetForeColor)( + const AEGP_ColorVal *fore_colorP); /* >> */ + + SPAPI A_Err (*AEGP_PaintPalSetBackColor)( + const AEGP_ColorVal *back_colorP); /* >> */ + + SPAPI A_Err (*AEGP_CharPalGetFillColor)( + A_Boolean *is_fill_color_definedPB, /* << */ + AEGP_ColorVal *fill_colorP); /* << only valid if is_fill_color_definedPB == TRUE */ + + SPAPI A_Err (*AEGP_CharPalGetStrokeColor)( + A_Boolean *is_stroke_color_definedPB, /* << */ + AEGP_ColorVal *stroke_colorP); /* << only valid if is_stroke_color_definedPB == TRUE */ + + SPAPI A_Err (*AEGP_CharPalSetFillColor)( + const AEGP_ColorVal *fill_colorP); /* >> */ + + SPAPI A_Err (*AEGP_CharPalSetStrokeColor)( + const AEGP_ColorVal *stroke_colorP); /* >> */ + + SPAPI A_Err (*AEGP_CharPalIsFillColorUIFrontmost)( /* Otherwise, StrokeColor is frontmost */ + A_Boolean *is_fill_color_selectedPB); /* << */ + + SPAPI A_Err (*AEGP_ConvertFpLongToHSFRatio)( + A_FpLong numberF, /* >> */ + A_Ratio *ratioPR); /* << */ + + SPAPI A_Err (*AEGP_ConvertHSFRatioToFpLong)( + A_Ratio ratioR, /* << */ + A_FpLong *numberPF); /* >> */ + + // this routine is safe to call from the non-main + // thread. It is asynchronous and will return before the idle handler is called. + // The Suite routines to get this pointer are not + // thread safe, therefore you need to save it off + // in the main thread for use by the child thread. + SPAPI A_Err (*AEGP_CauseIdleRoutinesToBeCalled)(void); + + + // Determine if after effects is running in a mode where there is no + // user interface, and attempting to interact with the user (via a modal dialog) + // will hang the application. + // This will not change during a run. Use it to optimize your plugin at startup + // to not create a user interface and make AE launch faster, and not break + // when running multiple instances of a service. + SPAPI A_Err (*AEGP_GetSuppressInteractiveUI)(A_Boolean* ui_is_suppressedPB); // out + + // this call writes text to the console if one is available. One is guaranteed to be available + // if ui_is_suppressedB == true. + // In general use the call AEGP_ReportInfo() as it will write to the console in + // non-interactive modes, and use a dialog in interactive modes. + SPAPI A_Err (*AEGP_WriteToOSConsole)(const A_char* textZ); // in + + // this writes an entry into the debug log, or to the command line if launched + // with the -debug flag. + SPAPI A_Err (*AEGP_WriteToDebugLog)(const A_char* subsystemZ, // in + const A_char* event_typeZ, // in + const A_char * infoZ); // in + + + SPAPI A_Err (*AEGP_IsScriptingAvailable)(A_Boolean* outAvailablePB); + + // Execute a script. + // The script text can either be in UTF-8, or the current + // application encoding. + // The result is the result string if OK. It is optional. + // The error is the error string if an error occurred. It is optional. + // the result and error are in the encoding specified by platform_encodingB + SPAPI A_Err (*AEGP_ExecuteScript)(AEGP_PluginID inPlugin_id, + const A_char* inScriptZ, // in + const A_Boolean platform_encodingB, // in + AEGP_MemHandle* outResultPH0, + AEGP_MemHandle* outErrorStringPH0); + + SPAPI A_Err (*AEGP_HostIsActivated)(A_Boolean *is_activatedPB); + + SPAPI A_Err (*AEGP_GetPluginPlatformRef)(AEGP_PluginID plug_id, void** plat_refPPV); // on the Mac, it is a CFBundleRef to your mach-o plugin or NULL for a CFM plug-in; on Windows it is set to NULL for now + + SPAPI A_Err (*AEGP_UpdateFontList)(void); // Rescan the system font list. This will return quickly if the font list hasn't changed. + +} AEGP_UtilitySuite5; + + + +#define kAEGPUtilitySuiteVersion4 10 /* frozen in AE 7.0 */ + +typedef struct AEGP_UtilitySuite4 { + + SPAPI A_Err (*AEGP_ReportInfo)( /* displays dialog with name of plugin followed by info string */ + AEGP_PluginID aegp_plugin_id, /* >> */ + const A_char *info_stringZ); /* >> */ + + + SPAPI A_Err (*AEGP_GetDriverPluginInitFuncVersion)( + A_short *major_versionPS, /* << */ + A_short *minor_versionPS); /* << */ + + SPAPI A_Err (*AEGP_GetDriverImplementationVersion)( + A_short *major_versionPS, /* << */ + A_short *minor_versionPS); /* << */ + + SPAPI A_Err (*AEGP_StartQuietErrors)( + AEGP_ErrReportState *err_stateP); /* << */ + + SPAPI A_Err (*AEGP_EndQuietErrors)( + A_Boolean report_quieted_errorsB, /* >> currently reports last quieted error */ + AEGP_ErrReportState *err_stateP); /* >> */ + + SPAPI A_Err (*AEGP_GetLastErrorMessage)( + A_long buffer_size, /* >> size of character buffer */ + A_char *error_string, /* << */ + A_Err *error_num); /* << */ + + SPAPI A_Err (*AEGP_StartUndoGroup)( /* MUST be balanced with call to AEGP_EndUndoGroup() */ + const A_char *undo_nameZ); /* >> */ + + SPAPI A_Err (*AEGP_EndUndoGroup)(void); + + SPAPI A_Err (*AEGP_RegisterWithAEGP)( + AEGP_GlobalRefcon global_refcon, /* >> global refcon passed in command handlers */ + const A_char *plugin_nameZ, /* >> name of this plugin. AEGP_MAX_PLUGIN_NAME_SIZE */ + AEGP_PluginID *plugin_id); /* << id for plugin to use in other AEGP calls */ + + SPAPI A_Err (*AEGP_GetMainHWND)( + void *main_hwnd); /* << */ + + SPAPI A_Err (*AEGP_ShowHideAllFloaters)( + A_Boolean include_tool_palB); /* >> */ + + SPAPI A_Err (*AEGP_PaintPalGetForeColor)( + AEGP_ColorVal *fore_colorP); /* << */ + + SPAPI A_Err (*AEGP_PaintPalGetBackColor)( + AEGP_ColorVal *back_colorP); /* << */ + + SPAPI A_Err (*AEGP_PaintPalSetForeColor)( + const AEGP_ColorVal *fore_colorP); /* >> */ + + SPAPI A_Err (*AEGP_PaintPalSetBackColor)( + const AEGP_ColorVal *back_colorP); /* >> */ + + SPAPI A_Err (*AEGP_CharPalGetFillColor)( + A_Boolean *is_fill_color_definedPB, /* << */ + AEGP_ColorVal *fill_colorP); /* << only valid if is_fill_color_definedPB == TRUE */ + + SPAPI A_Err (*AEGP_CharPalGetStrokeColor)( + A_Boolean *is_stroke_color_definedPB, /* << */ + AEGP_ColorVal *stroke_colorP); /* << only valid if is_stroke_color_definedPB == TRUE */ + + SPAPI A_Err (*AEGP_CharPalSetFillColor)( + const AEGP_ColorVal *fill_colorP); /* >> */ + + SPAPI A_Err (*AEGP_CharPalSetStrokeColor)( + const AEGP_ColorVal *stroke_colorP); /* >> */ + + SPAPI A_Err (*AEGP_CharPalIsFillColorUIFrontmost)( /* Otherwise, StrokeColor is frontmost */ + A_Boolean *is_fill_color_selectedPB); /* << */ + + SPAPI A_Err (*AEGP_ConvertFpLongToHSFRatio)( + A_FpLong numberF, /* >> */ + A_Ratio *ratioPR); /* << */ + + SPAPI A_Err (*AEGP_ConvertHSFRatioToFpLong)( + A_Ratio ratioR, /* << */ + A_FpLong *numberPF); /* >> */ + + // this routine is safe to call from the non-main + // thread. It is asynchronous and will return before the idle handler is called. + // The Suite routines to get this pointer are not + // thread safe, therefore you need to save it off + // in the main thread for use by the child thread. + SPAPI A_Err (*AEGP_CauseIdleRoutinesToBeCalled)(void); + + + // Determine if after effects is running in a mode where there is no + // user interface, and attempting to interact with the user (via a modal dialog) + // will hang the application. + // This will not change during a run. Use it to optimize your plugin at startup + // to not create a user interface and make AE launch faster, and not break + // when running multiple instances of a service. + SPAPI A_Err (*AEGP_GetSuppressInteractiveUI)(A_Boolean* ui_is_suppressedPB); // out + + // this call writes text to the console if one is available. One is guaranteed to be available + // if ui_is_suppressedB == true. + // In general use the call AEGP_ReportInfo() as it will write to the console in + // non-interactive modes, and use a dialog in interactive modes. + SPAPI A_Err (*AEGP_WriteToOSConsole)(const A_char* textZ); // in + + // this writes an entry into the debug log, or to the command line if launched + // with the -debug flag. + SPAPI A_Err (*AEGP_WriteToDebugLog)(const A_char* subsystemZ, // in + const A_char* event_typeZ, // in + const A_char * infoZ); // in + + + SPAPI A_Err (*AEGP_IsScriptingAvailable)(A_Boolean* outAvailablePB); + + // Execute a script. + // The script text can either be in UTF-8, or the current + // application encoding. + // The result is the result string if OK. It is optional. + // The error is the error string if an error occurred. It is optional. + // the result and error are in the encoding specified by platform_encodingB + SPAPI A_Err (*AEGP_ExecuteScript)(AEGP_PluginID inPlugin_id, + const A_char* inScriptZ, // in + const A_Boolean platform_encodingB, // in + AEGP_MemHandle* outResultPH0, + AEGP_MemHandle* outErrorStringPH0); + + SPAPI A_Err (*AEGP_HostIsActivated)(A_Boolean *is_activatedPB); + + SPAPI A_Err (*AEGP_GetPluginPlatformRef)(AEGP_PluginID plug_id, void** plat_refPPV); // on the Mac, it is a CFBundleRef to your mach-o plugin or NULL for a CFM plug-in; on Windows it is set to NULL for now + +} AEGP_UtilitySuite4; + + + +#define kAEGPUtilitySuiteVersion3 7 /* frozen in AE 6.5 */ + +typedef struct AEGP_UtilitySuite3 { + + SPAPI A_Err (*AEGP_ReportInfo)( /* displays dialog with name of plugin followed by info string */ + AEGP_PluginID aegp_plugin_id, /* >> */ + const A_char *info_stringZ); /* >> */ + + + SPAPI A_Err (*AEGP_GetDriverPluginInitFuncVersion)( + A_short *major_versionPS, /* << */ + A_short *minor_versionPS); /* << */ + + SPAPI A_Err (*AEGP_GetDriverImplementationVersion)( + A_short *major_versionPS, /* << */ + A_short *minor_versionPS); /* << */ + + SPAPI A_Err (*AEGP_StartQuietErrors)( + AEGP_ErrReportState *err_stateP); /* << */ + + SPAPI A_Err (*AEGP_EndQuietErrors)( + A_Boolean report_quieted_errorsB, /* >> currently reports last quieted error */ + AEGP_ErrReportState *err_stateP); /* >> */ + + SPAPI A_Err (*AEGP_StartUndoGroup)( /* MUST be balanced with call to AEGP_EndUndoGroup() */ + const A_char *undo_nameZ); /* >> */ + + SPAPI A_Err (*AEGP_EndUndoGroup)(void); + + SPAPI A_Err (*AEGP_RegisterWithAEGP)( + AEGP_GlobalRefcon global_refcon, /* >> global refcon passed in command handlers */ + const A_char *plugin_nameZ, /* >> name of this plugin. AEGP_MAX_PLUGIN_NAME_SIZE */ + AEGP_PluginID *plugin_id); /* << id for plugin to use in other AEGP calls */ + + SPAPI A_Err (*AEGP_GetMainHWND)( + void *main_hwnd); /* << */ + + SPAPI A_Err (*AEGP_ShowHideAllFloaters)( + A_Boolean include_tool_palB); /* >> */ + + SPAPI A_Err (*AEGP_PaintPalGetForeColor)( + AEGP_ColorVal *fore_colorP); /* << */ + + SPAPI A_Err (*AEGP_PaintPalGetBackColor)( + AEGP_ColorVal *back_colorP); /* << */ + + SPAPI A_Err (*AEGP_PaintPalSetForeColor)( + const AEGP_ColorVal *fore_colorP); /* >> */ + + SPAPI A_Err (*AEGP_PaintPalSetBackColor)( + const AEGP_ColorVal *back_colorP); /* >> */ + + SPAPI A_Err (*AEGP_CharPalGetFillColor)( + A_Boolean *is_fill_color_definedPB, /* << */ + AEGP_ColorVal *fill_colorP); /* << only valid if is_fill_color_definedPB == TRUE */ + + SPAPI A_Err (*AEGP_CharPalGetStrokeColor)( + A_Boolean *is_stroke_color_definedPB, /* << */ + AEGP_ColorVal *stroke_colorP); /* << only valid if is_stroke_color_definedPB == TRUE */ + + SPAPI A_Err (*AEGP_CharPalSetFillColor)( + const AEGP_ColorVal *fill_colorP); /* >> */ + + SPAPI A_Err (*AEGP_CharPalSetStrokeColor)( + const AEGP_ColorVal *stroke_colorP); /* >> */ + + SPAPI A_Err (*AEGP_CharPalIsFillColorUIFrontmost)( /* Otherwise, StrokeColor is frontmost */ + A_Boolean *is_fill_color_selectedPB); /* << */ + + SPAPI A_Err (*AEGP_ConvertFpLongToHSFRatio)( + A_FpLong numberF, /* >> */ + A_Ratio *ratioPR); /* << */ + + SPAPI A_Err (*AEGP_ConvertHSFRatioToFpLong)( + A_Ratio ratioR, /* << */ + A_FpLong *numberPF); /* >> */ + + // this routine is safe to call from the non-main + // thread. It is asynchronous and will return before the idle handler is called. + // The Suite routines to get this pointer are not + // thread safe, therefore you need to save it off + // in the main thread for use by the child thread. + SPAPI A_Err (*AEGP_CauseIdleRoutinesToBeCalled)(void); + + + // Determine if after effects is running in a mode where there is no + // user interface, and attempting to interact with the user (via a modal dialog) + // will hang the application. + // This will not change during a run. Use it to optimize your plugin at startup + // to not create a user interface and make AE launch faster, and not break + // when running multiple instances of a service. + SPAPI A_Err (*AEGP_GetSuppressInteractiveUI)(A_Boolean* ui_is_suppressedPB); // out + + // this call writes text to the console if one is available. One is guaranteed to be available + // if ui_is_suppressedB == true. + // In general use the call AEGP_ReportInfo() as it will write to the console in + // non-interactive modes, and use a dialog in interactive modes. + SPAPI A_Err (*AEGP_WriteToOSConsole)(const A_char* textZ); // in + + // this writes an entry into the debug log, or to the command line if launched + // with the -debug flag. + SPAPI A_Err (*AEGP_WriteToDebugLog)(const A_char* subsystemZ, // in + const A_char* event_typeZ, // in + const A_char * infoZ); // in +} AEGP_UtilitySuite3; + +#define kAEGPUtilitySuiteVersion2 5 /* frozen in AE 6.0 */ + +typedef struct AEGP_UtilitySuite2 { + + SPAPI A_Err (*AEGP_ReportInfo)( /* displays dialog with name of plugin followed by info string */ + AEGP_PluginID aegp_plugin_id, /* >> */ + const A_char *info_stringZ); /* >> */ + + + SPAPI A_Err (*AEGP_GetDriverPluginInitFuncVersion)( + A_short *major_versionPS, /* << */ + A_short *minor_versionPS); /* << */ + + SPAPI A_Err (*AEGP_GetDriverImplementationVersion)( + A_short *major_versionPS, /* << */ + A_short *minor_versionPS); /* << */ + + SPAPI A_Err (*AEGP_StartQuietErrors)( + AEGP_ErrReportState *err_stateP); /* << */ + + SPAPI A_Err (*AEGP_EndQuietErrors)( + A_Boolean report_quieted_errorsB, /* >> currently reports last quieted error */ + AEGP_ErrReportState *err_stateP); /* >> */ + + SPAPI A_Err (*AEGP_StartUndoGroup)( /* MUST be balanced with call to AEGP_EndUndoGroup() */ + const A_char *undo_nameZ); /* >> */ + + SPAPI A_Err (*AEGP_EndUndoGroup)(void); + + SPAPI A_Err (*AEGP_RegisterWithAEGP)( + AEGP_GlobalRefcon global_refcon, /* >> global refcon passed in command handlers */ + const A_char *plugin_nameZ, /* >> name of this plugin. AEGP_MAX_PLUGIN_NAME_SIZE */ + AEGP_PluginID *plugin_id); /* << id for plugin to use in other AEGP calls */ + + SPAPI A_Err (*AEGP_GetMainHWND)( + void *main_hwnd); /* << */ + + SPAPI A_Err (*AEGP_ShowHideAllFloaters)( + A_Boolean include_tool_palB); /* >> */ + + SPAPI A_Err (*AEGP_PaintPalGetForeColor)( + AEGP_ColorVal *fore_colorP); /* << */ + + SPAPI A_Err (*AEGP_PaintPalGetBackColor)( + AEGP_ColorVal *back_colorP); /* << */ + + SPAPI A_Err (*AEGP_PaintPalSetForeColor)( + const AEGP_ColorVal *fore_colorP); /* >> */ + + SPAPI A_Err (*AEGP_PaintPalSetBackColor)( + const AEGP_ColorVal *back_colorP); /* >> */ + + SPAPI A_Err (*AEGP_CharPalGetFillColor)( + A_Boolean *is_fill_color_definedPB, /* << */ + AEGP_ColorVal *fill_colorP); /* << only valid if is_fill_color_definedPB == TRUE */ + + SPAPI A_Err (*AEGP_CharPalGetStrokeColor)( + A_Boolean *is_stroke_color_definedPB, /* << */ + AEGP_ColorVal *stroke_colorP); /* << only valid if is_stroke_color_definedPB == TRUE */ + + SPAPI A_Err (*AEGP_CharPalSetFillColor)( + const AEGP_ColorVal *fill_colorP); /* >> */ + + SPAPI A_Err (*AEGP_CharPalSetStrokeColor)( + const AEGP_ColorVal *stroke_colorP); /* >> */ + + SPAPI A_Err (*AEGP_CharPalIsFillColorUIFrontmost)( /* Otherwise, StrokeColor is frontmost */ + A_Boolean *is_fill_color_selectedPB); /* << */ + +} AEGP_UtilitySuite2; + +#define kAEGPUtilitySuiteVersion1 3 /* frozen in AE 5.0 */ + +typedef struct AEGP_UtilitySuite1 { + + SPAPI A_Err (*AEGP_ReportInfo)( /* displays dialog with name of plugin followed by info string */ + AEGP_PluginID aegp_plugin_id, /* >> */ + const A_char *info_stringZ); /* >> */ + + + SPAPI A_Err (*AEGP_GetDriverPluginInitFuncVersion)( + A_short *major_versionPS, /* << */ + A_short *minor_versionPS); /* << */ + + SPAPI A_Err (*AEGP_GetDriverImplementationVersion)( + A_short *major_versionPS, /* << */ + A_short *minor_versionPS); /* << */ + + SPAPI A_Err (*AEGP_StartQuietErrors)( + AEGP_ErrReportState *err_stateP); /* << */ + + SPAPI A_Err (*AEGP_EndQuietErrors)( + A_Boolean report_quieted_errorsB, /* >> currently reports last quieted error */ + AEGP_ErrReportState *err_stateP); /* >> */ + + SPAPI A_Err (*AEGP_StartUndoGroup)( /* MUST be balanced with call to AEGP_EndUndoGroup() */ + const A_char *undo_nameZ); /* >> */ + + SPAPI A_Err (*AEGP_EndUndoGroup)(void); + + SPAPI A_Err (*AEGP_RegisterWithAEGP)( + AEGP_GlobalRefcon global_refcon, /* >> global refcon passed in command handlers */ + const A_char *plugin_nameZ, /* >> name of this plugin. AEGP_MAX_PLUGIN_NAME_SIZE */ + AEGP_PluginID *plugin_id); /* << id for plugin to use in other AEGP calls */ + + SPAPI A_Err (*AEGP_GetMainHWND)( + void *main_hwnd); /* << */ + +} AEGP_UtilitySuite1; + + + + +#define kAEGPQueryXformSuiteVersion1 1 /* frozen in AE 5.0 */ + + + +typedef struct AEGP_QueryXformSuite1 { + + SPAPI A_Err (*AEGP_QueryXformGetSrcType)( + PR_QueryContextH query_contextH, /* <> */ + AEGP_QueryXformType *src_type); /* << */ + + SPAPI A_Err (*AEGP_QueryXformGetDstType)( + PR_QueryContextH query_contextH, /* <> */ + AEGP_QueryXformType *dst_type); /* << */ + + SPAPI A_Err (*AEGP_QueryXformGetLayer)( + PR_QueryContextH query_contextH, /* <> */ + AEGP_LayerH *layerPH); /* << */ + + SPAPI A_Err (*AEGP_QueryXformGetComp)( + PR_QueryContextH query_contextH, /* <> */ + AEGP_CompH *compPH); /* << */ + + SPAPI A_Err (*AEGP_QueryXformGetTransformTime)( + PR_QueryContextH query_contextH, /* <> */ + A_Time *time); /* << */ + + SPAPI A_Err (*AEGP_QueryXformGetViewTime)( + PR_QueryContextH query_contextH, /* <> */ + A_Time *time); /* << */ + + SPAPI A_Err (*AEGP_QueryXformGetCamera)( + PR_QueryContextH query_contextH, /* <> */ + AEGP_LayerH *camera_layerPH); /* << */ + + SPAPI A_Err (*AEGP_QueryXformGetXform)( + PR_QueryContextH query_contextH, /* <> */ + A_Matrix4 *xform); /* << */ + + SPAPI A_Err (*AEGP_QueryXformSetXform)( + PR_QueryContextH query_contextH, /* <> */ + A_Matrix4 *xform); /* >> */ + +}AEGP_QueryXformSuite1; + + + + +#define kAEGPRenderSuiteVersion1 1 /* frozen in AE 5.5.1 */ + + +typedef struct { + SPAPI A_Err (*AEGP_RenderAndCheckoutFrame)( + AEGP_RenderOptionsH optionsH, /* >> */ + AEGP_RenderSuiteCheckForCancel cancel_functionP0, /* >> optional*/ + AEGP_CancelRefcon cancel_function_refconP0, /* >> optional */ + AEGP_FrameReceiptH *receiptPH); /* << check in using AEGP_CheckinFrame to release memory */ + + SPAPI A_Err (*AEGP_CheckinFrame)( + AEGP_FrameReceiptH receiptH); /* >> */ + + /* This returns a read only world that is not-owned by the plugin. + Call CheckinFrame to release the world when you are done reading from it. + */ + + SPAPI A_Err (*AEGP_GetReceiptWorld)( + AEGP_FrameReceiptH receiptH, /* >> */ + AEGP_WorldH *worldPH); /* << */ + + SPAPI A_Err (*AEGP_GetRenderedRegion)( + AEGP_FrameReceiptH receiptH, /* >> */ + A_LRect *rendered_regionP); /* << */ + + SPAPI A_Err (*AEGP_IsRenderedFrameSufficient)( + AEGP_RenderOptionsH rendered_optionsH, /* >> */ + AEGP_RenderOptionsH proposed_optionsH, /* >> */ + A_Boolean *rendered_is_sufficientPB); /* << */ + + SPAPI A_Err (*AEGP_RenderNewItemSoundData)( /* Works on Compositions and Footage items. */ + AEGP_ItemH itemH, /* >> */ + const A_Time *start_timePT, /* >> */ + const A_Time *durationPT, /* >> */ + const AEGP_SoundDataFormat *sound_formatP, /* >> */ + AEGP_RenderSuiteCheckForCancel cancel_functionP0, /* >> optional*/ + AEGP_CancelRefcon cancel_function_refconP0, /* >> optional */ + AEGP_SoundDataH *new_sound_dataPH); /* << AEGP_SoundDataH must be disposed. Returns NULL if no audio */ + +} AEGP_RenderSuite1; + + +#define kAEGPRenderSuiteVersion2 2 /* frozen in 6.5 */ + + +typedef A_Err (*AEGP_RenderSuiteCheckForCancelv1)( + void *refcon, + A_Boolean *cancelPB); + +typedef struct { + SPAPI A_Err (*AEGP_RenderAndCheckoutFrame)( + AEGP_RenderOptionsH optionsH, /* >> */ + AEGP_RenderSuiteCheckForCancelv1 cancel_functionP0, /* >> optional*/ + AEGP_CancelRefcon cancel_function_refconP0, /* >> optional */ + AEGP_FrameReceiptH *receiptPH); /* << check in using AEGP_CheckinFrame to release memory */ + + SPAPI A_Err (*AEGP_CheckinFrame)( + AEGP_FrameReceiptH receiptH); /* >> */ + + /* This returns a read only world that is not-owned by the plugin. + Call CheckinFrame to release the world when you are done reading from it. + */ + + SPAPI A_Err (*AEGP_GetReceiptWorld)( + AEGP_FrameReceiptH receiptH, /* >> */ + AEGP_WorldH *worldPH); /* << */ + + SPAPI A_Err (*AEGP_GetRenderedRegion)( + AEGP_FrameReceiptH receiptH, /* >> */ + A_LRect *rendered_regionP); /* << */ + + SPAPI A_Err (*AEGP_IsRenderedFrameSufficient)( + AEGP_RenderOptionsH rendered_optionsH, /* >> */ + AEGP_RenderOptionsH proposed_optionsH, /* >> */ + A_Boolean *rendered_is_sufficientPB); /* << */ + + SPAPI A_Err (*AEGP_RenderNewItemSoundData)( /* Works on Compositions and Footage items. */ + AEGP_ItemH itemH, /* >> */ + const A_Time *start_timePT, /* >> */ + const A_Time *durationPT, /* >> */ + const AEGP_SoundDataFormat *sound_formatP, /* >> */ + AEGP_RenderSuiteCheckForCancel cancel_functionP0, /* >> optional*/ + AEGP_CancelRefcon cancel_function_refconP0, /* >> optional */ + AEGP_SoundDataH *new_sound_dataPH); /* << AEGP_SoundDataH must be disposed. Returns NULL if no audio */ + + + // returns the current timestamp of the project.this is increased any time something is touched in the project + // that affects rendering + SPAPI A_Err (*AEGP_GetCurrentTimestamp)( + AEGP_TimeStamp * time_stampP); // out + + // Lets you know if the video of the item has changed since the input time stamp. + // Is not affected by audio. + SPAPI A_Err (*AEGP_HasItemChangedSinceTimestamp)(AEGP_ItemH itemH, // in + const A_Time * start_timeP, // in + const A_Time* durationP, //in + const AEGP_TimeStamp * time_stampP, //in + A_Boolean * item_has_changedPB); //out + + // checks whether this frame would be worth rendering externally and + // checking in to the cache. a speculative renderer should check this twice: + // (1) before sending the frame out to render + // (2) when it is complete, before calling AEGP_NewPlatformWorld and checking in. + // (don't forget to call AEGP_HasItemChangedSinceTimestamp also!) + SPAPI A_Err (*AEGP_IsItemWorthwhileToRender)( AEGP_RenderOptionsH roH, // in + const AEGP_TimeStamp* time_stampP, // in + A_Boolean *worthwhile_to_renderPB); // out + + // ticks_to_render is the approximate amount of time needed to render the frame + // on this machine. it is 60Hz. + SPAPI A_Err (*AEGP_CheckinRenderedFrame)( AEGP_RenderOptionsH roH, // in + const AEGP_TimeStamp* time_stampP, // in + A_u_long ticks_to_renderL, // in + AEGP_PlatformWorldH imageH); // in (adopted) +} AEGP_RenderSuite2; + + +#define kAEGPRenderSuiteVersion3 3 /* frozen in 11.0 */ + +typedef struct { + SPAPI A_Err (*AEGP_RenderAndCheckoutFrame)( + AEGP_RenderOptionsH optionsH, /* >> */ + AEGP_RenderSuiteCheckForCancel cancel_functionP0, /* >> optional*/ + AEGP_CancelRefcon cancel_function_refconP0, /* >> optional */ + AEGP_FrameReceiptH *receiptPH); /* << check in using AEGP_CheckinFrame to release memory */ + + SPAPI A_Err (*AEGP_CheckinFrame)( + AEGP_FrameReceiptH receiptH); /* >> */ + + /* This returns a read only world that is not-owned by the plugin. + Call CheckinFrame to release the world when you are done reading from it. + */ + + SPAPI A_Err (*AEGP_GetReceiptWorld)( + AEGP_FrameReceiptH receiptH, /* >> */ + AEGP_WorldH *worldPH); /* << */ + + SPAPI A_Err (*AEGP_GetRenderedRegion)( + AEGP_FrameReceiptH receiptH, /* >> */ + A_LRect *rendered_regionP); /* << */ + + SPAPI A_Err (*AEGP_IsRenderedFrameSufficient)( + AEGP_RenderOptionsH rendered_optionsH, /* >> */ + AEGP_RenderOptionsH proposed_optionsH, /* >> */ + A_Boolean *rendered_is_sufficientPB); /* << */ + + SPAPI A_Err (*AEGP_RenderNewItemSoundData)( /* Works on Compositions and Footage items. */ + AEGP_ItemH itemH, /* >> */ + const A_Time *start_timePT, /* >> */ + const A_Time *durationPT, /* >> */ + const AEGP_SoundDataFormat *sound_formatP, /* >> */ + AEGP_RenderSuiteCheckForCancel cancel_functionP0, /* >> optional*/ + AEGP_CancelRefcon cancel_function_refconP0, /* >> optional */ + AEGP_SoundDataH *new_sound_dataPH); /* << AEGP_SoundDataH must be disposed. Returns NULL if no audio */ + + + // returns the current timestamp of the project.this is increased any time something is touched in the project + // that affects rendering + SPAPI A_Err (*AEGP_GetCurrentTimestamp)( + AEGP_TimeStamp * time_stampP); // out + + // Lets you know if the video of the item has changed since the input time stamp. + // Is not affected by audio. + SPAPI A_Err (*AEGP_HasItemChangedSinceTimestamp)(AEGP_ItemH itemH, // in + const A_Time * start_timeP, // in + const A_Time* durationP, //in + const AEGP_TimeStamp * time_stampP, //in + A_Boolean * item_has_changedPB); //out + + // checks whether this frame would be worth rendering externally and + // checking in to the cache. a speculative renderer should check this twice: + // (1) before sending the frame out to render + // (2) when it is complete, before calling AEGP_NewPlatformWorld and checking in. + // (don't forget to call AEGP_HasItemChangedSinceTimestamp also!) + SPAPI A_Err (*AEGP_IsItemWorthwhileToRender)( AEGP_RenderOptionsH roH, // in + const AEGP_TimeStamp* time_stampP, // in + A_Boolean *worthwhile_to_renderPB); // out + + // ticks_to_render is the approximate amount of time needed to render the frame + // on this machine. it is 60Hz. + SPAPI A_Err (*AEGP_CheckinRenderedFrame)( AEGP_RenderOptionsH roH, // in + const AEGP_TimeStamp* time_stampP, // in + A_u_long ticks_to_renderL, // in + AEGP_PlatformWorldH imageH); // in (adopted) + + SPAPI A_Err (*AEGP_GetReceiptGuid) (AEGP_FrameReceiptH receiptH, // in + AEGP_MemHandle *guidMH); // out, must be disposed +} AEGP_RenderSuite3; + + +#define kAEGPRenderSuiteVersion4 5 /* frozen in 13.0 */ + +typedef struct { + SPAPI A_Err (*AEGP_RenderAndCheckoutFrame)( + AEGP_RenderOptionsH optionsH, /* >> */ + AEGP_RenderSuiteCheckForCancel cancel_functionP0, /* >> optional*/ + AEGP_CancelRefcon cancel_function_refconP0, /* >> optional */ + AEGP_FrameReceiptH *receiptPH); /* << check in using AEGP_CheckinFrame to release memory */ + + SPAPI A_Err (*AEGP_RenderAndCheckoutLayerFrame)( + AEGP_LayerRenderOptionsH optionsH, /* >> */ + A_Boolean render_plain_layer_frameB, /* >> true to render layer frame, false to render effect input frame */ + AEGP_RenderSuiteCheckForCancel cancel_functionP0, /* >> optional*/ + AEGP_CancelRefcon cancel_function_refconP0, /* >> optional */ + AEGP_FrameReceiptH *receiptPH); /* << check in using AEGP_CheckinFrame to release memory */ + + SPAPI A_Err (*AEGP_CheckinFrame)( + AEGP_FrameReceiptH receiptH); /* >> */ + + /* This returns a read only world that is not-owned by the plugin. + Call CheckinFrame to release the world when you are done reading from it. + */ + + SPAPI A_Err (*AEGP_GetReceiptWorld)( + AEGP_FrameReceiptH receiptH, /* >> */ + AEGP_WorldH *worldPH); /* << */ + + SPAPI A_Err (*AEGP_GetRenderedRegion)( + AEGP_FrameReceiptH receiptH, /* >> */ + A_LRect *rendered_regionP); /* << */ + + SPAPI A_Err (*AEGP_IsRenderedFrameSufficient)( + AEGP_RenderOptionsH rendered_optionsH, /* >> */ + AEGP_RenderOptionsH proposed_optionsH, /* >> */ + A_Boolean *rendered_is_sufficientPB); /* << */ + + SPAPI A_Err (*AEGP_RenderNewItemSoundData)( /* Works on Compositions and Footage items. */ + AEGP_ItemH itemH, /* >> */ + const A_Time *start_timePT, /* >> */ + const A_Time *durationPT, /* >> */ + const AEGP_SoundDataFormat *sound_formatP, /* >> */ + AEGP_RenderSuiteCheckForCancel cancel_functionP0, /* >> optional*/ + AEGP_CancelRefcon cancel_function_refconP0, /* >> optional */ + AEGP_SoundDataH *new_sound_dataPH); /* << AEGP_SoundDataH must be disposed. Returns NULL if no audio */ + + + // returns the current timestamp of the project.this is increased any time something is touched in the project + // that affects rendering + SPAPI A_Err (*AEGP_GetCurrentTimestamp)( + AEGP_TimeStamp * time_stampP); // out + + // Lets you know if the video of the item has changed since the input time stamp. + // Is not affected by audio. + SPAPI A_Err (*AEGP_HasItemChangedSinceTimestamp)(AEGP_ItemH itemH, // in + const A_Time * start_timeP, // in + const A_Time* durationP, //in + const AEGP_TimeStamp * time_stampP, //in + A_Boolean * item_has_changedPB); //out + + // checks whether this frame would be worth rendering externally and + // checking in to the cache. a speculative renderer should check this twice: + // (1) before sending the frame out to render + // (2) when it is complete, before calling AEGP_NewPlatformWorld and checking in. + // (don't forget to call AEGP_HasItemChangedSinceTimestamp also!) + SPAPI A_Err (*AEGP_IsItemWorthwhileToRender)( AEGP_RenderOptionsH roH, // in + const AEGP_TimeStamp* time_stampP, // in + A_Boolean *worthwhile_to_renderPB); // out + + // ticks_to_render is the approximate amount of time needed to render the frame + // on this machine. it is 60Hz. + SPAPI A_Err (*AEGP_CheckinRenderedFrame)( AEGP_RenderOptionsH roH, // in + const AEGP_TimeStamp* time_stampP, // in + A_u_long ticks_to_renderL, // in + AEGP_PlatformWorldH imageH); // in (adopted) + + SPAPI A_Err (*AEGP_GetReceiptGuid) (AEGP_FrameReceiptH receiptH, // in + AEGP_MemHandle *guidMH); // out, must be disposed +} AEGP_RenderSuite4; + + + +#define kAEGPWorldSuiteVersion2 2 /* frozen in AE 6.5 */ + +typedef struct { + SPAPI A_Err (*AEGP_New)( + AEGP_PluginID plugin_id, /* >> */ + AEGP_WorldType type, /* >> */ + A_long widthL, /* >> */ + A_long heightL, /* >> */ + AEGP_WorldH *worldPH); /* << */ + + SPAPI A_Err (*AEGP_Dispose)( + AEGP_WorldH worldH); /* >> */ + + SPAPI A_Err (*AEGP_GetType)( + AEGP_WorldH worldH, /* >> */ + AEGP_WorldType *typeP); /* << */ + + SPAPI A_Err (*AEGP_GetSize)( + AEGP_WorldH worldH, /* >> */ + A_long *widthPL, /* << */ + A_long *heightPL); /* << */ + + SPAPI A_Err (*AEGP_GetRowBytes)( + AEGP_WorldH worldH, /* >> */ + A_u_long *row_bytesPL); /* << */ + + SPAPI A_Err (*AEGP_GetBaseAddr8)( + AEGP_WorldH worldH, /* >> error if the worldH is not AEGP_WorldType_8 */ + PF_Pixel8 **base_addrP); /* << */ + + SPAPI A_Err (*AEGP_GetBaseAddr16)( + AEGP_WorldH worldH, /* >> error if the worldH is not AEGP_WorldType_16 */ + PF_Pixel16 **base_addrP); /* << */ + + SPAPI A_Err (*AEGP_FillOutPFEffectWorld)( /* Provided so you can use some of the PF routines with an AEGPWorld. Pass NULL as the ProgPtr to the PF routines.*/ + AEGP_WorldH worldH, /* >> */ + PF_EffectWorld *pf_worldP); /* << */ + + SPAPI A_Err (*AEGP_FastBlur)( + A_FpLong radiusF, /* >> */ + PF_ModeFlags mode, /* >> */ + PF_Quality quality, /* >> */ + AEGP_WorldH worldH); /* <> only for user allocated worlds; not for checked-out frames which are read only */ + + SPAPI A_Err (*AEGP_NewPlatformWorld)( + AEGP_PluginID plugin_id, /* >> */ + AEGP_WorldType type, /* >> */ + A_long widthL, /* >> */ + A_long heightL, /* >> */ + AEGP_PlatformWorldH *worldPH); /* << */ + + SPAPI A_Err (*AEGP_DisposePlatformWorld)( + AEGP_PlatformWorldH worldH); /* >> */ + + SPAPI A_Err (*AEGP_NewReferenceFromPlatformWorld)( + AEGP_PluginID plugin_id, /* >> */ + AEGP_PlatformWorldH platform_worldH, // >> + AEGP_WorldH *worldPH); /* << */ + + +} AEGP_WorldSuite2; + + +#define kAEGPWorldSuite "AEGP World Suite" +#define kAEGPWorldSuiteVersion1 1 /* frozen AE 6.0 */ + +typedef struct { + SPAPI A_Err (*AEGP_New)( + AEGP_PluginID plugin_id, /* >> */ + AEGP_WorldType type, /* >> */ + A_long widthL, /* >> */ + A_long heightL, /* >> */ + AEGP_WorldH *worldPH); /* << */ + + SPAPI A_Err (*AEGP_Dispose)( + AEGP_WorldH worldH); /* >> */ + + SPAPI A_Err (*AEGP_GetType)( + AEGP_WorldH worldH, /* >> */ + AEGP_WorldType *typeP); /* << */ + + SPAPI A_Err (*AEGP_GetSize)( + AEGP_WorldH worldH, /* >> */ + A_long *widthPL, /* << */ + A_long *heightPL); /* << */ + + SPAPI A_Err (*AEGP_GetRowBytes)( + AEGP_WorldH worldH, /* >> */ + A_u_long *row_bytesPL); /* << */ + + SPAPI A_Err (*AEGP_GetBaseAddr8)( + AEGP_WorldH worldH, /* >> error if the worldH is not AEGP_WorldType_8 */ + PF_Pixel8 **base_addrP); /* << */ + + SPAPI A_Err (*AEGP_GetBaseAddr16)( + AEGP_WorldH worldH, /* >> error if the worldH is not AEGP_WorldType_16 */ + PF_Pixel16 **base_addrP); /* << */ + + SPAPI A_Err (*AEGP_FillOutPFEffectWorld)( /* Provided so you can use some of the PF routines with an AEGPWorld. Pass NULL as the ProgPtr to the PF routines.*/ + AEGP_WorldH worldH, /* >> */ + PF_EffectWorld *pf_worldP); /* << */ + + SPAPI A_Err (*AEGP_FastBlur)( + A_FpLong radiusF, /* >> */ + PF_ModeFlags mode, /* >> */ + PF_Quality quality, /* >> */ + AEGP_WorldH worldH); /* <> only for user allocated worlds; not for checked-out frames which are read only */ +} AEGP_WorldSuite1; + + +typedef struct { + AEGP_CollectionItemType type; + union { + AEGP_LayerCollectionItem layer; + AEGP_MaskCollectionItem mask; + AEGP_EffectCollectionItem effect; + AEGP_StreamCollectionItem stream; + AEGP_MaskVertexCollectionItem mask_vertex; + AEGP_KeyframeCollectionItem keyframe; + } u; +} AEGP_CollectionItem; + + +#define kAEGPCollectionSuiteVersion1 1 /* frozen in AE 5.0 */ + +typedef struct { + SPAPI A_Err (*AEGP_NewCollection)( /* dispose with dispose collection */ + AEGP_PluginID plugin_id, /* >> */ + AEGP_CollectionH *collectionPH); /* << */ + + SPAPI A_Err (*AEGP_DisposeCollection)( + AEGP_CollectionH collectionH); /* >> */ + + SPAPI A_Err (*AEGP_GetCollectionNumItems)( /* constant time */ + AEGP_CollectionH collectionH, /* >> */ + A_u_long *num_itemsPL); /* << */ + + SPAPI A_Err (*AEGP_GetCollectionItemByIndex)( /* constant time */ + AEGP_CollectionH collectionH, /* >> */ + A_u_long indexL, /* >> */ + AEGP_CollectionItem *collection_itemP); /* << */ + + SPAPI A_Err (*AEGP_CollectionPushBack)( /* constant time */ + AEGP_CollectionH collectionH, /* <> */ + const AEGP_CollectionItem *collection_itemP); /* >> */ + + SPAPI A_Err (*AEGP_CollectionErase)( /* O(n) */ + AEGP_CollectionH collectionH, /* <> */ + A_u_long index_firstL, /* >> */ + A_u_long index_lastL); /* >> */ + +} AEGP_CollectionSuite1; + +#define kAEGPDynamicStreamSuiteVersion1 1 /* frozen in AE 6.0 */ + +typedef struct AEGP_DynamicStreamSuite1 { + + SPAPI A_Err (*AEGP_GetNewStreamRefForLayer)( // used to start recursive walk of layer, + AEGP_PluginID aegp_plugin_id, /* >> */ + AEGP_LayerH layerH, /* >> */ + AEGP_StreamRefH *streamPH); /* << must be disposed by caller! */ + + SPAPI A_Err (*AEGP_GetStreamDepth)( // layer is depth 0 + AEGP_StreamRefH streamH, /* >> */ + A_long *depthPL); /* << */ + + + SPAPI A_Err (*AEGP_GetStreamGroupingType)( + AEGP_StreamRefH streamH, /* >> */ + AEGP_StreamGroupingType *group_typeP); /* << */ + + SPAPI A_Err (*AEGP_GetNumStreamsInGroup)( // error on leaf + AEGP_StreamRefH streamH, /* >> */ + A_long *num_streamsPL); /* << */ + + + SPAPI A_Err (*AEGP_GetDynamicStreamFlags)( + AEGP_StreamRefH streamH, /* >> */ + AEGP_DynStreamFlags *stream_flagsP); /* << */ + + SPAPI A_Err (*AEGP_SetDynamicStreamFlag)( /* UNDOABLE */ + AEGP_StreamRefH streamH, /* >> */ + AEGP_DynStreamFlags one_flag, /* >> */ + A_Boolean setB); /* >> */ + + + SPAPI A_Err (*AEGP_GetNewStreamRefByIndex)( // legal for namedgroup, indexedgroup, not leaf + AEGP_PluginID aegp_plugin_id, /* >> */ + AEGP_StreamRefH parent_groupH, /* >> */ + A_long indexL, /* >> */ + AEGP_StreamRefH *streamPH); /* << must be disposed by caller! */ + + SPAPI A_Err (*AEGP_GetNewStreamRefByMatchname)( // legal for namedgroup + AEGP_PluginID aegp_plugin_id, /* >> */ + AEGP_StreamRefH parent_groupH, /* >> */ + const A_char *match_nameZ, /* >> */ + AEGP_StreamRefH *streamPH); /* << must be disposed by caller! */ + + SPAPI A_Err (*AEGP_DeleteStream)( /* UNDOABLE, only valid for children of AEGP_StreamGroupingType_INDEXED_GROUP */ + AEGP_StreamRefH streamH); /* >> */ // must still dispose the streamref later + + SPAPI A_Err (*AEGP_ReorderStream)( /* UNDOABLE, only valid for children of AEGP_StreamGroupingType_INDEXED_GROUP */ + AEGP_StreamRefH streamH, /* <> updated to refer to newly ordered stream */ + A_long new_indexL); /* >> */ + + SPAPI A_Err (*AEGP_DuplicateStream)( /* UNDOABLE, only valid for children of AEGP_StreamGroupingType_INDEXED_GROUP */ + AEGP_PluginID aegp_plugin_id, /* >> */ + AEGP_StreamRefH streamH, /* >> */ + A_long *new_indexPL0); /* << */ + + /* GetStreamName is in main kAEGPStreamSuite, and works on dynamic streams including groups */ + + SPAPI A_Err (*AEGP_SetStreamName)( /* UNDOABLE, only valid for children of AEGP_StreamGroupingType_INDEXED_GROUP */ + AEGP_StreamRefH streamH, /* >> */ + const A_char *nameZ); /* >> */ + + SPAPI A_Err (*AEGP_CanAddStream)( + AEGP_StreamRefH group_streamH, /* >> */ + const A_char *match_nameZ, /* >> */ + A_Boolean *can_addPB); /* << */ + + SPAPI A_Err (*AEGP_AddStream)( /* UNDOABLE, only valid for AEGP_StreamGroupingType_INDEXED_GROUP */ + AEGP_PluginID aegp_plugin_id, /* >> */ + AEGP_StreamRefH indexed_group_streamH, /* >> */ + const A_char *match_nameZ, + AEGP_StreamRefH *streamPH0); /* << must be disposed by caller! */ + + SPAPI A_Err (*AEGP_GetMatchName)( + AEGP_StreamRefH streamH, /* >> */ + A_char *nameZ); /* << use A_char[AEGP_MAX_STREAM_MATCH_NAME_SIZE] for buffer */ + + SPAPI A_Err (*AEGP_GetNewParentStreamRef)( + AEGP_PluginID aegp_plugin_id, /* >> */ + AEGP_StreamRefH streamH, /* >> */ + AEGP_StreamRefH *parent_streamPH); /* << must be disposed by caller! */ + + SPAPI A_Err (*AEGP_GetStreamIsModified)( // i.e. changed from defaults, like the UU key + AEGP_StreamRefH streamH, /* >> */ + A_Boolean *modifiedPB); /* << */ + +} AEGP_DynamicStreamSuite1; + +#define kAEGPDynamicStreamSuiteVersion2 2 /* frozen in AE 6.5 */ + +typedef struct AEGP_DynamicStreamSuite2 { + + SPAPI A_Err (*AEGP_GetNewStreamRefForLayer)( // used to start recursive walk of layer, + AEGP_PluginID aegp_plugin_id, /* >> */ + AEGP_LayerH layerH, /* >> */ + AEGP_StreamRefH *streamPH); /* << must be disposed by caller! */ + + SPAPI A_Err (*AEGP_GetStreamDepth)( // layer is depth 0 + AEGP_StreamRefH streamH, /* >> */ + A_long *depthPL); /* << */ + + + SPAPI A_Err (*AEGP_GetStreamGroupingType)( + AEGP_StreamRefH streamH, /* >> */ + AEGP_StreamGroupingType *group_typeP); /* << */ + + SPAPI A_Err (*AEGP_GetNumStreamsInGroup)( // error on leaf + AEGP_StreamRefH streamH, /* >> */ + A_long *num_streamsPL); /* << */ + + + SPAPI A_Err (*AEGP_GetDynamicStreamFlags)( + AEGP_StreamRefH streamH, /* >> */ + AEGP_DynStreamFlags *stream_flagsP); /* << */ + + SPAPI A_Err (*AEGP_SetDynamicStreamFlag)( + AEGP_StreamRefH streamH, /* >> */ + AEGP_DynStreamFlags one_flag, /* >> */ + A_Boolean undoableB, /* true if you want this to be an undoable change */ + /* if false, the only legal flag is AEGP_DynStreamFlag_HIDDEN */ + A_Boolean setB); /* >> */ + + + SPAPI A_Err (*AEGP_GetNewStreamRefByIndex)( // legal for namedgroup, indexedgroup, not leaf + AEGP_PluginID aegp_plugin_id, /* >> */ + AEGP_StreamRefH parent_groupH, /* >> */ + A_long indexL, /* >> */ + AEGP_StreamRefH *streamPH); /* << must be disposed by caller! */ + + SPAPI A_Err (*AEGP_GetNewStreamRefByMatchname)( // legal for namedgroup + AEGP_PluginID aegp_plugin_id, /* >> */ + AEGP_StreamRefH parent_groupH, /* >> */ + const A_char *match_nameZ, /* >> */ + AEGP_StreamRefH *streamPH); /* << must be disposed by caller! */ + + SPAPI A_Err (*AEGP_DeleteStream)( /* UNDOABLE, only valid for children of AEGP_StreamGroupingType_INDEXED_GROUP */ + AEGP_StreamRefH streamH); /* >> */ // must still dispose the streamref later + + SPAPI A_Err (*AEGP_ReorderStream)( /* UNDOABLE, only valid for children of AEGP_StreamGroupingType_INDEXED_GROUP */ + AEGP_StreamRefH streamH, /* <> updated to refer to newly ordered stream */ + A_long new_indexL); /* >> */ + + SPAPI A_Err (*AEGP_DuplicateStream)( /* UNDOABLE, only valid for children of AEGP_StreamGroupingType_INDEXED_GROUP */ + AEGP_PluginID aegp_plugin_id, /* >> */ + AEGP_StreamRefH streamH, /* >> */ + A_long *new_indexPL0); /* << */ + + /* GetStreamName is in main kAEGPStreamSuite, and works on dynamic streams including groups */ + + SPAPI A_Err (*AEGP_SetStreamName)( /* UNDOABLE, only valid for children of AEGP_StreamGroupingType_INDEXED_GROUP */ + AEGP_StreamRefH streamH, /* >> */ + const A_char *nameZ); /* >> */ + + SPAPI A_Err (*AEGP_CanAddStream)( + AEGP_StreamRefH group_streamH, /* >> */ + const A_char *match_nameZ, /* >> */ + A_Boolean *can_addPB); /* << */ + + SPAPI A_Err (*AEGP_AddStream)( /* UNDOABLE, only valid for AEGP_StreamGroupingType_INDEXED_GROUP */ + AEGP_PluginID aegp_plugin_id, /* >> */ + AEGP_StreamRefH indexed_group_streamH, /* >> */ + const A_char *match_nameZ, + AEGP_StreamRefH *streamPH0); /* << must be disposed by caller! */ + + SPAPI A_Err (*AEGP_GetMatchName)( + AEGP_StreamRefH streamH, /* >> */ + A_char *nameZ); /* << use A_char[AEGP_MAX_STREAM_MATCH_NAME_SIZE] for buffer */ + + SPAPI A_Err (*AEGP_GetNewParentStreamRef)( + AEGP_PluginID aegp_plugin_id, /* >> */ + AEGP_StreamRefH streamH, /* >> */ + AEGP_StreamRefH *parent_streamPH); /* << must be disposed by caller! */ + + SPAPI A_Err (*AEGP_GetStreamIsModified)( // i.e. changed from defaults, like the UU key + AEGP_StreamRefH streamH, /* >> */ + A_Boolean *modifiedPB); /* << */ + +} AEGP_DynamicStreamSuite2; + +#define kAEGPDynamicStreamSuiteVersion3 3 /* frozen in AE 7.0 */ + +typedef struct AEGP_DynamicStreamSuite3 { + + SPAPI A_Err (*AEGP_GetNewStreamRefForLayer)( // used to start recursive walk of layer, + AEGP_PluginID aegp_plugin_id, /* >> */ + AEGP_LayerH layerH, /* >> */ + AEGP_StreamRefH *streamPH); /* << must be disposed by caller! */ + + SPAPI A_Err (*AEGP_GetStreamDepth)( // layer is depth 0 + AEGP_StreamRefH streamH, /* >> */ + A_long *depthPL); /* << */ + + + SPAPI A_Err (*AEGP_GetStreamGroupingType)( + AEGP_StreamRefH streamH, /* >> */ + AEGP_StreamGroupingType *group_typeP); /* << */ + + SPAPI A_Err (*AEGP_GetNumStreamsInGroup)( // error on leaf + AEGP_StreamRefH streamH, /* >> */ + A_long *num_streamsPL); /* << */ + + + SPAPI A_Err (*AEGP_GetDynamicStreamFlags)( + AEGP_StreamRefH streamH, /* >> */ + AEGP_DynStreamFlags *stream_flagsP); /* << */ + + SPAPI A_Err (*AEGP_SetDynamicStreamFlag)( + AEGP_StreamRefH streamH, /* >> */ + AEGP_DynStreamFlags one_flag, /* >> */ + A_Boolean undoableB, /* true if you want this to be an undoable change */ + /* if false, the only legal flag is AEGP_DynStreamFlag_HIDDEN */ + A_Boolean setB); /* >> */ + + + SPAPI A_Err (*AEGP_GetNewStreamRefByIndex)( // legal for namedgroup, indexedgroup, not leaf + AEGP_PluginID aegp_plugin_id, /* >> */ + AEGP_StreamRefH parent_groupH, /* >> */ + A_long indexL, /* >> */ + AEGP_StreamRefH *streamPH); /* << must be disposed by caller! */ + + SPAPI A_Err (*AEGP_GetNewStreamRefByMatchname)( // legal for namedgroup + AEGP_PluginID aegp_plugin_id, /* >> */ + AEGP_StreamRefH parent_groupH, /* >> */ + const A_char *match_nameZ, /* >> */ + AEGP_StreamRefH *streamPH); /* << must be disposed by caller! */ + + SPAPI A_Err (*AEGP_DeleteStream)( /* UNDOABLE, only valid for children of AEGP_StreamGroupingType_INDEXED_GROUP */ + AEGP_StreamRefH streamH); /* >> */ // must still dispose the streamref later + + SPAPI A_Err (*AEGP_ReorderStream)( /* UNDOABLE, only valid for children of AEGP_StreamGroupingType_INDEXED_GROUP */ + AEGP_StreamRefH streamH, /* <> updated to refer to newly ordered stream */ + A_long new_indexL); /* >> */ + + SPAPI A_Err (*AEGP_DuplicateStream)( /* UNDOABLE, only valid for children of AEGP_StreamGroupingType_INDEXED_GROUP */ + AEGP_PluginID aegp_plugin_id, /* >> */ + AEGP_StreamRefH streamH, /* >> */ + A_long *new_indexPL0); /* << */ + + /* GetStreamName is in main kAEGPStreamSuite, and works on dynamic streams including groups */ + + SPAPI A_Err (*AEGP_SetStreamName)( /* UNDOABLE, only valid for children of AEGP_StreamGroupingType_INDEXED_GROUP */ + AEGP_StreamRefH streamH, /* >> */ + const A_char *nameZ); /* >> */ + + SPAPI A_Err (*AEGP_CanAddStream)( + AEGP_StreamRefH group_streamH, /* >> */ + const A_char *match_nameZ, /* >> */ + A_Boolean *can_addPB); /* << */ + + SPAPI A_Err (*AEGP_AddStream)( /* UNDOABLE, only valid for AEGP_StreamGroupingType_INDEXED_GROUP */ + AEGP_PluginID aegp_plugin_id, /* >> */ + AEGP_StreamRefH indexed_group_streamH, /* >> */ + const A_char *match_nameZ, + AEGP_StreamRefH *streamPH0); /* << must be disposed by caller! */ + + SPAPI A_Err (*AEGP_GetMatchName)( + AEGP_StreamRefH streamH, /* >> */ + A_char *nameZ); /* << use A_char[AEGP_MAX_STREAM_MATCH_NAME_SIZE] for buffer */ + + SPAPI A_Err (*AEGP_GetNewParentStreamRef)( + AEGP_PluginID aegp_plugin_id, /* >> */ + AEGP_StreamRefH streamH, /* >> */ + AEGP_StreamRefH *parent_streamPH); /* << must be disposed by caller! */ + + SPAPI A_Err (*AEGP_GetStreamIsModified)( // i.e. changed from defaults, like the UU key + AEGP_StreamRefH streamH, /* >> */ + A_Boolean *modifiedPB); /* << */ + + SPAPI A_Err (*AEGP_GetStreamIndexInParent)( // only valid for children of AEGP_StreamGroupingType_INDEXED_GROUP + AEGP_StreamRefH streamH, /* >> */ + A_long *indexPL); /* << */ + + + +} AEGP_DynamicStreamSuite3; + + +#define kAEGPRenderOptionsSuite "AEGP Render Options Suite" +#define kAEGPRenderOptionsSuiteVersion3 3 /* frozen in AE 7.01 */ + +typedef struct { + // fills out + // Time to 0 + // Time step to the frame duration + // field render to none + // depth is best resolution of item + SPAPI A_Err (*AEGP_NewFromItem)( + AEGP_PluginID plugin_id, /* >> */ + AEGP_ItemH itemH, /* >> */ + AEGP_RenderOptionsH *optionsPH); /* << */ + + SPAPI A_Err (*AEGP_Duplicate)( + AEGP_PluginID plugin_id, /* >> */ + AEGP_RenderOptionsH optionsH, /* >> */ + AEGP_RenderOptionsH *copyPH); /* << */ + + SPAPI A_Err (*AEGP_Dispose)( + AEGP_RenderOptionsH optionsH); /* >> */ + + SPAPI A_Err (*AEGP_SetTime)( /* the render time */ + AEGP_RenderOptionsH optionsH, /* <> */ + A_Time time); /* >> */ + + SPAPI A_Err (*AEGP_GetTime)( + AEGP_RenderOptionsH optionsH, /* >> */ + A_Time *timeP); /* << */ + + SPAPI A_Err (*AEGP_SetTimeStep)( /* duration of the frame; important for motion blur. */ + AEGP_RenderOptionsH optionsH, /* <> */ + A_Time time_step); /* >> */ + + SPAPI A_Err (*AEGP_GetTimeStep)( + AEGP_RenderOptionsH optionsH, /* >> */ + A_Time *timePT); /* << */ + + SPAPI A_Err (*AEGP_SetFieldRender)( /* How fields are to be handled. */ + AEGP_RenderOptionsH optionsH, /* <> */ + PF_Field field_render); /* >> */ + + SPAPI A_Err (*AEGP_GetFieldRender)( + AEGP_RenderOptionsH optionsH, /* >> */ + PF_Field *field_renderP); /* << */ + + + SPAPI A_Err (*AEGP_SetWorldType)( + AEGP_RenderOptionsH optionsH, /* <> */ + AEGP_WorldType type); /* >> */ + + SPAPI A_Err (*AEGP_GetWorldType)( + AEGP_RenderOptionsH optionsH, /* >> */ + AEGP_WorldType *typeP); /* << */ + + + // 1 == 100% + // 2 == 50% + // ... + SPAPI A_Err (*AEGP_SetDownsampleFactor)( + AEGP_RenderOptionsH optionsH, /* <> */ + A_short x, /* >> */ + A_short y); /* >> */ + + SPAPI A_Err (*AEGP_GetDownsampleFactor)( + AEGP_RenderOptionsH optionsH, /* >> */ + A_short *xP, /* >> */ + A_short *yP); /* << */ + + SPAPI A_Err (*AEGP_SetRegionOfInterest)( + AEGP_RenderOptionsH optionsH, /* <> */ + const A_LRect *roiP); /* >> {0,0,0,0} for all*/ + + SPAPI A_Err (*AEGP_GetRegionOfInterest)( + AEGP_RenderOptionsH optionsH, /* >> */ + A_LRect *roiP); /* << */ + + SPAPI A_Err (*AEGP_SetMatteMode)( + AEGP_RenderOptionsH optionsH, /* <> */ + AEGP_MatteMode mode); /* >> */ + + SPAPI A_Err (*AEGP_GetMatteMode)( + AEGP_RenderOptionsH optionsH, /* >> */ + AEGP_MatteMode *modeP); /* << */ + + SPAPI A_Err (*AEGP_SetChannelOrder)( + AEGP_RenderOptionsH optionsH, /* <> */ + AEGP_ChannelOrder channel_order); /* >> */ + + SPAPI A_Err (*AEGP_GetChannelOrder)( + AEGP_RenderOptionsH optionsH, /* >> */ + AEGP_ChannelOrder *channelP); /* << */ + + SPAPI A_Err (*AEGP_GetRenderGuideLayers)( + AEGP_RenderOptionsH optionsH, /* >> */ + A_Boolean *will_renderPB); /* << */ + + SPAPI A_Err (*AEGP_SetRenderGuideLayers)( + AEGP_RenderOptionsH optionsH, /* >> */ + A_Boolean render_themB); /* >> */ + +} AEGP_RenderOptionsSuite3; + + +#define kAEGPRenderOptionsSuite "AEGP Render Options Suite" +#define kAEGPRenderOptionsSuiteVersion2 2 /* frozen in AE 7.0 */ + +typedef struct { + // fills out + // Time to 0 + // Time step to the frame duration + // field render to none + // depth is best resolution of item + SPAPI A_Err (*AEGP_NewFromItem)( + AEGP_PluginID plugin_id, /* >> */ + AEGP_ItemH itemH, /* >> */ + AEGP_RenderOptionsH *optionsPH); /* << */ + + SPAPI A_Err (*AEGP_Duplicate)( + AEGP_PluginID plugin_id, /* >> */ + AEGP_RenderOptionsH optionsH, /* >> */ + AEGP_RenderOptionsH *copyPH); /* << */ + + SPAPI A_Err (*AEGP_Dispose)( + AEGP_RenderOptionsH optionsH); /* >> */ + + SPAPI A_Err (*AEGP_SetTime)( /* the render time */ + AEGP_RenderOptionsH optionsH, /* <> */ + A_Time time); /* >> */ + + SPAPI A_Err (*AEGP_GetTime)( + AEGP_RenderOptionsH optionsH, /* >> */ + A_Time *timeP); /* << */ + + SPAPI A_Err (*AEGP_SetTimeStep)( /* duration of the frame; important for motion blur. */ + AEGP_RenderOptionsH optionsH, /* <> */ + A_Time time_step); /* >> */ + + SPAPI A_Err (*AEGP_GetTimeStep)( + AEGP_RenderOptionsH optionsH, /* >> */ + A_Time *timePT); /* << */ + + SPAPI A_Err (*AEGP_SetFieldRender)( /* How fields are to be handled. */ + AEGP_RenderOptionsH optionsH, /* <> */ + PF_Field field_render); /* >> */ + + SPAPI A_Err (*AEGP_GetFieldRender)( + AEGP_RenderOptionsH optionsH, /* >> */ + PF_Field *field_renderP); /* << */ + + + SPAPI A_Err (*AEGP_SetWorldType)( + AEGP_RenderOptionsH optionsH, /* <> */ + AEGP_WorldType type); /* >> */ + + SPAPI A_Err (*AEGP_GetWorldType)( + AEGP_RenderOptionsH optionsH, /* >> */ + AEGP_WorldType *typeP); /* << */ + + + // 1 == 100% + // 2 == 50% + // ... + SPAPI A_Err (*AEGP_SetDownsampleFactor)( + AEGP_RenderOptionsH optionsH, /* <> */ + A_short x, /* >> */ + A_short y); /* >> */ + + SPAPI A_Err (*AEGP_GetDownsampleFactor)( + AEGP_RenderOptionsH optionsH, /* >> */ + A_short *xP, /* >> */ + A_short *yP); /* << */ + + SPAPI A_Err (*AEGP_SetRegionOfInterest)( + AEGP_RenderOptionsH optionsH, /* <> */ + const A_LRect *roiP); /* >> {0,0,0,0} for all*/ + + SPAPI A_Err (*AEGP_GetRegionOfInterest)( + AEGP_RenderOptionsH optionsH, /* >> */ + A_LRect *roiP); /* << */ + + SPAPI A_Err (*AEGP_SetMatteMode)( + AEGP_RenderOptionsH optionsH, /* <> */ + AEGP_MatteMode mode); /* >> */ + + SPAPI A_Err (*AEGP_GetMatteMode)( + AEGP_RenderOptionsH optionsH, /* >> */ + AEGP_MatteMode *modeP); /* << */ + + SPAPI A_Err (*AEGP_SetChannelOrder)( + AEGP_RenderOptionsH optionsH, /* <> */ + AEGP_ChannelOrder channel_order); /* >> */ + + SPAPI A_Err (*AEGP_GetChannelOrder)( + AEGP_RenderOptionsH optionsH, /* >> */ + AEGP_ChannelOrder *channelP); /* << */ +} AEGP_RenderOptionsSuite2; + + +#define kAEGPRenderOptionsSuite "AEGP Render Options Suite" +#define kAEGPRenderOptionsSuiteVersion1 1 /* frozen in AE 5.5.1 */ + +typedef struct { + // fills out + // Time to 0 + // Time step to the frame duration + // field render to none + // depth is best resolution of item + SPAPI A_Err (*AEGP_NewFromItem)( + AEGP_PluginID plugin_id, /* >> */ + AEGP_ItemH itemH, /* >> */ + AEGP_RenderOptionsH *optionsPH); /* << */ + + SPAPI A_Err (*AEGP_Duplicate)( + AEGP_PluginID plugin_id, /* >> */ + AEGP_RenderOptionsH optionsH, /* >> */ + AEGP_RenderOptionsH *copyPH); /* << */ + + SPAPI A_Err (*AEGP_Dispose)( + AEGP_RenderOptionsH optionsH); /* >> */ + + SPAPI A_Err (*AEGP_SetTime)( /* the render time */ + AEGP_RenderOptionsH optionsH, /* <> */ + A_Time time); /* >> */ + + SPAPI A_Err (*AEGP_GetTime)( + AEGP_RenderOptionsH optionsH, /* >> */ + A_Time *timeP); /* << */ + + SPAPI A_Err (*AEGP_SetTimeStep)( /* duration of the frame; important for motion blur. */ + AEGP_RenderOptionsH optionsH, /* <> */ + A_Time time_step); /* >> */ + + SPAPI A_Err (*AEGP_GetTimeStep)( + AEGP_RenderOptionsH optionsH, /* >> */ + A_Time *timePT); /* << */ + + SPAPI A_Err (*AEGP_SetFieldRender)( /* How fields are to be handled. */ + AEGP_RenderOptionsH optionsH, /* <> */ + PF_Field field_render); /* >> */ + + SPAPI A_Err (*AEGP_GetFieldRender)( + AEGP_RenderOptionsH optionsH, /* >> */ + PF_Field *field_renderP); /* << */ + + + SPAPI A_Err (*AEGP_SetWorldType)( + AEGP_RenderOptionsH optionsH, /* <> */ + AEGP_WorldType type); /* >> */ + + SPAPI A_Err (*AEGP_GetWorldType)( + AEGP_RenderOptionsH optionsH, /* >> */ + AEGP_WorldType *typeP); /* << */ + + + // 1 == 100% + // 2 == 50% + // ... + SPAPI A_Err (*AEGP_SetDownsampleFactor)( + AEGP_RenderOptionsH optionsH, /* <> */ + A_short x, /* >> */ + A_short y); /* >> */ + + SPAPI A_Err (*AEGP_GetDownsampleFactor)( + AEGP_RenderOptionsH optionsH, /* >> */ + A_short *xP, /* >> */ + A_short *yP); /* << */ + + SPAPI A_Err (*AEGP_SetRegionOfInterest)( + AEGP_RenderOptionsH optionsH, /* <> */ + const A_LRect *roiP); /* >> {0,0,0,0} for all*/ + + SPAPI A_Err (*AEGP_GetRegionOfInterest)( + AEGP_RenderOptionsH optionsH, /* >> */ + A_LRect *roiP); /* << */ + + SPAPI A_Err (*AEGP_SetMatteMode)( + AEGP_RenderOptionsH optionsH, /* <> */ + AEGP_MatteMode mode); /* >> */ + + SPAPI A_Err (*AEGP_GetMatteMode)( + AEGP_RenderOptionsH optionsH, /* >> */ + AEGP_MatteMode *modeP); /* << */ + +} AEGP_RenderOptionsSuite1; + + + + +#define kAEGPLayerRenderOptionsSuite "AEGP Layer Render Options Suite" +#define kAEGPLayerRenderOptionsSuiteVersion1 1 /* frozen in 13.0 */ + +typedef struct { + // optionsPH must be disposed by calling code + // + // fills out + // Time to the layer's current time + // Time step to layer's frame duration + // ROI to the layer's nominal bounds + // EffectsToRender to "all" + SPAPI A_Err (*AEGP_NewFromLayer)( + AEGP_PluginID plugin_id, /* >> */ + AEGP_LayerH layerH, /* >> */ + AEGP_LayerRenderOptionsH *optionsPH); /* << */ + + // optionsPH must be disposed by calling code + // like AEGP_NewFromLayer, but sets EffectsToRender to be the index fof effectH + SPAPI A_Err (*AEGP_NewFromUpstreamOfEffect)( + AEGP_PluginID plugin_id, /* >> */ + AEGP_EffectRefH effectH, /* >> */ + AEGP_LayerRenderOptionsH *optionsPH); /* << */ + + // copyPH must be disposed by calling code + SPAPI A_Err (*AEGP_Duplicate)( + AEGP_PluginID plugin_id, /* >> */ + AEGP_LayerRenderOptionsH optionsH, /* >> */ + AEGP_LayerRenderOptionsH *copyPH); /* << */ + + SPAPI A_Err (*AEGP_Dispose)( + AEGP_LayerRenderOptionsH optionsH); /* >> */ + + SPAPI A_Err (*AEGP_SetTime)( /* the render time */ + AEGP_LayerRenderOptionsH optionsH, /* <> */ + A_Time time); /* >> */ + + SPAPI A_Err (*AEGP_GetTime)( + AEGP_LayerRenderOptionsH optionsH, /* >> */ + A_Time *timeP); /* << */ + + SPAPI A_Err (*AEGP_SetTimeStep)( /* duration of the frame; important for motion blur. */ + AEGP_LayerRenderOptionsH optionsH, /* <> */ + A_Time time_step); /* >> */ + + SPAPI A_Err (*AEGP_GetTimeStep)( + AEGP_LayerRenderOptionsH optionsH, /* >> */ + A_Time *timePT); /* << */ + + SPAPI A_Err (*AEGP_SetWorldType)( + AEGP_LayerRenderOptionsH optionsH, /* <> */ + AEGP_WorldType type); /* >> */ + + SPAPI A_Err (*AEGP_GetWorldType)( + AEGP_LayerRenderOptionsH optionsH, /* >> */ + AEGP_WorldType *typeP); /* << */ + + // 1 == 100% + // 2 == 50% + // ... + SPAPI A_Err (*AEGP_SetDownsampleFactor)( + AEGP_LayerRenderOptionsH optionsH, /* <> */ + A_short x, /* >> */ + A_short y); /* >> */ + + SPAPI A_Err (*AEGP_GetDownsampleFactor)( + AEGP_LayerRenderOptionsH optionsH, /* >> */ + A_short *xP, /* >> */ + A_short *yP); /* << */ + + SPAPI A_Err (*AEGP_SetMatteMode)( + AEGP_LayerRenderOptionsH optionsH, /* <> */ + AEGP_MatteMode mode); /* >> */ + + SPAPI A_Err (*AEGP_GetMatteMode)( + AEGP_LayerRenderOptionsH optionsH, /* >> */ + AEGP_MatteMode *modeP); /* << */ +} AEGP_LayerRenderOptionsSuite1; + + + + +#define kAEGPColorSettingsSuiteVersion1 1 // frozen in AE 7.0 + +typedef struct AEGP_ColorSettingsSuite1 { + + SPAPI A_Err (*AEGP_GetBlendingTables)( + PR_RenderContextH render_contextH, + PF_EffectBlendingTables *blending_tables); + +} AEGP_ColorSettingsSuite1; + +#define kAEGPColorSettingsSuiteVersion2 3 // frozen in AE 8.0 + +typedef struct AEGP_ColorSettingsSuite2 { + + SPAPI A_Err (*AEGP_GetBlendingTables)( + PR_RenderContextH render_contextH, + PF_EffectBlendingTables *blending_tables); + + SPAPI A_Err (*AEGP_DoesViewHaveColorSpaceXform)( + AEGP_ItemViewP viewP, // >> + A_Boolean *has_xformPB); // << + + SPAPI A_Err (*AEGP_XformWorkingToViewColorSpace)( + AEGP_ItemViewP viewP, // >> + AEGP_WorldH srcH, // in + AEGP_WorldH dstH); // out; must be the same size (can be the same as source) + + SPAPI A_Err (*AEGP_GetNewWorkingSpaceColorProfile)( + AEGP_PluginID aegp_plugin_id, // >> + AEGP_CompH compH, // >> + AEGP_ColorProfileP *color_profilePP); // << caller must dispose with AEGP_DisposeColorProfile + + SPAPI A_Err (*AEGP_GetNewColorProfileFromICCProfile)( + AEGP_PluginID aegp_plugin_id, // >> + A_long icc_sizeL, // >> icc profile size + const void *icc_dataPV, // >> icc profile + AEGP_ColorProfileP *color_profilePP); // << builds AEGP_ColorProfile from icc profile; caller must dispose with AEGP_DisposeColorProfile + + SPAPI A_Err (*AEGP_GetNewICCProfileFromColorProfile)( + AEGP_PluginID aegp_plugin_id, // >> + AEGP_ConstColorProfileP color_profileP, // >> + AEGP_MemHandle *icc_profilePH); // << extract icc profile from AEGP_ColorProfile; caller must dispose with AEGP_FreeMemHandle + + SPAPI A_Err (*AEGP_GetNewColorProfileDescription)( + AEGP_PluginID aegp_plugin_id, // >> + AEGP_ConstColorProfileP color_profileP, // >> + AEGP_MemHandle *unicode_descPH); // << handle of A_UTF16Char (contains null terminated UTF16 string); must be disposed with AEGP_FreeMemHandle + + SPAPI A_Err (*AEGP_DisposeColorProfile)( + AEGP_ColorProfileP color_profileP); // >> + + SPAPI A_Err (*AEGP_GetColorProfileApproximateGamma)( + AEGP_ConstColorProfileP color_profileP, // >> + A_FpShort *approx_gammaP); // << + + SPAPI A_Err (*AEGP_IsRGBColorProfile)( + AEGP_ConstColorProfileP color_profileP, // << + A_Boolean *is_rgbPB); // >> + + +} AEGP_ColorSettingsSuite2; + +#define kAEGPMarkerSuiteVersion1 1 /* frozen in AE 8.0 */ + +typedef struct AEGP_MarkerSuite1 { + + SPAPI A_Err (*AEGP_NewMarker)( + AEGP_MarkerValP *markerPP); + + SPAPI A_Err (*AEGP_DisposeMarker)( + AEGP_MarkerValP markerP); + + SPAPI A_Err (*AEGP_DuplicateMarker)( + AEGP_MarkerValP markerP, // >> + AEGP_MarkerValP *new_markerP); // << + + SPAPI A_Err (*AEGP_SetMarkerFlag)( + AEGP_MarkerValP markerP, // >> + AEGP_MarkerFlagType flagType, // >> + A_Boolean valueB); // >> + + SPAPI A_Err (*AEGP_GetMarkerFlag)( + AEGP_ConstMarkerValP markerP, // >> + AEGP_MarkerFlagType flagType, // >> + A_Boolean *valueBP); // << + + SPAPI A_Err (*AEGP_GetMarkerString)( + AEGP_PluginID aegp_plugin_id, /* >> */ + AEGP_ConstMarkerValP markerP, // >> + AEGP_MarkerStringType strType, // >> + AEGP_MemHandle *unicodePH); /* << handle of A_u_short, UTF16, NULL terminated, must be disposed with AEGP_FreeMemHandle */ + + SPAPI A_Err (*AEGP_SetMarkerString)( + AEGP_MarkerValP markerP, // <<>> + AEGP_MarkerStringType strType, // >> + const A_u_short *unicodeP, // >> + A_long lengthL); // >> number of characters + + SPAPI A_Err (*AEGP_CountCuePointParams)( + AEGP_ConstMarkerValP markerP, // >> + A_long *paramsLP); // << + + SPAPI A_Err (*AEGP_GetIndCuePointParam)( + AEGP_PluginID aegp_plugin_id, // >> + AEGP_ConstMarkerValP markerP, // >> + A_long param_indexL, // >> must be between 0 and count - 1. else error + AEGP_MemHandle *unicodeKeyPH, // << handle of A_u_short, UTF16, NULL terminated, must be disposed with AEGP_FreeMemHandle + AEGP_MemHandle *unicodeValuePH); // << handle of A_u_short, UTF16, NULL terminated, must be disposed with AEGP_FreeMemHandle + + SPAPI A_Err (*AEGP_SetIndCuePointParam)( + AEGP_MarkerValP markerP, // >> + A_long param_indexL, // must be between 0 and count - 1. else error + const A_u_short *unicodeKeyP, // >> UTF16 + A_long key_lengthL, // >> number of characters + const A_u_short *unicodeValueP, // >> UTF16 + A_long value_lengthL); // >> number of characters + + // this call is followed by AEGP_SetIndCuePointParam() to actually set the data + // the ONLY thing this function does is reserve the space for the param, at the provided index + SPAPI A_Err (*AEGP_InsertCuePointParam)( + AEGP_MarkerValP markerP, // >> + A_long param_indexL); // must be between 0 and count. else error + + SPAPI A_Err (*AEGP_DeleteIndCuePointParam)( + AEGP_MarkerValP markerP, // >> + A_long param_indexL); // must be between 0 and count - 1. else error + +} AEGP_MarkerSuite1; + +#define kAEGPMarkerSuiteVersion2 2 /* frozen in AE 9.0 */ + +typedef struct AEGP_MarkerSuite2 { + + SPAPI A_Err (*AEGP_NewMarker)( + AEGP_MarkerValP *markerPP); + + SPAPI A_Err (*AEGP_DisposeMarker)( + AEGP_MarkerValP markerP); + + SPAPI A_Err (*AEGP_DuplicateMarker)( + AEGP_MarkerValP markerP, // >> + AEGP_MarkerValP *new_markerP); // << + + SPAPI A_Err (*AEGP_SetMarkerFlag)( + AEGP_MarkerValP markerP, // >> + AEGP_MarkerFlagType flagType, // >> + A_Boolean valueB); // >> + + SPAPI A_Err (*AEGP_GetMarkerFlag)( + AEGP_ConstMarkerValP markerP, // >> + AEGP_MarkerFlagType flagType, // >> + A_Boolean *valueBP); // << + + SPAPI A_Err (*AEGP_GetMarkerString)( + AEGP_PluginID aegp_plugin_id, /* >> */ + AEGP_ConstMarkerValP markerP, // >> + AEGP_MarkerStringType strType, // >> + AEGP_MemHandle *unicodePH); /* << handle of A_u_short, UTF16, NULL terminated, must be disposed with AEGP_FreeMemHandle */ + + SPAPI A_Err (*AEGP_SetMarkerString)( + AEGP_MarkerValP markerP, // <<>> + AEGP_MarkerStringType strType, // >> + const A_u_short *unicodeP, // >> + A_long lengthL); // >> number of characters + + SPAPI A_Err (*AEGP_CountCuePointParams)( + AEGP_ConstMarkerValP markerP, // >> + A_long *paramsLP); // << + + SPAPI A_Err (*AEGP_GetIndCuePointParam)( + AEGP_PluginID aegp_plugin_id, // >> + AEGP_ConstMarkerValP markerP, // >> + A_long param_indexL, // >> must be between 0 and count - 1. else error + AEGP_MemHandle *unicodeKeyPH, // << handle of A_u_short, UTF16, NULL terminated, must be disposed with AEGP_FreeMemHandle + AEGP_MemHandle *unicodeValuePH); // << handle of A_u_short, UTF16, NULL terminated, must be disposed with AEGP_FreeMemHandle + + SPAPI A_Err (*AEGP_SetIndCuePointParam)( + AEGP_MarkerValP markerP, // >> + A_long param_indexL, // must be between 0 and count - 1. else error + const A_u_short *unicodeKeyP, // >> UTF16 + A_long key_lengthL, // >> number of characters + const A_u_short *unicodeValueP, // >> UTF16 + A_long value_lengthL); // >> number of characters + + // this call is followed by AEGP_SetIndCuePointParam() to actually set the data + // the ONLY thing this function does is reserve the space for the param, at the provided index + SPAPI A_Err (*AEGP_InsertCuePointParam)( + AEGP_MarkerValP markerP, // >> + A_long param_indexL); // must be between 0 and count. else error + + SPAPI A_Err (*AEGP_DeleteIndCuePointParam)( + AEGP_MarkerValP markerP, // >> + A_long param_indexL); // must be between 0 and count - 1. else error + + SPAPI A_Err (*AEGP_SetMarkerDuration)( + AEGP_MarkerValP markerP, // >> + const A_Time *durationPT); // >> + + + SPAPI A_Err (*AEGP_GetMarkerDuration)( + AEGP_ConstMarkerValP markerP, // >> + A_Time *durationPT); // << + + +} AEGP_MarkerSuite2; + +#define kAEGPProjSuiteVersion5 8 /* frozen in AE 10.0 */ + +typedef struct AEGP_ProjSuite5 { + + SPAPI A_Err (*AEGP_GetNumProjects)( /* will always (in 5.0) return 1 if project is open */ + A_long *num_projPL); /* << */ + + SPAPI A_Err (*AEGP_GetProjectByIndex)( + A_long proj_indexL, /* >> */ + AEGP_ProjectH *projPH); /* << */ + + SPAPI A_Err (*AEGP_GetProjectName)( + AEGP_ProjectH projH, /* >> */ + A_char *nameZ); /* << space for A_char[AEGP_MAX_PROJ_NAME_SIZE] */ + + SPAPI A_Err (*AEGP_GetProjectPath)( + AEGP_ProjectH projH, /* >> */ + AEGP_MemHandle *unicode_pathPH); // << empty string if no file. handle of A_UTF16Char (contains null terminated UTF16 string); must be disposed with AEGP_FreeMemHandle + + SPAPI A_Err (*AEGP_GetProjectRootFolder)( + AEGP_ProjectH projH, /* >> */ + AEGP_ItemH *root_folderPH); /* << */ + + SPAPI A_Err (*AEGP_SaveProjectToPath)( + AEGP_ProjectH projH, /* >> */ + const A_UTF16Char *pathZ); // >> null terminated unicode path with platform separators + + SPAPI A_Err (*AEGP_GetProjectTimeDisplay)( + AEGP_ProjectH projH, /* >> */ + AEGP_TimeDisplay2 *time_displayP); /* << */ + + SPAPI A_Err (*AEGP_SetProjectTimeDisplay)( /* UNDOABLE */ + AEGP_ProjectH projH, /* <> */ + const AEGP_TimeDisplay2 *time_displayP); /* >> */ + + SPAPI A_Err (*AEGP_ProjectIsDirty)( + AEGP_ProjectH projH, /* >> */ + A_Boolean *is_dirtyPB); /* << */ + + SPAPI A_Err (*AEGP_SaveProjectAs)( + AEGP_ProjectH projH, /* >> */ + const A_UTF16Char *pathZ); // >> null terminated unicode path with platform separators + + SPAPI A_Err (*AEGP_NewProject)( + AEGP_ProjectH *new_projectPH); /* << WARNING: Will close any open projects! */ + + // WARNING: Will close any open projects! + SPAPI A_Err (*AEGP_OpenProjectFromPath)( + const A_UTF16Char *pathZ, // >> null terminated unicode path with platform separators + AEGP_ProjectH *projectPH); /* << */ + + SPAPI A_Err (*AEGP_GetProjectBitDepth)( + AEGP_ProjectH projectH, /* >> */ + AEGP_ProjBitDepth *bit_depthP); /* << */ + + SPAPI A_Err (*AEGP_SetProjectBitDepth)( /* UNDOABLE */ + AEGP_ProjectH projectH, /* >> */ + AEGP_ProjBitDepth bit_depth); /* >> */ + +} AEGP_ProjSuite5; + +#define kAEGPPersistentDataSuiteVersion3 3 /* frozen in AE 10.0 */ + +typedef struct { + // get a handle of the application blob, + // modifying this will modify the application + SPAPI A_Err (*AEGP_GetApplicationBlob)( + AEGP_PersistentBlobH *blobPH); /* >> */ + + // section and value key management + SPAPI A_Err (*AEGP_GetNumSections)( + AEGP_PersistentBlobH blobH, /* >> */ + A_long *num_sectionPL); /* << */ + + SPAPI A_Err (*AEGP_GetSectionKeyByIndex)( + AEGP_PersistentBlobH blobH, /* >> */ + A_long section_index, /* >> */ + A_long max_section_size, /* >> */ + A_char *section_keyZ); /* << */ + + SPAPI A_Err (*AEGP_DoesKeyExist)( + AEGP_PersistentBlobH blobH, /* >> */ + const A_char *section_keyZ, /* >> */ + const A_char *value_keyZ, /* >> */ + A_Boolean *existsPB); /* << */ + + SPAPI A_Err (*AEGP_GetNumKeys)( + AEGP_PersistentBlobH blobH, /* >> */ + const A_char *section_keyZ, /* >> */ + A_long *num_keysPL); /* << */ + + SPAPI A_Err (*AEGP_GetValueKeyByIndex)( + AEGP_PersistentBlobH blobH, /* >> */ + const A_char *section_keyZ, /* >> */ + A_long key_index, /* >> */ + A_long max_key_size, /* >> */ + A_char *value_keyZ); /* << */ + + // data access and manipulation + + // For the entry points below, if a given key is not found, + // the default value is both written to the blobH and + // returned as the value; if no default is provided, a blank value will be written + // and returned + + SPAPI A_Err (*AEGP_GetDataHandle)( + AEGP_PluginID plugin_id, + AEGP_PersistentBlobH blobH, /* >> */ + const A_char *section_keyZ, /* >> */ + const A_char *value_keyZ, /* >> */ + AEGP_MemHandle defaultH0, /* >> never adopted, NULL means no default data */ + AEGP_MemHandle *valuePH); /* << newly allocated, owned by caller, NULL if would be zero sized handle */ + + SPAPI A_Err (*AEGP_GetData)( + AEGP_PersistentBlobH blobH, /* >> */ + const A_char *section_keyZ, /* >> */ + const A_char *value_keyZ, /* >> */ + A_u_long data_sizeLu, /* >> bufPV & default must be this big, if pref isn't then the default will be used */ + const void *defaultPV0, /* >> NULL means all zeros for default */ + void *bufPV); /* << */ + + SPAPI A_Err (*AEGP_GetString)( + AEGP_PersistentBlobH blobH, /* >> */ + const A_char *section_keyZ, /* >> */ + const A_char *value_keyZ, /* >> */ + const A_char *defaultZ0, /* >> NULL means '\0' is the default */ + A_u_long buf_sizeLu, /* >> size of buffer. Behavior dependent on actual_buf_sizeLu0 */ + A_char *bufZ, /* << will be "" if buf_size is too small */ + A_u_long *actual_buf_sizeLu0); /* << actual size needed to store the buffer (includes terminating NULL). Pass NULL for error reporting if size mismatch.*/ + + SPAPI A_Err (*AEGP_GetLong)( + AEGP_PersistentBlobH blobH, /* >> */ + const A_char *section_keyZ, /* >> */ + const A_char *value_keyZ, /* >> */ + A_long defaultL, /* >> */ + A_long *valuePL); /* << */ + + SPAPI A_Err (*AEGP_GetFpLong)( + AEGP_PersistentBlobH blobH, /* >> */ + const A_char *section_keyZ, /* >> */ + const A_char *value_keyZ, /* >> */ + A_FpLong defaultF, /* >> */ + A_FpLong *valuePF); /* << */ + + // setters + SPAPI A_Err (*AEGP_SetDataHandle)( + AEGP_PersistentBlobH blobH, /* >> */ + const A_char *section_keyZ, /* >> */ + const A_char *value_keyZ, /* >> */ + const AEGP_MemHandle valueH); /* >> not adopted */ + + SPAPI A_Err (*AEGP_SetData)( + AEGP_PersistentBlobH blobH, /* >> */ + const A_char *section_keyZ, /* >> */ + const A_char *value_keyZ, /* >> */ + A_u_long data_sizeLu, /* >> */ + const void *dataPV); /* >> */ + + SPAPI A_Err (*AEGP_SetString)( + AEGP_PersistentBlobH blobH, /* >> */ + const A_char *section_keyZ, /* >> */ + const A_char *value_keyZ, /* >> */ + const A_char *strZ); /* >> */ + + SPAPI A_Err (*AEGP_SetLong)( + AEGP_PersistentBlobH blobH, /* >> */ + const A_char *section_keyZ, /* >> */ + const A_char *value_keyZ, /* >> */ + A_long valueL); /* >> */ + + + SPAPI A_Err (*AEGP_SetFpLong)( + AEGP_PersistentBlobH blobH, /* >> */ + const A_char *section_keyZ, /* >> */ + const A_char *value_keyZ, /* >> */ + A_FpLong valueF); /* >> */ + + SPAPI A_Err (*AEGP_DeleteEntry)( /* no error if entry not found */ + AEGP_PersistentBlobH blobH, /* >> */ + const A_char *section_keyZ, /* >> */ + const A_char *value_keyZ); /* >> */ + + SPAPI A_Err (*AEGP_GetPrefsDirectory)( + AEGP_MemHandle *unicode_pathPH); // << empty string if no file. handle of A_UTF16Char (contains null terminated UTF16 string); must be disposed with AEGP_FreeMemHandle + +} AEGP_PersistentDataSuite3; + +#define kAEGPIterateSuite "AEGP Iterate Suite" +#define kAEGPIterateSuiteVersion1 1 /* frozen in AE 5.0 */ + +typedef struct AEGP_IterateSuite1 { + + SPAPI A_Err(*AEGP_GetNumThreads)( + A_long* num_threadsPL); + + + SPAPI A_Err(*AEGP_IterateGeneric)( + A_long iterationsL, /* >> */ // can be PF_Iterations_ONCE_PER_PROCESSOR + void* refconPV, /* >> */ + A_Err(*fn_func)(void* refconPV, /* >> */ + A_long thread_indexL, /* >> */ + A_long i, /* >> */ + A_long iterationsL)); /* >> */ + +} AEGP_IterateSuite1; + +#define kAEGPIOInSuite "AEGP IO In Suite" +#define kAEGPIOInSuiteVersion4 5 /* frozen in AE 10 */ + +typedef struct AEGP_IOInSuite4 { + + SPAPI A_Err (*AEGP_GetInSpecOptionsHandle)( + AEIO_InSpecH inH, /* >> */ + void **optionsPPV); /* << */ + + SPAPI A_Err (*AEGP_SetInSpecOptionsHandle)( + AEIO_InSpecH inH, /* >> */ + void *optionsPV, /* >> */ + void **old_optionsPPV); /* << */ + + SPAPI A_Err (*AEGP_GetInSpecFilePath)( + AEIO_InSpecH inH, /* >> */ + AEGP_MemHandle *unicode_pathPH); // << handle of A_UTF16Char (contains null terminated UTF16 string); must be disposed with AEGP_FreeMemHandle + + SPAPI A_Err (*AEGP_GetInSpecNativeFPS)( + AEIO_InSpecH inH, /* >> */ + A_Fixed *native_fpsP); /* << */ + + SPAPI A_Err (*AEGP_SetInSpecNativeFPS)( + AEIO_InSpecH inH, /* >> */ + A_Fixed native_fps); /* >> */ + + SPAPI A_Err (*AEGP_GetInSpecDepth)( + AEIO_InSpecH inH, /* >> */ + A_short *depthPS); /* << */ + + SPAPI A_Err (*AEGP_SetInSpecDepth)( + AEIO_InSpecH inH, /* >> */ + A_short depthS); /* >> */ + + SPAPI A_Err (*AEGP_GetInSpecSize)( + AEIO_InSpecH inH, /* >> */ + AEIO_FileSize *sizePL); /* << */ + + SPAPI A_Err (*AEGP_SetInSpecSize)( + AEIO_InSpecH inH, /* >> */ + AEIO_FileSize sizeL); /* >> */ + + SPAPI A_Err (*AEGP_GetInSpecInterlaceLabel)( + AEIO_InSpecH inH, /* >> */ + FIEL_Label *interlaceP); /* << */ + + SPAPI A_Err (*AEGP_SetInSpecInterlaceLabel)( + AEIO_InSpecH inH, /* >> */ + const FIEL_Label *interlaceP); /* << */ + + SPAPI A_Err (*AEGP_GetInSpecAlphaLabel)( + AEIO_InSpecH inH, /* >> */ + AEIO_AlphaLabel *alphaP); /* << */ + + SPAPI A_Err (*AEGP_SetInSpecAlphaLabel)( + AEIO_InSpecH inH, /* >> */ + const AEIO_AlphaLabel *alphaP); /* << */ + + SPAPI A_Err (*AEGP_GetInSpecDuration)( + AEIO_InSpecH inH, /* >> */ + A_Time *durationP); /* << */ + + SPAPI A_Err (*AEGP_SetInSpecDuration)( + AEIO_InSpecH inH, /* >> */ + const A_Time *durationP); /* >> */ + + SPAPI A_Err (*AEGP_GetInSpecDimensions)( + AEIO_InSpecH inH, /* >> */ + A_long *widthPL0, /* << */ + A_long *heightPL0); + + SPAPI A_Err (*AEGP_SetInSpecDimensions)( + AEIO_InSpecH inH, /* >> */ + A_long widthL, /* >> */ + A_long heightL); /* >> */ + + SPAPI A_Err (*AEGP_InSpecGetRationalDimensions)( + AEIO_InSpecH inH, /* >> */ + const AEIO_RationalScale *rs0, /* << */ + A_long *width0, /* << */ + A_long *height0, /* << */ + A_Rect *r0); /* << */ + + SPAPI A_Err (*AEGP_GetInSpecHSF)( + AEIO_InSpecH inH, /* >> */ + A_Ratio *hsfP); /* << */ + + SPAPI A_Err (*AEGP_SetInSpecHSF)( + AEIO_InSpecH inH, /* >> */ + const A_Ratio *hsfP); /* >> */ + + SPAPI A_Err (*AEGP_GetInSpecSoundRate)( + AEIO_InSpecH inH, /* >> */ + A_FpLong *ratePF); /* << */ + + SPAPI A_Err (*AEGP_SetInSpecSoundRate)( + AEIO_InSpecH inH, /* >> */ + A_FpLong rateF); /* >> */ + + SPAPI A_Err (*AEGP_GetInSpecSoundEncoding)( + AEIO_InSpecH inH, /* >> */ + AEIO_SndEncoding *encodingP); /* << */ + + SPAPI A_Err (*AEGP_SetInSpecSoundEncoding)( + AEIO_InSpecH inH, /* >> */ + AEIO_SndEncoding encoding); /* >> */ + + SPAPI A_Err (*AEGP_GetInSpecSoundSampleSize)( + AEIO_InSpecH inH, /* >> */ + AEIO_SndSampleSize *bytes_per_sampleP);/* << */ + + SPAPI A_Err (*AEGP_SetInSpecSoundSampleSize)( + AEIO_InSpecH inH, /* >> */ + AEIO_SndSampleSize bytes_per_sample); /* >> */ + + SPAPI A_Err (*AEGP_GetInSpecSoundChannels)( + AEIO_InSpecH inH, /* >> */ + AEIO_SndChannels *num_channelsP); /* << */ + + SPAPI A_Err (*AEGP_SetInSpecSoundChannels)( + AEIO_InSpecH inH, /* >> */ + AEIO_SndChannels num_channels); /* >> */ + + SPAPI A_Err (*AEGP_AddAuxExtMap)( + const A_char *extension, /* >> */ + A_long file_type, /* >> */ + A_long creator); /* >> */ + + // In case of RGB data, if there is an embedded icc profile, build AEGP_ColorProfile out of this icc profile using AEGP_GetNewColorProfileFromICCProfile and pass it to + // AEGP_SetInSpecEmbeddedColorProfile, with profile description set to NULL. + // + // In case of non-RGB data, if there is an embedded non-RGB icc profile or you know the color space the data is in, pass its description as a null-terminated unicode string + // to AEGP_SetInSpecEmbeddedColorProfile, with color profile set to NULL. Doing this disables color management UI that allows user to affect + // profile choice in the application UI. + // + // If you are unpacking non-RGB data directly into working space (to get working space use AEGP_GetNewWorkingSpaceColorProfile), you are done. + // + // If you are unpacking non-RGB data into specific RGB color space, you must pass the profile describing this space to AEGP_SetInSpecAssignedColorProfile. + // Otherwise, your RGB data will be incorrectly interpreted as being in working space. + // + // Either color profile or profile description should be NULL in AEGP_SetInSpecEmbeddedColorProfile. You cannot use both. + SPAPI A_Err (*AEGP_SetInSpecEmbeddedColorProfile)( + AEIO_InSpecH inH, // << + AEGP_ConstColorProfileP color_profileP0, // << + const A_UTF16Char *profile_descP0); // << pointer to a null-terminated unicode string + + // Assign valid RGB profile to the footage + SPAPI A_Err (*AEGP_SetInSpecAssignedColorProfile)( + AEIO_InSpecH inH, // << + AEGP_ConstColorProfileP color_profileP); // << + +} AEGP_IOInSuite4; + +#define kAEGPIOOutSuiteVersion4 7 /* frozen in AE 10.0 */ + +typedef struct AEGP_IOOutSuite4 { + SPAPI A_Err (*AEGP_GetOutSpecOptionsHandle)( + AEIO_OutSpecH outH, /* >> */ + void **optionsPPV); /* << */ + + SPAPI A_Err (*AEGP_SetOutSpecOptionsHandle)( + AEIO_OutSpecH outH, /* >> */ + void *optionsPV, /* >> */ + void **old_optionsPPVO); /* <> */ + + SPAPI A_Err (*AEGP_GetOutSpecFilePath)( + AEIO_OutSpecH outH, /* >> */ + AEGP_MemHandle *unicode_pathPH, // << handle of A_UTF16Char (contains null terminated UTF16 string); must be disposed with AEGP_FreeMemHandle + A_Boolean *file_reservedPB); /* << If the file is reserved, do not create the file. + Otherwise, multi-machine rendering can fail. + If true, an empty file has already been created. */ + + SPAPI A_Err (*AEGP_GetOutSpecFPS)( + AEIO_OutSpecH outH, /* >> */ + A_Fixed *native_fpsP); /* << */ + + SPAPI A_Err (*AEGP_SetOutSpecNativeFPS)( + AEIO_OutSpecH outH, /* >> */ + A_Fixed native_fpsP); /* >> */ + + SPAPI A_Err (*AEGP_GetOutSpecDepth)( + AEIO_OutSpecH outH, /* >> */ + A_short *depthPS); /* << */ + + SPAPI A_Err (*AEGP_SetOutSpecDepth)( + AEIO_OutSpecH outH, /* >> */ + A_short depthPS); /* >> */ + + SPAPI A_Err (*AEGP_GetOutSpecInterlaceLabel)( + AEIO_OutSpecH outH, /* >> */ + FIEL_Label *interlaceP); /* << */ + + SPAPI A_Err (*AEGP_SetOutSpecInterlaceLabel)( + AEIO_OutSpecH outH, /* >> */ + const FIEL_Label *interlaceP); /* >> */ + + SPAPI A_Err (*AEGP_GetOutSpecAlphaLabel)( + AEIO_OutSpecH outH, /* >> */ + AEIO_AlphaLabel *alphaP); /* << */ + + SPAPI A_Err (*AEGP_SetOutSpecAlphaLabel)( + AEIO_OutSpecH outH, /* >> */ + const AEIO_AlphaLabel *alphaP); /* >> */ + + SPAPI A_Err (*AEGP_GetOutSpecDuration)( + AEIO_OutSpecH outH, /* >> */ + A_Time *durationP); /* << */ + + SPAPI A_Err (*AEGP_SetOutSpecDuration)( + AEIO_OutSpecH outH, /* >> */ + const A_Time *durationP); /* >> */ + + SPAPI A_Err (*AEGP_GetOutSpecDimensions)( + AEIO_OutSpecH outH, /* >> */ + A_long *widthPL, /* << */ + A_long *heightPL); /* << */ + + SPAPI A_Err (*AEGP_GetOutSpecHSF)( + AEIO_OutSpecH outH, /* >> */ + A_Ratio *hsfP); /* << */ + + SPAPI A_Err (*AEGP_SetOutSpecHSF)( + AEIO_OutSpecH outH, /* >> */ + const A_Ratio *hsfP); /* >> */ + + SPAPI A_Err (*AEGP_GetOutSpecSoundRate)( + AEIO_OutSpecH outH, /* >> */ + A_FpLong *ratePF); /* << */ + + SPAPI A_Err (*AEGP_SetOutSpecSoundRate)( + AEIO_OutSpecH outH, /* >> */ + A_FpLong rateF); /* >> */ + + SPAPI A_Err (*AEGP_GetOutSpecSoundEncoding)( + AEIO_OutSpecH outH, /* >> */ + AEIO_SndEncoding *encodingP); /* << */ + + SPAPI A_Err (*AEGP_SetOutSpecSoundEncoding)( + AEIO_OutSpecH outH, /* >> */ + AEIO_SndEncoding encoding); /* >> */ + + SPAPI A_Err (*AEGP_GetOutSpecSoundSampleSize)( + AEIO_OutSpecH outH, /* >> */ + AEIO_SndSampleSize *bytes_per_sampleP);/* << */ + + SPAPI A_Err (*AEGP_SetOutSpecSoundSampleSize)( + AEIO_OutSpecH outH, /* >> */ + AEIO_SndSampleSize bytes_per_sample); /* >> */ + + SPAPI A_Err (*AEGP_GetOutSpecSoundChannels)( + AEIO_OutSpecH outH, /* >> */ + AEIO_SndChannels *num_channelsP); /* << */ + + SPAPI A_Err (*AEGP_SetOutSpecSoundChannels)( + AEIO_OutSpecH outH, /* >> */ + AEIO_SndChannels num_channels); /* >> */ + + SPAPI A_Err (*AEGP_GetOutSpecIsStill)( + AEIO_OutSpecH outH, /* >> */ + A_Boolean *is_stillPB); /* << */ + + SPAPI A_Err (*AEGP_GetOutSpecPosterTime)( + AEIO_OutSpecH outH, /* >> */ + A_Time *poster_timeP); /* << */ + + SPAPI A_Err (*AEGP_GetOutSpecStartFrame)( + AEIO_OutSpecH outH, /* >> */ + A_long *start_frameP); /* << */ + + SPAPI A_Err (*AEGP_GetOutSpecPullDown)( + AEIO_OutSpecH outH, /* >> */ + AEIO_Pulldown *pulldownP); /* << */ + + SPAPI A_Err (*AEGP_GetOutSpecIsMissing)( + AEIO_OutSpecH outH, /* >> */ + A_Boolean *missingPB); /* << */ + + // see if you need to embed outspec's color profile as an icc profile + SPAPI A_Err (*AEGP_GetOutSpecShouldEmbedICCProfile)( + AEIO_OutSpecH outH, // >> + A_Boolean *embedPB); // << + + // query outspec's color profile + SPAPI A_Err (*AEGP_GetNewOutSpecColorProfile)( + AEGP_PluginID aegp_plugin_id, // >> + AEIO_OutSpecH outH, // >> + AEGP_ColorProfileP *color_profilePP); // << output color space; caller must dispose with AEGP_DisposeColorProfile + + // Fails if rq_itemP is not found. + // This API would also fail if the outH is not a confirmed outH and is a copy. + // e.g. if the Output Module settings dialog is Open. + SPAPI A_Err (*AEGP_GetOutSpecOutputModule)( + AEIO_OutSpecH outH, /* >> */ + AEGP_RQItemRefH *rq_itemP, /* << */ + AEGP_OutputModuleRefH *om_refP); /* << */ + + +} AEGP_IOOutSuite4; + +#define kAEGPFIMSuiteVersion3 3 /* frozen in AE 10.0 */ +typedef struct { + SPAPI A_Err (*AEGP_RegisterImportFlavor)( + const A_char *nameZ, // format name you'd like to appear + // in AE's Import Dialog Format pop-up + // menu. + // Limited to AE_FIM_MAX_IMPORT_FLAVOR_NAME_LEN. + // Everything after that will be truncated. + AE_FIM_ImportFlavorRef *imp_refP); // On return it is set to a valid opaque ref. + // If error occured, it will be returned to + // the caller and ref will be set to a special + // value - AE_FIM_ImportFlavorRef_NONE. + + SPAPI A_Err (*AEGP_RegisterImportFlavorFileTypes)( + AE_FIM_ImportFlavorRef imp_ref, // Received from AEGP_RegisterImportFlavor + A_long num_filekindsL, // number of supported file types for this format + const AEIO_FileKind *kindsAP, // Array of supported file types for this format + A_long num_fileextsL, // number of supported file exts for this format + const AEIO_FileKind *extsAP); // Array of supported file exts for this format + + + SPAPI A_Err (*AEGP_RegisterImportFlavorImportCallbacks)( + AE_FIM_ImportFlavorRef imp_ref, // Received from AEGP_RegisterImportFlavor + AE_FIM_ImportFlags single_flag, // You can register callbacks only per single flag + // this also registers the flag with the import flavor + const AE_FIM_ImportCallbacks *imp_cbsP); // Callbacks your format installs per each flag + + // optionally call once from AE_FIM_ImportFileCB. This is used by the application when re-importing + // from the render queue and replacing an existing item. + SPAPI A_Err (*AEGP_SetImportedItem)( + AE_FIM_ImportOptions imp_options, /* <> */ + AEGP_ItemH imported_itemH); /* >> */ + +} AEGP_FIMSuite3; + + +#include diff --git a/External/AE SDK/Headers/AE_GeneralPlugPanels.h b/External/AE SDK/Headers/AE_GeneralPlugPanels.h new file mode 100644 index 00000000..9f1e5e75 --- /dev/null +++ b/External/AE SDK/Headers/AE_GeneralPlugPanels.h @@ -0,0 +1,134 @@ +#ifndef _AEGP_PANELS_H_ +#define _AEGP_PANELS_H_ + +#include "AE_GeneralPlug.h" + +#if defined(__GNUC__) && defined(__MACH__) + #if defined(__LP64__) + #include + typedef NSView *AEGP_PlatformViewRef; + #else + typedef HIViewRef AEGP_PlatformViewRef; + #endif +#endif + +#if defined(WIN32) + #include + typedef HWND AEGP_PlatformViewRef; +#endif + +typedef struct _AEGP_CreatePanelRefcon *AEGP_CreatePanelRefcon; +typedef struct _AEGP_PanelRefcon *AEGP_PanelRefcon; + +#ifndef AEGP_INTERNAL + // opaque for everyone else + typedef struct _AEGP_PanelH *AEGP_PanelH; +#endif + + + +#include + + +enum {AEGP_FlyoutMenuCmdID_NONE = 0}; +typedef A_long AEGP_FlyoutMenuCmdID; + + +enum { + AEGP_FlyoutMenuMarkType_NORMAL, + AEGP_FlyoutMenuMarkType_CHECKED, + AEGP_FlyoutMenuMarkType_RADIO_BULLET, + AEGP_FlyoutMenuMarkType_SEPARATOR +}; +typedef A_long AEGP_FlyoutMenuMarkType; + +typedef A_long AEGP_FlyoutMenuIndent; + + +typedef struct +{ + AEGP_FlyoutMenuIndent indent; + AEGP_FlyoutMenuMarkType type; + A_Boolean enabledB; + AEGP_FlyoutMenuCmdID cmdID; // limited to MAX(A_long) - 201; + const A_u_char* utf8NameZ; +}AEGP_FlyoutMenuItem; + +/* +flyout menu's are a simple declarative structure + +AEGP_FlyoutMenuItem myMenu[] = { + {1, AEGP_FlyoutMenuMarkType_NORMAL, FALSE, AEGP_FlyoutMenuCmdID_NONE, "Hi!" }, + {1, AEGP_FlyoutMenuMarkType_SEPARATOR, TRUE, AEGP_FlyoutMenuCmdID_NONE, NULL }, + {1, AEGP_FlyoutMenuMarkType_NORMAL, TRUE, AEGP_FlyoutMenuCmdID_NONE, "Set BG Color" }, + {2, AEGP_FlyoutMenuMarkType_NORMAL, TRUE, PT_MenuCmd_RED, "Red" }, + {2, AEGP_FlyoutMenuMarkType_NORMAL, TRUE, PT_MenuCmd_GREEN, "Green" }, + {2, AEGP_FlyoutMenuMarkType_NORMAL, TRUE, PT_MenuCmd_BLUE, "Blue" }, + {1, AEGP_FlyoutMenuMarkType_NORMAL, TRUE, PT_MenuCmd_STANDARD, "Normal Fill Color" }, + {1, AEGP_FlyoutMenuMarkType_NORMAL, TRUE, AEGP_FlyoutMenuCmdID_NONE, "Set Title" }, + {2, AEGP_FlyoutMenuMarkType_NORMAL, TRUE, PT_MenuCmd_TITLE_LONGER, "Longer" }, + {2, AEGP_FlyoutMenuMarkType_NORMAL, TRUE, PT_MenuCmd_TITLE_SHORTER, "Shorter" } +}; + + +*/ + +typedef struct { + // no more than 5 snap sizes. Our algo can't really cope and it confuses + // the user. + A_Err (*GetSnapSizes)(AEGP_PanelRefcon refcon, A_LPoint* snapSizes, A_long * numSizesP); + + + A_Err (*PopulateFlyout)(AEGP_PanelRefcon refcon, AEGP_FlyoutMenuItem* itemsP, A_long * in_out_numItemsP); + A_Err (*DoFlyoutCommand)(AEGP_PanelRefcon refcon, AEGP_FlyoutMenuCmdID commandID); +} AEGP_PanelFunctions1; + +typedef A_Err (*AEGP_CreatePanelHook)( + AEGP_GlobalRefcon plugin_refconP, + AEGP_CreatePanelRefcon refconP, + AEGP_PlatformViewRef container, + AEGP_PanelH panelH, + AEGP_PanelFunctions1* outFunctionTable, + AEGP_PanelRefcon* outRefcon); +#define kAEGPPanelSuite "AEGP Workspace Panel Suite" +#define kAEGPPanelSuiteVersion1 1 /* frozen in AE 8.0 */ + +typedef struct { + SPAPI A_Err (*AEGP_RegisterCreatePanelHook)( + AEGP_PluginID in_plugin_id, + const A_u_char* in_utf8_match_nameZ, // do not localize + AEGP_CreatePanelHook in_update_menu_hook_func, + AEGP_CreatePanelRefcon in_refconP, + A_Boolean in_paint_backgroundB); + + + SPAPI A_Err (*AEGP_UnRegisterCreatePanelHook)( + const A_u_char* in_utf8_match_nameZ); // do not localize match name + + SPAPI A_Err (*AEGP_SetTitle)( + AEGP_PanelH in_panelH, + const A_u_char* in_utf8_nameZ // use this to localize the user visible name of the panel + ); + + /** Does the standard 'Window' menu operation + If tab is not in workspace, it creates it. + Otherwise, if the tab is not the front most tab in it's frame, it is made frontmost + Else, if it is visible and frontmost, it is closed. + */ + SPAPI A_Err (*AEGP_ToggleVisibility)( + const A_u_char* in_utf8_match_nameZ + ); + + SPAPI A_Err (*AEGP_IsShown)( + const A_u_char* in_utf8_match_nameZ, + A_Boolean* out_tab_is_shownB, + A_Boolean* out_panel_is_frontmostB + ); + +} AEGP_PanelSuite1; + + +#include + + +#endif \ No newline at end of file diff --git a/External/AE SDK/Headers/AE_GeneralPlugPost.h b/External/AE SDK/Headers/AE_GeneralPlugPost.h new file mode 100644 index 00000000..7b5fba7b --- /dev/null +++ b/External/AE SDK/Headers/AE_GeneralPlugPost.h @@ -0,0 +1,16 @@ + +#ifdef __cplusplus +} // end extern "C" +#endif + + + +#include + + + +#ifndef _AE_GENERAL_PLUG_PRE___ + #error "AE_GeneralPlugPost.h not balanced" +#else + #undef _AE_GENERAL_PLUG_PRE___ +#endif \ No newline at end of file diff --git a/External/AE SDK/Headers/AE_GeneralPlugPre.h b/External/AE SDK/Headers/AE_GeneralPlugPre.h new file mode 100644 index 00000000..8b2e28d9 --- /dev/null +++ b/External/AE SDK/Headers/AE_GeneralPlugPre.h @@ -0,0 +1,15 @@ + +/* This file should be included after all headers, but before the definition of any suites +or data structures. +*/ +#include + +#ifdef __cplusplus +extern "C" { +#endif + +#ifdef _AE_GENERAL_PLUG_PRE___ +#error "AE_GeneralPlugPre.h not balanced" +#endif + +#define _AE_GENERAL_PLUG_PRE___ \ No newline at end of file diff --git a/External/AE SDK/Headers/AE_HashSuite.h b/External/AE SDK/Headers/AE_HashSuite.h new file mode 100644 index 00000000..04859b8a --- /dev/null +++ b/External/AE SDK/Headers/AE_HashSuite.h @@ -0,0 +1,52 @@ +/******************************************************************** +* ADOBE CONFIDENTIAL +* __________________ +* +* Copyright 2020 Adobe Inc. +* All Rights Reserved. +* +* NOTICE: All information contained herein is, and remains +* the property of Adobe and its suppliers, if any. The intellectual +* and technical concepts contained herein are proprietary to Adobe +* and its suppliers and are protected by all applicable intellectual +* property laws, including trade secret and copyright laws. +* Dissemination of this information or reproduction of this material +* is strictly forbidden unless prior written permission is obtained +* from Adobe. +********************************************************************/ + +#ifndef _H_AE_HashSuite + #define _H_AE_HashSuite + +#ifdef AEGP_INTERNAL + #include +#endif + +#include + +#ifdef __cplusplus + extern "C" { +#endif + +#define kAEGPHashSuite "AEGP Hash Suite" +#define kAEGPHashSuiteVersion1 1 /* frozen in AE 17.5.1 */ + +typedef struct { + + SPAPI A_Err (*AEGP_CreateHashFromPtr)( + const A_u_longlong buf_sizeLu, /* >> size of the buffer */ + const void *bufPV, /* >> the buffer pointer */ + AEGP_GUID *hashP); /* << result */ + + SPAPI A_Err (*AEGP_HashMixInPtr)( + const A_u_longlong buf_sizeLu, /* >> size of the buffer */ + const void *bufPV, /* >> the buffer pointer */ + AEGP_GUID *hashP); /* <> guid to be mixed in */ + +} AEGP_HashSuite1; + +#ifdef __cplusplus + } // end extern "C" +#endif + +#endif diff --git a/External/AE SDK/Headers/AE_Hook.h b/External/AE SDK/Headers/AE_Hook.h new file mode 100644 index 00000000..6f747688 --- /dev/null +++ b/External/AE SDK/Headers/AE_Hook.h @@ -0,0 +1,155 @@ +/*******************************************************************/ +/* */ +/* ADOBE CONFIDENTIAL */ +/* _ _ _ _ _ _ _ _ _ _ _ _ _ */ +/* */ +/* Copyright 2007 Adobe Systems Incorporated */ +/* All Rights Reserved. */ +/* */ +/* NOTICE: All information contained herein is, and remains the */ +/* property of Adobe Systems Incorporated and its suppliers, if */ +/* any. The intellectual and technical concepts contained */ +/* herein are proprietary to Adobe Systems Incorporated and its */ +/* suppliers and may be covered by U.S. and Foreign Patents, */ +/* patents in process, and are protected by trade secret or */ +/* copyright law. Dissemination of this information or */ +/* reproduction of this material is strictly forbidden unless */ +/* prior written permission is obtained from Adobe Systems */ +/* Incorporated. */ +/* */ +/*******************************************************************/ + +#ifndef _H_HOOK_AE +#define _H_HOOK_AE + + +#include // for PF_Version, other types + + +#ifdef __cplusplus + extern "C" { +#endif + + +#define AE_HOOK_PLUGIN_TYPE 'AEgp' + +#define AE_HOOK_MAJOR_VERSION 3 +#define AE_HOOK_MINOR_VERSION 0 + +enum { + AE_PixFormat_NONE = -1, // sentinel -- meaningless + AE_PixFormat_ARGB = 0, + AE_PixFormat_BGRA +}; + +typedef A_long AE_PixFormat; + +enum { + AE_BlitOutFlag_NONE = 0, + AE_BlitOutFlag_ASYNCHRONOUS = 1L << 0 +}; + +enum { + AE_BlitInFlag_NONE = 0, + AE_BlitInFlag_RENDERING = 1L << 0 +}; + +typedef A_long AE_BlitInFlags; +typedef A_long AE_BlitOutFlags; + +// AE now supports 8bpp, 16bpp and 32bpc +// depthL, chan_bytesL, and plane_bytesL +// can now change. +typedef struct { + A_long widthL; + A_long heightL; + A_long depthL; // 32, 64, or 128 + AE_PixFormat pix_format; // always AE_PixFormat_ARGB on Mac, BGRA on Windows (for now) + + A_long row_bytesL; + A_long chan_bytesL; // 4, 8, or 16 + A_long plane_bytesL; // 1, 2, or 4 (for float) + + void *pixelsPV; + +} AE_PixBuffer; + + + +typedef struct { + A_long frame_widthL; // original size of image regardless of region of interest + A_long frame_heightL; + + A_long origin_xL; // where the pix buffer is placed in frame coords + A_long origin_yL; + + A_long view_rect_leftL; // what the user is actually seeing in the window + A_long view_rect_topL; + A_long view_rect_rightL; + A_long view_rect_bottomL; + + +} AE_ViewCoordinates; + + + +typedef struct _AE_BlitReceipt *AE_BlitReceipt; // opaque + +typedef struct _AE_CursorInfo *AE_CursorInfo; // opaque until I can decide what this means + + + +typedef void (*AE_DeathHook)( void *hook_refconPV); /* >> */ + +typedef void (*AE_VersionHook)( void *hook_refconPV, /* >> */ + A_u_long *versionPV); /* << */ + + +typedef struct FILE_Spec **AE_FileSpecH; + + +typedef void (*AE_BlitCompleteFunc)( AE_BlitReceipt receipt, + PF_Err err); // non zero if error during asynch operation + + +typedef PF_Err (*AE_BlitHook)( void *hook_refconPV, /* >> */ + const AE_PixBuffer *pix_bufP0, /* >> if NULL, display a blank frame */ + const AE_ViewCoordinates *viewP, /* >> */ + AE_BlitReceipt receipt, /* >> */ + AE_BlitCompleteFunc complete_func0, /* >> */ + AE_BlitInFlags in_flags, /* >> */ + AE_BlitOutFlags *out_flags); /* << */ + + + +typedef void (*AE_CursorHook)( void *hook_refconPV, /* >> */ + const AE_CursorInfo *cursorP); /* >> */ + +typedef struct { + // must match NIM_Hooks + + void *hook_refconPV; + void *reservedAPV[8]; + AE_DeathHook death_hook_func; + AE_VersionHook version_hook_func; + struct SPBasicSuite *pica_basicP; + AE_BlitHook blit_hook_func; + AE_CursorHook cursor_hook_func; + +} AE_Hooks; + + + +typedef PF_Err (*AE_HookPluginEntryFunc)( A_long major_version, /* >> */ + A_long minor_version, /* >> */ + AE_FileSpecH file_specH, /* >> */ + AE_FileSpecH res_specH, /* >> */ + AE_Hooks *hooksP); /* << */ + +#ifdef __cplusplus + } +#endif + + +#endif + diff --git a/External/AE SDK/Headers/AE_IO.h b/External/AE SDK/Headers/AE_IO.h new file mode 100644 index 00000000..88ccce2a --- /dev/null +++ b/External/AE SDK/Headers/AE_IO.h @@ -0,0 +1,789 @@ +/*******************************************************************/ +/* */ +/* ADOBE CONFIDENTIAL */ +/* _ _ _ _ _ _ _ _ _ _ _ _ _ */ +/* */ +/* Copyright 2007 Adobe Systems Incorporated */ +/* All Rights Reserved. */ +/* */ +/* NOTICE: All information contained herein is, and remains the */ +/* property of Adobe Systems Incorporated and its suppliers, if */ +/* any. The intellectual and technical concepts contained */ +/* herein are proprietary to Adobe Systems Incorporated and its */ +/* suppliers and may be covered by U.S. and Foreign Patents, */ +/* patents in process, and are protected by trade secret or */ +/* copyright law. Dissemination of this information or */ +/* reproduction of this material is strictly forbidden unless */ +/* prior written permission is obtained from Adobe Systems */ +/* Incorporated. */ +/* */ +/*******************************************************************/ + +#ifndef _AEIO_Public_H +#define _AEIO_Public_H + +#include +#include +#include +#include +#include + +#include + + +/////////////////////////////////////////////////// +////////////////// PUBLIC //////////////////////// +////////////////////////////////////////////////// + +#define AEIO_MAX_MODULE_NAME_LEN 31 +#define AEIO_MAX_TYPES 16 +#define AEIO_MAX_SEQ_NAME_LEN 31 +#define AEIO_MAX_MESSAGE_LEN 127 +#define AEIO_MAX_AUX_EXT 16 + +#define AEIO_ANY_CREATOR -1 + +#ifdef __cplusplus + extern "C" { +#endif + +#ifndef AEGP_INTERNAL + typedef const struct _AEGP_MarkerVal *AEGP_ConstMarkerValP; +#else +#ifndef _H_AE_GENERALPLUG_PRIVATE_H +#error include general plug private header before including AEIO +#endif +#endif + + + +/** + ** in data is passed to every function block function + **/ + +typedef void (*AEIO_MessageFunc) (A_Err err_number, const A_char *msgA); + +typedef struct AEIO_InData { + AEIO_MessageFunc msg_func; + const struct SPBasicSuite *pica_basicP; + A_long aegp_plug_id; + void *aegp_refconPV; +} AEIO_BasicData; + +enum { + AEIO_Err_UNSUPPORTED_CALLBACK = (((39)<<8)+1), + AEIO_Err_UNIMPLEMENTED, + AEIO_Err_UNSUPPORTED_FILETYPE, + AEIO_Err_INAPPROPRIATE_ACTION, + AEIO_Err_BAD_BMWORLD, + AEIO_Err_INCONSISTENT_PARAMETERS, + AEIO_Err_INVALID_TIME, + AEIO_Err_USE_DFLT_CALLBACK, + AEIO_Err_USER_CANCEL, + AEIO_Err_DISK_FULL, + AEIO_Err_INITIALIZE_FAILED, + AEIO_Err_BAD_FILENAME, + AEIO_Err_PARSING, + AEIO_Err_NOT_SEQUENCE, + AEIO_Err_USE_DFLT_GETSIZES_FREESPACE +}; + +typedef struct _Up_OpaqueMem **AEIO_Handle; + +enum { + AEIO_DFlags_NONE = 0, + AEIO_DFlags_DID_DEINT = (1L<<1), // I already did deinterlacing + AEIO_DFlags_DID_ALPHA_CONV = (1L<<2) // I already did alpha conversion to what you wanted. +}; +typedef A_long AEIO_DrawingFlags; + +/* NOTE: AEIO_DFlags_NO_SCALE and AEIO_DFlags_DID_TIME_FILTER, + previously included in the above, were never honored (so + we removed them). -bbb 8/14/02 +*/ + +enum { + AEIO_Qual_LOW, + AEIO_Qual_HIGH +}; +typedef A_short AEIO_Quality; + +enum { + AEIO_TimeDir_FORWARD = 0x0000, + AEIO_TimeDir_BACKWARD = 0x0001, + AEIO_TimeDir_INCLUDE_BASE_TIME = 0x1000 +}; +typedef A_short AEIO_TimeDir; + +enum { + AEIO_IdleFlag_NONE = 0, + AEIO_IdleFlag_PURGED_MEM = 1L << 0, + AEIO_IdleFlag_ADD_YOUR_OWN = 1L << 1 +}; +typedef A_long AEIO_IdleFlags; + +enum { + AEIO_SndQuality_APPROX = -1, // This quality is used to draw the audio waveform. -jja + AEIO_SndQuality_LO = 0, + AEIO_SndQuality_HI +}; + +typedef A_long AEIO_SndQuality; + +enum { + AEIO_E_UNSIGNED_PCM = 1, + AEIO_E_SIGNED_PCM = 2, + AEIO_E_SIGNED_FLOAT = 3 +}; +typedef A_short AEIO_SndEncoding; + +enum { + AEIO_SS_1 = 1, + AEIO_SS_2 = 2, + AEIO_SS_4 = 4 +}; +typedef A_short AEIO_SndSampleSize; + +enum { + AEIO_SndChannels_MONO = 1, + AEIO_SndChannels_STEREO = 2 +}; +typedef A_short AEIO_SndChannels; + +enum { + AEIO_Marker_URL_FLIP, + AEIO_Marker_CHAPTER, + AEIO_Marker_HOTSPOT, + AEIO_Marker_NONE +}; +typedef A_u_char AEIO_MarkerType; + +enum { + AEIO_Field_FRAME = 0, + AEIO_Field_UPPER, + AEIO_Field_LOWER +}; +typedef A_long AEIO_Field; + + +typedef struct { + const A_char *chapterZ0; + const A_char *commentZ0; + const A_char *urlZ0; + const A_char *url_frame_targetZ0; // optionally used if urlZ0 != NULL +} AEIO_Marker; + + +enum { + AEIO_FrameBlend_NONE = 0, + AEIO_FrameBlend_LOW = 1, + AEIO_FrameBlend_HIGH = 2 +}; +typedef A_char AEIO_FrameBlend; + + +enum { + AEIO_LFlag_ALFA = 0x1, + AEIO_LFlag_FIELDS = 0x2, + AEIO_LFlag_SIGNATURE = 0x4 +}; +typedef A_long AEIO_LabelFlags; + +enum { + AEIO_InputDepth_1 = 1, + AEIO_InputDepth_2 = 2, + AEIO_InputDepth_4 = 4, + AEIO_InputDepth_8 = 8, + AEIO_InputDepth_16 = 16, + AEIO_InputDepth_24 = 24, + AEIO_InputDepth_30 = 30, + AEIO_InputDepth_32 = 32, + AEIO_InputDepth_GRAY_2 = 34, + AEIO_InputDepth_GRAY_4 = 36, + AEIO_InputDepth_GRAY_8 = 40, + AEIO_InputDepth_48 = 48, + AEIO_InputDepth_64 = 64, + AEIO_InputDepth_96 = 96, // RGB float + AEIO_InputDepth_128 = 128, // ARGB float + AEIO_InputDepth_GRAY_16 = -16, + AEIO_InputDepth_GRAY_32 = -32 +}; + +typedef A_long AEIO_InputDepth; + +enum { + AEIO_SupportedDepthFlags_NONE = 0, + AEIO_SupportedDepthFlags_DEPTH_1 = 1L << 1, // Enable 1 bit images. Put an interface on it, if you like + AEIO_SupportedDepthFlags_DEPTH_2 = 1L << 2, // Enable 2 bit images. etc. + AEIO_SupportedDepthFlags_DEPTH_4 = 1L << 3, + AEIO_SupportedDepthFlags_DEPTH_8 = 1L << 4, + AEIO_SupportedDepthFlags_DEPTH_16 = 1L << 5, + AEIO_SupportedDepthFlags_DEPTH_24 = 1L << 6, + AEIO_SupportedDepthFlags_DEPTH_32 = 1L << 7, // Enable 32-bit images (with alpha channels) + AEIO_SupportedDepthFlags_DEPTH_GRAY_2 = 1L << 8, // greyscale + AEIO_SupportedDepthFlags_DEPTH_GRAY_4 = 1L << 9, + AEIO_SupportedDepthFlags_DEPTH_GRAY_8 = 1L << 10, + AEIO_SupportedDepthFlags_DEPTH_48 = 1L << 11, + AEIO_SupportedDepthFlags_DEPTH_64 = 1L << 12, + AEIO_SupportedDepthFlags_DEPTH_GRAY_16 = 1L << 13, + AEIO_SupportedDepthFlags_DEPTH_96 = 1L << 14, + AEIO_SupportedDepthFlags_DEPTH_128 = 1L << 15, + AEIO_SupportedDepthFlags_LAST = 1L << 16 +}; + +typedef A_long AEIO_SupportedDepthFlags; + +enum { + AEIO_Phase_NO_PULLDOWN = 0, + AEIO_Phase_WSSWW = 1, + AEIO_Phase_SSWWW, + AEIO_Phase_SWWWS, + AEIO_Phase_WWWSS, + AEIO_Phase_WWSSW +}; +typedef A_long AEIO_Pulldown; + +typedef A_long AEIO_FileType; +typedef A_long AEIO_Creator; + +typedef struct { + AEIO_FileType type; + AEIO_Creator creator; +} PFILE_FileKind; + + +typedef union { + PFILE_FileKind mac; + AEIO_FileExt ext; + A_long scrap; +} AEIO_FileKind; + + +typedef struct { + A_char name[AEIO_MAX_SEQ_NAME_LEN+1]; // usually the filename + A_char type[AEIO_MAX_SEQ_NAME_LEN+1]; // e.g. "PICT Sequence" "QT Movie" + A_char sub_type[AEIO_MAX_MESSAGE_LEN+1]; +} AEIO_Verbiage; + + +#ifdef __cplusplus + } +#endif + + +///////////////////////////////////////////////////////// +////////////////// redefined in PRIVATE ///////////////// +//////////////////////////////////////////////////////// + +#ifdef A_INTERNAL + #include +#else + #ifdef __cplusplus + extern "C" { + #endif + + typedef struct AEIO_SeqSpec **AEIO_InSpecH; + typedef struct AEIO_OutSpec **AEIO_OutSpecH; + + typedef A_long AEIO_ModuleSignature; // please register your module signature with adobe + // mailto:bbb@adobe.com?subject=AEIO_Signature + + typedef struct { + A_Ratio x; + A_Ratio y; + } AEIO_RationalScale; + + + #define AEIO_AlphaLabel_VERSION 0x0101 + + enum { + AEIO_AlphaPremul = 0x1, // otherwise straight + AEIO_AlphaInverted = 0x2 // 255 = transparent + }; + + typedef A_u_long AEIO_AlphaFlags; + + enum { + AEIO_Alpha_STRAIGHT, + AEIO_Alpha_PREMUL, + AEIO_Alpha_IGNORE, + AEIO_Alpha_NONE + }; + + typedef A_u_char AEIO_AlphaType; + + + #pragma pack( push, CoSAalign, 2 ) + + typedef struct { + A_short version; + AEIO_AlphaFlags flags; + A_u_char red; // color that was matted (if premul) + A_u_char green; + A_u_char blue; + AEIO_AlphaType alpha; + } AEIO_AlphaLabel; +#if defined(A_INTERNAL) && defined(__cplusplus) + AE_STRUCT_SIZE_ASSERT(AEIO_AlphaLabel, 10); +#endif + + #pragma pack( pop, CoSAalign) + + + typedef A_Err (*AEIO_AbortProc)(void *refcon); + typedef A_Err (*AEIO_ProgressProc)(void *refcon, A_long count, A_long total); + + + typedef struct { + void *refcon; + AEIO_AbortProc abort0; + AEIO_ProgressProc progress0; + } AEIO_InterruptFuncs; + + + // All coordinates are in the scaled coordinate system. + typedef struct { + AEIO_Quality qual; + AEIO_AlphaLabel alpha_label; + AEIO_Field field_request; + AEIO_RationalScale rs; + A_Time tr; + A_Time duration; + AEIO_FrameBlend time_filter; + // CW adds 1 pad byte here + A_LRect required_region0; // empty rect means entire + // CW adds 2 pad bytes here + AEIO_InterruptFuncs inter; + } AEIO_DrawFramePB; + + enum { + AEIO_RenderMarkerFlag_NONE = 0x00000000, + AEIO_RenderMarkerFlag_COMP = 0x00000001 // if 1 means comp marker; 0 means Layer marker + }; + typedef A_long AEIO_RenderMarkerFlag; + + #ifdef __cplusplus + } + #endif +#endif // A_INTERNAL + +#ifdef __cplusplus + extern "C" { +#endif + + +#define AEIO_FileType_DIR -2L +#define AEIO_FileType_NONE -1L +#define AEIO_FileType_ANY 0L +#define AEIO_FileType_GENERIC 1L + + +//////////////////////////////////////////////////////////////////// +///////////////////////// PUBLIC /////////////////////////////////// +//////////////////////////////////////////////////////////////////// + + +enum { + AEIO_MFlag_NONE = 0, + AEIO_MFlag_INPUT = (1L<<0), // input module + AEIO_MFlag_OUTPUT = (1L<<1), // output module (can be both) + AEIO_MFlag_FILE = (1L<<2), // direct correspondence to file in file system + AEIO_MFlag_STILL = (1L<<3), // still image support (not VIDEO) + AEIO_MFlag_VIDEO = (1L<<4), // multiple image support (not STILL) + AEIO_MFlag_AUDIO = (1L<<5), // audio support + AEIO_MFlag_NO_TIME = (1L<<6), // time-independent frame-store? always true if STILL; PICS example of non-STILL one + AEIO_MFlag_INTERACTIVE_GET = (1L<<7), // user interaction for new seq, required if !FILE & INPUT + AEIO_MFlag_INTERACTIVE_PUT = (1L<<8), // user interaction for new out, required if !FILE & OUTPUT + AEIO_MFlag_CANT_CLIP = (1L<<9), // DrawFrame can't accept worlds smaller than requested dimensions + AEIO_MFlag_MUST_INTERACT_PUT = (1L<<10), // dialog box can't be avoided, even if optionsH available + AEIO_MFlag_CANT_SOUND_INTERLEAVE = (1L<<11), // all frames must be added, then sound + AEIO_MFlag_CAN_ADD_FRAMES_NON_LINEAR= (1L<<12), // AddFrame can handle non-sequential times + AEIO_MFlag_HOST_DEPTH_DIALOG = (1L<<13), // expects host to bring up a dialog with depth + AEIO_MFlag_HOST_FRAME_START_DIALOG = (1L<<14), // expects host to bring up dialog with starting frame # + AEIO_MFlag_RESERVED1 = (1L<<15), + AEIO_MFlag_NO_OPTIONS = (1L<<16), // set this bit if the module does not accept output options + AEIO_MFlag_RESERVED2 = (1L<<17), + + AEIO_MFlag_RESERVED3 = (1L<<18), + AEIO_MFlag_NO_PIXELS = (1L<<19), // this file format doesn't store real pixels, only geometry (or whatever) + AEIO_MFlag_SEQUENCE_OPTIONS_OK = (1L<<20), // this module should take the options of its parent sequence when a folder is selected + AEIO_MFlag_INPUT_OPTIONS = (1L<<21), // this module has user options associated with an input sequence. NOTE: options must be flat. + AEIO_MFlag_HSF_AWARE = (1L<<22), // this module set the hsf for incoming sequences -> don't guess what it is! + AEIO_MFlag_HAS_LAYERS = (1L<<23), // this module supports multiple layers in a single document + AEIO_MFlag_SCRAP = (1L<<24), // module has a memory parsing (clipboard) component + AEIO_MFlag_NO_UI = (1L<<25), // don't show any UI for this module + AEIO_MFlag_SEQ_OPTIONS_DLG = (1L<<26), // module has sequence options + AEIO_MFlag_HAS_AUX_DATA = (1L<<27), // has depth, or normals, or anything that is on a per pixel basis besides color + AEIO_MFlag_HAS_META_DATA = (1L<<28), // supports user definable metadata + AEIO_MFlag_CAN_DO_MARKERS = (1L<<29), // supports markers (e.g. URL flips, chapters) + AEIO_MFlag_CAN_DRAW_DEEP = (1L<<30), // module can draw into 64 bpp BM_Worlds + AEIO_MFlag_RESERVED4 = (1L<<31) +}; +typedef A_u_long AEIO_ModuleFlags; + +enum { + AEIO_MFlag2_NONE = 0, + AEIO_MFlag2_AUDIO_OPTIONS = (1L<<0), // has audio options + AEIO_MFlag2_RESERVED1 = (1L<<1), + AEIO_MFlag2_SEND_ADDMARKER_BEFORE_ADDFRAME = (1L<<2), // otherwise it is sent just after; use with AEIO_MFlag_CAN_DO_MARKERS + AEIO_MFlag2_CAN_DO_MARKERS_2 = (1L<<3), // supports combined markers (e.g. URL flips, chapters, comments) + AEIO_MFlag2_CAN_DRAW_FLOAT = (1L<<4), + AEIO_MFlag2_RESERVED2 = (1L<<5), + AEIO_MFlag2_CAN_DO_AUDIO_32 = (1L<<6), // supports 32 bit audio output. + AEIO_MFlag2_RESERVED3 = (1L<<7), + AEIO_MFlag2_SUPPORTS_ICC_PROFILES = (1L<<8), + AEIO_MFlag2_CAN_DO_MARKERS_3 = (1L<<9), // supports cue points + AEIO_MFlag2_SEND_ADDMARKER_BEFORE_STARTADDING = (1L<<10), + AEIO_MFlag2_RESERVED4 = (1L<<11), + AEIO_MFlag2_USES_QUICKTIME = (1L<<12), // Module uses quicktime for decompression or compression + AEIO_MFlag2_RESERVED5 = (1L<<13), + AEIO_MFlag2_RESERVED6 = (1L<<14), + AEIO_MFlag2_RESERVED7 = (1L<<15), + AEIO_MFlag2_RESERVED8 = (1L<<16), + AEIO_MFlag2_RESERVED9 = (1L<<17), + AEIO_MFlag2_RESERVED10 = (1L<<18) +}; +typedef A_u_long AEIO_ModuleFlags2; + +typedef struct { + A_char extension[4]; // includes '.' + A_long type; // mac type + A_long creator; // mac creator +} AEIO_AuxExt; + +typedef struct { + AEIO_ModuleSignature sig; // please register number this with adobe + A_char name[AEIO_MAX_MODULE_NAME_LEN+1]; + AEIO_ModuleFlags flags; + AEIO_ModuleFlags2 flags2; + A_long max_width; + A_long max_height; + A_short num_filetypes; // # of filetype/creator pairs supported + A_short num_extensions; // # of .XXX extensions supported + A_short num_clips; // # of clipboard types supported + A_short pad; + PFILE_FileKind create_kind; // type/creator for newly created files + AEIO_FileExt create_ext; // extension for new created DOS files + AEIO_FileKind read_kinds[AEIO_MAX_TYPES]; // mac types first, then DOS, then clipboard + A_short num_aux_extensionsS; + // CW adds 2 pad bytes here + AEIO_AuxExt aux_ext[AEIO_MAX_AUX_EXT]; +} AEIO_ModuleInfo; + +typedef struct AEIO_OptionsCBInfo { + AEIO_SupportedDepthFlags o_flags; + AEIO_OutSpecH out_specH; +} AEIO_OptionsCBInfo; + +typedef struct { + AEIO_Quality qual; + // CW adds 2 pad bytes here + AEIO_RationalScale rs; + A_Time tr; + A_Time duration; + A_LRect required_region; // empty rect means entire + AEIO_InterruptFuncs inter; +} AEIO_DrawSparseFramePB; + + +/*********************** plugin entry points ***************************** + ** the main routine of each plugin fills in these function pointers + ** AE will call them as appropriate + ****************************************************************************/ + +typedef struct _AEIO_FunctionBlock4 { // revved to 4 in AE 10. Frozen in AE10. + + A_Err (*AEIO_InitInSpecFromFile)( + AEIO_BasicData *basic_dataP, + const A_UTF16Char *file_pathZ, // Null terminated UTF16 string with platform separators + AEIO_InSpecH inH); + + A_Err (*AEIO_InitInSpecInteractive)( + AEIO_BasicData *basic_dataP, + AEIO_InSpecH inH); + + A_Err (*AEIO_DisposeInSpec)( + AEIO_BasicData *basic_dataP, + AEIO_InSpecH inH); + + A_Err (*AEIO_FlattenOptions)( + AEIO_BasicData *basic_dataP, + AEIO_InSpecH inH, + AEIO_Handle *flat_optionsPH); + + A_Err (*AEIO_InflateOptions)( + AEIO_BasicData *basic_dataP, + AEIO_InSpecH inH, + AEIO_Handle flat_optionsH); + + A_Err (*AEIO_SynchInSpec)( + AEIO_BasicData *basic_dataP, + AEIO_InSpecH inH, + A_Boolean *changed0); + + A_Err (*AEIO_GetActiveExtent)( + AEIO_BasicData *basic_dataP, + AEIO_InSpecH inH, /* >> */ + const A_Time *tr, /* >> */ + A_LRect *extent); /* << */ + + A_Err (*AEIO_GetInSpecInfo)( + AEIO_BasicData *basic_dataP, + AEIO_InSpecH inH, + AEIO_Verbiage *verbiageP); + + // All coordinates are in the scaled coordinate system. + A_Err (*AEIO_DrawSparseFrame)( + AEIO_BasicData *basic_dataP, + AEIO_InSpecH inH, + const AEIO_DrawSparseFramePB *sparse_framePPB, + PF_EffectWorld *worldP, + AEIO_DrawingFlags *draw_flagsP); + + A_Err (*AEIO_GetDimensions)( + AEIO_BasicData *basic_dataP, + AEIO_InSpecH inH, + const AEIO_RationalScale *rs0, + A_long *width0, + A_long *height0); + + A_Err (*AEIO_GetDuration)( + AEIO_BasicData *basic_dataP, + AEIO_InSpecH inH, + A_Time *tr); + + A_Err (*AEIO_GetTime)( + AEIO_BasicData *basic_dataP, + AEIO_InSpecH inH, + A_Time *tr); + + A_Err (*AEIO_GetSound)( + AEIO_BasicData *basic_dataP, + AEIO_InSpecH inH, + AEIO_SndQuality quality, + const AEIO_InterruptFuncs *interrupt_funcsP0, + const A_Time *startPT, + const A_Time *durPT, + A_u_long start_sampLu, + A_u_long num_samplesLu, + void *dataPV); + + A_Err (*AEIO_InqNextFrameTime)( + AEIO_BasicData *basic_dataP, + AEIO_InSpecH inH, + const A_Time *base_time_tr, + AEIO_TimeDir time_dir, + A_Boolean *found0, + A_Time *key_time_tr0); + + A_Err (*AEIO_InitOutputSpec)( + AEIO_BasicData *basic_dataP, + AEIO_OutSpecH outH, + A_Boolean *user_interacted); + + A_Err (*AEIO_GetFlatOutputOptions)( + AEIO_BasicData *basic_dataP, + AEIO_OutSpecH outH, + AEIO_Handle *optionsH); + + A_Err (*AEIO_DisposeOutputOptions)( + AEIO_BasicData *basic_dataP, + void *optionsPV); + + A_Err (*AEIO_UserOptionsDialog)( + AEIO_BasicData *basic_dataP, + AEIO_OutSpecH outH, + const PF_EffectWorld *sample0, + A_Boolean *user_interacted0); + + A_Err (*AEIO_GetOutputInfo)( + AEIO_BasicData *basic_dataP, + AEIO_OutSpecH outH, + AEIO_Verbiage *verbiage); + + A_Err (*AEIO_OutputInfoChanged)( + AEIO_BasicData *basic_dataP, + AEIO_OutSpecH outH); + + A_Err (*AEIO_SetOutputFile)( + AEIO_BasicData *basic_dataP, + AEIO_OutSpecH outH, + const A_UTF16Char *file_pathZ); // Null terminated UTF16 string with platform separators + + A_Err (*AEIO_StartAdding)( + AEIO_BasicData *basic_dataP, + AEIO_OutSpecH outH, + A_long flags); + + A_Err (*AEIO_AddFrame)( + AEIO_BasicData *basic_dataP, + AEIO_OutSpecH outH, + A_long frame_index, + A_long frames, + const PF_EffectWorld *wP, + const A_LPoint *origin0, + A_Boolean was_compressedB, + AEIO_InterruptFuncs *inter0); + + A_Err (*AEIO_EndAdding)( + AEIO_BasicData *basic_dataP, + AEIO_OutSpecH outH, + A_long flags); + + A_Err (*AEIO_OutputFrame)( + AEIO_BasicData *basic_dataP, + AEIO_OutSpecH outH, + const PF_EffectWorld *wP); + + A_Err (*AEIO_WriteLabels)( + AEIO_BasicData *basic_dataP, + AEIO_OutSpecH outH, + AEIO_LabelFlags *written); + + A_Err (*AEIO_GetSizes)( + AEIO_BasicData *basic_dataP, + AEIO_OutSpecH outH, + A_u_longlong *free_space, + A_u_longlong *file_size); + + A_Err (*AEIO_Flush)( + AEIO_BasicData *basic_dataP, + AEIO_OutSpecH outH); + + A_Err (*AEIO_AddSoundChunk)( + AEIO_BasicData *basic_dataP, + AEIO_OutSpecH outH, + const A_Time *start, + A_u_long num_samplesLu, + const void *dataPV); + + A_Err (*AEIO_Idle)( + AEIO_BasicData *basic_dataP, + AEIO_ModuleSignature sig, + AEIO_IdleFlags *idle_flags0); /* >> */ + + A_Err (*AEIO_GetDepths)( + AEIO_BasicData *basic_dataP, + AEIO_OutSpecH outH, + AEIO_SupportedDepthFlags *which); + + A_Err (*AEIO_GetOutputSuffix)( + AEIO_BasicData *basic_dataP, + AEIO_OutSpecH outH, + A_char *suffix); + + A_Err (*AEIO_SeqOptionsDlg)( + AEIO_BasicData *basic_dataP, + AEIO_InSpecH inH, + A_Boolean *user_interactedPB0); + + A_Err (*AEIO_GetNumAuxChannels)( + AEIO_BasicData *basic_dataP, + AEIO_InSpecH inH, + A_long *num_channelsPL); + + A_Err (*AEIO_GetAuxChannelDesc)( + AEIO_BasicData *basic_dataP, + AEIO_InSpecH inH, + A_long chan_indexL, + PF_ChannelDesc *descP); + + A_Err (*AEIO_DrawAuxChannel)( + AEIO_BasicData *basic_dataP, + AEIO_InSpecH inH, + A_long chan_indexL, + const AEIO_DrawFramePB *pbP, + PF_ChannelChunk *chunkP); + + A_Err (*AEIO_FreeAuxChannel)( + AEIO_BasicData *basic_dataP, + AEIO_InSpecH inH, + PF_ChannelChunk *chunkP); + + A_Err (*AEIO_NumAuxFiles)( + AEIO_BasicData *basic_dataP, + AEIO_InSpecH seqH, + A_long *files_per_framePL0); + + A_Err (*AEIO_GetNthAuxFileSpec)( + AEIO_BasicData *basic_dataP, + AEIO_InSpecH seqH, + A_long frame_numL, + A_long n, + AEGP_MemHandle *pathPH); // << handle of A_UTF16Char (contains null terminated UTF16 string); must be disposed with AEGP_FreeMemHandle + + A_Err (*AEIO_CloseSourceFiles)( + AEIO_BasicData *basic_dataP, + AEIO_InSpecH seqH); + + A_Err (*AEIO_CountUserData)( + AEIO_BasicData *basic_dataP, + AEIO_InSpecH inH, + A_u_long typeLu, + A_u_long max_sizeLu, + A_u_long *num_of_typePLu); + + A_Err (*AEIO_SetUserData)( + AEIO_BasicData *basic_dataP, + AEIO_OutSpecH outH, + A_u_long typeLu, + A_u_long indexLu, + const AEIO_Handle dataH); + + A_Err (*AEIO_GetUserData)( + AEIO_BasicData *basic_dataP, + AEIO_InSpecH inH, + A_u_long typeLu, + A_u_long indexLu, + A_u_long max_sizeLu, + AEIO_Handle *dataPH); + + A_Err (*AEIO_AddMarker)( + AEIO_BasicData *basic_dataP, + AEIO_OutSpecH outH, + A_long frame_index, + AEIO_MarkerType marker_type, + void *marker_dataPV, + AEIO_InterruptFuncs *inter0); + + A_Err (*AEIO_VerifyFileImportable)( + AEIO_BasicData *basic_dataP, + AEIO_ModuleSignature sig, + const A_UTF16Char * file_pathZ, // Null terminated UTF16 string with platform separators + A_Boolean *importablePB); + + A_Err (*AEIO_UserAudioOptionsDialog)( + AEIO_BasicData *basic_dataP, + AEIO_OutSpecH outH, + A_Boolean *user_interacted0); + + A_Err (*AEIO_AddMarker2)( + AEIO_BasicData *basic_dataP, + AEIO_OutSpecH outH, + A_long frame_index, + const AEIO_Marker *markerP, + AEIO_InterruptFuncs *inter0); + + A_Err (*AEIO_AddMarker3)( + AEIO_BasicData *basic_dataP, + AEIO_OutSpecH outH, + A_long frame_index, + AEGP_ConstMarkerValP marker_valP, + AEIO_RenderMarkerFlag marker_flag, + AEIO_InterruptFuncs *inter0); + + A_Err (*AEIO_GetMimeType)( + AEIO_BasicData *basic_dataP, + AEIO_OutSpecH outH, + A_long mime_type_sizeL, + char *mime_typeZ); + +} AEIO_FunctionBlock4; + +#ifdef __cplusplus + } +#endif + +#include + +#endif diff --git a/External/AE SDK/Headers/AE_IO_FileExt.h b/External/AE SDK/Headers/AE_IO_FileExt.h new file mode 100644 index 00000000..27625bda --- /dev/null +++ b/External/AE SDK/Headers/AE_IO_FileExt.h @@ -0,0 +1,32 @@ +/*******************************************************************/ +/* */ +/* ADOBE CONFIDENTIAL */ +/* _ _ _ _ _ _ _ _ _ _ _ _ _ */ +/* */ +/* Copyright 2007 Adobe Systems Incorporated */ +/* All Rights Reserved. */ +/* */ +/* NOTICE: All information contained herein is, and remains the */ +/* property of Adobe Systems Incorporated and its suppliers, if */ +/* any. The intellectual and technical concepts contained */ +/* herein are proprietary to Adobe Systems Incorporated and its */ +/* suppliers and may be covered by U.S. and Foreign Patents, */ +/* patents in process, and are protected by trade secret or */ +/* copyright law. Dissemination of this information or */ +/* reproduction of this material is strictly forbidden unless */ +/* prior written permission is obtained from Adobe Systems */ +/* Incorporated. */ +/* */ +/*******************************************************************/ + +#ifndef _AEIO_FileExt_Public_H +#define _AEIO_FileExt_Public_H + +#include + +typedef struct { + A_char pad; // constant: always '.' + A_char extension[3]; +} AEIO_FileExt; + +#endif // _AEIO_FileExt_Public_H diff --git a/External/AE SDK/Headers/AE_Macros.h b/External/AE SDK/Headers/AE_Macros.h new file mode 100644 index 00000000..3f245cc7 --- /dev/null +++ b/External/AE SDK/Headers/AE_Macros.h @@ -0,0 +1,102 @@ +/*******************************************************************/ +/* */ +/* ADOBE CONFIDENTIAL */ +/* _ _ _ _ _ _ _ _ _ _ _ _ _ */ +/* */ +/* Copyright 1999 Adobe Systems Incorporated */ +/* All Rights Reserved. */ +/* */ +/* NOTICE: All information contained herein is, and remains the */ +/* property of Adobe Systems Incorporated and its suppliers, if */ +/* any. The intellectual and technical concepts contained */ +/* herein are proprietary to Adobe Systems Incorporated and its */ +/* suppliers and may be covered by U.S. and Foreign Patents, */ +/* patents in process, and are protected by trade secret or */ +/* copyright law. Dissemination of this information or */ +/* reproduction of this material is strictly forbidden unless */ +/* prior written permission is obtained from Adobe Systems */ +/* Incorporated. */ +/* */ +/*******************************************************************/ +/** AE_Macros.h + + Part of the Adobe After Effects 4.0 SDK. + Copyright 1998 Adobe Systems Incorporated. + All Rights Reserved. + + REVISION HISTORY + 06/12/96 bsa Updated for After Effects 3.1 + 04/06/97 bsa Updated for After Effects 3.1 Windows version + 03/01/99 bbb Added DH. + +**/ + +#ifndef _H_AE_MACROS +#define _H_AE_MACROS + +#include "A.h" + +#ifndef ERR + #define ERR(FUNC) do { if (!err) { err = (FUNC); } } while (0) +#endif + +#ifndef ERR2 + #define ERR2(FUNC) do { if (((err2 = (FUNC)) != A_Err_NONE) && !err) err = err2; } while (0) +#endif + +#ifndef AEFX_CLR_STRUCT +#define AEFX_CLR_STRUCT(STRUCT) \ + do { \ + A_long _t = sizeof(STRUCT); \ + A_char *_p = (A_char*)&(STRUCT); \ + while (_t--) { \ + *_p++ = 0; \ + } \ + } while (0); +#endif + +#ifndef DH +#define DH(h) (*(h)) +#endif + +#define FIX2INT(X) ((A_long)(X) >> 16) +#define INT2FIX(X) ((A_long)(X) << 16) +#define FIX2INT_ROUND(X) (FIX2INT((X) + 32768)) +#define FIX_2_FLOAT(X) ((A_FpLong)(X) / 65536.0) +#define FLOAT2FIX(F) ((PF_Fixed)((F) * 65536 + (((F) < 0) ? -0.5 : 0.5))) + +// These are already defined if using Objective-C +#ifndef ABS + #define ABS(N) ((N) < 0 ? -(N) : (N)) +#endif + +#ifndef MIN + #define MIN(A,B) ((A) < (B) ? (A) : (B)) +#endif + +#ifndef MAX + #define MAX(A, B) ((A) > (B) ? (A) : (B)) +#endif + +#define A_Fixed_ONE ((A_Fixed)0x00010000L) +#define A_Fixed_HALF ((A_Fixed)0x00008000L) + +#define PF_RECT_2_FIXEDRECT(R,FR) do { \ + (FR).left = INT2FIX((R).left); \ + (FR).top = INT2FIX((R).top); \ + (FR).right = INT2FIX((R).right); \ + (FR).bottom = INT2FIX((R).bottom); \ + } while (0) + +#define PF_FIXEDRECT_2_RECT(FR,R) do { \ + (R).left = (A_short)FIX2INT_ROUND((FR).left); \ + (R).top = (A_short)FIX2INT_ROUND((FR).top); \ + (R).right = (A_short)FIX2INT_ROUND((FR).right); \ + (R).bottom = (A_short)FIX2INT_ROUND((FR).bottom); \ + } while (0) + +#define CONVERT8TO16(A) ( (((long)(A) * PF_MAX_CHAN16) + PF_HALF_CHAN8) / PF_MAX_CHAN8 ) + +#define RATIO2FLOAT(R) (A_FpLong)((A_FpLong)(R).num / ((A_FpLong)(R).den)) + +#endif // _H_AX_MACROS diff --git a/External/AE SDK/Headers/AE_PluginData.h b/External/AE SDK/Headers/AE_PluginData.h new file mode 100644 index 00000000..790843f4 --- /dev/null +++ b/External/AE SDK/Headers/AE_PluginData.h @@ -0,0 +1,84 @@ +/*******************************************************************/ +/* */ +/* ADOBE CONFIDENTIAL */ +/* _ _ _ _ _ _ _ _ _ _ _ _ _ */ +/* */ +/* Copyright 2017 Adobe Systems Incorporated */ +/* All Rights Reserved. */ +/* */ +/* NOTICE: All information contained herein is, and remains the */ +/* property of Adobe Systems Incorporated and its suppliers, if */ +/* any. The intellectual and technical concepts contained */ +/* herein are proprietary to Adobe Systems Incorporated and its */ +/* suppliers and may be covered by U.S. and Foreign Patents, */ +/* patents in process, and are protected by trade secret or */ +/* copyright law. Dissemination of this information or */ +/* reproduction of this material is strictly forbidden unless */ +/* prior written permission is obtained from Adobe Systems */ +/* Incorporated. */ +/* */ +/*******************************************************************/ + + +#ifndef _H_AE_PLUGIN_DATA +#define _H_AE_PLUGIN_DATA + +#ifdef A_INTERNAL + #include "PF_Private.h" +#endif + +#include "A.h" + +#include + +#ifdef __cplusplus + extern "C" { +#endif + +typedef struct PF_PluginData * PF_PluginDataPtr; + +typedef A_Err (*PF_PluginDataCB)( + // The same plugin data pointer that was sent in the entry point + PF_PluginDataPtr inPtr, + const A_u_char* inNamePtr, + const A_u_char* inMatchNamePtr, + const A_u_char* inCategoryPtr, + const A_u_char* inEntryPointNamePtr, + // Type of plugin ( VFlt,eFKT ,8BFM) + A_long inkind, + // If the kind is eFKT, this argument must be PF_AE_PLUG_IN_VERSION + A_long inApiVersionMajor, + // If the kind is eFKT, this argument must be PF_AE_PLUG_IN_SUBVERS + A_long inApiVersionMinor, + A_long inReservedInfo + ) ; + +/* + * This is the Entry point function signature that must be implemented by the plugin + * Name of the function must be PluginDataEntryFunction +*/ +typedef A_Err (*PluginDataEntryFunctionPtr)( + // An opaque pointer, which must be sent as an argument in the callback + PF_PluginDataPtr inPtr, + // Callback function pointer + PF_PluginDataCB inPluginDataCallBackPtr, + // SPBasicSuite function pointer + struct SPBasicSuite* inSPBasicSuitePtr, + // Name of the host application which is invoking the plugin + const char* inHostName, + // Exact version of the host application e.x. 10.1.3 + const char* inHostVersion + ); + + + +#ifdef __cplusplus +} // end extern "C" +#endif + + + +#include + + +#endif /* _H_AE_PLUGIN_DATA */ diff --git a/External/AE SDK/Headers/DuckSuite.h b/External/AE SDK/Headers/DuckSuite.h new file mode 100644 index 00000000..59f9953c --- /dev/null +++ b/External/AE SDK/Headers/DuckSuite.h @@ -0,0 +1,13 @@ +#include "A.h" +#include + +#ifdef AE_OS_WIN + #include +#endif + +#define kDuckSuite1 "AEGP Duck Suite" +#define kDuckSuiteVersion1 1 + +typedef struct DuckSuite1 { + SPAPI A_Err (*Quack)(A_u_short timesSu); +} DuckSuite1; \ No newline at end of file diff --git a/External/AE SDK/Headers/FIEL_Public.h b/External/AE SDK/Headers/FIEL_Public.h new file mode 100644 index 00000000..8306b15b --- /dev/null +++ b/External/AE SDK/Headers/FIEL_Public.h @@ -0,0 +1,81 @@ +#ifndef _H_FIEL_PUBLIC +#define _H_FIEL_PUBLIC + +/* FIEL_Public.h + + (c) 1993 CoSA + + The purpose of this header is to define a standard way to communicate interlace information + within common image file formats. The FIEL_Label structure should be included as a + user data of type 'FIEL' of a QuickTime movie, and as 'FIEL' resouce 128 in an + image or animation file. + + The FIEL_Label structure may also be appended to the end of an ImageDescription if the creator + is unable to add the resource or user data. Only the first FIEL_Label in the movie may be + honored, however. If a sequence of frames is composed of multiple files, the FIEL_Label from only + the first frame may be honored. In a QuickTime movie, the first user data item (index 1) will be honored. + + If the version is increased, to preserve backward compatibility we will only add types + to the existing fields or add to the end of the FIEL_Label structure. + + *** Please note that most applications will only support interlaced full-height frames. The other + *** formats are included so the spec is as general as possible. If you choose to store field-rendered + *** video in one of the other formats it may not be de-interlaced properly by most applications. + + CoSA After Effects 1.0/1.1 outputs FIEL_Label version 0, with the obsolete tag 'Fiel' (not 'FIEL'). + The struct has a short version (set to 0) followed by a std::int32_t type that is 0 if field rendered, 1 + if upper field is first, and 2 if lower field is first. All field rendered frames output from + AE 1.0/1.1 are interlaced. + + Future versions of CoSA After Effects will label all output with a version 1 or higher FIEL_Label. + +*/ + +#include + +#define FIEL_Label_VERSION 1 + +#define FIEL_Tag 'FIEL' // use as udata and resource type +#define FIEL_ResID 128 + + +enum { + FIEL_Type_FRAME_RENDERED = 0, // FIEL_Order is irrelevant + FIEL_Type_INTERLACED = 1, + FIEL_Type_HALF_HEIGHT = 2, + FIEL_Type_FIELD_DOUBLED = 3, // 60 full size field-doubled frames/sec + FIEL_Type_UNSPECIFIED = 4 // do not use! +}; +typedef uint32_t FIEL_Type; + + +/* + If the frames are interlaced, the following structure tells which of the interlaced fields is + temporally first. If the frames are not interlaced but the animation was field rendered + (i.e. half height or field doubled), the structure tells which field the first sample (if the + label is attached to a multi-sample file like a QT movie) or the current sample (if the label is + attached to a single sample like a PICT file) contains. +*/ + +enum { + FIEL_Order_UPPER_FIRST = 0, + FIEL_Order_LOWER_FIRST = 1 +}; +typedef uint32_t FIEL_Order; + +#pragma pack(push, CoSAalign, 2) + typedef struct { + uint32_t signature; // always FIEL_Tag + int16_t version; + FIEL_Type type; + FIEL_Order order; + uint32_t reserved; + } FIEL_Label; + #if defined(A_INTERNAL) && defined(__cplusplus) + #include "AE_StructSizeAssert.h" + AE_STRUCT_SIZE_ASSERT(FIEL_Label, 18); + #endif + +#pragma pack(pop, CoSAalign) + +#endif diff --git a/External/AE SDK/Headers/Mach-O_prefix.h b/External/AE SDK/Headers/Mach-O_prefix.h new file mode 100644 index 00000000..e5da3715 --- /dev/null +++ b/External/AE SDK/Headers/Mach-O_prefix.h @@ -0,0 +1 @@ +#define __MACH__ 1 \ No newline at end of file diff --git a/External/AE SDK/Headers/MissingSuiteError.cpp b/External/AE SDK/Headers/MissingSuiteError.cpp new file mode 100644 index 00000000..5be71f4f --- /dev/null +++ b/External/AE SDK/Headers/MissingSuiteError.cpp @@ -0,0 +1,43 @@ +/*******************************************************************/ +/* */ +/* ADOBE CONFIDENTIAL */ +/* _ _ _ _ _ _ _ _ _ _ _ _ _ */ +/* */ +/* Copyright 2007 Adobe Systems Incorporated */ +/* All Rights Reserved. */ +/* */ +/* NOTICE: All information contained herein is, and remains the */ +/* property of Adobe Systems Incorporated and its suppliers, if */ +/* any. The intellectual and technical concepts contained */ +/* herein are proprietary to Adobe Systems Incorporated and its */ +/* suppliers and may be covered by U.S. and Foreign Patents, */ +/* patents in process, and are protected by trade secret or */ +/* copyright law. Dissemination of this information or */ +/* reproduction of this material is strictly forbidden unless */ +/* prior written permission is obtained from Adobe Systems */ +/* Incorporated. */ +/* */ +/*******************************************************************/ + +#include "AEGP_SuiteHandler.h" + +void AEGP_SuiteHandler::MissingSuiteError() const +{ + // Yes, we've read Scott Meyers, and know throwing + // a stack-based object can cause problems. Since + // the err is just a long, and since we aren't de- + // referencing it in any way, risk is mimimal. + + // As always, we expect those of you who use + // exception-based code to do a little less rudi- + // mentary job of it than we are here. + + // Also, excuse the Madagascar-inspired monkey + // joke; couldn't resist. + // -bbb 10/10/05 + + PF_Err poop = PF_Err_BAD_CALLBACK_PARAM; + + throw poop; +} + diff --git a/External/AE SDK/Headers/PF_Masks.h b/External/AE SDK/Headers/PF_Masks.h new file mode 100644 index 00000000..88870b82 --- /dev/null +++ b/External/AE SDK/Headers/PF_Masks.h @@ -0,0 +1,49 @@ +/* PF_Masks.h */ + + +#ifndef H_PF_MASKS +#define H_PF_MASKS + +#include +#include +#include +#include + + +#pragma pack( push, 2 ) + +#define PF_MASKS_MAJOR_VERSION 1 +#define PF_MASKS_MINOR_VERSION 0 + +#ifdef __cplusplus + extern "C" { +#endif + + +#define kPF_MaskSuite "AEGP Mask Suite" +#define kPF_MaskSuiteVersion1 1 + +typedef struct PF_MaskSuite1 { + + SPAPI A_Err (*PF_MaskWorldWithPath)( + PF_ProgPtr effect_ref, + PF_PathOutlinePtr *mask, /* >> */ + PF_FpLong feather_x, /* >> */ + PF_FpLong feather_y, /* >> */ + PF_Boolean invert, /* >> */ + PF_FpLong opacity, /* >> 0...1 */ + PF_Quality quality, /* >> */ + PF_EffectWorld *worldP, /* <> */ + PF_Rect *bboxPR0); /* >> */ + +} PF_MaskSuite1; + +#ifdef __cplusplus +} // end extern "C" +#endif + + +#pragma pack( pop ) + + +#endif /* H_PH_MASKS */ \ No newline at end of file diff --git a/External/AE SDK/Headers/PR_Public.h b/External/AE SDK/Headers/PR_Public.h new file mode 100644 index 00000000..b851a530 --- /dev/null +++ b/External/AE SDK/Headers/PR_Public.h @@ -0,0 +1,424 @@ +#ifndef _PR_Public_H +#define _PR_Public_H + +/** PR_Public.h + ** (C)2005 by Adobe Systems Inc. + ** Public header that defines the API for plug-in renderers + ** + ** Plugin renderers are known as artisans. They are AEGP modules which register + ** themselves with the plug-in render manager when they are loaded at + ** program startup. + ** Very little is passed to these functions, just an opaque context + ** and a handle to previously allocated data. The artisan must query + ** for other rendering parameters via AEGP suites. The appropriate + ** suites will take one of the opaque rendering contexts as one of their + ** parameters. + ** + ** The entry points are : + ** PR_GlobalSetupFunc + ** Called at artisan load. If necessary allocate global data that will be shared + ** among all instances of this type of artisan. + ** + ** PR_GlobalSetdownFunc + ** Called at program termination. Delete the global data if any allocated. + ** + ** PR_GlobalDoAboutFunc + ** Display an about box with revelant information about the artisan + ** + ** + ** PR_InstanceSetupFunc + ** An instance of the artisan is associated with each comp. Each instance has its + ** own data. It should be allocated within this function. + ** + ** PR_InstanceSetdownFunc + ** Delete allocated data if needed. + ** + ** PR_FlattenInstanceFunc + ** Return a flattened platform independent version of the instance data. + ** This is called when the artisan is being written to disk or a copy of the + ** artisan is being made. Do not disturb the src instance handle. + ** + ** PR_DoInstanceDialogFunc + ** Some artisans may have parameters. They may be set here. + ** + ** PR_FrameSetupFunc + ** Called just berfore render. Allocate the render handle, if needed. + ** + ** PR_RenderFunc + ** This is the main rendering function. + ** + ** PR_FrameSetdownFunc + ** Called just after render. Deallocate the render handle if needed. + ** + ** PR_Query + ** This can be called at any time after Instance Setup. It is used by AE + ** to inquire about geomertic transforms used by the artisan. AE uses this information + ** to draw layer handles, and manipulate the layers with a mouse better. + ** + **/ + + +#include +#include +#include + +#pragma pack( push, 4 ) + + + + +#ifdef __cplusplus + extern "C" { +#endif + + + + +#define PR_FileType_ARTISAN 'ARt' +#define PR_ARTISAN_EXTENSION ".aex" + +#define PR_ARTISAN_API_VERSION_MAJOR 1 +#define PR_ARTISAN_API_VERSION_MINOR 0 + + +#define PR_PUBLIC_MATCH_NAME_LEN 31 +#define PR_PUBLIC_ARTISAN_NAME_LEN 31 + + +/** $$$ move to aegp.h ***/ +typedef struct _Up_OpaqueMem **PR_Handle; +typedef PR_Handle PR_FlatHandle; + +typedef PR_Handle PR_GlobalDataH; // holds data private to the plug-in +typedef PR_Handle PR_InstanceDataH; +typedef PR_Handle PR_RenderDataH; + +typedef struct PR_GlobalContext **PR_GlobalContextH; // opaque until PR.h +typedef struct PR_InstanceContext **PR_InstanceContextH; // opaque until PR.h +typedef struct PR_RenderContext **PR_RenderContextH; // opaque until PR.h +typedef struct PR_QueryContext **PR_QueryContextH; // opaque until PR.h + +typedef struct PF_LayerDef *PF_EffectWorldPtr; +/** + ** in data is passed to every pr entry function + **/ +typedef void (*PR_MessageFunc) (A_Err err_number, const A_char *msgA); + + +typedef struct PR_InData { + PR_MessageFunc msg_func; + const struct SPBasicSuite *pica_basicP; + A_long aegp_plug_id; + void *aegp_refconPV; +} PR_InData; + + + + + +/** + ** response from dialog box function + **/ +enum { + PR_DialogResult_NO_CHANGE, + PR_DialogResult_CHANGE_MADE +}; +typedef A_long PR_DialogResult; + + + +/** + ** The types of queries that will be made. + ** + **/ +enum { + PR_QueryType_NONE = 0, + PR_QueryType_TRANSFORM, + PR_QueryType_INTERACTIVE_WINDOW_DISPOSE, + PR_QueryType_INTERACTIVE_WINDOW_CLEAR, + PR_QueryType_INTERACTIVE_WINDOW_FROZEN_PROXY, + PR_QueryType_INTERACTIVE_SWAP_BUFFER, + PR_QueryType_INTERACTIVE_DRAW_PROCS, + PR_QueryType_PREPARE_FOR_LINE_DRAWING, + PR_QueryType_UNPREPARE_FOR_LINE_DRAWING, + PR_QueryType_GET_CURRENT_CONTEXT_SAFE_FOR_LINE_DRAWING, + PR_QueryType_GET_ARTISAN_QUALITY, +}; + +typedef A_u_long PR_QueryType; + + +// If this sounds interesting, talk to us +enum { + PR_ArtisanFeature_NONE = 0 +}; +typedef A_long PR_ArtisanFeature_Flags; + + +/** + ** PR_InstanceSetupFunc flags + **/ +enum { + PR_InstanceFlags_NONE = 0x0, + PR_InstanceFlags_DUPLICATE +}; + +typedef A_u_long PR_InstanceFlags; + + +/*********************** plugin entry points ***************************** + ** the main routine of each plugin fills in these function pointers + ** AE will call them as appropriate + ****************************************************************************/ + + + +/** + ** called after main. This happens just once, after the plugin is loaded. + ** The global data is common across all instances of the plugin + **/ +typedef A_Err (*PR_GlobalSetupFunc)( const PR_InData *in_dataP, /* >> */ + PR_GlobalContextH global_contextH, /* >> */ + PR_GlobalDataH *global_dataPH); /* << */ + +/** + ** dispose of the global data + **/ +typedef A_Err (*PR_GlobalSetdownFunc)( const PR_InData *in_dataP, /* >> */ + PR_GlobalContextH global_contextH, /* >> */ + PR_GlobalDataH global_dataH); /* <> */ // must be disposed by plugin + + +/** + ** display an about box + **/ +typedef A_Err (*PR_GlobalDoAboutFunc)( const PR_InData *in_dataP, /* >> */ + PR_GlobalContextH global_contextH, /* >> */ + PR_GlobalDataH global_dataH); /* <> */ + + + +/** + ** Analogous to an Effect's Sequence setup call. This sets up the renderer's + ** instance data. + **/ +typedef A_Err (*PR_InstanceSetupFunc)( + const PR_InData *in_dataP, /* >> */ + PR_GlobalContextH global_contextH, /* >> */ + PR_InstanceContextH instance_contextH, /* >> */ + PR_GlobalDataH global_dataH, /* >> */ + PR_InstanceFlags flags, + PR_FlatHandle flat_dataH0, /* >> */ + PR_InstanceDataH *instance_dataPH); /* << */ + + +/** + ** dispose of the instance data + **/ +typedef A_Err (*PR_InstanceSetdownFunc)( + const PR_InData *in_dataP, /* >> */ + const PR_GlobalContextH global_contextH, /* >> */ + const PR_InstanceContextH instance_contextH, /* >> */ + PR_GlobalDataH global_dataH, /* >> */ + PR_InstanceDataH instance_dataH); /* >> */ // must be disposed by plugin + + + +/** + ** flatten your data in preparation to being written to disk. + ** Make sure its OS independent + **/ +typedef A_Err (*PR_FlattenInstanceFunc)( + const PR_InData *in_dataP, /* >> */ + PR_GlobalContextH global_contextH, /* >> */ + PR_InstanceContextH instance_contextH, /* >> */ + PR_GlobalDataH global_dataH, /* <> */ + PR_InstanceDataH instance_dataH, /* <> */ + PR_FlatHandle *flatH); /* << */ + + + + + +/** + ** if the renderer has parameters, this is where they get set or changed. + **/ + + +typedef A_Err (*PR_DoInstanceDialogFunc)( const PR_InData *in_dataP, /* >> */ + PR_GlobalContextH global_contextH, /* >> */ + PR_InstanceContextH instance_contextH, /* >> */ + PR_GlobalDataH global_dataH, /* <> */ + PR_InstanceDataH instance_dataH, /* <> */ + PR_DialogResult *resultP); /* << */ + + + +/** + ** allocate render data if needed + **/ +typedef A_Err (*PR_FrameSetupFunc)( + const PR_InData *in_dataP, /* >> */ + PR_GlobalContextH global_contextH, /* >> */ + PR_InstanceContextH instance_contextH, /* >> */ + PR_RenderContextH render_contextH, /* >> */ + PR_GlobalDataH global_dataH, /* <> */ + PR_InstanceDataH instance_dataH, /* <> */ + PR_RenderDataH *render_dataPH); /* << */ + + +/** + ** deallocate render data + **/ +typedef A_Err (*PR_FrameSetdownFunc)( + const PR_InData *in_dataP, /* >> */ + PR_GlobalContextH global_contextH, /* >> */ + PR_InstanceContextH instance_contextH, /* >> */ + PR_RenderContextH render_contextH, /* >> */ + PR_GlobalDataH global_dataH, /* <> */ + PR_InstanceDataH instance_dataH, /* <> */ + PR_RenderDataH render_dataH); + + +/** + ** the main drawing routine + **/ +typedef A_Err (*PR_RenderFunc)( + const PR_InData *in_dataP, /* >> */ + PR_GlobalContextH global_contextH, /* >> */ + PR_InstanceContextH instance_contextH, /* >> */ + PR_RenderContextH render_contextH, /* >> */ + PR_GlobalDataH global_dataH, /* <> */ + PR_InstanceDataH instance_dataH, /* <> */ + PR_RenderDataH render_dataH); + + + + +/** + ** AE will need to have the artisan process data on its behalf such as + ** projecting points to the screen, transforming axis, etc. This routine will handle + ** it all + **/ +typedef A_Err (*PR_QueryFunc)( const PR_InData *in_dataP, /* >> */ + PR_GlobalContextH global_contextH, /* >> */ + PR_InstanceContextH instance_contextH, /* >> */ + PR_QueryContextH query_contextH, /* <> */ + PR_QueryType query_type, /* >> */ + PR_GlobalDataH global_data, /* >> */ + PR_InstanceDataH instance_dataH); /* >> */ + + + + +/** + ** main fills this in, just once at plugin load time + ** These are the entry points that AE calls to use an artisan. + **/ + +typedef struct { + + PR_GlobalSetupFunc global_setup_func0; + PR_GlobalSetdownFunc global_setdown_func0; + PR_GlobalDoAboutFunc global_do_about_func0; + + PR_InstanceSetupFunc setup_instance_func0; + PR_InstanceSetdownFunc setdown_instance_func0; + PR_FlattenInstanceFunc flatten_instance_func0; + PR_DoInstanceDialogFunc do_instance_dialog_func0; + + PR_FrameSetupFunc frame_setup_func0; + PR_RenderFunc render_func; // must have at least this one function + PR_FrameSetdownFunc frame_setdown_func0; + + PR_QueryFunc query_func0; + +} PR_ArtisanEntryPoints; + + + + +/** + ** line drawing routines for interactive artisans + **/ +typedef void (*PR_Draw_MoveToFunc)(A_FpLong x, A_FpLong y); + +typedef void (*PR_Draw_LineToFunc)(A_FpLong x, A_FpLong y); + +typedef void (*PR_Draw_LineRelFunc)(A_FpLong dx, A_FpLong dy); + +typedef void (*PR_Draw_ForeColorFunc)(const A_Color *fore_color); + +typedef void (*PR_Draw_BackColorFunc)(const A_Color *fore_color); + +typedef void (*PR_Draw_FrameRectFunc)(const A_FloatRect *rectPR ); + +typedef void (*PR_Draw_PaintRectFunc)(const A_FloatRect *rectPR ); + +typedef void (*PR_Draw_FrameOvalFunc)(const A_FloatRect *rectPR ); + +typedef void (*PR_Draw_PaintOvalFunc)(const A_FloatRect *rectPR ); + +typedef void (*PR_Draw_InvertRectFunc)(const A_FloatRect *rectPR ); + +typedef void (*PR_Draw_SetClipFunc)(const A_FloatRect *rectPR, A_Boolean invertB ); + +typedef void (*PR_Draw_PenNormal)(void); + +typedef void (*PR_Draw_PenSize)(A_FpLong widthS, A_FpLong heightS); + +typedef void (*PR_Draw_PenPat)(A_u_char pattern); + +typedef void (*PR_Draw_Invert)(A_Boolean); + +typedef void (*PR_CacheIconFunc)(PF_EffectWorldPtr iconP); + +typedef void (*PR_DrawCachedIconFunc)(A_long x, A_long y); + +typedef void (*PR_DrawStringFunc)(const A_UTF16Char *nameZ, PF_FontStyleSheet style, const A_Color *fore_colorP, const A_Color *shadow_colorP, const A_FloatPoint *originP, const A_FloatPoint *shadow_offsetP); + +typedef void (*PR_StrokePolyFunc) (A_long nptsL, A_FloatPoint *ptsA); + +typedef void (*PR_PaintPolyFunc) (A_long nptsL, A_FloatPoint *ptsA); + + + +typedef struct { + + PR_Draw_MoveToFunc move_to_func; + PR_Draw_LineToFunc line_to_func; + PR_Draw_LineRelFunc line_rel_func; + PR_Draw_ForeColorFunc fore_color_func; + PR_Draw_BackColorFunc back_color_func; + PR_Draw_FrameRectFunc frame_rect_func; + PR_Draw_PaintRectFunc paint_rect_func; + PR_Draw_FrameOvalFunc frame_oval_func; + PR_Draw_PaintOvalFunc paint_oval_func; + PR_Draw_InvertRectFunc invert_rect_func; + PR_Draw_SetClipFunc set_clip_func; + PR_Draw_PenNormal pen_normal_func; + PR_Draw_PenSize pen_size_func; + PR_Draw_PenPat pen_pat_func; + PR_Draw_Invert invert_func; + PR_CacheIconFunc cache_icon_func; + PR_DrawCachedIconFunc draw_cached_icon_func; + PR_DrawStringFunc draw_string_func; + PR_StrokePolyFunc stroke_poly_func; + PR_PaintPolyFunc paint_poly_func; + +} PR_InteractiveDrawProcs; + + + + + +#pragma pack( pop ) + + + +#ifdef __cplusplus + } +#endif + + +#endif diff --git a/External/AE SDK/Headers/PT_Public.h b/External/AE SDK/Headers/PT_Public.h new file mode 100644 index 00000000..7065b1a9 --- /dev/null +++ b/External/AE SDK/Headers/PT_Public.h @@ -0,0 +1,120 @@ +/*******************************************************************/ +/* */ +/* ADOBE CONFIDENTIAL */ +/* _ _ _ _ _ _ _ _ _ _ _ _ _ */ +/* */ +/* Copyright 2007 Adobe Systems Incorporated */ +/* All Rights Reserved. */ +/* */ +/* NOTICE: All information contained herein is, and remains the */ +/* property of Adobe Systems Incorporated and its suppliers, if */ +/* any. The intellectual and technical concepts contained */ +/* herein are proprietary to Adobe Systems Incorporated and its */ +/* suppliers and may be covered by U.S. and Foreign Patents, */ +/* patents in process, and are protected by trade secret or */ +/* copyright law. Dissemination of this information or */ +/* reproduction of this material is strictly forbidden unless */ +/* prior written permission is obtained from Adobe Systems */ +/* Incorporated. */ +/* */ +/*******************************************************************/ + +#ifndef _H_PT_Public +#define _H_PT_Public + +/*** + + This header file defines public interface for tracker or pixel- + matching plug-ins. + + Their function is to implement a pixel matching algorithm that a + tracker in After Effects could use to track user specified features. + + Tracker in the application provides UI and sets the main parameters. + Tracker plug-ins, however, can provide a simple dialog-based UI for + parameters specific to the implemented algorithm(s). + + +***/ + +#include + +#pragma pack( push, 4 ) + +#ifdef __cplusplus + extern "C" { +#endif + +#define PT_TRACKER_API_VERSION_MAJOR 1 +#define PT_TRACKER_API_VERSION_MINOR 0 + +#define PT_TRACKER_MATCH_NAME_LEN 31 +#define PT_TRACKER_NAME_LEN 31 + +typedef A_long PT_Index; + + +typedef struct PT_Tracker *PT_TrackerPtr; +typedef struct PT_TrackerInstance *PT_TrackerInstancePtr; +typedef struct PT_TrackingContext *PT_TrackingContextPtr; + +// plug-in entry points +typedef A_Err (*PT_GlobalSetupFunc)( + const PT_TrackerPtr trackerP, + AEGP_MemHandle *global_dataPH); // << + +typedef A_Err (*PT_GlobalSetdownFunc)( + const PT_TrackerPtr trackerP); + +typedef A_Err (*PT_GlobalDoAboutFunc)( + const PT_TrackerPtr trackerP); + +typedef A_Err (*PT_InstanceSetupFunc)( + const PT_TrackerInstancePtr tracker_instanceP, + AEGP_MemHandle flat_instance_dataH0, + AEGP_MemHandle *instance_dataPH); // currently has to be flat (no handles inside a handle) + +typedef A_Err (*PT_InstanceSetdownFunc)( + const PT_TrackerInstancePtr tracker_instanceP); + +typedef A_Err (*PT_InstanceFlattenFunc)( + const PT_TrackerInstancePtr tracker_instanceP, + AEGP_MemHandle *flat_instance_dataPH); + +typedef A_Err (*PT_InstanceDoOptionsFunc)( + const PT_TrackerInstancePtr tracker_instanceP); + +typedef A_Err (*PT_PrepareTrackFunc)( + const PT_TrackingContextPtr contextP, + AEGP_MemHandle *tracker_dataPH); // << + +typedef A_Err (*PT_TrackFunc)( + const PT_TrackingContextPtr contextP); + +typedef A_Err (*PT_FinishTrackFunc)( + const PT_TrackingContextPtr contextP); + + +typedef struct { + PT_GlobalSetupFunc global_setup_func; + PT_GlobalSetdownFunc global_setdown_func; + PT_GlobalDoAboutFunc global_do_about_func; + + PT_InstanceSetupFunc instance_setup_func; + PT_InstanceSetdownFunc instance_setdown_func; + PT_InstanceFlattenFunc instance_flatten_func; + PT_InstanceDoOptionsFunc instance_do_options_func; + + PT_PrepareTrackFunc track_prepare_func; + PT_TrackFunc track_func; + PT_FinishTrackFunc track_finish_func; +} PT_TrackerEntryPoints; + + +#pragma pack( pop ) + +#ifdef __cplusplus + } +#endif + +#endif // _H_PT_Public \ No newline at end of file diff --git a/External/AE SDK/Headers/Param_Utils.h b/External/AE SDK/Headers/Param_Utils.h new file mode 100644 index 00000000..f4129069 --- /dev/null +++ b/External/AE SDK/Headers/Param_Utils.h @@ -0,0 +1,343 @@ +#ifndef H_PARAM_UTILS +#define H_PARAM_UTILS + +// do not include DVA headers here +#include +#include + +// requires the explicit use of 'def' for the struct name + +#define PF_ParamDef_IS_PUI_FLAG_SET(_defP, _puiFlag) \ + (((_defP)->ui_flags & _puiFlag) != 0) + +#define PF_ParamDef_IS_PARAM_FLAG_SET(_defP, _paramFlag) \ + (((_defP)->flags & _paramFlag) != 0) + + +#define PF_ADD_COLOR(NAME, RED, GREEN, BLUE, ID)\ + do {\ + PF_Err priv_err = PF_Err_NONE; \ + def.param_type = PF_Param_COLOR; \ + PF_STRCPY(def.name, (NAME) ); \ + def.u.cd.value.red = (RED); \ + def.u.cd.value.green = (GREEN); \ + def.u.cd.value.blue = (BLUE); \ + def.u.cd.value.alpha = 255; \ + def.u.cd.dephault = def.u.cd.value; \ + def.uu.id = (ID); \ + if ((priv_err = PF_ADD_PARAM(in_data, -1, &def)) != PF_Err_NONE) return priv_err; \ + } while (0) + +#define PF_ADD_ARBITRARY2(NAME, WIDTH, HEIGHT, PARAM_FLAGS, PUI_FLAGS, DFLT, ID, REFCON)\ + do {\ + PF_Err priv_err = PF_Err_NONE; \ + def.param_type = PF_Param_ARBITRARY_DATA; \ + def.flags = (PARAM_FLAGS); \ + PF_STRCPY(def.name, (NAME) ); \ + def.ui_width = (WIDTH);\ + def.ui_height = (HEIGHT);\ + def.ui_flags = (PUI_FLAGS); \ + def.u.arb_d.value = NULL;\ + def.u.arb_d.pad = 0;\ + def.u.arb_d.dephault = (DFLT); \ + def.uu.id = def.u.arb_d.id = (ID); \ + def.u.arb_d.refconPV = REFCON; \ + if ((priv_err = PF_ADD_PARAM(in_data, -1, &def)) != PF_Err_NONE) return priv_err; \ + } while (0) + +#define PF_ADD_ARBITRARY(NAME, WIDTH, HEIGHT, PUI_FLAGS, DFLT, ID, REFCON)\ + PF_ADD_ARBITRARY2(NAME, WIDTH, HEIGHT, PF_ParamFlag_NONE, PUI_FLAGS, DFLT, ID, REFCON) + +#define PF_ADD_SLIDER(NAME, VALID_MIN, VALID_MAX, SLIDER_MIN, SLIDER_MAX, DFLT, ID) \ + do {\ + PF_Err priv_err = PF_Err_NONE; \ + def.param_type = PF_Param_SLIDER; \ + PF_STRCPY(def.name, (NAME) ); \ + def.u.sd.value_str[0] = '\0'; \ + def.u.sd.value_desc[0] = '\0'; \ + def.u.sd.valid_min = (VALID_MIN); \ + def.u.sd.slider_min = (SLIDER_MIN); \ + def.u.sd.valid_max = (VALID_MAX); \ + def.u.sd.slider_max = (SLIDER_MAX); \ + def.u.sd.value = def.u.sd.dephault = (DFLT); \ + def.uu.id = (ID); \ + if ((priv_err = PF_ADD_PARAM(in_data, -1, &def)) != PF_Err_NONE) return priv_err; \ + } while (0) + +#define PF_ADD_FIXED(NAME, VALID_MIN, VALID_MAX, SLIDER_MIN, SLIDER_MAX, DFLT, PREC, DISP, FLAGS, ID) \ + do {\ + PF_Err priv_err = PF_Err_NONE; \ + def.param_type = PF_Param_FIX_SLIDER; \ + PF_STRCPY(def.name, (NAME) ); \ + def.u.fd.value_str[0] = '\0'; \ + def.u.fd.value_desc[0] = '\0'; \ + def.u.fd.valid_min = (PF_Fixed)((VALID_MIN) * 65536.0); \ + def.u.fd.slider_min = (PF_Fixed)((SLIDER_MIN) * 65536.0); \ + def.u.fd.valid_max = (PF_Fixed)((VALID_MAX) * 65536.0); \ + def.u.fd.slider_max = (PF_Fixed)((SLIDER_MAX) * 65536.0); \ + def.u.fd.value = def.u.fd.dephault = (PF_Fixed)((DFLT) * 65536.0); \ + def.u.fd.precision = (A_short)(PREC); \ + def.u.fd.display_flags |= (A_short)(DISP); \ + def.flags |= (FLAGS); \ + def.uu.id = (ID); \ + if ((priv_err = PF_ADD_PARAM(in_data, -1, &def)) != PF_Err_NONE) return priv_err; \ + } while (0) + +// why does fs_flags get or-ed in? and why is CURVE_TOLERANCE param ignored? and .flags is never set. oy. +#define PF_ADD_FLOAT_SLIDER(NAME, VALID_MIN, VALID_MAX, SLIDER_MIN, SLIDER_MAX, CURVE_TOLERANCE, DFLT, PREC, DISP, WANT_PHASE, ID) \ + do {\ + PF_Err priv_err = PF_Err_NONE; \ + def.param_type = PF_Param_FLOAT_SLIDER; \ + PF_STRCPY(def.name, (NAME) ); \ + def.u.fs_d.valid_min = (VALID_MIN); \ + def.u.fs_d.slider_min = (SLIDER_MIN); \ + def.u.fs_d.valid_max = (VALID_MAX); \ + def.u.fs_d.slider_max = (SLIDER_MAX); \ + def.u.fs_d.value = (DFLT); \ + def.u.fs_d.dephault = (PF_FpShort)(def.u.fs_d.value); \ + def.u.fs_d.precision = (PREC); \ + def.u.fs_d.display_flags = (DISP); \ + def.u.fs_d.fs_flags |= (WANT_PHASE) ? PF_FSliderFlag_WANT_PHASE : 0; \ + def.u.fs_d.curve_tolerance = AEFX_AUDIO_DEFAULT_CURVE_TOLERANCE;\ + def.uu.id = (ID); \ + if ((priv_err = PF_ADD_PARAM(in_data, -1, &def)) != PF_Err_NONE) return priv_err; \ + } while (0) + +// safer newer version +#define PF_ADD_FLOAT_SLIDERX(NAME, VALID_MIN, VALID_MAX, SLIDER_MIN, SLIDER_MAX, DFLT, PREC, DISP, FLAGS, ID) \ + do { \ + AEFX_CLR_STRUCT(def); \ + def.flags = (FLAGS); \ + PF_ADD_FLOAT_SLIDER(NAME, VALID_MIN, VALID_MAX, SLIDER_MIN, SLIDER_MAX, 0, DFLT, PREC, DISP, 0, ID); \ + } while (0) + +// copied from Pr version of Param_Utils.h. It is used in some of Pr versions of AE effects +#define PF_ADD_FLOAT_EXPONENTIAL_SLIDER(NAME, VALID_MIN, VALID_MAX, SLIDER_MIN, SLIDER_MAX, CURVE_TOLERANCE, DFLT, PREC, DISP, WANT_PHASE, EXPONENT, ID) \ +do {\ +PF_Err priv_err = PF_Err_NONE; \ +def.param_type = PF_Param_FLOAT_SLIDER; \ +PF_STRCPY(def.name, (NAME) ); \ +def.u.fs_d.valid_min = (VALID_MIN); \ +def.u.fs_d.slider_min = (SLIDER_MIN); \ +def.u.fs_d.valid_max = (VALID_MAX); \ +def.u.fs_d.slider_max = (SLIDER_MAX); \ +def.u.fs_d.value = (DFLT); \ +def.u.fs_d.dephault = (DFLT); \ +def.u.fs_d.precision = (PREC); \ +def.u.fs_d.display_flags = (DISP); \ +def.u.fs_d.fs_flags |= (WANT_PHASE) ? PF_FSliderFlag_WANT_PHASE : 0; \ +def.u.fs_d.curve_tolerance = AEFX_AUDIO_DEFAULT_CURVE_TOLERANCE;\ +def.u.fs_d.useExponent = true;\ +def.u.fs_d.exponent = EXPONENT;\ +def.uu.id = (ID); \ +if ((priv_err = PF_ADD_PARAM(in_data, -1, &def)) != PF_Err_NONE) return priv_err; \ +} while (0) + +enum { PF_Precision_INTEGER, PF_Precision_TENTHS, PF_Precision_HUNDREDTHS, PF_Precision_THOUSANDTHS, PF_Precision_TEN_THOUSANDTHS }; + +#define PF_ADD_CHECKBOX(NAME_A, NAME_B, DFLT, FLAGS, ID)\ + do {\ + PF_Err priv_err = PF_Err_NONE; \ + def.param_type = PF_Param_CHECKBOX; \ + PF_STRCPY(def.name, NAME_A); \ + def.u.bd.u.nameptr = (NAME_B); \ + def.u.bd.value = (DFLT); \ + def.u.bd.dephault = (PF_Boolean)(def.u.bd.value); \ + def.flags |= (FLAGS); \ + def.uu.id = (ID); \ + if ((priv_err = PF_ADD_PARAM(in_data, -1, &def)) != PF_Err_NONE) return priv_err; \ + } while (0) + +// safer newer version +#define PF_ADD_CHECKBOXX(NAME, DFLT, FLAGS, ID)\ + do {\ + AEFX_CLR_STRUCT(def); \ + PF_ADD_CHECKBOX(NAME, "", DFLT, FLAGS, ID); \ + } while (0) + +#define PF_ADD_BUTTON(PARAM_NAME, BUTTON_NAME, PUI_FLAGS, PARAM_FLAGS, ID)\ + do {\ + AEFX_CLR_STRUCT(def); \ + PF_Err priv_err = PF_Err_NONE; \ + def.param_type = PF_Param_BUTTON; \ + PF_STRCPY(def.name, PARAM_NAME); \ + def.u.button_d.u.namesptr = (BUTTON_NAME); \ + def.flags = (PARAM_FLAGS); \ + def.ui_flags = (PUI_FLAGS); \ + def.uu.id = (ID); \ + if ((priv_err = PF_ADD_PARAM(in_data, -1, &def)) != PF_Err_NONE) return priv_err; \ + } while (0) + +#define PF_ADD_ANGLE(NAME, DFLT, ID) \ + do {\ + PF_Err priv_err = PF_Err_NONE; \ + def.param_type = PF_Param_ANGLE; \ + PF_STRCPY(def.name, (NAME) ); \ + def.u.ad.value = def.u.ad.dephault = (PF_Fixed)((DFLT) * 65536.0); \ + def.uu.id = (ID); \ + if ((priv_err = PF_ADD_PARAM(in_data, -1, &def)) != PF_Err_NONE) return priv_err; \ + } while (0) + + +#define PF_ADD_NULL(NAME, ID) \ + do {\ + PF_Err priv_err = PF_Err_NONE; \ + def.param_type = PF_Param_NO_DATA; \ + PF_STRCPY(def.name, (NAME) ); \ + def.uu.id = (ID); \ + if ((priv_err = PF_ADD_PARAM(in_data, -1, &def)) != PF_Err_NONE) return priv_err; \ + } while (0) + + +#define PF_ADD_POPUP(NAME, CHOICES, DFLT, STRING, ID) \ + do {\ + PF_Err priv_err = PF_Err_NONE; \ + def.param_type = PF_Param_POPUP; \ + PF_STRCPY(def.name, (NAME) ); \ + def.u.pd.num_choices = (CHOICES); \ + def.u.pd.dephault = (DFLT); \ + def.u.pd.value = def.u.pd.dephault; \ + def.u.pd.u.namesptr = (STRING); \ + def.uu.id = (ID); \ + if ((priv_err = PF_ADD_PARAM(in_data, -1, &def)) != PF_Err_NONE) return priv_err; \ + } while (0) + +#define PF_ADD_LAYER(NAME, DFLT, ID) \ + do {\ + PF_Err priv_err = PF_Err_NONE; \ + def.param_type = PF_Param_LAYER; \ + PF_STRCPY(def.name, (NAME) ); \ + def.u.ld.dephault = (DFLT); \ + def.uu.id = ID;\ + if ((priv_err = PF_ADD_PARAM(in_data, -1, &def)) != PF_Err_NONE) return priv_err; \ + } while (0) + +#define PF_ADD_255_SLIDER(NAME, DFLT, ID)\ + PF_ADD_SLIDER( (NAME), 0, 255, 0, 255, (DFLT), (ID)) + +#define PF_ADD_PERCENT(NAME, DFLT, ID)\ + PF_ADD_FIXED( (NAME), 0, 100, 0, 100, (DFLT), 1, 1, 0, (ID)) + +#define PF_ADD_POINT(NAME, X_DFLT, Y_DFLT, RESTRICT_BOUNDS, ID) \ + do {\ + PF_Err priv_err = PF_Err_NONE; \ + def.param_type = PF_Param_POINT; \ + PF_STRCPY(def.name, (NAME) ); \ + def.u.td.restrict_bounds = RESTRICT_BOUNDS;\ + def.u.td.x_value = def.u.td.x_dephault = (X_DFLT << 16); \ + def.u.td.y_value = def.u.td.y_dephault = (Y_DFLT << 16); \ + def.uu.id = (ID); \ + if ((priv_err = PF_ADD_PARAM(in_data, -1, &def)) != PF_Err_NONE) return priv_err; \ + } while (0) + +#define PF_ADD_POINT_3D(NAME, X_DFLT, Y_DFLT, Z_DFLT, ID) \ + do {\ + AEFX_CLR_STRUCT(def); \ + PF_Err priv_err = PF_Err_NONE; \ + def.param_type = PF_Param_POINT_3D; \ + PF_STRCPY(def.name, (NAME) ); \ + def.u.point3d_d.x_value = def.u.point3d_d.x_dephault = X_DFLT; \ + def.u.point3d_d.y_value = def.u.point3d_d.y_dephault = Y_DFLT; \ + def.u.point3d_d.z_value = def.u.point3d_d.z_dephault = Y_DFLT; \ + def.uu.id = (ID); \ + if ((priv_err = PF_ADD_PARAM(in_data, -1, &def)) != PF_Err_NONE) return priv_err; \ + } while (0) + +#define PF_ADD_TOPIC(NAME, ID) \ + do {\ + PF_Err priv_err = PF_Err_NONE; \ + def.param_type = PF_Param_GROUP_START; \ + PF_STRCPY(def.name, (NAME) ); \ + def.uu.id = (ID); \ + if ((priv_err = PF_ADD_PARAM(in_data, -1, &def)) != PF_Err_NONE) return priv_err; \ + } while (0) + +#define PF_END_TOPIC(ID) \ + do {\ + PF_Err priv_err = PF_Err_NONE; \ + def.param_type = PF_Param_GROUP_END; \ + def.uu.id = (ID); \ + if ((priv_err = PF_ADD_PARAM(in_data, -1, &def)) != PF_Err_NONE) return priv_err; \ + } while (0) + +#define PF_ADD_VERSIONED_FLAG(NAME) \ + do {\ + PF_Err priv_err = PF_Err_NONE; \ + def.param_type = PF_Param_CHECKBOX; \ + def.name[0] = 0; \ + def.u.bd.u.nameptr = (NAME); \ + def.u.bd.value = true; \ + def.u.bd.dephault = false; \ + def.flags = PF_ParamFlag_USE_VALUE_FOR_OLD_PROJECTS; \ + def.ui_flags = PF_PUI_INVISIBLE; \ + if ((priv_err = PF_ADD_PARAM(in_data, -1, &def)) != PF_Err_NONE) return priv_err; \ + } while (0) + +// newer safer version +#define PF_ADD_TOPICX(NAME, FLAGS, ID) \ + do {\ + AEFX_CLR_STRUCT(def); \ + def.flags = (FLAGS); \ + PF_ADD_TOPIC(NAME, ID); \ + } while (0) + +#define PF_ADD_POPUPX(NAME, NUM_CHOICES, DFLT, ITEMS_STRING, FLAGS, ID) \ + do { \ + AEFX_CLR_STRUCT(def); \ + def.flags = (FLAGS); \ + PF_ADD_POPUP(NAME, NUM_CHOICES, DFLT, ITEMS_STRING, ID); \ + } while (0) + +enum { PF_ParamFlag_NONE=0 }; // SBI:AE_Effect.h + +#define PF_ADD_FLOAT_SLIDERX_DISABLED(NAME, VALID_MIN, VALID_MAX, SLIDER_MIN, SLIDER_MAX, DFLT, PREC, DISP, FLAGS, ID) \ + do { \ + AEFX_CLR_STRUCT(def); \ + def.flags = (FLAGS);\ + def.ui_flags = PF_PUI_DISABLED;\ + PF_ADD_FLOAT_SLIDER(NAME, VALID_MIN, VALID_MAX, SLIDER_MIN, SLIDER_MAX, 0, DFLT, PREC, DISP, 0, ID); \ + } while (0) + +namespace fxparam_utility { + + template + inline int RoundF(T x) + { + int ret; + + if (x > 0) { + ret = (int)(x + (T)0.5); + } else { + if ((int)(x + (T)0.5) == (x + (T)0.5)) { + ret = (int)x; + } else { + ret = (int)(x - (T)0.5); + } + } + + return ret; + } +}; + +inline PF_Err PF_AddPointControl(PF_InData *in_data, + const char *nameZ, + float x_defaultF, // 0-1 + float y_defaultF, // 0-1 + bool restrict_boundsB, + PF_ParamFlags param_flags, + PF_ParamUIFlags pui_flags, + A_long param_id) +{ + PF_ParamDef def = {{0}}; + namespace du = fxparam_utility; + + def.flags = param_flags; + def.ui_flags = pui_flags; + + PF_ADD_POINT(nameZ, du::RoundF(x_defaultF*100), du::RoundF(y_defaultF*100), restrict_boundsB, param_id); // has error return in macro + + return PF_Err_NONE; +} + + +#endif // H_PARAM_UTILS diff --git a/External/AE SDK/Headers/PrSDKAESupport.h b/External/AE SDK/Headers/PrSDKAESupport.h new file mode 100644 index 00000000..7bf914f0 --- /dev/null +++ b/External/AE SDK/Headers/PrSDKAESupport.h @@ -0,0 +1,547 @@ +/*******************************************************************/ +/* */ +/* ADOBE CONFIDENTIAL */ +/* _ _ _ _ _ _ _ _ _ _ _ _ _ */ +/* */ +/* Copyright 2002 Adobe Systems Incorporated */ +/* All Rights Reserved. */ +/* */ +/* NOTICE: All information contained herein is, and remains the */ +/* property of Adobe Systems Incorporated and its suppliers, if */ +/* any. The intellectual and technical concepts contained */ +/* herein are proprietary to Adobe Systems Incorporated and its */ +/* suppliers and may be covered by U.S. and Foreign Patents, */ +/* patents in process, and are protected by trade secret or */ +/* copyright law. Dissemination of this information or */ +/* reproduction of this material is strictly forbidden unless */ +/* prior written permission is obtained from Adobe Systems */ +/* Incorporated. */ +/* */ +/*******************************************************************/ + +#ifndef PRSDKAESUPPORT_H +#define PRSDKAESUPPORT_H + +#ifdef PREMIERE_INTERNAL + +#ifndef PRSDKTYPES_H +#include "PrSDKTypes.h" +#endif + +#ifndef PRSDKTIMESUITE_H +#include "PrSDKTimeSuite.h" +#endif + +#endif + +#ifndef PRSDKPIXELFORMAT_H +#include "PrSDKPixelFormat.h" +#endif + +#ifdef _WIN32 +// Required for AE Stuff +#ifndef MSWindows +#define MSWindows 1 +#endif +#endif + +#ifndef _H_AE_Effect +#include "AE_Effect.h" +#endif + +#ifndef _H_AE_EffectCB +#include "AE_EffectCB.h" +#endif + +#ifndef PREMIERE_INTERNAL +#ifndef csSDK_uint32 +typedef unsigned int csSDK_uint32; +typedef int csSDK_int32; + +#ifdef AE_OS_WIN +typedef signed __int64 csSDK_int64; +#elif defined AE_OS_MAC +typedef int64_t csSDK_int64; +#endif + +typedef csSDK_int64 prInt64; +typedef csSDK_int32 prFieldType; +typedef csSDK_int32 PrTimelineID; +typedef csSDK_int32 PrClipID; +typedef prInt64 PrTime; +// This is a conflicting redefinition for any host +// other than PPRO because PREMIERE_INTERNAL +// is not defined for other hosts and PrSDKTypes.h +// will be included through other headers. +// We need to fix it. We go ahead and redefine it +// only if PrSDKTypes.h has not been included. +#ifndef PRSDKTYPES_H +typedef struct +{ + csSDK_int64 opaque[2]; +} PrSDKString; +#endif // PRSDKTYPES_H +#endif + +enum { + PF_TimeDisplay_24 = 1, + PF_TimeDisplay_25, + PF_TimeDisplay_30Drop, + PF_TimeDisplay_30NonDrop, + PF_TimeDisplay_50, + PF_TimeDisplay_60Drop, + PF_TimeDisplay_60NonDrop, + PF_TimeDisplay_NonStandard, + PF_TimeDisplay_Invalid +}; +typedef csSDK_uint32 PF_TimeDisplay; +#endif + +#define kPFPixelFormatSuite "PF Pixel Format Suite" +#define kPFPixelFormatSuiteVersion1 1 +#define kPFPixelFormatSuiteVersion kPFPixelFormatSuiteVersion1 + +typedef struct PF_PixelFormatSuite +{ + SPAPI PF_Err (*AddSupportedPixelFormat)( + PF_ProgPtr effect_ref, /* reference from in_data */ + PrPixelFormat pixelFormat); /* add a supported pixel format */ + + SPAPI PF_Err (*ClearSupportedPixelFormats)( + PF_ProgPtr effect_ref); /* reference from in_data */ + + // not implemented yet + SPAPI PF_Err (*NewWorldOfPixelFormat)( + PF_ProgPtr effect_ref, /* reference from in_data */ + A_u_long width, + A_u_long height, + PF_NewWorldFlags flags, /* should be pre-cleared to zeroes */ + PrPixelFormat pixelFormat, + PF_EffectWorld *world); /* always 32 bit */ + + // not implemented yet + SPAPI PF_Err (*DisposeWorld)( /* Identical to dispose_world in PF_WorldSuite */ + PF_ProgPtr effect_ref, /* reference from in_data */ + PF_EffectWorld *world); + + SPAPI PF_Err (*GetPixelFormat)( + PF_EffectWorld *inWorld, /* the pixel buffer of interest */ + PrPixelFormat *pixelFormat); /* one of the above PF_PixelFormat types */ + + SPAPI PF_Err (*GetBlackForPixelFormat)( + PrPixelFormat pixelFormat, + void* pixelData); + + SPAPI PF_Err (*GetWhiteForPixelFormat)( + PrPixelFormat pixelFormat, + void* pixelData); + + SPAPI PF_Err (*ConvertColorToPixelFormattedData)( + PrPixelFormat pixelFormat, + float alpha, + float red, + float green, + float blue, + void* pixelData); +} PF_PixelFormatSuite; + +typedef PF_PixelFormatSuite PF_PixelFormatSuite1; + +/********** Documentation *********************************************** +AddSupportedPixelFormat() + During PF_Cmd_GLOBAL_SETUP a plug-in can add the formats it supports. By definition, + the 8-bit ARGB pixel format in use today will be the lowest priority, the default and doesn't + need to be added. The default pixel format will be used when the rendering pipeline + indicates it would be optimal and minimizes color space conversions. Within the scope of + Premiere, the effect_ref will be a reference to one of the many types of plug-ins (import, + compile, export, etc...). + +NewWorldOfPixelFormat() + Since the pixel buffers for some of the formats are very different in structure, an allocator + that understands the new formats would be a nice convenience and have some performance benefits. + For example, YCbCr(YUV) is often stored planar rather than packed. + +DisposeWorld() + This call is to balance the suite, however it's functionally equivalent to the dispose_world + in the PF_WorldSuite or the dispose_world callback in the _PF_UtilCallbacks. However, all dispose + world calls will need to be updated to understand how to dispose of planar pixels. + +GetPixelFormat() + Retrieves the pixel format label of the PF_EffectWorld of interest. + +SetPixelFormat() + Sets the pixel format label of the PF_EffectWorld of interest. It does not convert the pixels to the + format specified. Perhaps this call doesn't need to be public, as the user will be using the + ConvertToPixelFormat() call which will set the format? + +ConvertToPixelFormat() + Used to convert a PF_EffectWorld to another pixel format, such as converting ARGB to YCbCr(YUV). The + function would use built in conversion routines and would account for white and black levels while + performing appropriate clipping or scaling. +***********************************************************************/ + +#define kPFBackgroundFrameSuite "PF Background Frame Suite" +#define kPFBackgroundFrameSuiteVersion1 1 +#define kPFBackgroundFrameSuiteVersion kPFBackgroundFrameSuiteVersion1 + +typedef struct PF_BackgroundFrameSuite +{ + SPAPI PF_Err (*AddSupportedBackgroundTransferMode)( + PF_ProgPtr inEffectRef, /* reference from in_data */ + PF_TransferMode supportedTransferMode, /* transfer mode that an effect can use to composite on the background */ + PrPixelFormat supportedPixelFormat); /* pixel format that the effect can composite with */ + + SPAPI PF_Err (*GetBackgroundFrame)( + PF_ProgPtr inEffectRef, /* reference from in_data */ + PF_LayerDef** backgroundFrame, /* the background frame, if any */ + PF_TransferMode* backgroundTransferMode); /* the transfer mode to be used on the background frame */ +} PF_BackgroundFrameSuite; + +typedef PF_BackgroundFrameSuite PF_BackgroundFrameSuite1; + +/********** Documentation *********************************************** +AddSupportedBackgroundTransferMode + Called to register support for a transfer mode in a filter. + The filter must be able to do its effect and composite onto the background. + +GetBackgroundLayer() + Get the background layer and the transfer mode. + If the returned PF_LayerDef* is nil, there is no background frame. +***********************************************************************/ + +#define kPFUtilitySuite "PF Utility Suite" +#define kPFUtilitySuiteVersion2 2 +#define kPFUtilitySuiteVersion3 3 +#define kPFUtilitySuiteVersion4 4 +#define kPFUtilitySuiteVersion5 5 +#define kPFUtilitySuiteVersion6 6 +#define kPFUtilitySuiteVersion7 7 +#define kPFUtilitySuiteVersion8 8 +#define kPFUtilitySuiteVersion9 9 +#define kPFUtilitySuiteVersion kPFUtilitySuiteVersion9 + +typedef struct PF_UtilitySuite4 +{ + SPAPI PF_Err (*GetFilterInstanceID)( + PF_ProgPtr effect_ref, + A_long* outFilterInstanceID); + SPAPI PF_Err (*GetMediaTimecode)( + PF_ProgPtr effect_ref, + A_long* outCurrentFrame, + PF_TimeDisplay* outTimeDisplay); + SPAPI PF_Err (*GetClipSpeed)( + PF_ProgPtr effect_ref, + double* speed); + SPAPI PF_Err (*GetClipDuration)( + PF_ProgPtr effect_ref, + A_long* frameDuration); + SPAPI PF_Err (*GetClipStart)( + PF_ProgPtr effect_ref, + A_long* frameDuration); + SPAPI PF_Err (*GetUnscaledClipDuration)( + PF_ProgPtr effect_ref, + A_long* frameDuration); + SPAPI PF_Err (*GetUnscaledClipStart)( + PF_ProgPtr effect_ref, + A_long* frameDuration); + SPAPI PF_Err (*GetTrackItemStart)( + PF_ProgPtr effect_ref, + A_long* frameDuration); + SPAPI PF_Err (*GetMediaFieldType)( + PF_ProgPtr effect_ref, + prFieldType* outFieldType); + SPAPI PF_Err (*GetMediaFrameRate)( + PF_ProgPtr effect_ref, + PrTime* outTicksPerFrame); + SPAPI PF_Err (*GetContainingTimelineID)( + PF_ProgPtr effect_ref, + PrTimelineID* outTimelineID); + SPAPI PF_Err (*GetClipName)( + PF_ProgPtr effect_ref, + PrSDKString * outSDKString); + SPAPI PF_Err (*EffectWantsCheckedOutFramesToMatchRenderPixelFormat)( + PF_ProgPtr effect_ref); +} PF_UtilitySuite4; + +typedef struct PF_UtilitySuite +{ + SPAPI PF_Err (*GetFilterInstanceID)( + PF_ProgPtr effect_ref, + A_long* outFilterInstanceID); + SPAPI PF_Err (*GetMediaTimecode)( + PF_ProgPtr effect_ref, + A_long* outCurrentFrame, + PF_TimeDisplay* outTimeDisplay); + SPAPI PF_Err (*GetClipSpeed)( + PF_ProgPtr effect_ref, + double* speed); + SPAPI PF_Err (*GetClipDuration)( + PF_ProgPtr effect_ref, + A_long* frameDuration); + SPAPI PF_Err (*GetClipStart)( + PF_ProgPtr effect_ref, + A_long* frameDuration); + SPAPI PF_Err (*GetUnscaledClipDuration)( + PF_ProgPtr effect_ref, + A_long* frameDuration); + SPAPI PF_Err (*GetUnscaledClipStart)( + PF_ProgPtr effect_ref, + A_long* frameDuration); + SPAPI PF_Err (*GetTrackItemStart)( + PF_ProgPtr effect_ref, + A_long* frameDuration); + SPAPI PF_Err (*GetMediaFieldType)( + PF_ProgPtr effect_ref, + prFieldType* outFieldType); + SPAPI PF_Err (*GetMediaFrameRate)( + PF_ProgPtr effect_ref, + PrTime* outTicksPerFrame); + SPAPI PF_Err (*GetContainingTimelineID)( + PF_ProgPtr effect_ref, + PrTimelineID* outTimelineID); + SPAPI PF_Err (*GetClipName)( + PF_ProgPtr effect_ref, + A_Boolean inGetMasterClipName, + PrSDKString * outSDKString); + SPAPI PF_Err (*EffectWantsCheckedOutFramesToMatchRenderPixelFormat)( + PF_ProgPtr effect_ref); + SPAPI PF_Err (*EffectDependsOnClipName)( + PF_ProgPtr effect_ref, + A_Boolean inDependsOnClipName); + SPAPI PF_Err (*SetEffectInstanceName)( + PF_ProgPtr effect_ref, + const PrSDKString* inSDKString); + SPAPI PF_Err (*GetFileName)( + PF_ProgPtr effect_ref, + PrSDKString* outSDKString); + SPAPI PF_Err (*GetOriginalClipFrameRate)( + PF_ProgPtr effect_ref, + PrTime* outTicksPerFrame); + SPAPI PF_Err (*GetSourceTrackMediaTimecode)( + PF_ProgPtr effect_ref, + csSDK_uint32 inLayerParamIndex, + bool inApplyTransform, + bool inAddStartTimeOffset, + A_long* outCurrentFrame); + SPAPI PF_Err (*GetSourceTrackClipName)( + PF_ProgPtr effect_ref, + csSDK_uint32 inLayerParamIndex, + A_Boolean inGetMasterClipName, + PrSDKString* outSDKString); + SPAPI PF_Err (*GetSourceTrackFileName)( + PF_ProgPtr effect_ref, + csSDK_uint32 inLayerParamIndex, + PrSDKString* outSDKString); + SPAPI PF_Err (*EffectDependsOnClipName2)( + PF_ProgPtr effect_ref, + A_Boolean inDependsOnClipName, + csSDK_uint32 inLayerParamIndex); + SPAPI PF_Err (*GetMediaTimecode2)( + PF_ProgPtr effect_ref, + bool inApplyTrim, + A_long* outCurrentFrame, + PF_TimeDisplay* outTimeDisplay); + SPAPI PF_Err (*GetSourceTrackMediaTimecode2)( + PF_ProgPtr effect_ref, + csSDK_uint32 inLayerParamIndex, + bool inApplyTransform, + bool inAddStartTimeOffset, + PrTime inSequenceTime, + A_long* outCurrentFrame); + SPAPI PF_Err (*GetSourceTrackClipName2)( + PF_ProgPtr effect_ref, + csSDK_uint32 inLayerParamIndex, + A_Boolean inGetMasterClipName, + PrSDKString* outSDKString, + PrTime inSequenceTime); + SPAPI PF_Err (*GetSourceTrackFileName2)( + PF_ProgPtr effect_ref, + csSDK_uint32 inLayerParamIndex, + PrSDKString* outSDKString, + PrTime inSequenceTime); + SPAPI PF_Err (*GetCommentString)( + PF_ProgPtr inEffectRef, + int32_t inSourceTrack, + PrTime inSequenceTime, + PrSDKString* outSDKString); + SPAPI PF_Err (*GetLogNoteString)( + PF_ProgPtr inEffectRef, + int32_t inSourceTrack, + PrTime inSequenceTime, + PrSDKString* outSDKString); + SPAPI PF_Err (*GetCameraRollString)( + PF_ProgPtr inEffectRef, + int32_t inSourceTrack, + PrTime inSequenceTime, + PrSDKString* outSDKString); + SPAPI PF_Err (*GetClientMetadataString)( + PF_ProgPtr inEffectRef, + int32_t inSourceTrack, + PrTime inSequenceTime, + PrSDKString* outSDKString); + SPAPI PF_Err (*GetDailyRollString)( + PF_ProgPtr inEffectRef, + int32_t inSourceTrack, + PrTime inSequenceTime, + PrSDKString* outSDKString); + SPAPI PF_Err (*GetDescriptionString)( + PF_ProgPtr inEffectRef, + int32_t inSourceTrack, + PrTime inSequenceTime, + PrSDKString* outSDKString); + SPAPI PF_Err (*GetLabRollString)( + PF_ProgPtr inEffectRef, + int32_t inSourceTrack, + PrTime inSequenceTime, + PrSDKString* outSDKString); + SPAPI PF_Err (*GetSceneString)( + PF_ProgPtr inEffectRef, + int32_t inSourceTrack, + PrTime inSequenceTime, + PrSDKString* outSDKString); + SPAPI PF_Err (*GetShotString)( + PF_ProgPtr inEffectRef, + int32_t inSourceTrack, + PrTime inSequenceTime, + PrSDKString* outSDKString); + SPAPI PF_Err (*GetTapeNameString)( + PF_ProgPtr inEffectRef, + int32_t inSourceTrack, + PrTime inSequenceTime, + PrSDKString* outSDKString); + SPAPI PF_Err (*GetVideoCodecString)( + PF_ProgPtr inEffectRef, + int32_t inSourceTrack, + PrTime inSequenceTime, + PrSDKString* outSDKString); + SPAPI PF_Err (*GetGoodMetadataString)( + PF_ProgPtr inEffectRef, + int32_t inSourceTrack, + PrTime inSequenceTime, + PrSDKString* outSDKString); + SPAPI PF_Err (*GetSoundRollString)( + PF_ProgPtr inEffectRef, + int32_t inSourceTrack, + PrTime inSequenceTime, + PrSDKString* outSDKString); + SPAPI PF_Err (*GetSequenceTime)( + PF_ProgPtr inEffectRef, + PrTime* outSequenceTime); + SPAPI PF_Err (*GetSoundTimecode)( + PF_ProgPtr inEffectRef, + int32_t inSourceTrack, + PrTime inSequenceTime, + A_long* outCurrentFrame); + SPAPI PF_Err (*GetOriginalClipFrameRateForSourceTrack)( + PF_ProgPtr inEffectRef, + int32_t inSourceTrack, + PrTime* outTicksPerFrame); + SPAPI PF_Err (*GetMediaFrameRateForSourceTrack)( + PF_ProgPtr inEffectRef, + int32_t inSourceTrack, + PrTime inSequenceTime, + PrTime* outTicksPerFrame); + SPAPI PF_Err (*GetSourceTrackMediaActualStartTime)( + PF_ProgPtr inEffectRef, + csSDK_uint32 inLayerParamIndex, + PrTime inSequenceTime, + PrTime* outClipActualStartTime); + SPAPI PF_Err (*IsSourceTrackMediaTrimmed)( + PF_ProgPtr inEffectRef, + csSDK_uint32 inLayerParamIndex, + PrTime inSequenceTime, + bool* outTrimApplied); + SPAPI PF_Err (*IsMediaTrimmed)( + PF_ProgPtr inEffectRef, + PrTime inSequenceTime, + bool* outTrimApplied); + SPAPI PF_Err (*IsTrackEmpty)( + PF_ProgPtr inEffectRef, + csSDK_uint32 inLayerParamIndex, + PrTime inSequenceTime, + bool* outIsTrackEmpty); + SPAPI PF_Err (*IsTrackItemEffectAppliedToSynthetic)( + PF_ProgPtr inEffectRef, + bool* outIsTrackItemEffectAppliedToSynthetic); +} PF_UtilitySuite; + +// Legacy function tables +// Please note that version 4 didn't version the GetClipName API correctly, which is why it needs a separate table. But this was fixed in later versions, and that API didn't exist in prior versions, so all of the rest can use PF_UtilitySuite. +typedef PF_UtilitySuite PF_UtilitySuiteVersion1; +typedef PF_UtilitySuite PF_UtilitySuite2; +typedef PF_UtilitySuite PF_UtilitySuite3; +typedef PF_UtilitySuite4 PF_UtilitySuite4; +typedef PF_UtilitySuite PF_UtilitySuite5; +typedef PF_UtilitySuite PF_UtilitySuite6; +typedef PF_UtilitySuite PF_UtilitySuite7; +typedef PF_UtilitySuite PF_UtilitySuite8; + +#define kPFSourceSettingsSuite "PF Source Settings Suite" +#define kPFSourceSettingsSuiteVersion 1 + +typedef struct PF_SourceSettingsSuite +{ + SPAPI PF_Err (*PerformSourceSettingsCommand)( + PF_ProgPtr effect_ref, + void * ioCommandStruct, + csSDK_uint32 inDataSize); + +} PF_SourceSettingsSuite; + +/********** Documentation *********************************************** +GetFilterInstanceID + An AE filter running in Premiere can call this method to obtain + its instance ID from the PF_InData->effect_ref. The instance ID + obtained is the same value contained in the prtFilterRec of its RT segment. +GetMediaTimecode + Returns the starting timecode of the media file. +GetClipSpeed + Returns the playback rate of the underlying clip in the timeline + (negative speed means backwards playback). +GetClipDuration + Returns the trimmed duration (in frames) of the underlying clip in + the timeline. +***********************************************************************/ + + + +#define kPFTransitionSuite "PF Transition Suite" +#define kPFTransitionSuiteVersion1 1 +#define kPFTransitionSuiteVersion2 2 // Added RegisterTransitionStartParam and RegisterTransitionEndParam +#define kPFTransitionSuiteVersion kPFTransitionSuiteVersion2 + +typedef struct PF_TransitionSuite +{ + /** + ** Register an effect as a transition using the passed in + ** input layer as the outgoing clip. When registered the effect + ** will be available to be dragged directly onto clip ends rather + ** than only applied to layers. + */ + SPAPI PF_Err (*RegisterTransitionInputParam)( + PF_ProgPtr inEffectRef, + PF_ParamIndex inIndex); + + /** + ** Register a PF_ADD_FLOAT_SLIDER parameter to receive + ** changes to the start of the transition region through the + ** PF_Cmd_USER_CHANGED_PARAM command. + */ + SPAPI PF_Err (*RegisterTransitionStartParam)( + PF_ProgPtr inEffectRef, + PF_ParamIndex inIndex); + + /** + ** Register a PF_ADD_FLOAT_SLIDER parameter to receive + ** changes to the end of the transition region through the + ** PF_Cmd_USER_CHANGED_PARAM command. + */ + SPAPI PF_Err (*RegisterTransitionEndParam)( + PF_ProgPtr inEffectRef, + PF_ParamIndex inIndex); + +} PF_TransitionSuite; + + +#endif // PRSDKAESUPPORT_H + diff --git a/External/AE SDK/Headers/PrSDKPixelFormat.h b/External/AE SDK/Headers/PrSDKPixelFormat.h new file mode 100644 index 00000000..c39889b8 --- /dev/null +++ b/External/AE SDK/Headers/PrSDKPixelFormat.h @@ -0,0 +1,160 @@ +/*******************************************************************/ +/* */ +/* ADOBE CONFIDENTIAL */ +/* _ _ _ _ _ _ _ _ _ _ _ _ _ */ +/* */ +/* Copyright 2002 Adobe Systems Incorporated */ +/* All Rights Reserved. */ +/* */ +/* NOTICE: All information contained herein is, and remains the */ +/* property of Adobe Systems Incorporated and its suppliers, if */ +/* any. The intellectual and technical concepts contained */ +/* herein are proprietary to Adobe Systems Incorporated and its */ +/* suppliers and may be covered by U.S. and Foreign Patents, */ +/* patents in process, and are protected by trade secret or */ +/* copyright law. Dissemination of this information or */ +/* reproduction of this material is strictly forbidden unless */ +/* prior written permission is obtained from Adobe Systems */ +/* Incorporated. */ +/* */ +/*******************************************************************/ + +#ifndef PRSDKPIXELFORMAT_H +#define PRSDKPIXELFORMAT_H + +#ifdef PREMIERE_INTERNAL + +#ifndef PRSDKTYPES_H +#include "PrSDKTypes.h" +#endif + +#endif + +#ifndef MAKE_PIXEL_FORMAT_FOURCC +#define MAKE_PIXEL_FORMAT_FOURCC(ch0, ch1, ch2, ch3) \ + (static_cast(static_cast(ch0)) | \ + (static_cast(static_cast(ch1)) << 8) | \ + (static_cast(static_cast(ch2)) << 16) | \ + (static_cast(static_cast(ch3)) << 24 )) +#endif + +/** +** Premiere supported pixel formats for RenderFrame and PPixs +*/ + +enum PrPixelFormat +{ + +/** +** Currently supported types +*/ + +// Packed formats +PrPixelFormat_BGRA_4444_8u = MAKE_PIXEL_FORMAT_FOURCC('b', 'g', 'r', 'a'), // 4 byte BGRA, standard windows 32 bit pixels (was kPixelFormat_BGRA32) +PrPixelFormat_VUYA_4444_8u = MAKE_PIXEL_FORMAT_FOURCC('v', 'u', 'y', 'a'), // 4 byte VUYA (was kPixelFormat_VUYA32) +PrPixelFormat_VUYA_4444_8u_709 = MAKE_PIXEL_FORMAT_FOURCC('V', 'U', 'Y', 'A'), // 4 byte VUYA (was kPixelFormat_VUYA32) +PrPixelFormat_ARGB_4444_8u = MAKE_PIXEL_FORMAT_FOURCC('a', 'r', 'g', 'b'), // 4 byte ARGB (the format used by AE) (was kPixelFormat_ARGB32) + +PrPixelFormat_BGRX_4444_8u = MAKE_PIXEL_FORMAT_FOURCC('b', 'g', 'r', 'x'), // 4 byte BGRX +PrPixelFormat_VUYX_4444_8u = MAKE_PIXEL_FORMAT_FOURCC('v', 'u', 'y', 'x'), // 4 byte VUYX +PrPixelFormat_VUYX_4444_8u_709 = MAKE_PIXEL_FORMAT_FOURCC('v', 'u', 'x', '7'), // 4 byte VUYX +PrPixelFormat_XRGB_4444_8u = MAKE_PIXEL_FORMAT_FOURCC('x', 'r', 'g', 'b'), // 4 byte XRGB + +PrPixelFormat_BGRP_4444_8u = MAKE_PIXEL_FORMAT_FOURCC('b', 'g', 'r', 'p'), // 4 byte BGRP +PrPixelFormat_VUYP_4444_8u = MAKE_PIXEL_FORMAT_FOURCC('v', 'u', 'y', 'p'), // 4 byte VUYP +PrPixelFormat_VUYP_4444_8u_709 = MAKE_PIXEL_FORMAT_FOURCC('v', 'u', 'p', '7'), // 4 byte VUYP +PrPixelFormat_PRGB_4444_8u = MAKE_PIXEL_FORMAT_FOURCC('p', 'r', 'g', 'b'), // 4 byte PRGB + +PrPixelFormat_BGRA_4444_16u = MAKE_PIXEL_FORMAT_FOURCC('B', 'g', 'r', 'a'), // 16 bit integer per component BGRA +PrPixelFormat_VUYA_4444_16u = MAKE_PIXEL_FORMAT_FOURCC('V', 'u', 'y', 'a'), // 16 bit integer per component VUYA +PrPixelFormat_ARGB_4444_16u = MAKE_PIXEL_FORMAT_FOURCC('A', 'r', 'g', 'b'), // 16 bit integer per component ARGB + +PrPixelFormat_BGRX_4444_16u = MAKE_PIXEL_FORMAT_FOURCC('B', 'g', 'r', 'x'), // 16 bit integer per component BGRX +PrPixelFormat_XRGB_4444_16u = MAKE_PIXEL_FORMAT_FOURCC('X', 'r', 'g', 'b'), // 16 bit integer per component XRGB + +PrPixelFormat_BGRP_4444_16u = MAKE_PIXEL_FORMAT_FOURCC('B', 'g', 'r', 'p'), // 16 bit integer per component BGRP +PrPixelFormat_PRGB_4444_16u = MAKE_PIXEL_FORMAT_FOURCC('P', 'r', 'g', 'b'), // 16 bit integer per component PRGB + +PrPixelFormat_BGRA_4444_32f = MAKE_PIXEL_FORMAT_FOURCC('B', 'G', 'r', 'a'), // 32 bit float per component BGRA +PrPixelFormat_VUYA_4444_32f = MAKE_PIXEL_FORMAT_FOURCC('V', 'U', 'y', 'a'), // 32 bit float per component VUYA +PrPixelFormat_VUYA_4444_32f_709 = MAKE_PIXEL_FORMAT_FOURCC('v', 'U', 'Y', 'a'), // 32 bit float per component VUYA +PrPixelFormat_ARGB_4444_32f = MAKE_PIXEL_FORMAT_FOURCC('A', 'R', 'g', 'b'), // 32 bit float per component ARGB + +PrPixelFormat_BGRX_4444_32f = MAKE_PIXEL_FORMAT_FOURCC('B', 'G', 'r', 'x'), // 32 bit float per component BGRX +PrPixelFormat_VUYX_4444_32f = MAKE_PIXEL_FORMAT_FOURCC('V', 'U', 'y', 'x'), // 32 bit float per component VUYX +PrPixelFormat_VUYX_4444_32f_709 = MAKE_PIXEL_FORMAT_FOURCC('V', 'U', 'x', '7'), // 32 bit float per component VUYX +PrPixelFormat_XRGB_4444_32f = MAKE_PIXEL_FORMAT_FOURCC('X', 'R', 'g', 'b'), // 32 bit float per component XRGB + +PrPixelFormat_BGRP_4444_32f = MAKE_PIXEL_FORMAT_FOURCC('B', 'G', 'r', 'p'), // 32 bit float per component BGRX +PrPixelFormat_VUYP_4444_32f = MAKE_PIXEL_FORMAT_FOURCC('V', 'U', 'y', 'p'), // 32 bit float per component VUYX +PrPixelFormat_VUYP_4444_32f_709 = MAKE_PIXEL_FORMAT_FOURCC('V', 'U', 'p', '7'), // 32 bit float per component VUYX +PrPixelFormat_PRGB_4444_32f = MAKE_PIXEL_FORMAT_FOURCC('P', 'R', 'g', 'b'), // 32 bit float per component XRGB + +PrPixelFormat_RGB_444_10u = MAKE_PIXEL_FORMAT_FOURCC('R', 'G', 'B', '1'), // Full range 10-bit 444 RGB little-endian + +PrPixelFormat_YUYV_422_8u_601 = MAKE_PIXEL_FORMAT_FOURCC('y', 'u', 'y', '2'), // 8 bit 422 YUY2 601 colorspace +PrPixelFormat_YUYV_422_8u_709 = MAKE_PIXEL_FORMAT_FOURCC('y', 'u', 'y', '3'), // 8 bit 422 YUY2 709 colorspace + +PrPixelFormat_UYVY_422_8u_601 = MAKE_PIXEL_FORMAT_FOURCC('u', 'y', 'v', 'y'), // 8 bit 422 UYVY 601 colorspace +PrPixelFormat_UYVY_422_8u_709 = MAKE_PIXEL_FORMAT_FOURCC('u', 'y', 'v', '7'), // 8 bit 422 UYVY 709 colorspace + +PrPixelFormat_V210_422_10u_601 = MAKE_PIXEL_FORMAT_FOURCC('v', '2', '1', '0'), // packed uncompressed 10 bit 422 YUV aka V210 601 colorspace +PrPixelFormat_V210_422_10u_709 = MAKE_PIXEL_FORMAT_FOURCC('v', '2', '1', '1'), // packed uncompressed 10 bit 422 YUV aka V210 709 colorspace + +PrPixelFormat_UYVY_422_32f_601 = MAKE_PIXEL_FORMAT_FOURCC('U', 'Y', 'v', 'y'), +PrPixelFormat_UYVY_422_32f_709 = MAKE_PIXEL_FORMAT_FOURCC('U', 'Y', 'v', '7'), + +PrPixelFormat_BGRA_4444_32f_Linear = MAKE_PIXEL_FORMAT_FOURCC('B', 'G', 'a', 'L'), // 32 bit float per component linear BGRA +PrPixelFormat_BGRP_4444_32f_Linear = MAKE_PIXEL_FORMAT_FOURCC('B', 'G', 'p', 'L'), // 32 bit float per component linear BGRP +PrPixelFormat_BGRX_4444_32f_Linear = MAKE_PIXEL_FORMAT_FOURCC('B', 'G', 'x', 'L'), // 32 bit float per component linear BGRX +PrPixelFormat_ARGB_4444_32f_Linear = MAKE_PIXEL_FORMAT_FOURCC('A', 'R', 'g', 'L'), // 32 bit float per component linear ARGB +PrPixelFormat_PRGB_4444_32f_Linear = MAKE_PIXEL_FORMAT_FOURCC('P', 'R', 'g', 'L'), // 32 bit float per component linear PRGB +PrPixelFormat_XRGB_4444_32f_Linear = MAKE_PIXEL_FORMAT_FOURCC('X', 'R', 'g', 'L'), // 32 bit float per component linear XRGB + +PrPixelFormat_RGB_444_12u_PQ_709 = MAKE_PIXEL_FORMAT_FOURCC('@', 'P', 'Q', '7'), // 12 bit integer (in 16 bit words) per component RGB with PQ curve, Rec.709 primaries +PrPixelFormat_RGB_444_12u_PQ_P3 = MAKE_PIXEL_FORMAT_FOURCC('@', 'P', 'Q', 'P'), // 12 bit integer (in 16 bit words) per component RGB with PQ curve, P3 primaries +PrPixelFormat_RGB_444_12u_PQ_2020 = MAKE_PIXEL_FORMAT_FOURCC('@', 'P', 'Q', '2'), // 12 bit integer (in 16 bit words) per component RGB with PQ curve, Rec.2020 primaries + +// Planar formats +PrPixelFormat_YUV_420_MPEG2_FRAME_PICTURE_PLANAR_8u_601 = MAKE_PIXEL_FORMAT_FOURCC('y', 'v', '1', '2'), // YUV with 2x2 chroma subsampling. Planar. (for MPEG-2) +PrPixelFormat_YUV_420_MPEG2_FIELD_PICTURE_PLANAR_8u_601 = MAKE_PIXEL_FORMAT_FOURCC('y', 'v', 'i', '2'), // YUV with 2x2 chroma subsampling. Planar. (for MPEG-2) +PrPixelFormat_YUV_420_MPEG2_FRAME_PICTURE_PLANAR_8u_601_FullRange = MAKE_PIXEL_FORMAT_FOURCC('y', 'v', '1', 'f'), // YUV with 2x2 chroma subsampling. Planar. (for MPEG-2) +PrPixelFormat_YUV_420_MPEG2_FIELD_PICTURE_PLANAR_8u_601_FullRange = MAKE_PIXEL_FORMAT_FOURCC('y', 'v', 'i', 'f'), // YUV with 2x2 chroma subsampling. Planar. (for MPEG-2) +PrPixelFormat_YUV_420_MPEG2_FRAME_PICTURE_PLANAR_8u_709 = MAKE_PIXEL_FORMAT_FOURCC('y', 'v', '1', '7'), // YUV with 2x2 chroma subsampling. Planar. (for MPEG-2) 709 colorspace +PrPixelFormat_YUV_420_MPEG2_FIELD_PICTURE_PLANAR_8u_709 = MAKE_PIXEL_FORMAT_FOURCC('y', 'v', 'i', '7'), // YUV with 2x2 chroma subsampling. Planar. (for MPEG-2) 709 colorspace +PrPixelFormat_YUV_420_MPEG2_FRAME_PICTURE_PLANAR_8u_709_FullRange = MAKE_PIXEL_FORMAT_FOURCC('y', 'v', '1', 'F'), // YUV with 2x2 chroma subsampling. Planar. (for MPEG-2) 709 colorspace +PrPixelFormat_YUV_420_MPEG2_FIELD_PICTURE_PLANAR_8u_709_FullRange = MAKE_PIXEL_FORMAT_FOURCC('y', 'v', 'i', 'F'), // YUV with 2x2 chroma subsampling. Planar. (for MPEG-2) 709 colorspace + +PrPixelFormat_YUV_420_MPEG4_FRAME_PICTURE_PLANAR_8u_601 = MAKE_PIXEL_FORMAT_FOURCC('Y', 'v', '1', '2'), // YUV with 2x2 chroma subsampling, center chroma. Planar. +PrPixelFormat_YUV_420_MPEG4_FIELD_PICTURE_PLANAR_8u_601 = MAKE_PIXEL_FORMAT_FOURCC('Y', 'v', 'i', '2'), // YUV with 2x2 chroma subsampling, center chroma. Planar. +PrPixelFormat_YUV_420_MPEG4_FRAME_PICTURE_PLANAR_8u_601_FullRange = MAKE_PIXEL_FORMAT_FOURCC('Y', 'v', '1', 'f'), // YUV with 2x2 chroma subsampling, center chroma. Planar. +PrPixelFormat_YUV_420_MPEG4_FIELD_PICTURE_PLANAR_8u_601_FullRange = MAKE_PIXEL_FORMAT_FOURCC('Y', 'v', 'i', 'f'), // YUV with 2x2 chroma subsampling, center chroma. Planar. +PrPixelFormat_YUV_420_MPEG4_FRAME_PICTURE_PLANAR_8u_709 = MAKE_PIXEL_FORMAT_FOURCC('Y', 'v', '1', '7'), // YUV with 2x2 chroma subsampling, center chroma. Planar. 709 colorspace +PrPixelFormat_YUV_420_MPEG4_FIELD_PICTURE_PLANAR_8u_709 = MAKE_PIXEL_FORMAT_FOURCC('Y', 'v', 'i', '7'), // YUV with 2x2 chroma subsampling, center chroma. Planar. 709 colorspace +PrPixelFormat_YUV_420_MPEG4_FRAME_PICTURE_PLANAR_8u_709_FullRange = MAKE_PIXEL_FORMAT_FOURCC('Y', 'v', '1', 'F'), // YUV with 2x2 chroma subsampling, center chroma. Planar. 709 colorspace +PrPixelFormat_YUV_420_MPEG4_FIELD_PICTURE_PLANAR_8u_709_FullRange = MAKE_PIXEL_FORMAT_FOURCC('Y', 'v', 'i', 'F'), // YUV with 2x2 chroma subsampling, center chroma. Planar. 709 colorspace + +// Compressed formats +PrPixelFormat_NTSCDV25 = MAKE_PIXEL_FORMAT_FOURCC('d', 'v', 'n', '2'), // compressed DV-25 +PrPixelFormat_PALDV25 = MAKE_PIXEL_FORMAT_FOURCC('d', 'v', 'p', '2'), // compressed DV-25 +PrPixelFormat_NTSCDV50 = MAKE_PIXEL_FORMAT_FOURCC('d', 'v', 'n', '5'), +PrPixelFormat_PALDV50 = MAKE_PIXEL_FORMAT_FOURCC('d', 'v', 'p', '5'), +PrPixelFormat_NTSCDV100_720p = MAKE_PIXEL_FORMAT_FOURCC('d', 'v', 'n', '7'), // compressed DV-100 720p, 60 Hz +PrPixelFormat_PALDV100_720p = MAKE_PIXEL_FORMAT_FOURCC('d', 'v', 'p', '7'), // compressed DV-100 720p, 50 Hz +PrPixelFormat_NTSCDV100_1080i = MAKE_PIXEL_FORMAT_FOURCC('d', 'v', 'n', '1'), // compressed DV-100 1080i, 60 Hz +PrPixelFormat_PALDV100_1080i = MAKE_PIXEL_FORMAT_FOURCC('d', 'v', 'p', '1'), // compressed DV-100 1080i, 50 Hz + +// Raw, opaque data formats +PrPixelFormat_Raw = MAKE_PIXEL_FORMAT_FOURCC('r', 'a', 'w', 'w'), // raw, opaque data, with no row bytes or height. + +// Invalid +PrPixelFormat_Invalid = MAKE_PIXEL_FORMAT_FOURCC('b', 'a', 'd', 'f'), // invalid pixel format - this is used for intialization and erorr conditions + +PrPixelFormat_Any = 0 +}; + +#define MAKE_ADOBE_PRIVATE_PIXEL_FORMAT_FOURCC(ch1, ch2, ch3) (static_cast(MAKE_PIXEL_FORMAT_FOURCC('@', ch1, ch2, ch3))) +#define MAKE_THIRD_PARTY_CUSTOM_PIXEL_FORMAT_FOURCC(ch1, ch2, ch3) (static_cast(MAKE_PIXEL_FORMAT_FOURCC('_', ch1, ch2, ch3))) + +#endif // PRSDKPIXELFORMAT_H + diff --git a/External/AE SDK/Headers/SP/PSIntTypes.h b/External/AE SDK/Headers/SP/PSIntTypes.h new file mode 100644 index 00000000..7811e58d --- /dev/null +++ b/External/AE SDK/Headers/SP/PSIntTypes.h @@ -0,0 +1,79 @@ +// ADOBE SYSTEMS INCORPORATED +// (c) Copyright 2009 Adobe Systems Incorporated +// All Rights Reserved +// +// NOTICE: Adobe permits you to use, modify, and distribute this +// file in accordance with the terms of the Adobe license agreement +// accompanying it. If you have received this file from a source +// other than Adobe, then your use, modification, or distribution +// of it requires the prior written permission of Adobe. +//------------------------------------------------------------------- +/** +* +* \file PSIntTypes.h +* +* \brief +* Fixed sized integer types used in Photoshop +* +* Distribution: +* PUBLIC +* +*/ + +#ifndef __PSIntTypes__ +#define __PSIntTypes__ + +//------------------------------------------------------------------- + +#if defined(_MSC_VER) && defined(__cplusplus) +#include +#else +#include +#endif + +typedef int8_t int8; +typedef int16_t int16; +typedef int32_t int32; +typedef int64_t int64; + +typedef uint8_t uint8; +typedef uint16_t uint16; +typedef uint32_t uint32; +typedef uint64_t uint64; + +typedef uint8_t unsigned8; +typedef uint16_t unsigned16; +typedef uint32_t unsigned32; +typedef uint64_t unsigned64; + + +//------------------------------------------------------------------- +//------------------------------------------------------------------- + +#ifndef _BOOL8 + #define _BOOL8 + typedef unsigned char Bool8; +#endif + +#ifndef _BOOL32 + #define _BOOL32 + typedef uint32 Bool32; +#endif + +//------------------------------------------------------------------- +//------------------------------------------------------------------- +//REVISIT - PSFixedTypes.h would probably be a more appropriate name for this file + +#ifndef _REAL32 + #define _REAL32 + typedef float real32; +#endif + +#ifndef _REAL64 + #define _REAL64 + typedef double real64; +#endif + +typedef double nativeFloat; + +#endif /* __PSIntTypes.h__ */ diff --git a/External/AE SDK/Headers/SP/SPAccess.h b/External/AE SDK/Headers/SP/SPAccess.h new file mode 100644 index 00000000..79240f28 --- /dev/null +++ b/External/AE SDK/Headers/SP/SPAccess.h @@ -0,0 +1,387 @@ +/***********************************************************************/ +/* */ +/* SPAccess.h */ +/* */ +/* Copyright 1995-2006 Adobe Systems Incorporated. */ +/* All Rights Reserved. */ +/* */ +/* Patents Pending */ +/* */ +/* NOTICE: All information contained herein is the property of Adobe */ +/* Systems Incorporated. Many of the intellectual and technical */ +/* concepts contained herein are proprietary to Adobe, are protected */ +/* as trade secrets, and are made available only to Adobe licensees */ +/* for their internal use. Any reproduction or dissemination of this */ +/* software is strictly forbidden unless prior written permission is */ +/* obtained from Adobe. */ +/* */ +/***********************************************************************/ + +#ifndef __SPAccess__ +#define __SPAccess__ + + +/******************************************************************************* + ** + ** Imports + ** + **/ + +#include "SPTypes.h" +#include "SPPlugs.h" +#include "SPMData.h" + +#ifdef __cplusplus +extern "C" { +#endif + + +/******************************************************************************* + ** + ** Constants + ** + **/ + +/* + * The name and version number of the Sweet Pea Plug-in Access suite. + */ + +#define kSPAccessSuite "SP Access Suite" +/** Plug-in Access suite name */ +#define kSPAccessSuiteVersion 3 + +/** @ingroup Callers + The \c #SPAccessSuite sends a reload message (\c #kSPAccessReloadSelector) + to a plug-in when it has just been loaded, and an unload message + (\c #kSPAccessUnloadSelector) when it is about to be unloaded. + A plug-in is automatically loaded when the application or another + plug-in calls it or acquires as suite that it exports. + A plug-in can be unloaded at any time if it is not being used. + + A plug-in that exports a suite should unload the suite's procedure pointers + when it is unloaded, and restore them when the plug-in is reloaded. + \li On unload, replace the suite's procedure pointers + with the address of the \c #SPBasicSuite::Undefined() function + (which is always available). This is a protective measure + against other plug-ins that may mistakenly use the suite after they have + released it. + \li On reload, restore the suite's procedure + pointers with the updated addresses of their functions. + + For example: + @code + SPErr UnloadSuite( MySuite *mySuite, SPAccessMessage *message ) { + mySuite->functionA = (void *) message->d.basic->Undefined; + mySuite->functionB = (void *) message->d.basic->Undefined; + } + + SPErr ReloadSuite( MySuite *mySuite, SPAccessMessage *message ) { + mySuite->functionA = functionA; + mySuite->functionB = functionB; + } + @endcode + */ +#define kSPAccessCaller "SP Access" +/** @ingroup Selectors + The first message a plug-in receives on startup (whether + loaded or reloaded). Allows you to restore saved state information, + before startup initialization. + See \c #kSPAccessCaller, \c #SPAccessSuite */ +#define kSPAccessReloadSelector "Reload" +/** @ingroup Selectors + The first message a plug-in receives before being unloaded. + Allows you to save state information + See \c #kSPAccessCaller, \c #SPAccessSuite */ +#define kSPAccessUnloadSelector "Unload" + +/** The name of the object that the \c #SPAccessSuite caches, + which can be purged when caches are flushed. During a cache flush, + if this is the type sent to the \c #SPFlushCachesProc, it can + make calls to the Access suite to collect information about + the access object before deciding to purge it or not. + + For example, this purges filter plug-ins before window plug-ins: +@code +int32 myFlushCachesProc( const char *type, void *data, SPErr *error ) { +int32 flush = TRUE; +if ( strcmp( type, kSPFlushAccessType ) == 0 ) { + SPAccessRef access = data; + SPPluginRef plugin = sAccess->GetAccessPlugin( access, error ); + fail( error ); + switch ( myPluginType( plugin ) ) { + case kMyFilterPlugin: + if ( gPurgeLevel < kFilterPurgeLevel ) + flush = FALSE; + break; + case kMyWindowPlugin: + if ( gPurgeLevel < kWindowPurgeLevel ) + flush = FALSE; + break; + } + } + return flush; +} +@endcode +*/ +#define kSPFlushAccessType "SP Flush Access" + + +/******************************************************************************* + ** + ** Types + ** + **/ + +/** Prototype for a plug-in entry point, which receives messages from + the application or other plug-ins. + @param caller The caller, which identifies what suite or subsystem + made the call. See @ref Callers. + @param selector The specific event that triggered the call. See @ref Selectors. + @param message The message data, whose type depends on the specific event. + */ +typedef SPAPI SPErr (*SPEntry)( const char *caller, const char *selector, void *message ); + + +/** A plug-in access object, used with the \c #SPAccessSuite to make calls + to a plug-in. These objects are reference counted. The count is + incremented when you acquire the object using \c #SPAccessSuite::AcquirePlugin() + and decremented when you release it with \c #SPAccessSuite::ReleasePlugin(), + so you must be careful to balance these calls. The object is automatically + created and the plug-in loaded if necessary, and the object is destroyed + and the plug-in unloaded when the reference count is 0.*/ +typedef struct SPAccess *SPAccessRef; + + + + + +/** Plug-in library handle on Windows, resource chain on Mac. \deprecated */ +typedef void *SPPlatformAccessRef; + + +/** Access information for the resource chain on Mac OS, or library information on Windows. + See \c #SPAccessSuite::GetAccessInfo(). */ +typedef struct { + /** File access for entry and resources, when resource-access has not been set. \deprecated */ + SPPlatformAccessRef defaultAccess; /* */ + /** \deprecated File access for entry and resources, when resource-access + has been set using \c #SPAccessSuite::SetPluginResourceAccess(). + Otherwise \c NULL. */ + SPPlatformAccessRef resourceAccess; + /** The time since the last access operation, in clock-ticks (1/60th second). */ + uint32 lastAccessTicks; +} SPPlatformAccessInfo; + + + +/** Sent in the \c #SPAccessMessage to identify when an access call was made. + Use to distinguish a start-up load from a run-time load or reload, + and a run-time unload from a shut-down unload. */ +typedef enum { + /** The receiving plug-in has been loaded at application startup, and not yet initialized. + Sent with the \c #kSPAccessReloadSelector.*/ + kStartup = 0, + /** The receiving plug-in has been loaded programmatically while the application + is running, and not yet initialized. <> + Sent with the \c #kSPAccessReloadSelector.*/ + kRuntime, + /** The receiving plug-in is about to be unloaded. + Sent with the \c #kSPAccessUnloadSelector. */ + kShutdown, + /** The receiving plug-in has a non-zero access count and the application is shutting down. + Sent with the \c #kSPAccessUnloadSelector. + If the plug-in has acquired itself in order to remain in memory, + it should not free any resources and not acquire others when this + call is received.*/ + kTerminal +} SPAccessPoint; + +/** Message sent with the \c #kSPAccessCaller. */ +typedef struct SPAccessMessage { + /** The message data. */ + SPMessageData d; + /** When the access occurred. */ + SPAccessPoint when; +} SPAccessMessage; + + +/******************************************************************************* + ** + ** Suite + ** + **/ + +/** @ingroup Suites + This suite is used to load and unload plug-ins. The functions allow + you to send messages directly to another plug-in. For example: +@code + SPErr SendMessage( SPPluginRef plugin, const char *caller, const char *selector, void *message, SPErr *error ) { + + SPErr result; + SPAccessRef access; + + access = sAccess->AcquirePlugin( plugin, error ); + fail( error ); + + result = sAccess->CallPlugin( access, caller, selector, message, error ); + fail( error ); + + sAccess->ReleasePlugin( access, error ); + fail( error ); + + return result; + } +@endcode + Standard PICA plug-ins rarely call one another directly. Usually program + control flows from plug-in to plug-in through higher-level suites. + Plug-in adapters, which provide protocol conversion to non-PICA plug-ins, + can add their own access suites to provide access to their foreign plug-ins. + + @see \c #SPInterfaceSuite + + \li Acquire this suite using \c #SPBasicSuite::AcquireSuite() with the constants + \c #kSPAccessSuite and \c #kSPAccessSuiteVersion. +*/ +typedef struct SPAccessSuite { + + /** Loads a plug-in if necessary, and prepares it to be called. Creates + an accessor object if necessary, or increments the reference count + of the existing accessor. Use \c #ReleasePlugin() to decrement + the count when you not longer need the accessor. + + A plug-in can acquire itself in order to remain in memory, even if + not referenced by any other plug-in. + @param plugin The plug-in object. + @param access [out] A buffer in which to return the new access object. + */ + SPAPI SPErr (*AcquirePlugin)( SPPluginRef plugin, SPAccessRef *access ); + + /** Decrements the reference count of an accessor object. + When the reference count reaches 0, frees the accessor object + and allows the associated plug-in to be unloaded. + @param access The access object. + */ + SPAPI SPErr (*ReleasePlugin)( SPAccessRef access ); + + /** Retrieves the accessor object for a plug-in. + You can use this to get the accessor for your own plug-in, in order + to access the resource chain or library information. + + Used by plug-ins that export suites to manually establish a + resource context within any of the suite procedures, so that + they can access resources. Not needed when a plug-in is called + through its entry point. \c #SPAccessSuite::CallPlugin() + sets up the resource context for you. + + @param plugin The plug-in object. + @param access [out] A buffer in which to return the access object, + or \c NULL if the plug-in is not loaded. + */ + SPAPI SPErr (*GetPluginAccess)( SPPluginRef plugin, SPAccessRef *access ); + /** Retrieves the plug-in for an accessor. + @param access The access object. + @param plugin [out] A buffer in which to return the plug-in object, + or \c NULL if the plug-in is not loaded. <> + */ + SPAPI SPErr (*GetAccessPlugin)( SPAccessRef access, SPPluginRef *plugin ); + /** Retrieves the entry point of a plug-in accessor. This is the point to + which \c #CallPlugin() jumps. Before accessing the entry point directly, + use \c #SetCurrentPlugin() to make the plug-in current. + @param access The access object. + @param entry [out] A buffer in which to return the entry point structure. + */ + SPAPI SPErr (*GetAccessEntry)( SPAccessRef access, SPEntry *entry ); + /** Retrieves the current reference count of an accessor object. + @param access The access object. + @param count [out] A buffer in which to return the count. + */ + SPAPI SPErr (*GetAccessCount)( SPAccessRef access, int32 *count ); + /** Retrieves the platform-specific resource access information of a plug-in accessor. + This is for the resource-chain in Mac OS, or the plug-in library in Windows. + @param access The access object. + @param info [out] A buffer in which to return the information structure. + */ + SPAPI SPErr (*GetAccessInfo)( SPAccessRef access, SPPlatformAccessInfo *info ); + + /** Retrieves the platform-specific resource access information of a plug-in accessor. + This is for the resource-chain in Mac OS, or the plug-in library in Windows. + <> + @param access The access object. + @param info [out] A buffer in which to return the information structure. + */ + SPAPI SPErr (*GetPluginResourceAccess)( SPPluginRef plugin, SPPlatformAccessRef *resourceAccess ); + /** <> */ + SPAPI SPErr (*SetPluginResourceAccess)( SPPluginRef plugin, SPPlatformAccessRef resourceAccess ); + + /** Sends a message to a plug-in, using an accessor object. + @param access The access object. + @param caller The caller. + @param slector The selector. + @param message The message, as required for the selector. + @param result [out] A buffer in which to return the result of the call, + returned by the called plug-in. + */ + SPAPI SPErr (*CallPlugin)( SPAccessRef access, const char *caller, const char *selector, + void *message, SPErr *result ); + + /** Retrieves the current plug-in, whose access information is the current + resource context. This is typically the last plug-in to + receive a call, but can be set by a plug-in adapter, or by + \c #SetCurrentPlugin(). + @param plugin [out] A buffer in which to return the plug-in object, + */ + SPAPI SPErr (*GetCurrentPlugin)( SPPluginRef *plugin ); + /** Makes a plug-in and its resource context current. An adapter can use + this to set the resource context before making a call to a plug-in. + Before making this call, you should save the reference for the current + plug-in, and restore it when this plug-in no longer needs to be current. + @param plugin The plug-in object, + */ + SPAPI SPErr (*SetCurrentPlugin)( SPPluginRef plugin ); + +} SPAccessSuite; + +/** Internal */ +SPAPI SPErr SPAcquirePlugin( SPPluginRef plugin, SPAccessRef *access ); +/** Internal */ +SPAPI SPErr SPReleasePlugin( SPAccessRef access ); + +/** Internal */ +SPAPI SPErr SPGetPluginAccess( SPPluginRef plugin, SPAccessRef *access ); +/** Internal */ +SPAPI SPErr SPGetAccessPlugin( SPAccessRef access, SPPluginRef *plugin ); +/** Internal */ +SPAPI SPErr SPGetAccessEntry( SPAccessRef access, SPEntry *entry ); +/** Internal */ +SPAPI SPErr SPGetAccessCount( SPAccessRef access, int32 *count ); +/** Internal */ +SPAPI SPErr SPGetAccessInfo( SPAccessRef access, SPPlatformAccessInfo *info ); + +/** Internal */ +SPAPI SPErr SPGetPluginResourceAccess( SPPluginRef plugin, SPPlatformAccessRef *resourceAccess ); +/** Internal */ +SPAPI SPErr SPSetPluginResourceAccess( SPPluginRef plugin, SPPlatformAccessRef resourceAccess ); + +/** Internal */ +SPAPI SPErr SPCallPlugin( SPAccessRef access, const char *caller, const char *selector, + void *message, SPErr *result ); + +/** Internal */ +SPAPI SPErr SPGetCurrentPlugin( SPPluginRef *plugin ); +/** Internal */ +SPAPI SPErr SPSetCurrentPlugin( SPPluginRef plugin ); + + +/******************************************************************************* + ** + ** Errors + ** + **/ + +#include "SPErrorCodes.h" + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/External/AE SDK/Headers/SP/SPAdapts.h b/External/AE SDK/Headers/SP/SPAdapts.h new file mode 100644 index 00000000..9f12d5bb --- /dev/null +++ b/External/AE SDK/Headers/SP/SPAdapts.h @@ -0,0 +1,406 @@ +/***********************************************************************/ +/* */ +/* SPAdapts.h */ +/* */ +/* Copyright 1995-2006 Adobe Systems Incorporated. */ +/* All Rights Reserved. */ +/* */ +/* Patents Pending */ +/* */ +/* NOTICE: All information contained herein is the property of Adobe */ +/* Systems Incorporated. Many of the intellectual and technical */ +/* concepts contained herein are proprietary to Adobe, are protected */ +/* as trade secrets, and are made available only to Adobe licensees */ +/* for their internal use. Any reproduction or dissemination of this */ +/* software is strictly forbidden unless prior written permission is */ +/* obtained from Adobe. */ +/* */ +/***********************************************************************/ + +#ifndef __SPAdapters__ +#define __SPAdapters__ + + +/******************************************************************************* + ** + ** Imports + ** + **/ + +#include "SPTypes.h" +#include "SPCaches.h" +#include "SPMData.h" +#include "SPProps.h" + +#ifdef __cplusplus +extern "C" { +#endif + + + +/******************************************************************************* + ** + ** Constants + ** + **/ + +/** SPAdapters suite name */ +#define kSPAdaptersSuite "SP Adapters Suite" +/** SPAdapters suite version */ +#define kSPAdaptersSuiteVersion 3 + +/** @ingroup Callers + Caller for a plug-in adapter. Sent to plug-ins + with adapters to allow the adapter to load or unload + files of managed types, or to make translations for + compatability with legacy versions of PICA, the application, + or earlier versions of the plug-in. + See \c #SPAdaptersSuite. */ +#define kSPAdaptersCaller "SP Adapters" + +/** @ingroup Selectors + Received by a plug-in with an adapter on application startup, after + PICA completes its plug-in startup process. Use for initialization + related to the adapter. + See \c #kSPAdaptersCaller, \c #SPAdaptersMessage, \c #SPAdaptersSuite. */ +#define kSPAdaptersStartupSelector "Start up" +/** @ingroup Selectors + Received by a plug-in with an adapter on application shutdown, after + PICA completes its plug-in shutdown process. Use for termination cleanup + related to the adapter. + See \c #kSPAdaptersCaller, \c #SPAdaptersMessage, \c #SPAdaptersSuite. */ +#define kSPAdaptersShutdownSelector "Shut down" +/** @ingroup Selectors + Received by a plug-in with an adapter after a call to + \c #SPCachesSuite::SPFlushCaches(), for a final flush of + any memory used for private data, including PICA lists and + string pools. + See \c #kSPAdaptersCaller, \c #SPAdaptersMessage, \c #SPAdaptersSuite. */ +#define kSPAdaptersDisposeInfoSelector "Dispose info" +/** @ingroup Selectors + Received by a plug-in with an adapter when the application + frees memory, to allow garbage collection. + See \c #kSPAdaptersCaller, \c #SPAdaptersMessage, \c #SPAdaptersSuite. */ +#define kSPAdaptersFlushSelector "Flush" + +// Second generation adapters (has property 'adpt'/2) +//--------------------------------------------------- +/** @ingroup Selectors + Received by a plug-in after its initialization, to allow it to + register its own adapter. Get the adapter list from PICA and + use \c #SPAdaptersSuite::AddAdapter( ) to register your adapter. + For example: + @code +SPAdapterRef oldAPI; +SPAdapterListRef adapterList; +SPErr error; +error = sSPRuntime->GetRuntimeAdapterList( &adapterList); +error = sSPAdapters->AddAdapter( adapterList, message->d.self, "old API adapter", &oldAPI ); + @endcode + + See \c #kSPAdaptersCaller, \c #SPAdaptersMessage, \c #SPAdaptersSuite. */ +#define kSPAdaptersRegisterPluginsSelector "Register plugins" + +/** @ingroup Selectors + Received by a plug-in with an adapter before it is loaded, to allow the + adapter to perform needed translations before the load occurs. The + handler does not need to call the load operation. + See \c #kSPAdaptersCaller, \c #SPAdaptersMessage, \c #SPAdaptersSuite. */ +#define kSPAdaptersLoadPluginSelector "Load plugin" +/** @ingroup Selectors + Received by a plug-in with an adapter before it is unloaded, to allow the + adapter to perform needed translations before the unload occurs. The + handler does not need to call the unload operation. + See \c #kSPAdaptersCaller, \c #SPAdaptersMessage, \c #SPAdaptersSuite. */ +#define kSPAdaptersReleasePluginSelector "Release plugin" + +/** @ingroup Selectors + Received by a plug-in with an adapter when the application needs to + communicate with it. The adapter should relay the message, performing + any required translation. + See \c #kSPAdaptersCaller, \c #SPAdaptersMessage, \c #SPAdaptersSuite. */ +#define kSPAdaptersSendMessageSelector "Send message" + +// First generation adapters (no 'adpt' property, or 'adpt'/1 ) +//------------------------------------------------------------- +// These messages are only for the "SP2 Adapter" that is built into +// Sweet Pea and maybe legacy adapters (i.e., AI6Adapter for AI7). +// For newer adapters, all of these methods are now deprecated. +// New adapters should do the vast majority of their processing via +// the message kSPAdaptersSendMessageSelector. +/** @deprecated Used internally. */ +#define kSPAdaptersFindPropertySelector "Find property" +/** @deprecated Used internally. */ +#define kSPAdaptersAboutSelector "About" +/** @deprecated Used internally. */ +#define kSPAdaptersAcquireSuiteHostSelector "Acquire Suite" +/** @deprecated Used internally. */ +#define kSPAdaptersReleaseSuiteHostSelector "Release Suite" + +/** PICA global list of registered plug-in adapters. + @see \c #SPAdaptersSuite::AddAdapter(), \c #SPRuntimeSuite::GetRuntimeAdapterList(). */ +#define kSPRuntimeAdapterList ((SPAdapterListRef)NULL) + + +/******************************************************************************* + ** + ** Types + ** + **/ + +/** An opaque reference to an adapter object. Access using the \c #SPAdaptersSuite. */ +typedef struct SPAdapter *SPAdapterRef; +/** A list of adapter objects. Create with + \c #SPAdaptersSuite::AllocateAdapterList(), or use + the global list, \c #kSPRuntimeAdapterList. */ +typedef struct SPAdapterList *SPAdapterListRef; +/** An iterator object for examining an adapter list. + See \c #SPAdaptersSuite::NewAdapterListIterator(). */ +typedef struct SPAdapterListIterator *SPAdapterListIteratorRef; + +/** The message passed with all \c #kSPAdaptersCaller calls. + Fields are used by specific selectors as indicated. */ +typedef struct SPAdaptersMessage { + /** The message data. All selectors. */ + SPMessageData d; + /** The adapter object. All selectors. If you add more than + one adapter for a plug-in, use this to determine which handler to use. */ + SPAdapterRef adapter; + + /** For \c #kSPAdaptersAboutSelector, the plug-in object for which to display information. + No longer used. <> */ + struct SPPlugin *targetPlugin; + /** For \c #kSPAdaptersAboutSelector, the target result of the handler, if any. + No longer used. <> */ + SPErr targetResult; + + /** For \c #kSPAdaptersFindPropertySelector. + No longer used. */ + PIType vendorID; + /** For \c #kSPAdaptersFindPropertySelector. + No longer used. */ + PIType propertyKey; + /** For \c #kSPAdaptersFindPropertySelector. + No longer used. */ + int32 propertyID; + /** For \c #kSPAdaptersFindPropertySelector. + No longer used. */ + void *property; + + /** For \c #kSPAdaptersFlushSelector. The procedure with which to flush caches, + passed from the call to \c #SPCachesSuite::SPFlushCaches(). + The adapter should call this to determine which plug-ins are being removed from + memory, and unload them. */ + SPFlushCachesProc flushProc; + /** For \c #kSPAdaptersFlushSelector. Return the result of the flush procedure, + the number of plug-ins removed.*/ + int32 flushed; + + /** For \c #kSPAdaptersAcquireSuiteHostSelector and \c #kSPAdaptersReleaseSuiteHostSelector. + No longer used.*/ + struct SPSuiteList *suiteList; /* use these if you need name, apiVersion, internalVersion */ + /** For \c #kSPAdaptersAcquireSuiteHostSelector and \c #kSPAdaptersReleaseSuiteHostSelector. + No longer used.*/ + struct SPSuite *suite; + /** For \c #kSPAdaptersAcquireSuiteHostSelector and \c #kSPAdaptersReleaseSuiteHostSelector. + No longer used.*/ + struct SPPlugin *host; /* plug-in hosting the suite, to be aquired/released by adapter */ + /** For \c #kSPAdaptersAcquireSuiteHostSelector and \c #kSPAdaptersReleaseSuiteHostSelector. + No longer used.*/ + const void *suiteProcs; /* returned here if reallocated */ + /** For \c #kSPAdaptersAcquireSuiteHostSelector and \c #kSPAdaptersReleaseSuiteHostSelector. + No longer used.*/ + int32 acquired; /* returned here */ + + /** For \c #kSPAdaptersSendMessageSelector. + The caller to pass to the adapted plug-in. */ + const char *plugin_caller; + /** For \c #kSPAdaptersSendMessageSelector. + The selector to pass to the adapted plug-in. */ + const char *plugin_selector; + /** For \c #kSPAdaptersSendMessageSelector. + The message to pass to the adapted plug-in. */ + void *plugin_message; +} SPAdaptersMessage; + +/** A string pool structure. See \c #SPStringsSuite. */ +struct SPStringPool; + +/******************************************************************************* + ** + ** Suite + ** + **/ +/** @ingroup Suites + An adapter is an interface between the PICA plug-in manager and + an individual plug-in. PICA and application plug-ins are hosted by + internal PICA adapters. Plug-ins can add other adapters to PICA's + \e adapter \e list, allowing non-PICA plug-ins to run under the PICA API. + + \li Acquire this suite using \c #SPBasicSuite::AcquireSuite() with the constants + \c #kSPAdaptersSuite and \c #kSPAdaptersSuiteVersion. + + An adapter searches the PICA \e file \e list (\c #kSPRuntimeFileList) + for plug-ins types that it supports, and adds them to the \e plug-in \e list + (\c #kSPRuntimePluginList). When notified by PICA to do so, the adapter is + responsible for loading and calling the plug-ins it adds, and must + do any conversion of messages, data structures or other API elements. + An adapter can be used to update + + There are always at least two adapters, the internal adapters for PICA + and for the application, in the global adapter list (\c #kSPRuntimeAdapterList). + The internal adapters translate any legacy function calls into those + currently supported by PICA and the application. + + You can provide an adapter for backward compatability with older + versions of your own plug-ins, or to interpret your own file types. + To make an adapter available for your plug-in, add it in response to the + \c #kSPAdaptersRegisterPluginsSelector when your plug-in is loaded. + + You can also use this suite to create and maintain your own adapter list, + in addition to the global list. + + Use the adapter to load and call the adapted plug-in. For example, to + verify that a message could be sent to a plug-in: +@code +SPErr error; +SPPluginRef pluginToCall; +SPAdapterRef pluginsAdapter; +char *adapterName; +int32 adapterVersion; + +error = sSPPlugins->GetPluginAdapter( pluginToCall, &pluginsAdapter ); +error = sSPAdapters->GetAdapterName( pluginsAdapter, &adapterName ); +if ( strcmp( adapterName, kSPSweetPea2Adapter ) == 0 ) { + // it is a PICA plug-in, call it as such with sSPInterface. + } else if ( strcmp( adapterName, "MYAPP Legacy Plug-in Adapter" ) == 0 ) { + // it is an adapted plug-in, call it with the adapter's + // interface suite + error = sSPAdapters->GetAdapterVersion( pluginsAdapter, &adapterVersion ); + if ( adapterVersion == 1 ) { + // use one hypothetical interface suite + } else if ( adapterVersion == 2) { + // use another hypothetical interface suite + } + } +@endcode +*/ +typedef struct SPAdaptersSuite { + + /** Allocates a new list of adapters. You can keep your own list, + or obtain the global list with \c #SPRuntimeSuite::GetRuntimeAdapterList(). + @param stringPool The string pool in which to keep adapter names. + @param adapterList [out] A buffer in which to return the new list object. + */ + SPAPI SPErr (*AllocateAdapterList)( struct SPStringPool *stringPool, SPAdapterListRef *adapterList ); + /** Frees a list of adapters allocated with \c #AllocateAdapterList(), and + also frees any entries in the list. Do not free the global list (\c #kSPRuntimeAdapterList). + @param adapterList The adapter list object. + */ + SPAPI SPErr (*FreeAdapterList)( SPAdapterListRef adapterList ); + /** Creates a new adapter object and adds it to an adapter list. Do this in + response to the \c #kSPAdaptersRegisterPluginsSelector message. + @param adapterList The adapter list object, or \c NULL to use the + global list. + @param host This plug-in object, for which the adapter is responsible. + @param name The unique, identifying name of the adapter. + @param version The version number of the adapter. Only the latest version + of any adapter is used to start up plug-ins. + @param adapter [out] A buffer in which to return the new adapter object, or + \c NULL if you add only one adapter. If you add more than one adapter, + compare this to \c #SPAdaptersMessage::adapter to determine which handler to use. + @see \c #AllocateAdapterList() + */ + SPAPI SPErr (*AddAdapter)( SPAdapterListRef adapterList, struct SPPlugin *host, const char *name, + int32 version, SPAdapterRef *adapter ); + + /** Retrieves an adapter by name. + @param adapterList The adapter list object, or \c NULL to use the + global list. + @param name The unique, identifying name of the adapter. + @param adapter [out] A buffer in which to return the adapter object. + */ + SPAPI SPErr (*SPFindAdapter)( SPAdapterListRef adapterList, const char *name, SPAdapterRef *adapter ); + + /** Creates an iterator object with which to traverse an adapter list. + The iterator is initially set to the first adapter in the list. + @param adapterList The adapter list object, or \c NULL to use the + global list. + @param iter [out] A buffer in which to return the new iterator object. + @see \c #NextAdapter(), \c #DeleteAdapterListIterator() + */ + SPAPI SPErr (*NewAdapterListIterator)( SPAdapterListRef adapterList, SPAdapterListIteratorRef *iter ); + /** Retrieves the current adapter and advances an adapter-list iterator to the + next adapter in the list. + @param iter The adapter-list iterator object. + @param adapter [out] A buffer in which to return the current adapter object, \c NULL + if the end of the list has been reached. + @see \c #NewAdapterListIterator(), + */ + SPAPI SPErr (*NextAdapter)( SPAdapterListIteratorRef iter, SPAdapterRef *adapter ); + /** Frees an adapter-list iterator that is no longer needed. + @param iter The adapter-list iterator object. + @see \c #NewAdapterListIterator(), + */ + SPAPI SPErr (*DeleteAdapterListIterator)( SPAdapterListIteratorRef iter ); + + /** Retrieves the plug-in that an adapter manages. + @param adapter The adapter object. + @param plug-in [out] A buffer in which to return the plug-in object. + */ + SPAPI SPErr (*GetAdapterHost)( SPAdapterRef adapter, struct SPPlugin **plugin ); + /** Retrieves the unique, identifying name of an adapter. + @param adapter The adapter object. + @param name [out] A buffer in which to return the name string. + */ + SPAPI SPErr (*GetAdapterName)( SPAdapterRef adapter, const char **name ); + /** Retrieves the version of an adapter. + @param adapter The adapter object. + @param version [out] A buffer in which to return the version number. + */ + SPAPI SPErr (*GetAdapterVersion)( SPAdapterRef adapter, int32 *version ); + +} SPAdaptersSuite; + + +/** Internal */ +SPAPI SPErr SPAllocateAdapterList( struct SPStringPool *stringPool, SPAdapterListRef *adapterList ); +/** Internal */ +SPAPI SPErr SPFreeAdapterList( SPAdapterListRef adapterList ); + +/** Internal */ +SPAPI SPErr SPAddAdapter( SPAdapterListRef adapterList, struct SPPlugin *host, const char *name, + int32 version, SPAdapterRef *adapter ); + +/** Internal */ +SPAPI SPErr SPFindAdapter( SPAdapterListRef adapterList, const char *name, SPAdapterRef *adapter ); + +/** Internal */ +SPAPI SPErr SPNewAdapterListIterator( SPAdapterListRef adapterList, SPAdapterListIteratorRef *iter ); +/** Internal */ +SPAPI SPErr SPNextAdapter( SPAdapterListIteratorRef iter, SPAdapterRef *adapter ); +/** Internal */ +SPAPI SPErr SPDeleteAdapterListIterator( SPAdapterListIteratorRef iter ); + +/** Internal */ +SPAPI SPErr SPGetAdapterHost( SPAdapterRef adapter, struct SPPlugin **plugin ); +/** Internal */ +SPAPI SPErr SPGetAdapterName( SPAdapterRef adapter, const char **name ); +/** Internal */ +SPAPI SPErr SPGetAdapterVersion( SPAdapterRef adapter, int32 *version ); + + +/******************************************************************************* + ** + ** Errors + ** + **/ + +#include "SPErrorCodes.h" + + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/External/AE SDK/Headers/SP/SPBasic.h b/External/AE SDK/Headers/SP/SPBasic.h new file mode 100644 index 00000000..c0273a40 --- /dev/null +++ b/External/AE SDK/Headers/SP/SPBasic.h @@ -0,0 +1,184 @@ +/***********************************************************************/ +/* */ +/* SPBasic.h */ +/* */ +/* Copyright 1995-2006 Adobe Systems Incorporated. */ +/* All Rights Reserved. */ +/* */ +/* Patents Pending */ +/* */ +/* NOTICE: All information contained herein is the property of Adobe */ +/* Systems Incorporated. Many of the intellectual and technical */ +/* concepts contained herein are proprietary to Adobe, are protected */ +/* as trade secrets, and are made available only to Adobe licensees */ +/* for their internal use. Any reproduction or dissemination of this */ +/* software is strictly forbidden unless prior written permission is */ +/* obtained from Adobe. */ +/* */ +/***********************************************************************/ + +#ifndef __SPBasic__ +#define __SPBasic__ + + +/******************************************************************************* + ** + ** Imports + ** + **/ + +#include "SPTypes.h" +#include + +#ifdef __cplusplus +extern "C" { +#endif + + +/******************************************************************************* + ** + ** Constants + ** + **/ +/** PICA basic suite name */ +#define kSPBasicSuite "SP Basic Suite" +/** PICA basic suite version */ +#define kSPBasicSuiteVersion 4 + + +/******************************************************************************* + ** + ** Suite + ** + **/ + +/** @ingroup Suites + This suite provides basic memory management for PICA (the Adobe plug-in manager) + and defines the basic functions for acquiring and releasing other suites. + + A suite consists of a list of function pointers. The application, or a + plug-in that loads a suite, provides valid pointers when the suite is + acquired. When a suite is not available, the pointers are set to the + address of the \c #Undefined() function. + + Do not attempt to acquire a suite (other than the \c #SPBlocksSuite) + in response to a PICA access (\c #kSPAccessCaller) or property + (\c #kSPPropertiesCaller) message. Most suites are unavailable + during these load and unload operations. + + You can acquire all the suites you will need when your plug-in is first + loaded, as long as you release them before your plug-in is unloaded. + At shutdown, however, it is most efficient to acquire only those + suites explicitly needed to shut down; for example, to free memory + and save preferences. + + The \c SPBasicSuite itself is a part of the message data passed + to your plug-in with any call. To access it from the message data structure: + @code + SPBasicSuite sBasic = message->d.basic; + sBasic->function( ) + @endcode + */ +typedef struct SPBasicSuite { + /** Acquires a function suite. Loads the suite if necessary, + and increments its reference count. For example: + @code +SPErr error; +SPBasicSuite *sBasic = message->d.basic; +AIRandomSuite *sRandom; +sBasic->AcquireSuite( kAIRandomSuite, kAIRandomVersion, &sRandom ); + @endcode + @param name The suite name. + @param version The suite version number. + @param suite [out] A buffer in which to return the suite pointer. + @see \c #SPSuitesSuite::AcquireSuite() + */ + SPAPI SPErr (*AcquireSuite)( const char *name, int32 version, const void **suite ); + /** Decrements the reference count of a suite and unloads it when the + reference count reaches 0. + @param name The suite name. + @param version The suite version number. + */ + SPAPI SPErr (*ReleaseSuite)( const char *name, int32 version ); + /** Compares two strings for equality. + @param token1 The first null-terminated string. + @param token2 The second null-terminated string. + @return True if the strings are the same, false otherwise. + */ + SPAPI SPBoolean (*IsEqual)( const char *token1, const char *token2 ); + /** Allocates a block of memory. + @param size The number of bytes. + @param block [out] A buffer in which to return the block pointer. + @see \c #SPBlocksSuite::AllocateBlock() + */ + SPAPI SPErr (*AllocateBlock)( size_t size, void **block ); + /** Frees a block of memory allocated with \c #AllocateBlock(). + @param block The block pointer. + @see \c #SPBlocksSuite::FreeBlock() + */ + SPAPI SPErr (*FreeBlock)( void *block ); + /** Reallocates a block previously allocated with \c #AllocateBlock(). + Increases the size without changing the location, if possible. + @param block The block pointer. + @param newSize The new number of bytes. + @param newblock [out] A buffer in which to return the new block pointer. + @see \c #SPBlocksSuite::ReallocateBlock() + */ + SPAPI SPErr (*ReallocateBlock)( void *block, size_t newSize, void **newblock ); + /** A function pointer for unloaded suites. This is a protective measure + against other plug-ins that may mistakenly use the suite after they have + released it. + + A plug-in that exports a suite should unload the suite's procedure pointers + when it is unloaded, and restore them when the plug-in is reloaded. + \li On unload, replace the suite's procedure pointers + with the address of this function. + \li On reload, restore the suite's procedure + pointers with the updated addresses of their functions. + + For example: + @code + SPErr UnloadSuite( MySuite *mySuite, SPAccessMessage *message ) { + mySuite->functionA = (void *) message->d.basic->Undefined; + mySuite->functionB = (void *) message->d.basic->Undefined; + } + + SPErr ReloadSuite( MySuite *mySuite, SPAccessMessage *message ) { + mySuite->functionA = functionA; + mySuite->functionB = functionB; + } + @endcode + */ + SPAPI SPErr (*Undefined)( void ); + +} SPBasicSuite; + + +/** Internal */ +SPAPI SPErr SPBasicAcquireSuite( const char *name, int32 version, const void **suite ); +/** Internal */ +SPAPI SPErr SPBasicReleaseSuite( const char *name, int32 version ); +/** Internal */ +SPAPI SPBoolean SPBasicIsEqual( const char *token1, const char *token2 ); +/** Internal */ +SPAPI SPErr SPBasicAllocateBlock( size_t size, void **block ); +/** Internal */ +SPAPI SPErr SPBasicFreeBlock( void *block ); +/** Internal */ +SPAPI SPErr SPBasicReallocateBlock( void *block, size_t newSize, void **newblock ); +/** Internal */ +SPAPI SPErr SPBasicUndefined( void ); + +/******************************************************************************* + ** + ** Errors + ** + **/ + +#include "SPErrorCodes.h" + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/External/AE SDK/Headers/SP/SPBckDbg.h b/External/AE SDK/Headers/SP/SPBckDbg.h new file mode 100644 index 00000000..b7bfe08c --- /dev/null +++ b/External/AE SDK/Headers/SP/SPBckDbg.h @@ -0,0 +1,118 @@ +/***********************************************************************/ +/* */ +/* SPBckDbg.h */ +/* */ +/* Copyright 1995-2006 Adobe Systems Incorporated. */ +/* All Rights Reserved. */ +/* */ +/* Patents Pending */ +/* */ +/* NOTICE: All information contained herein is the property of Adobe */ +/* Systems Incorporated. Many of the intellectual and technical */ +/* concepts contained herein are proprietary to Adobe, are protected */ +/* as trade secrets, and are made available only to Adobe licensees */ +/* for their internal use. Any reproduction or dissemination of this */ +/* software is strictly forbidden unless prior written permission is */ +/* obtained from Adobe. */ +/* */ +/***********************************************************************/ + +#ifndef __SPBlockDebug__ +#define __SPBlockDebug__ + + +/******************************************************************************* + ** + ** Imports + ** + **/ + +#include "SPTypes.h" + +#ifdef __cplusplus +extern "C" { +#endif + + +/******************************************************************************* + ** + ** Constants + ** + **/ +/** SPBlockDebug suite name */ +#define kSPBlockDebugSuite "SP Block Debug Suite" +/** SPBlockDebug suite version */ +#define kSPBlockDebugSuiteVersion 2 + + +/******************************************************************************* + ** + ** Suite + ** + **/ + +/** @ingroup Suites + This suite provides basic debugging capability for blocks of memory + allocated with the \c #SPBlocksSuite. Debugging can only be enabled + in the developement environment. + + \li Acquire this suite using \c #SPBasicSuite::AcquireSuite() with the constants + \c #kSPBlockDebugSuite and \c #kSPBlockDebugSuiteVersion. + */ +typedef struct SPBlockDebugSuite { + /** Reports whether block debugging is enabled. + @param enabled [out] A buffer in which to return 1 if debugging + is enabled, 0 otherwise. + */ + SPAPI SPErr (*GetBlockDebugEnabled)( int32 *enabled ); + /** Turns debugging on or off. + @param debug 1 to turn debugging on, 0 to turn it off. + */ + SPAPI SPErr (*SetBlockDebugEnabled)( int32 debug ); + /** Retrieves the first block of memory allocated. Use with \c #GetNextBlock() + to iterate through all allocated blocks. + @param block [out] A buffer in which to return the block pointer. + */ + SPAPI SPErr (*GetFirstBlock)( void **block ); + /** Retrieves the block of memory allocated immediately after a given block. + Use with \c #GetFirstBlock() to iterate through all allocated blocks. + @param block The current block pointer + @param nextblock [out] A buffer in which to return the next block pointer. + */ + SPAPI SPErr (*GetNextBlock)( void *block, void **nextblock ); + /** Retrieves the debugging tag assigned to a block of memory when it + was allocated or reallocated. + @param block The block pointer. + @param debug [out] A buffer in which to return the tag string. + @see \c #SPBlocksSuite::AllocateBlock(), \c #SPBlocksSuite::ReallocateBlock() + */ + SPAPI SPErr (*GetBlockDebug)( void *block, const char **debug ); + +} SPBlockDebugSuite; + + +/** Internal */ +SPAPI SPErr SPGetBlockDebugEnabled( int32 *enabled ); +/** Internal */ +SPAPI SPErr SPSetBlockDebugEnabled( int32 debug ); +/** Internal */ +SPAPI SPErr SPGetFirstBlock( void **block ); +/** Internal */ +SPAPI SPErr SPGetNextBlock( void *block, void **nextblock ); +/** Internal */ +SPAPI SPErr SPGetBlockDebug( void *block, const char **debug ); + + +/******************************************************************************* + ** + ** Errors + ** + **/ + +#include "SPErrorCodes.h" + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/External/AE SDK/Headers/SP/SPBlocks.h b/External/AE SDK/Headers/SP/SPBlocks.h new file mode 100644 index 00000000..cdb0effd --- /dev/null +++ b/External/AE SDK/Headers/SP/SPBlocks.h @@ -0,0 +1,118 @@ +/***********************************************************************/ +/* */ +/* SPBlocks.h */ +/* */ +/* Copyright 1995-2006 Adobe Systems Incorporated. */ +/* All Rights Reserved. */ +/* */ +/* Patents Pending */ +/* */ +/* NOTICE: All information contained herein is the property of Adobe */ +/* Systems Incorporated. Many of the intellectual and technical */ +/* concepts contained herein are proprietary to Adobe, are protected */ +/* as trade secrets, and are made available only to Adobe licensees */ +/* for their internal use. Any reproduction or dissemination of this */ +/* software is strictly forbidden unless prior written permission is */ +/* obtained from Adobe. */ +/* */ +/***********************************************************************/ + +#ifndef __SPBlocks__ +#define __SPBlocks__ + + +/******************************************************************************* + ** + ** Imports + ** + **/ + +#ifdef SWEETPEA_STRICTER_HOST_COMPATIBILITY +#include +#endif +#include "SPTypes.h" + +#ifdef __cplusplus +extern "C" { +#endif + + +/******************************************************************************* + ** + ** Constants + ** + **/ +/** SPBlocks suite name */ +#define kSPBlocksSuite "SP Blocks Suite" +/** SPBlocks suite version */ +#define kSPBlocksSuiteVersion 2 + + +/******************************************************************************* + ** + ** Suite + ** + **/ +/** @ingroup Suites + This suite provides basic memory management for PICA (the Adobe plug-in manager), + with debugging capability for the development version of the application. + + Unlike other suites, this suite is available during plug-in load and unload operations. + You can acquire it in response to a PICA access (\c #kSPAccessCaller) or property + (\c #kSPPropertiesCaller) message, and use it to allocate and free memory + for the plug-in you are loading or unloading. + + \li Acquire this suite using \c #SPBasicSuite::AcquireSuite() with the constants + \c #kSPBlocksSuite and \c #kSPBlocksSuiteVersion. + */ +typedef struct SPBlocksSuite { + + /** Allocates a block of memory. + @param size The number of bytes. + @param debug Optional. A tag for the block, available in the + developement version of the application. Otherwise ignored. + See \c #SPBlockDebugSuite::GetBlockDebug(). + @param block [out] A buffer in which to return the block pointer. + @see \c #SPBasicSuite::AllocateBlock() + */ + SPAPI SPErr (*AllocateBlock)( size_t size, const char *debug, void **block ); + /** Frees a block of memory allocated with \c #AllocateBlock(). + @param block The block pointer. + @see \c #SPBasicSuite::FreeBlock() + */ + SPAPI SPErr (*FreeBlock)( void *block ); + /** Reallocates a block previously allocated with \c #AllocateBlock(). + Increases the size without changing the location, if possible. + @param block The block pointer. + @param newSize The new number of bytes. + @param debug Optional. A tag for the block, available in the + developement version of the application. Otherwise ignored. + See \c #SPBlockDebugSuite::GetBlockDebug(). + @param newblock [out] A buffer in which to return the new block pointer. + @see \c #SPBasicSuite::ReallocateBlock() + */ + SPAPI SPErr (*ReallocateBlock)( void *block, size_t newSize, const char *debug, void **rblock ); + +} SPBlocksSuite; + +/** Internal */ +SPAPI SPErr SPAllocateBlock( size_t size, const char *debug, void **block ); +/** Internal */ +SPAPI SPErr SPFreeBlock( void *block ); +/** Internal */ +SPAPI SPErr SPReallocateBlock( void *block, size_t newSize, const char *debug, void **rblock ); + + +/******************************************************************************* + ** + ** Errors + ** + **/ + +#include "SPErrorCodes.h" + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/External/AE SDK/Headers/SP/SPCOM.h b/External/AE SDK/Headers/SP/SPCOM.h new file mode 100644 index 00000000..0783c1fb --- /dev/null +++ b/External/AE SDK/Headers/SP/SPCOM.h @@ -0,0 +1,9 @@ +/* (c) Copyright 2002. Adobe Systems, Incorporated. All rights reserved. */ + +#pragma once + +#ifndef __SPCOM__ +#define __SPCOM__ +/* This module is obsolete. */ +#endif // __SPCOM__ + diff --git a/External/AE SDK/Headers/SP/SPCaches.h b/External/AE SDK/Headers/SP/SPCaches.h new file mode 100644 index 00000000..c2150f6e --- /dev/null +++ b/External/AE SDK/Headers/SP/SPCaches.h @@ -0,0 +1,128 @@ +/***********************************************************************/ +/* */ +/* SPCaches.h */ +/* */ +/* Copyright 1995-2006 Adobe Systems Incorporated. */ +/* All Rights Reserved. */ +/* */ +/* Patents Pending */ +/* */ +/* NOTICE: All information contained herein is the property of Adobe */ +/* Systems Incorporated. Many of the intellectual and technical */ +/* concepts contained herein are proprietary to Adobe, are protected */ +/* as trade secrets, and are made available only to Adobe licensees */ +/* for their internal use. Any reproduction or dissemination of this */ +/* software is strictly forbidden unless prior written permission is */ +/* obtained from Adobe. */ +/* */ +/***********************************************************************/ + +#ifndef __SPCaches__ +#define __SPCaches__ + + +/******************************************************************************* + ** + ** Imports + ** + **/ + +#include "SPTypes.h" +#include "SPMData.h" + +#ifdef __cplusplus +extern "C" { +#endif + + +/******************************************************************************* + ** + ** Constants + ** + **/ +/** Cache suite name */ +#define kSPCachesSuite "SP Caches Suite" +/** Cache suite version */ +#define kSPCachesSuiteVersion 2 + +/* To receive these, an PIConditionalMessages property must be present + * with the PIAcceptsPurgeCachesMessage flag set. */ +/** @ingroup Callers + The cache management caller. See \c #SPCachesSuite */ +#define kSPCacheCaller "SP Cache" +/** @ingroup Selectors + Received by plug-in adapters with the \c #PIAcceptsPurgeCachesMessage flag set + in the \c #PIConditionalMessages property, when a call has + been made to \c #SPCachesSuite::SPFlushCaches(). Accompanied by + the \c #SPPurgeCachesMessage. + @see \c #SPAdaptersSuite, \c #kSPAdaptersDisposeInfoSelector + */ +#define kSPPluginPurgeCachesSelector "Plug-in Purge" + +/* The plug-in should return one of these two responses when it receives the kSPPluginPurgeCachesSelector */ +//<> +//#define kSPPluginCachesFlushResponse 'pFls' +//#define kSPPluginCouldntFlushResponse kSPNoError; +#include "SPErrorCodes.h" + +/******************************************************************************* + ** + ** Types + ** + **/ +/** Prototype for the cache-flushing procedure an adapter calls in response to the + \c #kSPAdaptersDisposeInfoSelector, to determine which plug-ins to unload, + and inform the caller of whether its managed plug-in have been unloaded. + @param type The plug-in type, as set by the adapter.<> + @param data A pointer to the adapter-defined plug-in data. <> + @param flushed [out] A buffer in which to return the result, + the number of plug-ins actually unloaded. + */ +typedef SPErr (*SPFlushCachesProc)( const char *type, void *data, int32 *flushed ); + +/** Message passed with the \c #kSPPluginPurgeCachesSelector. */ +typedef struct SPPurgeCachesMessage { + /** The message data. */ + SPMessageData d; +} SPPurgeCachesMessage; + + +/******************************************************************************* + ** + ** Suite + ** + **/ +/** @ingroup Suites + This suite allows you to manage PICA cache memory. + + PICA plug-ins are intended to move in and out of memory (cache) as necessary, + to allow a small memory footprint. By default, PICA keeps loaded plug-ins in + cache until the application heap has been filled, and then unloads them. + Beyond this simple strategy, the application and plug-ins can use this + function to unload plug-ins when needed. Plug-ins do not typically need + to do this. + + \li Acquire this suite using \c #SPBasicSuite::AcquireSuite() with the constants + \c #kSPCachesSuite and \c #kSPCachesSuiteVersion. +*/ +typedef struct SPCachesSuite { + /** Sends a message to all plug-in adapters telling them to unload any + unused plug-ins from memory. + @param flushProc The procedure the adapter uses to determine which + plug-ins to unload. + @param flushed [out] A buffer in which to return the result of the + procedure calls, the total number of plug-ins actually unloaded. + */ + SPAPI SPErr (*SPFlushCaches)( SPFlushCachesProc flushProc, int32 *flushed ); + +} SPCachesSuite; + +/** Internal */ +SPAPI SPErr SPFlushCaches( SPFlushCachesProc flushProc, int32 *flushed ); + + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/External/AE SDK/Headers/SP/SPConfig.h b/External/AE SDK/Headers/SP/SPConfig.h new file mode 100644 index 00000000..499d7b25 --- /dev/null +++ b/External/AE SDK/Headers/SP/SPConfig.h @@ -0,0 +1,76 @@ +/***********************************************************************/ +/* */ +/* SPConfig.h */ +/* */ +/* Copyright 1995-2006 Adobe Systems Incorporated. */ +/* All Rights Reserved. */ +/* */ +/* Patents Pending */ +/* */ +/* NOTICE: All information contained herein is the property of Adobe */ +/* Systems Incorporated. Many of the intellectual and technical */ +/* concepts contained herein are proprietary to Adobe, are protected */ +/* as trade secrets, and are made available only to Adobe licensees */ +/* for their internal use. Any reproduction or dissemination of this */ +/* software is strictly forbidden unless prior written permission is */ +/* obtained from Adobe. */ +/* */ +/***********************************************************************/ + +/** + + SPConfig.h is the environment configuration file for Sweet Pea. It + defines MAC_ENV or WIN_ENV. These are used to control platform-specific + sections of code. + + **/ + +#ifndef __SPCnfig__ +#define __SPCnfig__ + +#if defined(__APPLE_CC__) +#if !defined (MAC_ENV) && !defined(SIMULATED_WASM) +#define MAC_ENV 1 +#endif +#endif + +/* + * Windows + */ +#if defined(_WINDOWS) || defined(_MSC_VER) || defined(WINDOWS) // PSMod, better compiler check +#ifndef WIN_ENV +#define WIN_ENV 1 +#endif +#endif + +#ifndef qiOS +#if defined(MAC_ENV) && defined(__arm__) +#define qiOS 1 +#endif +#endif + +/* + * Make certain that one and only one of the platform constants is defined. + */ + +#ifdef __ANDROID__ + #define ANDROID_ENV 1 +#endif + +#ifdef __LINUX__ + #define UNIX_ENV 1 +#endif + +#if defined (__EMSCRIPTEN__) + #define WEB_ENV 1 +#endif + +#if !defined(WIN_ENV) && !defined(MAC_ENV) && !defined(ANDROID_ENV) && !defined(UNIX_ENV) && !defined(WEB_ENV) + #error +#endif + +#if defined(WIN_ENV) && defined(MAC_ENV) && defined(ANDROID_ENV) && defined(UNIX_ENV) && defined (WEB_ENV) + #error +#endif + +#endif diff --git a/External/AE SDK/Headers/SP/SPEDebug.c b/External/AE SDK/Headers/SP/SPEDebug.c new file mode 100644 index 00000000..97c14e3e --- /dev/null +++ b/External/AE SDK/Headers/SP/SPEDebug.c @@ -0,0 +1,2 @@ +// (c) Copyright 2002. Adobe Systems, Incorporated. All rights reserved. + diff --git a/External/AE SDK/Headers/SP/SPErrorCodes.h b/External/AE SDK/Headers/SP/SPErrorCodes.h new file mode 100644 index 00000000..137faaed --- /dev/null +++ b/External/AE SDK/Headers/SP/SPErrorCodes.h @@ -0,0 +1,172 @@ +/***********************************************************************/ +/* */ +/* SPErrorCodes.h */ +/* */ +/* Copyright 1995-2006 Adobe Systems Incorporated. */ +/* All Rights Reserved. */ +/* */ +/* Patents Pending */ +/* */ +/* NOTICE: All information contained herein is the property of Adobe */ +/* Systems Incorporated. Many of the intellectual and technical */ +/* concepts contained herein are proprietary to Adobe, are protected */ +/* as trade secrets, and are made available only to Adobe licensees */ +/* for their internal use. Any reproduction or dissemination of this */ +/* software is strictly forbidden unless prior written permission is */ +/* obtained from Adobe. */ +/* */ +/***********************************************************************/ + +#ifndef __SPErrorCodes__ +#define __SPErrorCodes__ + +#if PRAGMA_ONCE +#pragma once +#endif + +/******************************************************************************* + ** + ** General Errors + ** + **/ + +// General errors +#define kASNoError 0 +#define kASUnimplementedError '!IMP' +#define kASUserCanceledError 'stop' + + +/******************************************************************************* + ** + ** SP Errors + ** + **/ + +// General errors +/** @ingroup Errors + PICA no-error code is \c NULL. All other + PICA errors are strings, except \c #kSPOutOfMemoryError. See \c SPTypes.h. */ +#define kSPNoError 0 +/** @ingroup Errors + PICA error, applies to all PICA suites. See \c SPTypes.h. */ +#define kSPUnimplementedError '!IMP' +/** @ingroup Errors + PICA error. */ +#define kSPUserCanceledError 'stop' +#define kSPOperationInterrupted 'intr' +#define kSPLogicError 'fbar' // general programming error + +// SPAccessSuite errors +/** @ingroup Errors + PICA access error. See \c #SPAccessSuite. */ +#define kSPCantAcquirePluginError '!Acq' +/** @ingroup Errors + PICA access error. See \c #SPAccessSuite. */ +#define kSPCantReleasePluginError '!Rel' +/** @ingroup Errors + PICA access error. See \c #SPAccessSuite. */ +#define kSPPluginAlreadyReleasedError 'AlRl' + +// SPAdaptsSuite errors +/** @ingroup Errors + PICA adapter error. See \c #SPAdaptsSuite */ +#define kSPAdapterAlreadyExistsError 'AdEx' +/** @ingroup Errors + PICA adapter error.See \c #SPAdaptsSuite */ +#define kSPBadAdapterListIteratorError 'BdAL' + +// SPBasicSuite errors +/** @ingroup Errors + Basic PICA error. See \c #SPBasicSuite */ +#define kSPBadParameterError 'Parm' + +// Block debugging errors +/** @ingroup Errors + PICA debugging error. See \c #SPBlockDebugSuite */ +#define kSPCantChangeBlockDebugNowError '!Now' +/** @ingroup Errors + PICA debugging error. See \c #SPBlockDebugSuite */ +#define kSPBlockDebugNotEnabledError '!Nbl' + +// SPBlocks errors +/** @ingroup Errors + PICA memory management error. See \c #SPBlocksSuite */ +#define kSPOutOfMemoryError (int32(0xFFFFFF6c)) /* -108, same as Mac memFullErr */ +/** @ingroup Errors + PICA memory management error. See \c #SPBlocksSuite */ +#define kSPBlockSizeOutOfRangeError 'BkRg' + +// SPCaches errors +/** @ingroup Errors + PICA cache-flushing error. See \c #SPCachesSuite */ +#define kSPPluginCachesFlushResponse 'pFls' +/** @ingroup Errors + PICA cache-flushing error. See \c #SPCachesSuite */ +#define kSPPluginCouldntFlushResponse kSPNoError; + +// SPFiles errors +/** @ingroup Errors + PICA file-access error. See \c #SPFilesSuite */ +#define kSPTroubleAddingFilesError 'TAdd' +/** @ingroup Errors + PICA file-access error. See \c #SPFilesSuite */ +#define kSPBadFileListIteratorError 'BFIt' + +// SPHost errors +/** @ingroup Errors + PICA plug-in atart-up error. See \c #SPHostSuite */ +#define kSPTroubleInitializingError 'TIni' // Some non-descript problem encountered while starting up. +/** @ingroup Errors PICA plug-in atart-up error. See \c #SPHostSuite */ +#define kHostCanceledStartupPluginsError 'H!St' + +// SPInterface errors +/** @ingroup Errors + PICA interface error. See \c #SPInterfaceSuite */ +#define kSPNotASweetPeaPluginError 'NSPP' +/** @ingroup Errors + PICA interface error. See \c #SPInterfaceSuite */ +#define kSPAlreadyInSPCallerError 'AISC' + +// SPPlugins errors +/** @ingroup Errors + PICA plug-in error. See \c #SPPluginsSuite */ +#define kSPUnknownAdapterError '?Adp' +/** @ingroup Errors + PICA plug-in error. See \c #SPPluginsSuite */ +#define kSPBadPluginListIteratorError 'PiLI' +/** @ingroup Errors + PICA plug-in error. See \c #SPPluginsSuite */ +#define kSPBadPluginHost 'PiH0' +/** @ingroup Errors + PICA plug-in error. See \c #SPPluginsSuite */ +#define kSPCantAddHostPluginError 'AdHo' +/** @ingroup Errors + PICA plug-in error. See \c #SPPluginsSuite */ +#define kSPPluginNotFound 'P!Fd' + +// SPProperties errors +/** @ingroup Errors + PICA properties error. See \c #SPPropertiesSuite */ +#define kSPCorruptPiPLError 'CPPL' +/** @ingroup Errors + PICA properties error. See \c #SPPropertiesSuite */ +#define kSPBadPropertyListIteratorError 'BPrI' + +// SPSuites errors +/** @ingroup Errors + PICA suite access error. See \c #SPSuitesSuite */ +#define kSPSuiteNotFoundError 'S!Fd' +/** @ingroup Errors + PICA suite access error. See \c #SPSuitesSuite */ +#define kSPSuiteAlreadyExistsError 'SExi' +/** @ingroup Errors + PICA suite access error. See \c #SPSuitesSuite */ +#define kSPSuiteAlreadyReleasedError 'SRel' +/** @ingroup Errors + PICA suite access error. See \c #SPSuitesSuite */ +#define kSPBadSuiteListIteratorError 'SLIt' +/** @ingroup Errors + PICA suite access error. See \c #SPSuitesSuite */ +#define kSPBadSuiteInternalVersionError 'SIVs' + +#endif diff --git a/External/AE SDK/Headers/SP/SPErrors.h b/External/AE SDK/Headers/SP/SPErrors.h new file mode 100644 index 00000000..7b8fd8f3 --- /dev/null +++ b/External/AE SDK/Headers/SP/SPErrors.h @@ -0,0 +1,34 @@ +/***********************************************************************/ +/* */ +/* SPErrors.h */ +/* */ +/* Copyright 1995-2006 Adobe Systems Incorporated. */ +/* All Rights Reserved. */ +/* */ +/* Patents Pending */ +/* */ +/* NOTICE: All information contained herein is the property of Adobe */ +/* Systems Incorporated. Many of the intellectual and technical */ +/* concepts contained herein are proprietary to Adobe, are protected */ +/* as trade secrets, and are made available only to Adobe licensees */ +/* for their internal use. Any reproduction or dissemination of this */ +/* software is strictly forbidden unless prior written permission is */ +/* obtained from Adobe. */ +/* */ +/***********************************************************************/ + + +/******************************************************************************* + ** + ** Errors + ** + **/ +/** @ingroup Errors + PICA access error. See \c #SPAccessSuite. */ +#define kSPCantAcquirePluginError '!Acq' +/** @ingroup Errors + PICA access error. See \c #SPAccessSuite. */ +#define kSPCantReleasePluginError '!Rel' +/** @ingroup Errors + PICA access error. See \c #SPAccessSuite. */ +#define kSPPluginAlreadyReleasedError 'AlRl' diff --git a/External/AE SDK/Headers/SP/SPFiles.h b/External/AE SDK/Headers/SP/SPFiles.h new file mode 100644 index 00000000..fa19c09c --- /dev/null +++ b/External/AE SDK/Headers/SP/SPFiles.h @@ -0,0 +1,511 @@ +/***********************************************************************/ +/* */ +/* SPFiles.h */ +/* */ +/* Copyright 1995-2006 Adobe Systems Incorporated. */ +/* All Rights Reserved. */ +/* */ +/* Patents Pending */ +/* */ +/* NOTICE: All information contained herein is the property of Adobe */ +/* Systems Incorporated. Many of the intellectual and technical */ +/* concepts contained herein are proprietary to Adobe, are protected */ +/* as trade secrets, and are made available only to Adobe licensees */ +/* for their internal use. Any reproduction or dissemination of this */ +/* software is strictly forbidden unless prior written permission is */ +/* obtained from Adobe. */ +/* */ +/***********************************************************************/ + +#ifndef __SPFiles__ +#define __SPFiles__ + + +/******************************************************************************* + ** + ** Imports + ** + **/ + +#include "SPTypes.h" +#include "SPProps.h" + +#include "photoshop/config/platform.hpp" + +#if PS_PLATFORM_APPLE +#include "CoreFoundation/CoreFoundation.h" +#if PS_OS_MAC +#include "Carbon/Carbon.h" +#endif +#endif + +#if PS_OS_IOS +#include "photoshop/platform/EmulateEndianOnIOS.h" +#include "photoshop/platform/EmulateMacErrorsOnIOS.h" +#include "photoshop/platform/EmulateQuickdrawOnIOS.h" +#include "photoshop/platform/EmulateOSAPIsOnIOS.h" +#include "photoshop/platform/EmulateCarbonFilesOnIOS.h" +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +/******************************************************************************* + ** + ** Constants + ** + **/ +/** Files suite name */ +#define kSPFilesSuite "SP Files Suite" +/** Files suite version */ +#define kSPFilesSuitePrevVers 3 +#define kSPFilesSuiteVersion 4 + +/** PICA global list of potential plug-in files. . + @see \c #SPRuntimeSuite::GetRuntimeFileList().*/ +#define kSPRuntimeFileList ((SPFileListRef)NULL) + +/** Return value for \c #SPFilesSuite::GetFilePropertyList(), + indicating that the file has no property list. */ +#define kFileDoesNotHavePiPL (SPPropertyListRef)((intptr_t)-1) +/** Return value for \c #SPFilesSuite::GetFilePropertyList(), + indicating that the file has multiple property lists. <> */ +#define kFileHasMulitplePiPLs NULL + +/******************************************************************************* + ** + ** Types + ** + **/ + +/** The maximum number of characters allowed in a file path specification. */ +#define kMaxPathLength 300 + +/** Opaque reference to a file. Access with the \c #SPFilesSuite. */ +typedef struct SPFile *SPFileRef; +/** Opaque reference to a file list. Access with the \c #SPFilesSuite. */ +typedef struct SPFileList *SPFileListRef; +/** Opaque reference to a file-list iterator. Access with the \c #SPFilesSuite. */ +typedef struct SPFileListIterator *SPFileListIteratorRef; +/** Opaque reference to a platform-specific file specification. Access with the \c #SPFilesSuite. */ +typedef struct OpaqueSPPlatformFileRef SPPlatformFileRef; + +#define kXPlatFileSpecVersion 1 + +/** The replacement for SPPlatformFileSpecification and SPPlatformFileSpecificationW, +** used in SP Files Suite version 4 and later */ +typedef struct XPlatFileSpec { + int32 mFileSpecVersion; ///< \brief kXPlatFileSpecVersion + ///< + ///< A value of zero implies "not initialized", + ///< and you should not attempt to use mFileReference +#if defined(WIN_ENV) || defined(ANDROID_ENV) || WEB_ENV || defined(UNIX_ENV) + uint16* mFileReference; ///< \brief mFileReference could be as long as 64K but MUST be NULL terminated. +#elif defined(MAC_ENV) + CFURLRef mFileReference; ///< \brief A CFURLRef, as defined by Mac OS X +#endif +} XPlatFileSpec; + + +/*******************************************************************************/ + +#if defined (MAC_ENV) +#if PRAGMA_STRUCT_ALIGN // DRSWAT +#pragma options align=mac68k +#endif // PRAGMA_STRUCT_ALIGN + + +/** A file specification: + \li In Mac OS 32 bit, the same as \c FSSpec. + \li In Windows, a path string. */ + + +#if USE_POSIX_API + +typedef struct SPPlatformFileSpecification { /* this handles unicode file names */ + /** The file path string. */ + char path[kMaxPathLength]; +} SPPlatformFileSpecification; + +typedef struct SPPlatformFileSpecificationW { /* this handles unicode file names */ + /** mReference could be as long as 64K but MUST be NULL terminated. */ + uint16 *mReference; +} SPPlatformFileSpecificationW; + +/**Platform-specific file metadata. */ +typedef struct SPPlatformFileInfo { + /** File attribute flags; see Windows documentation. */ + uint32 attributes; + /** Least-significant byte of the file creation date-time (Windows).*/ + uint32 lowCreationTime; + /** Most-significant byte of the file creation date-time (Windows).*/ + uint32 highCreationTime; + /** Least-significant byte of the file modification date-time (Windows).*/ + uint32 lowModificationTime; + /** Most-significant byte of the file cremodification date-time (Windows).*/ + uint32 highModificationTime; + /** The file-name extension indicating the file type (Windows). */ + const char *extension; +} SPPlatformFileInfo; + +#elif PS_PLATFORM_APPLE + +typedef struct SPPlatformFileSpecification { /* this handles unicode file names */ + FSRef mReference; +} SPPlatformFileSpecification; + +typedef struct SPPlatformFileSpecificationW { /* this handles unicode file names */ + FSRef mReference; +} SPPlatformFileSpecificationW; + +#if PRAGMA_STRUCT_ALIGN // DRSWAT +#pragma options align=reset +#endif + + /*******************************************************************************/ + + /** Platform-specific file metadata. */ + typedef struct SPPlatformFileInfo { /* On Mac OS*/ + /** Not used. */ + uint32 attributes; //Unused, but still required to maintain binary compatibility + /** Date file was created (Mac OS). */ + uint32 creationDate; + /** Data file was last modified (Mac OS). */ + uint32 modificationDate; + /** Type of file for Finder (Mac OS). */ + uint32 finderType; + /** File creator (Mac OS). */ + uint32 finderCreator; + /** File flags for Finder; see Mac OS documentation. */ + uint16 finderFlags; + } SPPlatformFileInfo; +#endif // PS_PLATFORM_APPLE + +#endif // MAC_ENV + +/*******************************************************************************/ + +#ifdef WIN_ENV +/** A file specification in Windows. */ +typedef struct SPPlatformFileSpecification { + /** The file path string. */ + char path[kMaxPathLength]; +} SPPlatformFileSpecification; + +/** A widechar file specification in Windows to handle unicode file names. */ +typedef struct SPPlatformFileSpecificationW { + /** mReference could be as long as 64K but MUST be NULL terminated. */ + uint16 *mReference; +} SPPlatformFileSpecificationW; + +/*******************************************************************************/ + +/**Platform-specific file metadata. */ +typedef struct SPPlatformFileInfo { + /** File attribute flags; see Windows documentation. */ + uint32 attributes; + /** Least-significant byte of the file creation date-time (Windows).*/ + uint32 lowCreationTime; + /** Most-significant byte of the file creation date-time (Windows).*/ + uint32 highCreationTime; + /** Least-significant byte of the file modification date-time (Windows).*/ + uint32 lowModificationTime; + /** Most-significant byte of the file cremodification date-time (Windows).*/ + uint32 highModificationTime; + /** The file-name extension indicating the file type (Windows). */ + const uint16 *extension; +} SPPlatformFileInfo; +#endif // WIN_ENV + +/*******************************************************************************/ + + +#if defined(__ANDROID__) || defined(__LINUX__) || defined (__EMSCRIPTEN__) || defined(SIMULATED_WASM) +typedef struct SPPlatformFileSpecification { + /** The file path string. */ + char path[kMaxPathLength]; +} SPPlatformFileSpecification; + +/** A widechar file specification in Windows to handle unicode file names. */ +typedef struct SPPlatformFileSpecificationW { + /** mReference could be as long as 64K but MUST be NULL terminated. */ + uint16 *mReference; +} SPPlatformFileSpecificationW; + +/*******************************************************************************/ + +/**Platform-specific file metadata. */ +typedef struct SPPlatformFileInfo { + uint32 attributes; + uint32 lowCreationTime; + uint32 highCreationTime; + uint32 lowModificationTime; + uint32 highModificationTime; + const uint16 *extension; +} SPPlatformFileInfo; +#endif // __ANDROID__ + +/** Conversion from new platform file specification to old platform file +** specification, and vice-versa. It's okay to pass NULL pointers to these +** functions. If you do, the value returned will be a default constructed +** structure (i.e. zero-filled) +*/ +/** Internal ? */ +SPAPI SPPlatformFileSpecification OldFileSpecFromXplatFileSpec(const XPlatFileSpec* newSpec); + +SPAPI SPPlatformFileSpecificationW OldFileSpecWFromXplatFileSpec(const XPlatFileSpec* newSpec); + +/// Caller owns the CFURLRef contained in XPlatFileSpec::mFileReference +SPAPI XPlatFileSpec XplatFileSpecFromOldFileSpec(const SPPlatformFileSpecification* oldSpec); + +/// Caller owns the CFURLRef contained in XPlatFileSpec::mFileReference +SPAPI XPlatFileSpec XplatFileSpecFromOldFileSpecW(const SPPlatformFileSpecificationW* oldSpecW); + +/*******************************************************************************/ + +/** Internal */ +typedef SPBoolean (*SPAddPiPLFilterProc)( SPPlatformFileInfo *info ); + +/******************************************************************************* + ** + ** Suite + ** + **/ +/** @ingroup Suites + This suite allows you to access the PICA files list. This list, created at startup, + contains references to every file in the application's plug-in folder, including + any resolved file and folder aliases. PICA maintains this list, and uses it to find plug-ins. + + Use this suite to access the plug-in file list, in order to avoid redundant directory + scans. Adapters looking for their own plug-ins and PICA plug-ins looking for + support files should scan the list to locate relevant files rather than walking + platform directory structures on their own. + + Similarly, you can use this suite to create, maintain, and access your own lists + of files in a platform-independant and efficient manner. + + \li Acquire this suite using \c #SPBasicSuite::AcquireSuite() with the constants + \c #kSPFilesSuite and \c #kSPFilesSuiteVersion (4). + */ + +typedef struct SPFilesSuite { + /** Creates a new file list. Typically, you use the main PICA file list to access + plug-in files, available through \c #SPRuntimeSuite::GetRuntimeFileList(). + You can use this to track other file collections. If you create a new list, you + must free it when it is no longer needed, using \c #FreeFileList(). + @param fileList [out] A buffer in which to return the new file list object. + */ + SPAPI SPErr (*AllocateFileList)( SPFileListRef *fileList ); + /** Frees a file list created with \c #AllocateFileList(), and any entries in the list. + @param fileList The file list object. + */ + SPAPI SPErr (*FreeFileList)( SPFileListRef fileList ); + + /** Adds a file or all files in a directory to a file list. Searches a directory + recursively for contained files. + @param fileList The file list object. + @param file The file or directory specification. + */ + SPAPI SPErr (*AddFiles)( SPFileListRef fileList, const XPlatFileSpec *file ); + + /** Creates a file-list iterator object to use with \c #NextFile() for iterating + through a file list. The iterator is initially set to the first file in the list. + When the iterator is no longer needed, free it with \c #DeleteFileListIterator(). + @param fileList The file list object. + @param iter [out] A buffer in which to return the new iterator object. + */ + SPAPI SPErr (*NewFileListIterator)( SPFileListRef fileList, SPFileListIteratorRef *iter ); + /** Retrieves the current file from a file list iterator, and advances the iterator. + @param iter The iterator object. + @param file [out] A buffer in which to return the current file object, or \c NULL + if the end of the list has been reached. + */ + SPAPI SPErr (*NextFile)( SPFileListIteratorRef iter, SPFileRef *file ); + /** Frees a file-list iterator created with /c #NewFileListIterator(). + @param iter The iterator object. + */ + SPAPI SPErr (*DeleteFileListIterator)( SPFileListIteratorRef iter ); + + /** Retrieves the platform-specific file specification for a file. + @param file The file object. + @param fileSpec [out] A buffer in which to return the file specification. + */ + SPAPI SPErr (*GetFileSpecification)( SPFileRef file, XPlatFileSpec *fileSpec ); + /** Retrieves the metadata for a file. + @param file The file object. + @param info [out] A buffer in which to return the file information. + */ + SPAPI SPErr (*GetFileInfo)( SPFileRef file, SPPlatformFileInfo *info ); + + /** Reports whether a file in a file list is a plug-in. + @param file The file object. + @param isAPlugin [out] A buffer in which to return true if the file is a plug-in. + */ + SPAPI SPErr (*GetIsAPlugin)( SPFileRef file, SPBoolean *isAPlugin ); + /** Sets whether a file in a file list is a plug-in. + @param file The file object. + @param isAPlugin True to mark the file as a plug-in, false to mark it as not a plug-in. + */ + SPAPI SPErr (*SetIsAPlugin)( SPFileRef file, SPBoolean isAPlugin ); + + /** Retrieves the property list for a file. + @param file The file object. + @param propertList [out] A buffer in which to return the property list, + or \c #kFileDoesNotHavePiPL if the file does not have a property list, + or \c #kFileHasMulitplePiPLs if the file has multiple property lists. + @see \c SPPiPL.h + */ + SPAPI SPErr (*GetFilePropertyList)( SPFileRef file, SPPropertyListRef *propertList ); + /** Sets the property list for a file. + @param file The file object. + @param propertList The new property list. + */ + SPAPI SPErr (*SetFilePropertyList)( SPFileRef file, SPPropertyListRef propertList ); + +} SPFilesSuite; + + +/******************************************************************************* + ** + ** Suite + ** + **/ +/** @ingroup Suites + This suite allows you to access the PICA files list. This list, created at startup, + contains references to every file in the application's plug-in folder, including + any resolved file and folder aliases. PICA maintains this list, and uses it to find plug-ins. + + Use this suite to access the plug-in file list, in order to avoid redundant directory + scans. Adapters looking for their own plug-ins and PICA plug-ins looking for + support files should scan the list to locate relevant files rather than walking + platform directory structures on their own. + + Similarly, you can use this suite to create, maintain, and access your own lists + of files in a platform-independant and efficient manner. + + \li Acquire this suite using \c #SPBasicSuite::AcquireSuite() with the constants + \c #kSPFilesSuite and \c #kSPFilesSuitePrevVers (3). + */ +typedef struct SPFilesV3Suite { + /** Creates a new file list. Typically, you use the main PICA file list to access + plug-in files, available through \c #SPRuntimeSuite::GetRuntimeFileList(). + You can use this to track other file collections. If you create a new list, you + must free it when it is no longer needed, using \c #FreeFileList(). + @param fileList [out] A buffer in which to return the new file list object. + */ + SPAPI SPErr (*AllocateFileList)( SPFileListRef *fileList ); + /** Frees a file list created with \c #AllocateFileList(), and any entries in the list. + @param fileList The file list object. + */ + SPAPI SPErr (*FreeFileList)( SPFileListRef fileList ); + + /** Adds a file or all files in a directory to a file list. Searches a directory + recursively for contained files. + @param fileList The file list object. + @param file The file or directory specification. + */ + SPAPI SPErr (*AddFiles)( SPFileListRef fileList, const SPPlatformFileSpecification *file ); + + /** Creates a file-list iterator object to use with \c #NextFile() for iterating + through a file list. The iterator is initially set to the first file in the list. + When the iterator is no longer needed, free it with \c #DeleteFileListIterator(). + @param fileList The file list object. + @param iter [out] A buffer in which to return the new iterator object. + */ + SPAPI SPErr (*NewFileListIterator)( SPFileListRef fileList, SPFileListIteratorRef *iter ); + /** Retrieves the current file from a file list iterator, and advances the iterator. + @param iter The iterator object. + @param file [out] A buffer in which to return the current file object, or \c NULL + if the end of the list has been reached. + */ + SPAPI SPErr (*NextFile)( SPFileListIteratorRef iter, SPFileRef *file ); + /** Frees a file-list iterator created with /c #NewFileListIterator(). + @param iter The iterator object. + */ + SPAPI SPErr (*DeleteFileListIterator)( SPFileListIteratorRef iter ); + + /** Retrieves the platform-specific file specification for a file. + @param file The file object. + @param fileSpec [out] A buffer in which to return the file specification. + */ + SPAPI SPErr (*GetFileSpecification)( SPFileRef file, SPPlatformFileSpecification *fileSpec ); + /** Retrieves the metadata for a file. + @param file The file object. + @param info [out] A buffer in which to return the file information. + */ + SPAPI SPErr (*GetFileInfo)( SPFileRef file, SPPlatformFileInfo *info ); + + /** Reports whether a file in a file list is a plug-in. + @param file The file object. + @param isAPlugin [out] A buffer in which to return true if the file is a plug-in. + */ + SPAPI SPErr (*GetIsAPlugin)( SPFileRef file, SPBoolean *isAPlugin ); + /** Sets whether a file in a file list is a plug-in. + @param file The file object. + @param isAPlugin True to mark the file as a plug-in, false to mark it as not a plug-in. + */ + SPAPI SPErr (*SetIsAPlugin)( SPFileRef file, SPBoolean isAPlugin ); + + /** Retrieves the property list for a file. + @param file The file object. + @param propertList [out] A buffer in which to return the property list, + or \c #kFileDoesNotHavePiPL if the file does not have a property list, + or \c #kFileHasMulitplePiPLs if the file has multiple property lists. + @see \c SPPiPL.h + */ + SPAPI SPErr (*GetFilePropertyList)( SPFileRef file, SPPropertyListRef *propertList ); + /** Sets the property list for a file. + @param file The file object. + @param propertList The new property list. + */ + SPAPI SPErr (*SetFilePropertyList)( SPFileRef file, SPPropertyListRef propertList ); + +} SPFilesV3Suite; + + +/** Internal */ +SPAPI SPErr SPAllocateFileList( SPFileListRef *fileList ); +/** Internal */ +SPAPI SPErr SPFreeFileList( SPFileListRef fileList ); +/** Internal */ +SPAPI SPErr SPAddFiles( SPFileListRef fileList, const SPPlatformFileSpecification *file ); +/** Internal */ +SPAPI SPErr SPNewAddFiles( SPFileListRef fileList, const XPlatFileSpec *file ); + +/** Internal */ +SPAPI SPErr SPNewFileListIterator( SPFileListRef fileList, SPFileListIteratorRef *iter ); +/** Internal */ +SPAPI SPErr SPNextFile( SPFileListIteratorRef iter, SPFileRef *file ); +/** Internal */ +SPAPI SPErr SPDeleteFileListIterator( SPFileListIteratorRef iter ); + +/** Internal */ +SPAPI SPErr SPGetFileSpecification( SPFileRef file, SPPlatformFileSpecification *fileSpec ); +/** Internal */ +SPAPI SPErr SPNewGetFileSpecification( SPFileRef file, XPlatFileSpec *fileSpec ); +/** Internal */ +SPAPI SPErr SPGetFileInfo( SPFileRef file, SPPlatformFileInfo *info ); +/** Internal */ +SPAPI SPErr SPGetIsAPlugin( SPFileRef file, SPBoolean *isAPlugin ); +/** Internal */ +SPAPI SPErr SPSetIsAPlugin( SPFileRef file, SPBoolean isAPlugin ); + +/** Internal */ +SPAPI SPErr SPGetFilePropertyList( SPFileRef file, SPPropertyListRef *propertList ); +/** Internal */ +SPAPI SPErr SPSetFilePropertyList( SPFileRef file, SPPropertyListRef propertList ); + +/******************************************************************************* + ** + ** Errors + ** + **/ + +#include "SPErrorCodes.h" + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/External/AE SDK/Headers/SP/SPHost.h b/External/AE SDK/Headers/SP/SPHost.h new file mode 100644 index 00000000..601bf736 --- /dev/null +++ b/External/AE SDK/Headers/SP/SPHost.h @@ -0,0 +1,176 @@ +/***********************************************************************/ +/* */ +/* SPHost.h */ +/* */ +/* Copyright 1995-1999 Adobe Systems Incorporated. */ +/* All Rights Reserved. */ +/* */ +/* Patents Pending */ +/* */ +/* NOTICE: All information contained herein is the property of Adobe */ +/* Systems Incorporated. Many of the intellectual and technical */ +/* concepts contained herein are proprietary to Adobe, are protected */ +/* as trade secrets, and are made available only to Adobe licensees */ +/* for their internal use. Any reproduction or dissemination of this */ +/* software is strictly forbidden unless prior written permission is */ +/* obtained from Adobe. */ +/* */ +/***********************************************************************/ + +#ifndef __SPHost__ +#define __SPHost__ + + +/******************************************************************************* + ** + ** Imports + ** + **/ + +#include "SPTypes.h" +#include "SPAccess.h" +#include "SPAdapts.h" +#include "SPBasic.h" +#include "SPBckDbg.h" +#include "SPBlocks.h" +#include "SPCaches.h" +#include "SPFiles.h" +#include "SPInterf.h" +#include "SPPlugs.h" +#include "SPProps.h" +#include "SPRuntme.h" +#include "SPStrngs.h" +#include "SPSuites.h" + +#ifdef __cplusplus +extern "C" { +#endif + + +/******************************************************************************* + ** + ** Constants + ** + **/ + + +/* + * The version number of the Sweet Pea host interface. You can compare it to the + * version number that Sweet Pea was compiled with to determine that you are + * running the version you think you are. See SPVersion() below. + * + * This number consists of a hi word which is the major version number reflecting + * changes to the SP inteface, and a low word which is the minor revision number, + * for instance indicating bug fixes. + */ + +#define kSPVersion 0x000B0002 // version 11.2 + + +/* + * Options available to the host at init time. They are: + * + * kSPHostBlockDebugOption - block allocation debugging is enabled. See + * SPBckDbg.h for details. + * + * Examples: + * + * SPInit( hostProcs, pluginsFolder, kSPHostNoOptions, error ); + * // No debugging. + * + * SPInit( hostProcs, pluginsFolder, kSPHostBlockDebugOption, error ); + * // Enable block debugging. + */ + +#define kSPHostNoOptions 0 +#define kSPHostBlockDebugOption (1<<0L) + + +/******************************************************************************* + ** + ** Functions + ** + **/ + +/* + * SPInit() initializes Sweet Pea. It is the first call made to Sweet Pea. It + * initializes its suites and builds the list of application files. + * + * HostProcs points to a filled-in structure of host callbacks, as described + * in SPRuntme.h. It may be NULL, in which case Sweet Pea uses its default + * versions for all of the host callbacks. PluginFolder is the file spec of the + * plug-ins folder. The contents of this folder are collected into the application + * files list (see SPFiles.h). Options may be any of the host options described + * above. + */ +SPErr SPInit( SPHostProcs *hostProcs, const SPPlatformFileSpecification *pluginFolder, int32 options ); + +/* + * SPXPlatInit() uses the XPlatFileSpec rather than the SPPlatformFileSpecification. + * + * Otherwise it's identical to SPInit (and actually calls through to it for Photoshop 17.0) + */ +SPErr SPXPlatInit( SPHostProcs *hostProcs, const XPlatFileSpec *pluginFolder, int32 options ); + +SPBoolean SPInited( void ); + +/* + * SPTerm() terminates Sweet Pea. Call this when your application quits. + */ +SPErr SPTerm( void ); + +/* + * SPStartupPlugins() scans the list of application files and builds the list + * of plug-ins. It then starts them up, calling each in turn with a start up + * message (see SPPlugs.h). Call this sometime after SPInit(). + */ +SPErr SPStartupPlugins( void ); + +/* + * SPShutdownPlugins() shuts down the plug-ins. It calls each in turn with a + * shut down message (see SPPlugs.h). Call this when your application quits + * before calling SPTerm(). + */ +SPErr SPShutdownPlugins( void ); + + +#ifdef MAC_ENV +/* + * SPSetPPCLoadHeap() sets the destination heap of plug-in accesses on PowerPPC + * Macintoshes. Plug-ins can load into the system heap or the application heap. + */ +typedef enum { + kAppHeap = 0, + kSysHeap +} SPTargetHeap; + +SPErr SPSetPPCLoadHeap( SPTargetHeap target ); + +/* + * SPSetHostBundleRef() lets sweet pea know the bundle ref of the host. + */ +SPErr SPSetHostBundleRef(CFBundleRef hostBundle); +#endif + + +/* + * SPVersion() returns the version number of the Sweet Pea host interface (this + * file) for which Sweet Pea was built. You can compare this to the constant + * kSPVersion to make sure you're using the version you think you are. + */ +uint32 SPVersion( void ); + + +/******************************************************************************* + ** + ** Errors + ** + **/ + +#include "SPErrorCodes.h" + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/External/AE SDK/Headers/SP/SPInterf.h b/External/AE SDK/Headers/SP/SPInterf.h new file mode 100644 index 00000000..276d09f0 --- /dev/null +++ b/External/AE SDK/Headers/SP/SPInterf.h @@ -0,0 +1,180 @@ +/***********************************************************************/ +/* */ +/* SPInterf.h */ +/* */ +/* Copyright 1995-2006 Adobe Systems Incorporated. */ +/* All Rights Reserved. */ +/* */ +/* Patents Pending */ +/* */ +/* NOTICE: All information contained herein is the property of Adobe */ +/* Systems Incorporated. Many of the intellectual and technical */ +/* concepts contained herein are proprietary to Adobe, are protected */ +/* as trade secrets, and are made available only to Adobe licensees */ +/* for their internal use. Any reproduction or dissemination of this */ +/* software is strictly forbidden unless prior written permission is */ +/* obtained from Adobe. */ +/* */ +/***********************************************************************/ + +#ifndef __SPInterface__ +#define __SPInterface__ + + +/******************************************************************************* + ** + ** Imports + ** + **/ + +#include "SPTypes.h" +#include "SPBasic.h" +#include "SPFiles.h" +#include "SPMData.h" +#include "SPPlugs.h" +#include "SPProps.h" + +#ifdef __cplusplus +extern "C" { +#endif + + +/******************************************************************************* + ** + ** Constants + ** + **/ +/** PICA Interface suite name. */ +#define kSPInterfaceSuite "SP Interface Suite" +/** PICA Interface suite version. */ +#define kSPInterfaceSuiteVersion 2 + +/** PICA messaging system caller; see \c #SPInterfaceSuite. */ +#define kSPInterfaceCaller "SP Interface" +/** PICA messaging system startup; see \c #SPInterfaceSuite. */ +#define kSPInterfaceStartupSelector "Startup" +/** PICA messaging system shutdown; see \c #SPInterfaceSuite. */ +#define kSPInterfaceShutdownSelector "Shutdown" +/** PICA messaging system request for information; see \c #SPInterfaceSuite. + Illustrator sends this call to all plug-ins to implement + the "About Plug-ins" feature.*/ +#define kSPInterfaceAboutSelector "About" + +/** Adapter name for PICA version 2. */ +#define kSPSweetPea2Adapter "Sweet Pea 2 Adapter" +/** Adapter version for PICA version 2.*/ +#define kSPSweetPea2AdapterVersion 1 + +/******************************************************************************* + ** + ** Types + ** + **/ + +/** A basic message, sent with \c #kSPInterfaceCaller. */ +typedef struct SPInterfaceMessage { + + /** The message data. */ + SPMessageData d; + +} SPInterfaceMessage; + + +/******************************************************************************* + ** + ** Suite + ** + **/ +/** @ingroup Suites + This suite provides is the ability for a plug-in to call + other plug-ins, by sending a message to the main entry point. + This is how the application communicates with plug-ins. + + Use \c #SetupMessageData() to prepare the message for a call, + \c #SendMessage() to send the call with the message, and + \c #EmptyMessageData() to terminate the operation, allowing + PICA to release the basic suite and store global variables. + + These calls work only with PICA plug-ins. Before making the calls, + use \c #SPAdaptersSuite::GetAdapterName() to determine that + the target is a PICA plug-in. For non-PICA plug-ins, use the + interface suite provided by the adapter. See \c #SPAdaptersSuite. + + \li Acquire this suite using \c #SPBasicSuite::AcquireSuite() with the constants + \c #kSPInterfaceSuite and \c #kSPInterfaceSuiteVersion. +*/ +typedef struct SPInterfaceSuite { + + /** Sends a message to a PICA plug-in, loading it if needed and + passing the caller, selector, and message to the main entry point. + @param plug-in The target plug-in object. + @param caller The caller constant. See @ref Callers. + @param selector The selector constant. See @ref Selectors. + @param message The message, initialized by \c #SetupMessageData(). + @param result [out] A buffer in which to return the result of the call, + as returned by the target plug-in. + */ + SPAPI SPErr (*SendMessage)( SPPluginRef plugin, const char *caller, const char *selector, + void *message, SPErr *result ); + + /** Initializes a message to be sent with \c #SendMessage(). + The function fills in the basic suite, the plug-in reference, + and the globals pointer that PICA keeps for that plug-in. + You must provide any additional data needed. + @param plugin The target plug-in object. + @param data The message structure, initialized with data required + for the intended call. + */ + SPAPI SPErr (*SetupMessageData)( SPPluginRef plugin, SPMessageData *data ); + /** Terminates a call to another plug-in, releasing the basic suite and + updating the target plug-in's globals pointer, in case it has changed. + Use after a call to \c #SendMessage(). + @param plugin The target plug-in object. + @param data The message structure, updated during the call. + */ + SPAPI SPErr (*EmptyMessageData)( SPPluginRef plugin, SPMessageData *data ); + + /** Starts up the plug-in in a plug-in list that exports a given suite. + Searches in the given plug-in list for the plug-in that exports the named + suite, and, if found, sends it the startup message. + @param pluginList The plug-in list object. Access PICA's global plug-in + list using \c #SPRuntimeSuite::GetRuntimePluginList(), + or create your own lists with \c #SPPluginsSuite::AllocatePluginList(). + @param name The suite name constant. + @param version The suite version number constant. + @param started [out] A buffer in which to return true (non-zero) if a + plug-in that exports the suite was found, false (0) if not. + */ + SPAPI SPErr (*StartupExport)( SPPluginListRef pluginList, const char *name, int32 version, + int32 *started ); + +} SPInterfaceSuite; + + +/** Internal */ +SPAPI SPErr SPSendMessage( SPPluginRef plugin, const char *caller, const char *selector, + void *message, SPErr *result ); + +/** Internal */ +SPAPI SPErr SPSetupMessageData( SPPluginRef plugin, SPMessageData *data ); +/** Internal */ +SPAPI SPErr SPEmptyMessageData( SPPluginRef plugin, SPMessageData *data ); + +/** Internal */ +SPAPI SPErr SPStartupExport( SPPluginListRef pluginList, const char *name, int32 version, + int32 *started ); + + +/******************************************************************************* + ** + ** Errors + ** + **/ + +#include "SPErrorCodes.h" + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/External/AE SDK/Headers/SP/SPMData.h b/External/AE SDK/Headers/SP/SPMData.h new file mode 100644 index 00000000..507e5fff --- /dev/null +++ b/External/AE SDK/Headers/SP/SPMData.h @@ -0,0 +1,66 @@ +/***********************************************************************/ +/* */ +/* SPMData.h */ +/* */ +/* Copyright 1995-2006 Adobe Systems Incorporated. */ +/* All Rights Reserved. */ +/* */ +/* Patents Pending */ +/* */ +/* NOTICE: All information contained herein is the property of Adobe */ +/* Systems Incorporated. Many of the intellectual and technical */ +/* concepts contained herein are proprietary to Adobe, are protected */ +/* as trade secrets, and are made available only to Adobe licensees */ +/* for their internal use. Any reproduction or dissemination of this */ +/* software is strictly forbidden unless prior written permission is */ +/* obtained from Adobe. */ +/* */ +/***********************************************************************/ + +#ifndef __SPMessageData__ +#define __SPMessageData__ + + +/******************************************************************************* + ** + ** Imports + ** + **/ + +#include "SPTypes.h" + +#ifdef __cplusplus +extern "C" { +#endif + + +/******************************************************************************* + ** + ** Types + ** + **/ + +/** The value of \c #SPMessageData::SPCheck, if the message data associated + with a call to a plug-in has come from \c #SPInterfaceSuite::SendMessage(), + or is prepared using \c #SPInterfaceSuite::SetupMessageData(). */ +#define kSPValidSPMessageData 'SPCk' + +/** Basic suite-access information provided with every call. */ +typedef struct SPMessageData { + /** \c #kSPValidSPMessageData if this is a valid PICA message. */ + int32 SPCheck; + /** This plug-in, an \c #SPPluginRef. */ + struct SPPlugin *self; + /** An array of application-wide global variables. */ + void *globals; + /** A pointer to the basic PICA suite, which you use to obtain all other suites. */ + struct SPBasicSuite *basic; + +} SPMessageData; + + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/External/AE SDK/Headers/SP/SPObject.h b/External/AE SDK/Headers/SP/SPObject.h new file mode 100644 index 00000000..9c419b2b --- /dev/null +++ b/External/AE SDK/Headers/SP/SPObject.h @@ -0,0 +1,15 @@ +/****************************************************************************** + SPObject.h + +Purpose: + Defines the suite for registering and creating Sweet Pea objects. + It is a "conventional" Sweet Pea suite used to provide + COM-like objects from Sweet Pea plugins. + + Copyright (c) 1995-1998, 2002 Adobe Systems Incorporated. +******************************************************************************/ +#pragma once +#ifndef __SPObject__ +#define __SPObject__ +/* This module is obsolete. */ +#endif /* __SPObject__ */ diff --git a/External/AE SDK/Headers/SP/SPPiPL.h b/External/AE SDK/Headers/SP/SPPiPL.h new file mode 100644 index 00000000..02aac5d8 --- /dev/null +++ b/External/AE SDK/Headers/SP/SPPiPL.h @@ -0,0 +1,302 @@ +/***********************************************************************/ +/* */ +/* SPPiPL.h */ +/* */ +/* Copyright 1995-2006 Adobe Systems Incorporated. */ +/* All Rights Reserved. */ +/* */ +/* Patents Pending */ +/* */ +/* NOTICE: All information contained herein is the property of Adobe */ +/* Systems Incorporated. Many of the intellectual and technical */ +/* concepts contained herein are proprietary to Adobe, are protected */ +/* as trade secrets, and are made available only to Adobe licensees */ +/* for their internal use. Any reproduction or dissemination of this */ +/* software is strictly forbidden unless prior written permission is */ +/* obtained from Adobe. */ +/* */ +/***********************************************************************/ + +#ifndef __SPPiPL__ +#define __SPPiPL__ + + +/******************************************************************************* + ** + ** Imports and alignment + ** + **/ + +#include "SPTypes.h" + + +#if PRAGMA_STRUCT_ALIGN +#pragma options align=mac68k +#endif + + +/******************************************************************************* + ** + ** Constants + ** + ** Note: 4-character long IDs must be defined in hexidecimal, not long + ** literal ('long'), due to Windows RC compilers not understanding what + ** to do with them. + ** + **/ + +/** Vendor identifier for a plug-in resource, \c #PIProperty::vendorID value. +
'ADBE' Vendor identifier for PICA-generic applications. */ +#define PIAdobeVendorID (PIType)0x41444245L + +/** Property mechanism version property, \c #PIProperty::propertyKey value +
'ivrs' PICA plug-in version. */ +#define PISPVersionProperty (PIType)0x69767273L + +/** Plug-in resource type, \c #PIProperty::propertyKey value. +
'impt' Suite import information. */ +#define PIImportsProperty (PIType)0x696D7074L + +/** Plug-in resource type, \c #PIProperty::propertyKey value. +
'expt' Suite export information. */ +#define PIExportsProperty (PIType)0x65787074L + +/** Plug-in resource type, \c #PIProperty::propertyKey value. +
'ppcR' Power PC resource information. */ +#define PIPowerPCCodeResProperty (PIType)0x70706352L + +/** Plug-in resource type, \c #PIProperty::propertyKey value. +
'heap' Mac OS PPC-only. +
If not defined, loads application default heap. +
If 0, loads system heap */ +#define PIDestinationHeapProperty (PIType)0x68656170L +/** Value of \c #PIDestinationHeapProperty, loads system heap */ +#define PILoadInAppHeap (1L<<0) + +/** Plug-in resource type, \c #PIProperty::propertyKey value. +
'adpt' Adapter version property (a long value) */ +#define PIAdapterProperty (PIType)0x61647074L + +/** Plug-in resource type, \c #PIProperty::propertyKey value. +
'pinm' Internal plug-in name */ +#define PIPluginNameProperty (PIType)0x70696E6DL + +/** Plug-in resource type, \c #PIProperty::propertyKey value. +
'AcpM' Message flags */ +#define PIConditionalMessages (PIType)0x4163704DL +/** Flag bit for \c #PIConditionalMessages: plug-in accepts property changes. <> */ +#define PIAcceptsPropertyMessage (1L<<0) +/** Flag bit for \c #PIConditionalMessages: skip shutdown. <> */ +#define PISkipShutDownMessage (1L<<1) +/** Flag bit for \c #PIConditionalMessages: plug-in accepts purge-cache messages. */ +#define PIAcceptsPurgeCachesMessage (1L<<2) +/** Flag bit for \c #PIConditionalMessages: skip startup message. <> */ +#define PISkipStartupMessage (1L<<3) + +/** Internal. Plug-in resource type, \c #PIProperty::propertyKey value. +
'RelP' generated by Illustrator to optimize program launch */ +#define PIReleasePluginEarly 0x52656c50 + +/******************************************************************************* + ** + ** General PiPL properties and structures + ** + ** Many hosts multiply define these properties, so we bracket them + ** so they are only defined once. + ** + **/ + +#ifndef kGeneralPiPLPropertiesDefined // Already defined? +/** Internal: Defines the general properties only if the application has + not already done so. */ +#define kGeneralPiPLPropertiesDefined // Only define once. + +/** Data type for plug-in property key and vendor ID. See \c #PIProperty. */ +typedef SPUInt32 PIType; + +/** Plug-in properties version number. */ +#define kCurrentPiPLVersion 0 + +// 'kind' giving the plug-in's kind: +#define PIKindProperty (PIType)0x6b696e64L + +// 'm68k' 68k code descriptor. See struct below. +#define PI68KCodeProperty (PIType)0x6d36386bL + +// 'pwpc' PowerPC code descriptor. See struct below. +#define PIPowerPCCodeProperty (PIType)0x70777063L + +// 'ppcb' PowerPC CARBON code descriptor. See struct below. +#define PIPowerPCCarbonCodeProperty 'ppcb' + +// 'mach' PowerPC Mach-O code descriptor. See struct below. +#define PIPowerPCMachOCodeProperty 'mach' + +// 'mi32' Intel 32 Mach-O code descriptor. See struct below. +#define PIMacIntel32Property 'mi32' + +// 'mi64' Intel 64 Mach-O code descriptor. See struct below. +#define PIMacIntel64Property 'mi64' + +// 'ma64' ARM 64 Mach-O code descriptor. See struct below. +#define PIMacARM64Property 'ma64' + +// 'frag' PowerPC fragment descriptor. See struct below. +#define PICodeFragmentProperty 'frag' + +// 'frgc' PowerPC CARBON fragment descriptor. See struct below. +#define PICarbonCodeFragmentProperty 'frgc' + +// '8664' Win32 Intel code descriptor. See struct below. +#define PIWin64X86CodeProperty (PIType)0x38363634L + +// 'wx86' Win32 Intel code descriptor. See struct below. +#define PIWin32X86CodeProperty (PIType)0x77783836L + +// \deprecated 'fx86' Win16 Intel code descriptor. See struct below. +#define PIWin16X86CodeProperty (PIType)0x66783836L + +/** Plug-in property. Properties contain information about + plug-in resource files, such as their type and location. */ +typedef struct PIProperty { + /** Vendor-specific identifier. */ + PIType vendorID; + /** Identification key for this resource type. */ + PIType propertyKey; + /** 0-based index of this resource within its type. + Must be unique for properties of a given type within + a property list. */ + SPInt32 propertyID; + /** Number of characters in the data array. Rounded to a multiple of 4. */ + SPInt32 propertyLength; + /** The property data array that contains the property value, a string of 4 characters. */ + char propertyData[1]; +} PIProperty; + +/** Plug-in property list. Provides the version number of the plug-in + property mechanism itself, and properties for the associated plug-in. + */ +typedef struct PIPropertyList { + /** Version number for the \c #PIProperty structure. */ + SPInt32 version; + /** Number of properties in the list. */ + SPInt32 count; + /** The properties array. */ + PIProperty properties[1]; +} PIPropertyList; + +/* Following structures describe resource file types used in plug-in property lists. + * These structures obey Macintosh 68k alignment and padding rules though + * generally they are laid out so fields have natural alignment and any + * needed padding is explicit in the structure. + */ + //<> + +/** 68k code descriptor. */ +typedef struct PI68KCodeDesc { + /** Property type key code. */ + PIType fType; + /** Property type unique identifier. */ + int16 fID; +} PI68KCodeDesc; + +/** PowerPC code descriptor. */ +typedef struct PICFMCodeDesc { + /** The offset within the data fork for the start of this plugin's + code fragment. This allows more than one code-fragment-based + plug-in per file. */ + SPInt32 fContainerOffset; + /** The length of this plug-in's code fragment. If this + is the only fragment in the file, the length is 0. */ + SPInt32 fContainerLength; + /** The entry-point name, used to look up the address of + the function to call within the fragment; allows a single code + fragment to export more than one plug-in. + + If the name is an empty string, the default entry point + for the code fragment is used. The entry-point name + must be an exported symbol of the code fragment. */ + unsigned char fEntryName[1]; +} PICFMCodeDesc; + +/** PowerPC Mach-O code descriptor. */ +typedef struct PIMachCodeDesc +{ + /** Property type key code <> */ + unsigned char fEntryName[1]; +} PIMachCodeDesc; + +// For 'mi32' PICodeMacIntel32Property: +// For 'mi64' PICodeMacIntel64Property: +typedef struct PIMacIntelMachCodeDesc +{ + unsigned char fEntryName[1]; +} PIMacIntelMachCodeDesc; + +typedef struct PIFragmentCodeDesc +{ + SPInt32 fFragmentResource; + SPInt32 fFramentNumber; + unsigned char fEntryName[1]; +} PIFragmentCodeDesc; + +/** The entry point name for 64 bit windows, used to lookup the function +which is called to invoke the plug-in. A \c NULL terminated string, padded +with additional \ NULL charcters if needed to satisfy the 4-byte alignment +requirement. See @ref PIWin64X86CodeProperty above. */ +typedef struct PIWin64X86CodeDesc +{ + char fEntryName[1]; +} PIWin64X86CodeDesc; + +/** The entry point name for 32 bit windows, used to lookup the function +which is called to invoke the plug-in. A \c NULL terminated string, padded +with additional \ NULL charcters if needed to satisfy the 4-byte alignment +requirement. See @ref PIWin32X86CodeProperty above. */ +typedef struct PIWin32X86CodeDesc { + char fEntryName[1]; +} PIWin32X86CodeDesc; + +/** \deprecated Win16 Intel code descriptor. +See @ref PIWin16X86CodeProperty above. */ +typedef struct PIWin16X86CodeDesc { + char fEntryName[1]; +} PIWin16X86CodeDesc; + +#endif // kGeneralPiPLPropertiesDefined + + +/******************************************************************************* + ** + ** Additional Types + ** + **/ + +/** CFM code descriptor */ +typedef struct PICFMCodeResourceDesc { + /** Not used. */ + SPInt32 fContainerOffset; /* Currently unused, reserved. */ + /** The length of this plug-in's code fragment. If this + is the only fragment in the file, the length is 0. */ + SPInt32 fContainerLength; + /** Resource type key code. <> */ + PIType fType; + /** Unique identifier for the resource within the type. <> */ + int16 fID; + /** The entry-point name, used to look up the address of + the function to call within the fragment; allows a single code + fragment to export more than one plug-in. + + If the name is an empty string, the default entry point + for the code fragment is used. The entry-point name + must be an exported symbol of the code fragment. */ + unsigned char fEntryName[1]; +} PICFMCodeResourceDesc; + +/*******************************************************************************/ + +#if PRAGMA_STRUCT_ALIGN +#pragma options align=reset +#endif + +#endif // SPPiPL diff --git a/External/AE SDK/Headers/SP/SPPlugs.h b/External/AE SDK/Headers/SP/SPPlugs.h new file mode 100644 index 00000000..7cbd83be --- /dev/null +++ b/External/AE SDK/Headers/SP/SPPlugs.h @@ -0,0 +1,631 @@ +/***********************************************************************/ +/* */ +/* SPPlugs.h */ +/* */ +/* Copyright 1995-2006 Adobe Systems Incorporated. */ +/* All Rights Reserved. */ +/* */ +/* Patents Pending */ +/* */ +/* NOTICE: All information contained herein is the property of Adobe */ +/* Systems Incorporated. Many of the intellectual and technical */ +/* concepts contained herein are proprietary to Adobe, are protected */ +/* as trade secrets, and are made available only to Adobe licensees */ +/* for their internal use. Any reproduction or dissemination of this */ +/* software is strictly forbidden unless prior written permission is */ +/* obtained from Adobe. */ +/* */ +/***********************************************************************/ + +#ifndef __SPPlugins__ +#define __SPPlugins__ + + +/******************************************************************************* + ** + ** Imports + ** + **/ + +#include "SPTypes.h" +#include "SPFiles.h" +#include "SPAdapts.h" +#include "SPProps.h" +#include "SPStrngs.h" + +#ifdef __cplusplus +extern "C" { +#endif + + +/******************************************************************************* + ** + ** Constants + ** + **/ +/** PICA plugins suite name */ +#define kSPPluginsSuite "SP Plug-ins Suite" +/** PICA plugins suite version */ +#define kSPPluginsSuiteVersion4 4 +/** PICA plugins suite version */ +#define kSPPluginsSuiteVersion5 5 +/** PICA plugins suite version */ +#define kSPPluginsSuiteVersion6 6 + +#define kSPPluginsSuiteVersion kSPPluginsSuiteVersion4 + +/** PICA global list of available plug-ins.. + @see \c #SPRuntimeSuite::GetRuntimePluginList(). */ +#define kSPRuntimePluginList ((SPPluginListRef)NULL) + + +/******************************************************************************* + ** + ** Types + ** + **/ + +/** Opaque reference to a plug-in object. Access with the \c #SPPluginsSuite. */ +typedef struct SPPlugin *SPPluginRef; +/** A list of plug-in objects. Create with + \c #SPPluginsSuite::AllocatePluginList(), or use + the global list, \c #kSPRuntimePluginList. */ +typedef struct SPPluginList *SPPluginListRef; +/** An iterator object for examining a plug-in list. + See \c #SPPluginsSuite::NewPluginListIterator(). */ +typedef struct SPPluginListIterator *SPPluginListIteratorRef; + +/** PICA file-access error */ +typedef struct _SPErrorData +{ + /** The file for which the error occurred. */ + SPPlatformFileSpecification mErrorFile; + /** Error code, see @ref Errors. */ + SPErr mErrorCode; +} SPErrorData, *SPErrorDataPtr; + +/** File-access error */ +typedef struct _SPXPlatErrorData +{ + /** The file for which the error occurred. */ + XPlatFileSpec mErrorFile; + /** Error code, see @ref Errors. */ + SPErr mErrorCode; +} SPXPlatErrorData, *SPXPlatErrorDataPtr; + +/** */ +typedef SPAPI SPErr (*SPPluginEntryFunc)( const char *caller, const char *selector, void *message ); + +/******************************************************************************* + ** + ** Suite + ** + **/ + +/** This suite allows you to access and manipulate the plug-in object for your own + and those of other plug-ins managed by the Adobe plug-in manager (PICA). + You can access both plug-ins provided with the application (\e host plug-ins), + and external plug-ins.You can query and set plug-in states, + including the "broken" state, which indicates that a plug-in has + become unavailable due to an error condition. + + You can also use this suite to create and use your own lists of plug-ins, + in addition to the global list kept by the application. + + For higher-level access to plug-ins, see \c #AIPluginSuite. + + \li Acquire this suite using \c #SPBasicSuite::AcquireSuite() with the constants + \c #kSPPluginsSuite and \c #kSPPluginsSuiteVersion. + */ +typedef struct SPPluginsSuite { + + /** Creates a new plug-in list. You can also access PICA's global plug-in list, + using \c #SPRuntimeSuite::GetRuntimePluginList(). + @param stringPool The string pool in which to keep plug-in names. + @param pluginList [out] A buffer in which to return the new list object. + */ + SPAPI SPErr (*AllocatePluginList)( SPStringPoolRef strings, SPPluginListRef *pluginList ); + /** Frees a list of plug-ins allocated with \c #AllocatePluginList(), and + also frees any entries in the list. Do not free the global list (\c #kSPRuntimePluginList). + @param pluginList The plug-in list object. + */ + SPAPI SPErr (*FreePluginList)( SPPluginListRef pluginList ); + + /** Creates a new plug-in object and adds it to a plug-in list. + @param pluginList The plug-in list object, or \c NULL to use the + global list. + @param fileSpec The file specification for the plug-in code and resources. + @param PiPL The structure containing the plug-in properties. + @param adapterName The unique identifiying name of the adapter for the new plug-in. + @param adapterInfo A pointer to the adapter-defined structure that stores needed + information about this plug-in. + @param plugin [out] A buffer in which to return the new plug-in object. + @see \c #AllocatePluginList(), \c #SPAdaptersSuite + */ + SPAPI SPErr (*AddPlugin)( SPPluginListRef pluginList, const SPPlatformFileSpecification *fileSpec, + PIPropertyList *PiPL, const char *adapterName, void *adapterInfo, SPPluginRef *plugin ); + + /** Creates an iterator object with which to traverse a plug-in list. + The iterator is initially set to the first plug-in in the list. + @param pluginList The plug-in list object, or \c NULL to use the + global list. + @param iter [out] A buffer in which to return the new iterator object. + @see \c #NextPlugin(), \c #DeletePluginListIterator() + */ + SPAPI SPErr (*NewPluginListIterator)( SPPluginListRef pluginList, SPPluginListIteratorRef *iter ); + /** Retrieves the current plug-in and advances a plug-in-list iterator to the next plug-in in the list. + @param iter The plug-in-list iterator object. + @param plugin [out] A buffer in which to return the current plug-in object, \c NULL + if the end of the list has been reached. + @see \c #NewPluginListIterator(), + */ + SPAPI SPErr (*NextPlugin)( SPPluginListIteratorRef iter, SPPluginRef *plugin ); + /** Frees a plug-in-list iterator that is no longer needed. + @param iter The plug-in-list iterator object. + @see \c #NewPluginListIterator(), + */ + SPAPI SPErr (*DeletePluginListIterator)( SPPluginListIteratorRef iter ); + /** Reports whether a plug-in that is needed <> is + available in a plug-in list. + @param pluginList The plug-in list object, or \c NULL to use the global list. + @param available [out] A buffer in which to return true if the plug-in <> + is found in the list. + @see \c #SPInterfaceSuite::StartupExport() + */ + SPAPI SPErr (*GetPluginListNeededSuiteAvailable)( SPPluginListRef pluginList, SPBoolean *available ); + + /** Retrieves <> for a plug-in provided by the application. <> + @param plugin The plug-in object. + @param host A pointer to the callback procedure. <> + */ + SPAPI SPErr (*GetPluginHostEntry)( SPPluginRef plugin, SPPluginEntryFunc *hostEntry ); + /** Retrieves the code and resources file of a plug-in. + @param plugin The plug-in object. + @param fileSpec [out] A buffer in which to return the file specification. + @see \c #SPFilesSuite + */ + SPAPI SPErr (*GetPluginFileSpecification)( SPPluginRef plugin, SPPlatformFileSpecification *fileSpec ); + /** Retrieves the property list of a plug-in. + @param plugin The plug-in object. + @param propertList [out] A buffer in which to return the property list object. + @see \c #SPPropertiesSuite + */ + SPAPI SPErr (*GetPluginPropertyList)( SPPluginRef plugin, SPPropertyListRef *propertList ); + /** Retrieves the global variables of a plug-in. This is the same value passed in messages + to the plug-in, which PICA stores when the plug-in is unloaded. + @param plugin The plug-in object. + @param globals [out] A buffer in which to return a pointer to the global variable array. + */ + SPAPI SPErr (*GetPluginGlobals)( SPPluginRef plugin, void **globals ); + /** Sets the global variables for a plug-in. This is the same value passed in messages + to the plug-in, which PICA stores when the plug-in is unloaded. + @param plugin The plug-in object. + @param globals The new global variable array. + */ + SPAPI SPErr (*SetPluginGlobals)( SPPluginRef plugin, void *globals ); + /** Reports whether a plug-in has received and returned from the interface start-up message. + @param plugin The plug-in object. + @param started [out] A buffer in which to return true (non-zero) if the plug-in has been started, + false (0) otherwise. + */ + SPAPI SPErr (*GetPluginStarted)( SPPluginRef plugin, int32 *started ); + /** Sets whether a plug-in has received and returned from the interface start-up message. + @param plugin The plug-in object. + @param started True (non-zero) if the plug-in has been started, false (0) otherwise. + */ + SPAPI SPErr (*SetPluginStarted)( SPPluginRef plugin, int32 started ); + /** Reports whether a plug-in is instructed to skip the start-up message. + @param plugin The plug-in object. + @param skipShutdown [out] A buffer in which to return true (non-zero) if the plug-in skips + the start-up message, false (0) otherwise. + */ + SPAPI SPErr (*GetPluginSkipShutdown)( SPPluginRef plugin, int32 *skipShutdown ); + /** Instructs a plug-in to respond or not to respond to the start-up message. + @param plugin The plug-in object. + @param skipShutdown True (non-zero) to skip the start-up message, false (0) + to respond normally to the start-up message. + */ + SPAPI SPErr (*SetPluginSkipShutdown)( SPPluginRef plugin, int32 skipShutdown ); + /** Reports whether a plug-in has reported an error condition that makes it unavailable. + @param plugin The plug-in object. + @param broken [out] A buffer in which to return true (non-zero) if + the plug-in is marked as broken, false (0) otherwise. + */ + SPAPI SPErr (*GetPluginBroken)( SPPluginRef plugin, int32 *broken ); + /** Sets or clears the broken flag that marks a plug-in as unavailable due to an + error condition. + @param plugin The plug-in object. + @param broken True (non-zero) to mark the plug-in as broken, false (0) + to clear the broken flag. + */ + SPAPI SPErr (*SetPluginBroken)( SPPluginRef plugin, int32 broken ); + /** Retrieves the adapter for a plug-in. + @param plugin The plug-in object. + @param adapter [out] A buffer in which to return the adapter object. + @see \c #SPAdaptersSuite + */ + SPAPI SPErr (*GetPluginAdapter)( SPPluginRef plugin, SPAdapterRef *adapter ); + /** Retrieves the adapter-specific information for a plug-in. Typically + used only by the adapter that defined the information. Other plug-ins + should use \c #AIPluginSuite::GetPluginOptions(). + @param plugin The plug-in object. + @param adapterInfo [out] A buffer in which to return a pointer to the adapter-defined + information structure. + @see \c #SPAdaptersSuite + */ + SPAPI SPErr (*GetPluginAdapterInfo)( SPPluginRef plugin, void **adapterInfo ); + /** Sets the adapter-specific information for a plug-in. Typically + used only by the adapter that defined the information. Other plug-ins + should use \c #AIPluginSuite::SetPluginOptions(). + @param plugin The plug-in object. + @param adapterInfo The adapter-defined information structure. + @see \c #SPAdaptersSuite + */ + SPAPI SPErr (*SetPluginAdapterInfo)( SPPluginRef plugin, void *adapterInfo ); + + /** Retrieves a specific property from the property list for a plug-in. If + the property is not found in the list, sends the plug-in the + \c #kSPPropertiesAcquireSelector message. The plug-in can ignore the + message, or it can create and return the requested property. In either + case, this function adds the (possibly \c NULL) property to the list + and returns it. + @param plugin The plug-in object. + @param vendorID The property vendor ID code. + @param propetyKey The property type key code. + @param propertyID The specific property identifier. + @param p [out] A buffer in which to return a pointer to the property object. + @see \c #SPPropertiesSuite + */ + SPAPI SPErr (*FindPluginProperty)( SPPluginRef plugin, PIType vendorID, PIType propertyKey, int32 propertyID, PIProperty **p ); + + /** Retrieves the name of a plug-in. + @param plugin The plug-in object. + @param name [out] A buffer in which to return the name string. + */ + SPAPI SPErr (*GetPluginName)( SPPluginRef plugin, const char **name ); + /** Sets the name of a plug-in. + @param plugin The plug-in object. + @param name The new name string. + */ + SPAPI SPErr (*SetPluginName)( SPPluginRef plugin, const char *name ); + /** Retrieves a plug-in by name. + @param name The name string. + @param plugin [out] A buffer in which to return the plug-in object. + */ + SPAPI SPErr (*GetNamedPlugin)( const char *name, SPPluginRef *plugin); + + /** Sets the property list for a plug-in. + @param plugin The plug-in object. + @param file The file containing the property list. <> + */ + SPAPI SPErr (*SetPluginPropertyList)( SPPluginRef plugin, SPFileRef file ); + + // Plug-ins suite version 5 + /* This attribute frees the adapterInfo field for private data for adapters. + <> */ + /** Retrieves host information for a plug-in. <> + @param plugin The plug-in object. + @param hostInfo [out] A buffer in which to return a pointer to the + host information structure. + */ + SPAPI SPErr (*GetPluginHostInfo)( SPPluginRef plugin, void **hostInfo ); + /** Sets host information for a plug-in. <> + @param plugin The plug-in object. + @param hostInfo The new host information structure. + */ + SPAPI SPErr (*SetPluginHostInfo)( SPPluginRef plugin, void *hostInfo ); + +} SPPluginsSuite; + + + +/******************************************************************************* + ** + ** Suite + ** + **/ + +/** This suite allows you to access and manipulate the plug-in object but uses + the XPlatFileSpec rather than the SPPlatformFileSpecification as in previous + versions. + + For higher-level access to plug-ins, see \c #AIPluginSuite. + + \li Acquire this suite using \c #SPBasicSuite::AcquireSuite() with the constants + \c #kSPPluginsSuite and \c #kSPPluginsSuiteVersion6. + */ +typedef struct SPXPlatPluginsSuite { + + /** Creates a new plug-in list. You can also access PICA's global plug-in list, + using \c #SPRuntimeSuite::GetRuntimePluginList(). + @param stringPool The string pool in which to keep plug-in names. + @param pluginList [out] A buffer in which to return the new list object. + */ + SPAPI SPErr (*AllocatePluginList)( SPStringPoolRef strings, SPPluginListRef *pluginList ); + /** Frees a list of plug-ins allocated with \c #AllocatePluginList(), and + also frees any entries in the list. Do not free the global list (\c #kSPRuntimePluginList). + @param pluginList The plug-in list object. + */ + SPAPI SPErr (*FreePluginList)( SPPluginListRef pluginList ); + + /** Creates a new plug-in object and adds it to a plug-in list. + @param pluginList The plug-in list object, or \c NULL to use the + global list. + @param fileSpec The file specification for the plug-in code and resources. + @param PiPL The structure containing the plug-in properties. + @param adapterName The unique identifiying name of the adapter for the new plug-in. + @param adapterInfo A pointer to the adapter-defined structure that stores needed + information about this plug-in. + @param plugin [out] A buffer in which to return the new plug-in object. + @see \c #AllocatePluginList(), \c #SPAdaptersSuite + */ + SPAPI SPErr (*AddXPlatPlugin)( SPPluginListRef pluginList, const XPlatFileSpec *fileSpec, + PIPropertyList *PiPL, const char *adapterName, void *adapterInfo, SPPluginRef *plugin ); + + /** Creates an iterator object with which to traverse a plug-in list. + The iterator is initially set to the first plug-in in the list. + @param pluginList The plug-in list object, or \c NULL to use the + global list. + @param iter [out] A buffer in which to return the new iterator object. + @see \c #NextPlugin(), \c #DeletePluginListIterator() + */ + SPAPI SPErr (*NewPluginListIterator)( SPPluginListRef pluginList, SPPluginListIteratorRef *iter ); + /** Retrieves the current plug-in and advances a plug-in-list iterator to the next plug-in in the list. + @param iter The plug-in-list iterator object. + @param plugin [out] A buffer in which to return the current plug-in object, \c NULL + if the end of the list has been reached. + @see \c #NewPluginListIterator(), + */ + SPAPI SPErr (*NextPlugin)( SPPluginListIteratorRef iter, SPPluginRef *plugin ); + /** Frees a plug-in-list iterator that is no longer needed. + @param iter The plug-in-list iterator object. + @see \c #NewPluginListIterator(), + */ + SPAPI SPErr (*DeletePluginListIterator)( SPPluginListIteratorRef iter ); + /** Reports whether a plug-in that is needed <> is + available in a plug-in list. + @param pluginList The plug-in list object, or \c NULL to use the global list. + @param available [out] A buffer in which to return true if the plug-in <> + is found in the list. + @see \c #SPInterfaceSuite::StartupExport() + */ + SPAPI SPErr (*GetPluginListNeededSuiteAvailable)( SPPluginListRef pluginList, SPBoolean *available ); + + /** Retrieves <> for a plug-in provided by the application. <> + @param plugin The plug-in object. + @param host A pointer to the callback procedure. <> + */ + SPAPI SPErr (*GetPluginHostEntry)( SPPluginRef plugin, SPPluginEntryFunc *hostEntry ); + /** Retrieves the code and resources file of a plug-in. + @param plugin The plug-in object. + @param fileSpec [out] A buffer in which to return the file specification. + @see \c #SPFilesSuite + */ + SPAPI SPErr (*GetPluginXplatFileSpec)( SPPluginRef plugin, XPlatFileSpec *fileSpec ); + /** Retrieves the property list of a plug-in. + @param plugin The plug-in object. + @param propertList [out] A buffer in which to return the property list object. + @see \c #SPPropertiesSuite + */ + SPAPI SPErr (*GetPluginPropertyList)( SPPluginRef plugin, SPPropertyListRef *propertList ); + /** Retrieves the global variables of a plug-in. This is the same value passed in messages + to the plug-in, which PICA stores when the plug-in is unloaded. + @param plugin The plug-in object. + @param globals [out] A buffer in which to return a pointer to the global variable array. + */ + SPAPI SPErr (*GetPluginGlobals)( SPPluginRef plugin, void **globals ); + /** Sets the global variables for a plug-in. This is the same value passed in messages + to the plug-in, which PICA stores when the plug-in is unloaded. + @param plugin The plug-in object. + @param globals The new global variable array. + */ + SPAPI SPErr (*SetPluginGlobals)( SPPluginRef plugin, void *globals ); + /** Reports whether a plug-in has received and returned from the interface start-up message. + @param plugin The plug-in object. + @param started [out] A buffer in which to return true (non-zero) if the plug-in has been started, + false (0) otherwise. + */ + SPAPI SPErr (*GetPluginStarted)( SPPluginRef plugin, int32 *started ); + /** Sets whether a plug-in has received and returned from the interface start-up message. + @param plugin The plug-in object. + @param started True (non-zero) if the plug-in has been started, false (0) otherwise. + */ + SPAPI SPErr (*SetPluginStarted)( SPPluginRef plugin, int32 started ); + /** Reports whether a plug-in is instructed to skip the start-up message. + @param plugin The plug-in object. + @param skipShutdown [out] A buffer in which to return true (non-zero) if the plug-in skips + the start-up message, false (0) otherwise. + */ + SPAPI SPErr (*GetPluginSkipShutdown)( SPPluginRef plugin, int32 *skipShutdown ); + /** Instructs a plug-in to respond or not to respond to the start-up message. + @param plugin The plug-in object. + @param skipShutdown True (non-zero) to skip the start-up message, false (0) + to respond normally to the start-up message. + */ + SPAPI SPErr (*SetPluginSkipShutdown)( SPPluginRef plugin, int32 skipShutdown ); + /** Reports whether a plug-in has reported an error condition that makes it unavailable. + @param plugin The plug-in object. + @param broken [out] A buffer in which to return true (non-zero) if + the plug-in is marked as broken, false (0) otherwise. + */ + SPAPI SPErr (*GetPluginBroken)( SPPluginRef plugin, int32 *broken ); + /** Sets or clears the broken flag that marks a plug-in as unavailable due to an + error condition. + @param plugin The plug-in object. + @param broken True (non-zero) to mark the plug-in as broken, false (0) + to clear the broken flag. + */ + SPAPI SPErr (*SetPluginBroken)( SPPluginRef plugin, int32 broken ); + /** Retrieves the adapter for a plug-in. + @param plugin The plug-in object. + @param adapter [out] A buffer in which to return the adapter object. + @see \c #SPAdaptersSuite + */ + SPAPI SPErr (*GetPluginAdapter)( SPPluginRef plugin, SPAdapterRef *adapter ); + /** Retrieves the adapter-specific information for a plug-in. Typically + used only by the adapter that defined the information. Other plug-ins + should use \c #AIPluginSuite::GetPluginOptions(). + @param plugin The plug-in object. + @param adapterInfo [out] A buffer in which to return a pointer to the adapter-defined + information structure. + @see \c #SPAdaptersSuite + */ + SPAPI SPErr (*GetPluginAdapterInfo)( SPPluginRef plugin, void **adapterInfo ); + /** Sets the adapter-specific information for a plug-in. Typically + used only by the adapter that defined the information. Other plug-ins + should use \c #AIPluginSuite::SetPluginOptions(). + @param plugin The plug-in object. + @param adapterInfo The adapter-defined information structure. + @see \c #SPAdaptersSuite + */ + SPAPI SPErr (*SetPluginAdapterInfo)( SPPluginRef plugin, void *adapterInfo ); + + /** Retrieves a specific property from the property list for a plug-in. If + the property is not found in the list, sends the plug-in the + \c #kSPPropertiesAcquireSelector message. The plug-in can ignore the + message, or it can create and return the requested property. In either + case, this function adds the (possibly \c NULL) property to the list + and returns it. + @param plugin The plug-in object. + @param vendorID The property vendor ID code. + @param propetyKey The property type key code. + @param propertyID The specific property identifier. + @param p [out] A buffer in which to return a pointer to the property object. + @see \c #SPPropertiesSuite + */ + SPAPI SPErr (*FindPluginProperty)( SPPluginRef plugin, PIType vendorID, PIType propertyKey, int32 propertyID, PIProperty **p ); + + /** Retrieves the name of a plug-in. + @param plugin The plug-in object. + @param name [out] A buffer in which to return the name string. + */ + SPAPI SPErr (*GetPluginName)( SPPluginRef plugin, const char **name ); + /** Sets the name of a plug-in. + @param plugin The plug-in object. + @param name The new name string. + */ + SPAPI SPErr (*SetPluginName)( SPPluginRef plugin, const char *name ); + /** Retrieves a plug-in by name. + @param name The name string. + @param plugin [out] A buffer in which to return the plug-in object. + */ + SPAPI SPErr (*GetNamedPlugin)( const char *name, SPPluginRef *plugin); + + /** Sets the property list for a plug-in. + @param plugin The plug-in object. + @param file The file containing the property list. <> + */ + SPAPI SPErr (*SetPluginPropertyList)( SPPluginRef plugin, SPFileRef file ); + + // Plug-ins suite version 5 + /* This attribute frees the adapterInfo field for private data for adapters. + <> */ + /** Retrieves host information for a plug-in. <> + @param plugin The plug-in object. + @param hostInfo [out] A buffer in which to return a pointer to the + host information structure. + */ + SPAPI SPErr (*GetPluginHostInfo)( SPPluginRef plugin, void **hostInfo ); + /** Sets host information for a plug-in. <> + @param plugin The plug-in object. + @param hostInfo The new host information structure. + */ + SPAPI SPErr (*SetPluginHostInfo)( SPPluginRef plugin, void *hostInfo ); + +} SPXPlatPluginsSuite; + + +/** Internal */ +SPAPI SPErr SPAllocatePluginList( SPStringPoolRef strings, SPPluginListRef *pluginList ); +/** Internal */ +SPAPI SPErr SPFreePluginList( SPPluginListRef pluginList ); +/** Internal */ +SPAPI SPErr SPGetPluginListNeededSuiteAvailable( SPPluginListRef pluginList, SPBoolean *available ); + +/** Internal */ +SPAPI SPErr SPAddPlugin( SPPluginListRef pluginList, const SPPlatformFileSpecification *fileSpec, + PIPropertyList *PiPL, const char *adapterName, void *adapterInfo, SPPluginRef *plugin ); + +/** Internal */ +SPAPI SPErr SPAddXPlatPlugin( SPPluginListRef pluginList, const XPlatFileSpec *fileSpec, + PIPropertyList *PiPL, const char *adapterName, void *adapterInfo, SPPluginRef *plugin ); + +/** Internal */ +SPAPI SPErr SPNewPluginListIterator( SPPluginListRef pluginList, SPPluginListIteratorRef *iter ); +/** Internal */ +SPAPI SPErr SPNextPlugin( SPPluginListIteratorRef iter, SPPluginRef *plugin ); +/** Internal */ +SPAPI SPErr SPDeletePluginListIterator( SPPluginListIteratorRef iter ); + +/** Internal */ +SPAPI SPErr SPGetHostPluginEntry( SPPluginRef plugin, SPPluginEntryFunc *hostEntry ); +/** Internal */ +SPAPI SPErr SPGetPluginFileSpecification( SPPluginRef plugin, SPPlatformFileSpecification *fileSpec ); +/** Internal */ +SPAPI SPErr SPGetPluginXplatFileSpec( SPPluginRef plugin, XPlatFileSpec *fileSpec ); +/** Internal */ +SPAPI SPErr SPGetPluginPropertyList( SPPluginRef plugin, SPPropertyListRef *propertyList ); +/** Internal */ +SPAPI SPErr SPGetPluginGlobals( SPPluginRef plugin, void **globals ); +/** Internal */ +SPAPI SPErr SPSetPluginGlobals( SPPluginRef plugin, void *globals ); +/** Internal */ +SPAPI SPErr SPGetPluginStarted( SPPluginRef plugin, int32 *started ); +/** Internal */ +SPAPI SPErr SPSetPluginStarted( SPPluginRef plugin, int32 started ); +/** Internal */ +SPAPI SPErr SPGetPluginSkipShutdown( SPPluginRef plugin, int32 *skipShutdown ); +/** Internal */ +SPAPI SPErr SPSetPluginSkipShutdown( SPPluginRef plugin, int32 skipShutdown ); +/** Internal */ +SPAPI SPErr SPGetPluginBroken( SPPluginRef plugin, int32 *broken ); +/** Internal */ +SPAPI SPErr SPSetPluginBroken( SPPluginRef plugin, int32 broken ); +/** Internal */ +SPAPI SPErr SPGetPluginAdapter( SPPluginRef plugin, SPAdapterRef *adapter ); +/** Internal */ +SPAPI SPErr SPGetPluginAdapterInfo( SPPluginRef plugin, void **adapterInfo ); +/** Internal */ +SPAPI SPErr SPSetPluginAdapterInfo( SPPluginRef plugin, void *adapterInfo ); + +/** Internal */ +SPAPI SPErr SPFindPluginProperty( SPPluginRef plugin, PIType vendorID, PIType propertyKey, + int32 propertyID, PIProperty **p ); + +/** Internal */ +SPAPI SPErr SPGetPluginName( SPPluginRef plugin, const char **name ); +/** Internal */ +SPAPI SPErr SPSetPluginName( SPPluginRef plugin, const char *name ); +/** Internal */ +SPAPI SPErr SPGetNamedPlugin( const char *name, SPPluginRef *plugin); + +/** Internal */ +SPAPI SPErr SPSetPluginPropertyList( SPPluginRef plugin, SPFileRef file ); + +/** Internal */ +SPErr SPAddHostPlugin( SPPluginListRef pluginList, SPPluginEntryFunc entry, void *access, const char *adapterName, + void *adapterInfo, SPPluginRef *plugin, const char *name); + /* access is SPPlatformAccessRef */ + + +// Plug-ins suite version 5 +/* This attribute frees the adapterInfo field for private data for adapters. */ +/** Internal */ +SPAPI SPErr SPGetPluginHostInfo( SPPluginRef plugin, void **hostInfo ); +/** Internal */ +SPAPI SPErr SPSetPluginHostInfo( SPPluginRef plugin, void *hostInfo ); + + +/******************************************************************************* + ** + ** Errors + ** + **/ + +#include "SPErrorCodes.h" + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/External/AE SDK/Headers/SP/SPProps.h b/External/AE SDK/Headers/SP/SPProps.h new file mode 100644 index 00000000..748c7ba7 --- /dev/null +++ b/External/AE SDK/Headers/SP/SPProps.h @@ -0,0 +1,316 @@ +/***********************************************************************/ +/* */ +/* SPProps.h */ +/* */ +/* Copyright 1995-2006 Adobe Systems Incorporated. */ +/* All Rights Reserved. */ +/* */ +/* Patents Pending */ +/* */ +/* NOTICE: All information contained herein is the property of Adobe */ +/* Systems Incorporated. Many of the intellectual and technical */ +/* concepts contained herein are proprietary to Adobe, are protected */ +/* as trade secrets, and are made available only to Adobe licensees */ +/* for their internal use. Any reproduction or dissemination of this */ +/* software is strictly forbidden unless prior written permission is */ +/* obtained from Adobe. */ +/* */ +/***********************************************************************/ + +#ifndef __SPProperties__ +#define __SPProperties__ + + +/******************************************************************************* + ** + ** Imports + ** + **/ + +#include "SPTypes.h" +#include "SPMData.h" +#include "SPPiPL.h" + +#ifdef __cplusplus +extern "C" { +#endif + + +/******************************************************************************* + ** + ** Constants + ** + **/ + +/** PICA properties suite name */ +#define kSPPropertiesSuite "SP Properties Suite" +/** PICA properties suite version */ +#define kSPPropertiesSuiteVersion2 2 +/** PICA properties suite version */ +#define kSPPropertiesSuiteVersion kSPPropertiesSuiteVersion2 // minimal is default +/** PICA properties suite version */ +#define kSPPropertiesSuiteVersion3 3 + +/** @ingroup Callers + PICA plug-in property operation; sent with \c #SPPropertiesMessage. + See \c #SPPropertiesSuite. */ +#define kSPPropertiesCaller "SP Properties" +/** @ingroup Selectors + Acquire PICA plug-in properties; sent with \c #SPPropertiesMessage. + See \c #SPPropertiesSuite.*/ +#define kSPPropertiesAcquireSelector "Acquire" +/** @ingroup Selectors + Release PICA plug-in properties; sent with \c #SPPropertiesMessage. + See \c #SPPropertiesSuite.*/ +#define kSPPropertiesReleaseSelector "Release" + + +/******************************************************************************* + ** + ** Types + ** + **/ +/** An opaque reference to a plug-in property. Access with the \c #SPPropertiesSuite. */ +typedef struct SPProperty *SPPropertyRef; +/** An opaque reference to a plug-in property list. Create and access with the \c #SPPropertiesSuite. */ +typedef struct SPPropertyList *SPPropertyListRef; +/** An opaque reference to an iterator for a plug-in property list. Create and access with the \c #SPPropertiesSuite. */ +typedef struct SPPropertyListIterator *SPPropertyListIteratorRef; + +/** Message passed with the \c #kSPPropertiesCaller. */ +typedef struct SPPropertiesMessage { + /** The message data. */ + SPMessageData d; + + /** Unique identifier for the vendor defining this property type. This allows + you to define your own properties in a way that + does not conflict with either Adobe or other vendors. + Use a registered application creator code to ensure uniqueness. + All PICA properties use \c #PIAdobeVendorID.*/ + PIType vendorID; + /** The property type key code, typically identifies a resource type. */ + PIType propertyKey; + /** The unique property identifier, for multiple resources of a given + type. Normally, there is only one, and the ID value is 0. */ + int32 propertyID; + + /** A structure containing the property data, or value. */ + void *property; + /** Reference count. Increment when a property is acquired, decrement + when it is released. */ + int32 refCon; + /** True (non-zero) if this property does not change betweeen sessions + and can be cached by the application in the start-up preferences + file, false (0) otherwise. Typically true. */ + int32 cacheable; + +} SPPropertiesMessage; + + +/******************************************************************************* + ** + ** Suite + ** + **/ +/** @ingroup Suites + Use these functions to create, access, and manage plug-in property lists + associated with a specific plug-in. Plug-in properties provide the + application with resource information for the plug-in, such as the types + and locations of code files, and the plug-in version. + + A plug-in can be associated with multiple properties lists. + + \li Acquire this suite using \c #SPBasicSuite::AcquireSuite() with the constants + \c #kSPPropertiesSuite and \c #kSPPropertiesSuiteVersion. + */ +typedef struct SPPropertiesSuite { + + /** Creates a new plug-in property list. + @param stringPool The string pool in which to keep plug-in names. + @param propertyList [out] A buffer in which to return the new list object. + */ + SPAPI SPErr (*AllocatePropertyList)( SPPropertyListRef *propertyList ); + /** Frees a list of plug-in properties allocated with \c #AllocatePropertyList(), and + also frees any entries in the list. If the list is one of a chain, frees the + entire chain. + @param propertyList The plug-in properties list object. + @see \c #SPHasMultiplePropertyLists() + */ + SPAPI SPErr (*FreePropertyList)( SPPropertyListRef propertyList ); + + /** Adds a set of properties to a plug-in properties list. This set is typically + read from a resource file.Creates an \c #SPPropertyRef for each property, + but does not return these objects. + @param propertyList The plug-in properties list object. + @param pList A pointer to the low-level structure for the set of properties to add. + @param refCon The initial reference count for properties in the set. + @param cacheable True (non-zero) if these properties do not change betweeen sessions + and can be cached by the application in the start-up preferences + file, false (0) otherwise. Typically true. + @see \c #AddProperty() + */ + SPAPI SPErr (*AddProperties)( SPPropertyListRef propertyList, PIPropertyList *pList, int32 refCon, int32 cacheable ); + + /** Creates a new individual property and adds it to a plug-in properties list. + Typically called to install a property returned from an \c #kSPPropertiesAcquireSelector message. + @param propertyList The plug-in properties list object. + @param vendorID The vendor identifier for the new property. + @param propertyKey The type key code for the new property. + @param propertyID The unique identifier for the individual property (normally 0). + @param p A pointer to the property value structure. + <> + @param refCon The initial reference count for property. + @param cacheable True (non-zero) if this property does not change betweeen sessions + and can be cached by the application in the start-up preferences + file, false (0) otherwise. Typically true. + @param property [out] A buffer in which to return the new property object. + @see \c #AllocatePropertyList(), \c #AddProperties() + */ + SPAPI SPErr (*AddProperty)( SPPropertyListRef propertyList, PIType vendorID, PIType propertyKey, int32 propertyID, PIProperty *p, + int32 refCon, int32 cacheable, SPPropertyRef *property ); + + /** Retrieves a property from a plug-in properties list, or from any list in its chain. + @param propertyList The plug-in properties list object. + @param vendorID The vendor identifier for the new property. + @param propertyKey The type key code for the new property. + @param propertyID The unique identifier for the individual property (normally 0). + @param property [out] A buffer in which to return the property object, or \c NULL if a + matching property is not found. + @param \c #FindPropertyLocal() + */ + SPAPI SPErr (*FindProperty)( SPPropertyListRef propertyList, PIType vendorID, PIType propertyKey, int32 propertyID, SPPropertyRef *property ); + + /** Creates an iterator object with which to traverse a plug-in properties list. + The iterator is initially set to the first property in the list. + @param propertyList The plug-in properties list object. + @param iter [out] A buffer in which to return the new iterator object. + @see \c #NextProperty(), \c #DeletePropertyListIterator() + */ + SPAPI SPErr (*NewPropertyListIterator)( SPPropertyListRef propertyList, SPPropertyListIteratorRef *iter ); + /** Retrieves the current property and advances a plug-in properties list iterator + to the next property in the list. + @param iter The plug-in properties list iterator object. + @param property [out] A buffer in which to return the current property object, \c NULL + if the end of the list has been reached. + @see \c #NewPropertyListIterator(), + */ + SPAPI SPErr (*NextProperty)( SPPropertyListIteratorRef iter, SPPropertyRef *property ); + /** Frees a plug-in properties list iterator that is no longer needed. + @param iter The plug-in properties list iterator object. + @see \c #NewPropertyListIterator(), + */ + SPAPI SPErr (*DeletePropertyListIterator)( SPPropertyListIteratorRef iter ); + + /** Retrieves the low-level property structure of a property object. + @param property The property object. + @param p [out] A buffer in which to return a pointer to the property structure. + */ + SPAPI SPErr (*GetPropertyPIProperty)( SPPropertyRef property, PIProperty **p ); + /** Retrieves the current reference count of a property. + @param property The property object. + @param refCon [out] A buffer in which to return the reference count. + */ + SPAPI SPErr (*GetPropertyRefCon)( SPPropertyRef property, int32 *refCon ); + /** Reports whether a property is cacheable. + @param property The property object. + @param cacheable [out] A buffer in which to return true (non-zero) + if this property does not change betweeen sessions + and can be cached by the application in the start-up preferences + file, false (0) otherwise. + */ + SPAPI SPErr (*GetPropertyCacheable)( SPPropertyRef property, int32 *cacheable ); + /** Reports whether a property was allocated by the plug-in that contains it. + @param property The property object. + @param allocatedByPlugin [out] A buffer in which to return true (non-zero) + if this property was created after being acquired from a + \c #kSPPropertiesAcquireSelector message, false (0) if the + property was read from a resource file. + @see \c #AddProperty(), \c #AddProperties() + */ + SPAPI SPErr (*GetPropertyAllocatedByPlugin)( SPPropertyRef property, int32 *allocatedByPlugin ); + + // kSPPropertiesSuiteVersion3 + /** Reports whether a plug-in properties list is one of a chain of properties lists for its plug-in. + (Note that this function returns a boolean value, not an error code.) + @param propertyList The plug-in properties list object. + @return True (non-zero) if the list is one of a chain, false (0) otherwise. + @see \c #GetNextPropertyList() + */ + SPAPI SPBoolean (*SPHasMultiplePropertyLists)(SPPropertyListRef propertyList); + /** Retrieves the next plug-in properties list in a properties-list chain. + @param propertyList The current plug-in properties list object. + @param nextPropertyList [out] A buffer in which to return the next properties list object, + or \c NULL if the end of the chain has been reached. + */ + SPAPI SPErr (*GetNextPropertyList)(SPPropertyListRef propertyList, SPPropertyListRef *nextPropertyList); + /** Retrieves a property from a plug-in properties list, but does not search in other + lists in the chain. + @param propertyList The plug-in properties list object. + @param vendorID The vendor identifier for the new property. + @param propertyKey The type key code for the new property. + @param propertyID The unique identifier for the individual property (normally 0). + @param property [out] A buffer in which to return the property object, or \c NULL if a + matching property is not found. + @see \c #FindProperty() + */ + SPAPI SPErr (*FindPropertyLocal)( SPPropertyListRef propertyList, PIType vendorID, PIType propertyKey, + int32 propertyID, SPPropertyRef *property ); + +} SPPropertiesSuite; + + +/** Internal */ +SPAPI SPErr SPAllocatePropertyList( SPPropertyListRef *propertyList ); +/** Internal */ +SPAPI SPErr SPFreePropertyList( SPPropertyListRef propertyList ); + +/** Internal */ +SPAPI SPErr SPAddProperties( SPPropertyListRef propertyList, PIPropertyList *pList, int32 refCon, + int32 cacheable ); + +/** Internal */ +SPAPI SPErr SPAddProperty( SPPropertyListRef propertyList, PIType vendorID, PIType propertyKey, + int32 propertyID, PIProperty *p, int32 refCon, int32 cacheable, SPPropertyRef *property ); + +/** Internal */ +SPAPI SPErr SPFindProperty( SPPropertyListRef propertyList, PIType vendorID, PIType propertyKey, + int32 propertyID, SPPropertyRef *property ); + +/** Internal */ +SPAPI SPErr SPNewPropertyListIterator( SPPropertyListRef propertyList, SPPropertyListIteratorRef *iter ); +/** Internal */ +SPAPI SPErr SPNextProperty( SPPropertyListIteratorRef iter, SPPropertyRef *property ); +/** Internal */ +SPAPI SPErr SPDeletePropertyListIterator( SPPropertyListIteratorRef iter ); + +/** Internal */ +SPAPI SPErr SPGetPropertyPIProperty( SPPropertyRef property, PIProperty **p ); +/** Internal */ +SPAPI SPErr SPGetPropertyRefCon( SPPropertyRef property, int32 *refCon ); +/** Internal */ +SPAPI SPErr SPGetPropertyCacheable( SPPropertyRef property, int32 *cacheable ); +/** Internal */ +SPAPI SPErr SPGetPropertyAllocatedByPlugin( SPPropertyRef property, int32 *allocatedByPlugin ); + +/** Internal */ +SPAPI SPBoolean SPHasMultiplePropertyLists(SPPropertyListRef propertyList); +/** Internal */ +SPAPI SPErr SPGetNextPropertyList(SPPropertyListRef propertyList, SPPropertyListRef *nextPropertyList); + +/** Internal */ +SPAPI SPErr SPFindPropertyLocal( SPPropertyListRef propertyList, PIType vendorID, + PIType propertyKey, int32 propertyID, SPPropertyRef *property ); + +/******************************************************************************* + ** + ** Errors + ** + **/ + +#include "SPErrorCodes.h" + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/External/AE SDK/Headers/SP/SPRuntme.h b/External/AE SDK/Headers/SP/SPRuntme.h new file mode 100644 index 00000000..8f6f6aa6 --- /dev/null +++ b/External/AE SDK/Headers/SP/SPRuntme.h @@ -0,0 +1,500 @@ +/***********************************************************************/ +/* */ +/* SPRuntme.h */ +/* */ +/* Copyright 1995-2006 Adobe Systems Incorporated. */ +/* All Rights Reserved. */ +/* */ +/* Patents Pending */ +/* */ +/* NOTICE: All information contained herein is the property of Adobe */ +/* Systems Incorporated. Many of the intellectual and technical */ +/* concepts contained herein are proprietary to Adobe, are protected */ +/* as trade secrets, and are made available only to Adobe licensees */ +/* for their internal use. Any reproduction or dissemination of this */ +/* software is strictly forbidden unless prior written permission is */ +/* obtained from Adobe. */ +/* */ +/***********************************************************************/ + +#ifndef __SPRuntime__ +#define __SPRuntime__ + + +/******************************************************************************* + ** + ** Imports + ** + **/ + +#include "SPTypes.h" +#include "SPAdapts.h" +#include "SPFiles.h" +#include "SPPlugs.h" +#include "SPStrngs.h" +#include "SPSuites.h" +#include "SPStrngs.h" + +#ifdef __cplusplus +extern "C" { +#endif + + +/******************************************************************************* + ** + ** Constants + ** + **/ + +#define kSPRuntimeSuite "SP Runtime Suite" +#define kSPRuntimeSuiteVersion 5 +#define kSPRuntimeSuiteXPlatVersion 6 + + +/******************************************************************************* + ** + ** Types + ** + **/ + +/* INTERNAL DOCS + * PICA makes callbacks into the host through the host procs. The host + * procs are filled in by the host and passed to Sweet Pea at SPInit(). + * + * hostData - data that is given back to each host proc when Sweet Pea + * calls it. Sweet Pea does nothing with it itself. + * + * extAllocate - implementation of the Block Suite's AllocateBlock() routine. + * It is identical to ANSI C malloc(). It returns a pointer to the + * beginning of the allocated block or NULL. + * + * extFree - implementation of the Block Suite's FreeBlock() routine. It is + * identical to ANSI C free(). Note that you can pass it NULL. + * + * extReallocate - implementation of the Block Suite's ReallocateBlock() + * routine. It is identical to ANSI C realloc(). It returns a pointer + * to the resized block or NULL. Note that you can pass it NULL or a + * newSize of 0. + * + * intAllocate, intFree, intReallocate - routines used by Sweet Pea for + * its own memory needs. You may want to allocate blocks differently + * with plug-ins and Sweet Pea. Plug-ins are unbounded in their memory + * needs, while Sweet Pea's memory usage can be approximated. + * + * startupNotify - called as each plug-in is started up. This is intended + * as a way to tell the user what's happening during start up. + * Note that plug-ins may start up at any time, not just during + * SPStartupPlugins(). + * + * shutdownNotify - called as each plug-in is shut down. Also intended as + * a way to let users know what's going on. + * + * assertTrap - called when a fatal assert is triggered. Sweet Pea does + * not expect execution to continue after an assert. + * + * throwTrap - called when an internal error is thrown. This can be used + * during debugging to catch errors as they happen. It should return + * to allow Sweet Pea to handle the error. + * + * + * To aid in getting Sweet Pea up and running quickly, you can set any of + * these to NULL and Sweet Pea will use a default implementation. However: + * you cannot mix your implementations of the memory routines with + * Sweet Pea's defaults. + * + * + * The string pool functions replace the default routines used internally + * and exported by the Strings suite. Because they are exported, the behaviors + * listed below should be followed. + * + * allocateStringPool - creates a new string pool instance. The host app and + * Sweet Pea have a string pool which can be used by a plug-in, or a plug-in + * can create its own. See the notes in SPStrngs.h on how the pool is + * implemented. + * The function should return kSPNoError if the pool is allocated successfully + * or kSPOutOfMemoryError if allocation fails. + * + * freeStringPool - disposes of the string pool and any associated memory. The + * funtion should return kSPNoError + * + * makeWString - the string pool keeps a list of added strings. When a new string is + * added with MakeWString(), the routine checks to see if it is already in the + * pool. If so, the address of the string instance in the pool is returned. If + * not, it will add it to the pool and return the address of the newly + * created string instance. The behavior is: + * + * if ( string == NULL ) + * *wString = NULL; + * returns kSPNoError; + * else if ( string in string pool ) + * *wString = found string; + * returns kSPNoError; + * else add string + * if successful + * *wString = new string; + * returns kSPNoError; + * else + * *wString = nil + * returns kSPOutOfMemoryError + * + * appStringPool - if the host application has already allocated a string pool to use, + * it's reference should be passed here. If this value is NULL, Sweet Pea will + * allocate the pool when initialized and dispose of it at termination. + * + * filterEvent - a function called for each event allowing the host to cancel it. + * The event type is indicative of what the filter is to do. A file validation + * is called before a directory entry is added to the file list (kAddFile). + * A plug-in validation before a file is checked for PiPL information (kAddPlugin); + * the host might examine the file name/type to determine whether it should be added. + * For these 'add' events the return value is TRUE if the item should be skipped + * or FALSE if should be should be added. The default filter proc, used (if NULL) + * is passed, will skip files/folders in ( ). + * The other event is kSuitesAvailable. It is called when the last suite adding + * plug-in (as determined by available PiPL information) has been added. This is + * a point at which the host can cancel the startup process; for instance, if the host + * requires a suite from a plug-in, this is the time to check for it. If the + * host returns TRUE, the startup process continues. If it returns FALSE, the + * plug-in startup is canceled and the host would likely terminate or startup in + * an alternate manner. + * + * overrideAddPlugins - if supplied, SP will call the host to create the runtime + * plug-in list. This occurs at SPStartupPlugins(). The function takes no parameters + * as it is up to the host to determine how to do this. For instance, the host can do + * this from cached data or, as SP would, from the file list. A returned error will + * stop the plug-in startup process. + * + * overrideStartup - a function called for each SP2 plug-in before it is sent the + * startup message. If the host returns FALSE, SP will startup the plug-in normal. + * If the host returns true, it is assumed that the host has handled the startup + * for the plug-in, so SP will not do anything for the plug-in. This is intended + * to be used with a plug-in caching scheme. + * The host would be responsible, for instance, for defining the cacheable + * information in the PiPL, adding it when the callback is made, and later issuing + * a startup message when the plug-in is actually needed (e.g. when a menu item + * is selected.) Two notes: don't forget to SetPluginStarted(), and make sure + * to use a string pooled char* to kSPInterfaceCaller and kSPInterfaceStartupSelector. + * + * resolveLink - Windows only. If the search for plug-ins is to recurse sub-folders, + * the host needs to suply this routine. When a .lnk file is encountered, the + * resolveLink host callback function will be called and should return a resolved path. + * This is a host callback due to OLE issues such as initialization, which the SP + * libary does not currently handle. If it returns an error code, the result will + * be ignored. + * + * getPluginAccess - Allows the host to set the plug-in access information. This would + * be used if, for instance, the host kept its own plug-in list (ala, Photoshop), but + * still needed these to be compatible with SPPlugins (e.g. whose accesses are used by ADM) + * + * memoryIsCritical - Mac only. Allows the host to indicate that memory is in a critical state + * (really low, but can't be purged because you are, say, shutdown.) + * If so and the plug-in load target heap is the app heap, when a plug-in fails to load + * SP will then try to load the plug-in into the system heap + */ + +/* These are passed in startup and shutdown host notify procs and the filter file proc. */ +/** A notification event type, that an adapter passes to the \c #SPStartupNotifyProc + and \c #SPShutdownNotifyProc when the associated plug-in is loaded or unloaded. + */ +typedef enum { + /** Sent to the \c #SPStartupNotifyProc after a file has been added as a plug-in. + The \c notifyData value is the plug-in object, an \c #SPPluginRef. */ + kAddFile, /* Internal: for filter file, received before a file is + added to a file list, notifyData is a pointer to the + SPPlatformFileSpecification */ + /** Sent to the \c #SPStartupNotifyProc after a plug-in has been added. + The \c notifyData value is the plug-in object, an \c #SPPluginRef. */ + kAddPlugin, /* Internal: for filter file, received before a file is + checked to see if it is a plugin, notifyData is the + files SPFileRef */ + /** Sent to the \c #SPStartupNotifyProc to specify a general message for the application splash screen. + The \c notifyData value is a pointer to a C string, char**. */ + kSetMessage, + /** Internal */ + kSuitesAvailable, /* Internal: used only by event filter to allow host to + check for suites it requires, notifyDatais NULL */ + /** Internal */ + kError, /* Internal: notifyData is SPErrorDataPtr*/ + /** Sent to the \c #SPStartupNotifyProc after the plug-in is started. + The \c notifyData value is the plug-in object, an \c #SPPluginRef. */ + kStartingupPlugin, /* Internal: for filter file, received before a file is + checked to see if it is a plugin, notifyData is the + files SPFileRef */ + kXPlatError, /* Internal: notifyData is SPXPlatErrorData */ + /** Sent to the \c #SPStartupNotifyProc after the plug-in is started. + The \c notifyData value is the plug-in object, an \c #SPPluginRef. */ + /** Internal */ + kNoEvent = 0xffffffff + } NotifyEvent; + +/** Internal */ +typedef void *(*SPAllocateProc)( size_t size, void *hostData ); +/** Internal */ +typedef void (*SPFreeProc)( void *block, void *hostData ); +/** Internal */ +typedef void *(*SPReallocateProc)( void *block, size_t newSize, void *hostData ); +/** Called by an adapter to inform the application that a plug-in is being started up. + The application uses this information to track the start-up process; for example, + to display a list of plug-ins being loaded. + @param event The notification event constant that identifies which event occurred. + @param notifyData A pointer to plug-in-defined initialization data. + @param hostData A pointer to application-defined initialization data. + @return Nothing. + */ +typedef void (*SPStartupNotifyProc)( NotifyEvent event, void *notifyData, void *hostData ); +/** Called by an adapter to inform the application that a plug-in is being shut down. + The application uses this information to track the shut-down process. + @param event The notificatin event. + @param notifyData A pointer to plug-in-defined termination data. + @param hostData A pointer to application-defined termination data. + @return Nothing. + */ +typedef void (*SPShutdownNotifyProc)( NotifyEvent event, void *notifyData, void *hostData ); +/** Internal */ +typedef void (*SPAssertTrapProc)( const char *failMessage, void *hostData ); +/** Internal */ +typedef void (*SPThrowTrapProc)( SPErr error, void *hostData ); +/** Internal */ +typedef void (*SPDebugTrapProc)( const char *debugMessage, void *hostData ); + +/** Internal */ +typedef SPAPI SPErr (*SPAllocateStringPoolProc)( SPStringPoolRef *pool ); +/** Internal */ +typedef SPAPI SPErr (*SPFreeStringPoolProc)( SPStringPoolRef stringPool ); +/** Internal */ +typedef SPAPI SPErr (*SPMakeWStringProc)( SPStringPoolRef stringPool, const char *string, + const char **wString ); + +/** Internal */ +typedef SPAPI SPErr (*SPGetHostAccessInfoProc)( SPPlatformAccessInfo *spHostAccessInfo ); + +/** Internal */ +typedef SPAPI SPBoolean (*SPFilterEventProc)( NotifyEvent event, const void *eventData ); +/** Internal */ +typedef SPAPI SPErr (*SPAddPluginsProc)( void ); +/** Internal */ +typedef SPAPI SPBoolean (*SPOverrideStartupProc)( SPPluginRef currentPlugin ); + +#if defined(WIN_ENV) || defined(ANDROID_ENV) +/** Internal */ +typedef SPAPI SPErr (*SPResolveLinkProc)(const char *shortcutFile, char *resolvedPath); +#endif + +/** Internal */ +typedef SPAPI SPErr (*GetNativePluginAccessProc)(SPPluginRef plugin, SPAccessRef *access); + +/** Internal */ +typedef SPAPI SPBoolean (*MemoryIsCriticalProc)( void ); + +/** Callback procedures provided to PICA by the application. + Plug-ins do not use these, except for adapters, which + call the initialization and termination procedures. + @see \c #SPRuntimeSuite::GetRuntimeHostFileSpec() */ +typedef struct SPHostProcs { + + void *hostData; + + SPAllocateProc extAllocate; + SPFreeProc extFree; + SPReallocateProc extReallocate; + + SPAllocateProc intAllocate; + SPFreeProc intFree; + SPReallocateProc intReallocate; + /** Plug-in initialization procedure */ + SPStartupNotifyProc startupNotify; + /** Plug-in termination procedure */ + SPShutdownNotifyProc shutdownNotify; + + SPAssertTrapProc assertTrap; + SPThrowTrapProc throwTrap; + SPDebugTrapProc debugTrap; + + SPAllocateStringPoolProc allocateStringPool; + SPFreeStringPoolProc freeStringPool; + SPMakeWStringProc makeWString; + SPStringPoolRef appStringPool; + + SPFilterEventProc filterEvent; + SPAddPluginsProc overrideAddPlugins; + SPOverrideStartupProc overridePluginStartup; + +#if defined(WIN_ENV) || defined(ANDROID_ENV) + SPResolveLinkProc resolveLink; +#endif + + GetNativePluginAccessProc getPluginAccess; + +#ifdef MAC_ENV + // enable second-chance plugin loading for success-critical situations + MemoryIsCriticalProc memoryIsCritical; +#endif + +} SPHostProcs; + + +/******************************************************************************* + ** + ** Suite + ** + **/ +/** @ingroup Suites + This suite allows you to obtain specific references to the + PICA global lists and string pool. + + \li Acquire this suite using \c #SPBasicSuite::AcquireSuite() with the constants + \c #kSPRuntimeSuite and \c #kSPRuntimeSuiteVersion. + */ +typedef struct SPRuntimeSuite { + /** Retrieves the PICA global string pool. + @param stringPool [out] A buffer in which to return the string-pool object. + @see \c #SPStringsSuite + */ + SPAPI SPErr (*GetRuntimeStringPool)( SPStringPoolRef *stringPool ); + /** Retrieves the PICA global suite list. + @param suiteList [out] A buffer in which to return the list object. + @see \c #SPSuitesSuite + */ + SPAPI SPErr (*GetRuntimeSuiteList)( SPSuiteListRef *suiteList ); + /** Retrieves the PICA global file list. + @param fileList [out] A buffer in which to return the list object. + @see \c #SPFilesSuite + */ + SPAPI SPErr (*GetRuntimeFileList)( SPFileListRef *fileList ); + /** Retrieves the PICA global plug-in list. + @param pluginList [out] A buffer in which to return the list object. + @see \c #SPPluginsSuite + */ + SPAPI SPErr (*GetRuntimePluginList)( SPPluginListRef *pluginList ); + /** Retrieves the PICA global adapter list. + @param adapterList [out] A buffer in which to return the list object. + @see \c #SPAdaptersSuite + */ + SPAPI SPErr (*GetRuntimeAdapterList)( SPAdapterListRef *adapterList ); + /** Retrieves the block of function pointers supplied to PICA by the + application, which contains memory management routines, notification routines, + exception handling, and string pool routines. + + A plug-in does not normally call the host functions directly; you + can use the PICA suite functions for most operations. An adapter, however, + uses the host functions for start-up and shut-down notification. + @param hostProcs [out] A buffer in which to return a pointer to the + block of function pointers. + */ + SPAPI SPErr (*GetRuntimeHostProcs)( SPHostProcs **hostProcs ); + /** Retrieves the location of the application's plug-in folder. + @param pluginFolder [out] A buffer in which to return the + file specification for the directory that contains plug-ins. + */ + SPAPI SPErr (*GetRuntimePluginsFolder)( SPPlatformFileSpecification *pluginFolder ); + /** Retrieves the location of the application's executable file. + @param hostFileSpec [out] A buffer in which to return the + file specification for the application's executable file. + */ + SPAPI SPErr (*GetRuntimeHostFileSpec)( SPPlatformFileSpecification *hostFileSpec ); +} SPRuntimeSuite; + + + +/******************************************************************************* + ** + ** Suite + ** + **/ +/** @ingroup Suites + This suite allows you to obtain specific references to the + PICA global lists and string pool using the new XPlatFileSpec + rather than the old SPPlatformFileSpecification. + + \li Acquire this suite using \c #SPBasicSuite::AcquireSuite() with the constants + \c #kSPRuntimeSuite and \c #kSPRuntimeSuiteXPlatVersion. + */ +typedef struct SPXPlatRuntimeSuite { + /** Retrieves the PICA global string pool. + @param stringPool [out] A buffer in which to return the string-pool object. + @see \c #SPStringsSuite + */ + SPAPI SPErr (*GetRuntimeStringPool)( SPStringPoolRef *stringPool ); + /** Retrieves the PICA global suite list. + @param suiteList [out] A buffer in which to return the list object. + @see \c #SPSuitesSuite + */ + SPAPI SPErr (*GetRuntimeSuiteList)( SPSuiteListRef *suiteList ); + /** Retrieves the PICA global file list. + @param fileList [out] A buffer in which to return the list object. + @see \c #SPFilesSuite + */ + SPAPI SPErr (*GetRuntimeFileList)( SPFileListRef *fileList ); + /** Retrieves the PICA global plug-in list. + @param pluginList [out] A buffer in which to return the list object. + @see \c #SPPluginsSuite + */ + SPAPI SPErr (*GetRuntimePluginList)( SPPluginListRef *pluginList ); + /** Retrieves the PICA global adapter list. + @param adapterList [out] A buffer in which to return the list object. + @see \c #SPAdaptersSuite + */ + SPAPI SPErr (*GetRuntimeAdapterList)( SPAdapterListRef *adapterList ); + /** Retrieves the block of function pointers supplied to PICA by the + application, which contains memory management routines, notification routines, + exception handling, and string pool routines. + + A plug-in does not normally call the host functions directly; you + can use the PICA suite functions for most operations. An adapter, however, + uses the host functions for start-up and shut-down notification. + @param hostProcs [out] A buffer in which to return a pointer to the + block of function pointers. + */ + SPAPI SPErr (*GetRuntimeHostProcs)( SPHostProcs **hostProcs ); + /** Retrieves the location of the application's plug-in folder. + @param pluginFolder [out] A buffer in which to return the + file specification for the directory that contains plug-ins. + */ + SPAPI SPErr (*XPlatGetRuntimePluginsFolder)( XPlatFileSpec *pluginFolder ); + /** Retrieves the location of the application's executable file. + @param hostFileSpec [out] A buffer in which to return the + file specification for the application's executable file. + */ + SPAPI SPErr (*XPlatGetRuntimeHostFileSpec)( XPlatFileSpec *hostFileSpec ); +} SPXPlatRuntimeSuite; + + +/** Internal */ +SPAPI SPErr SPGetRuntimeStringPool( SPStringPoolRef *stringPool ); +/** Internal */ +SPAPI SPErr SPGetRuntimeSuiteList( SPSuiteListRef *suiteList ); +/** Internal */ +SPAPI SPErr SPGetRuntimeFileList( SPFileListRef *fileList ); +/** Internal */ +SPAPI SPErr SPGetRuntimePluginList( SPPluginListRef *pluginList ); +/** Internal */ +SPAPI SPErr SPGetRuntimeAdapterList( SPAdapterListRef *adapterList ); +/** Internal */ +SPAPI SPErr SPGetRuntimeHostProcs( SPHostProcs **hostProcs ); +/** Internal */ +SPAPI SPErr SPGetRuntimePluginsFolder( SPPlatformFileSpecification *pluginFolder ); +/** Internal */ +SPAPI SPErr SPXPlatGetRuntimePluginsFolder( XPlatFileSpec *pluginFolder ); +/** Internal */ +SPAPI SPErr SPGetRuntimeHostFileSpec( SPPlatformFileSpecification *hostFileSpec ); +/** Internal */ +SPAPI SPErr SPXPlatGetRuntimeHostFileSpec( XPlatFileSpec *hostFileSpec ); + +/** Internal */ +typedef struct +{ + SPAPI SPErr (*SPAcquireSuiteFunc)( SPSuiteListRef suiteList, const char *name, int32 apiVersion, int32 internalVersion, const void **suiteProcs ); + SPAPI SPErr (*SPReleaseSuiteFunc)( SPSuiteListRef suiteList, const char *name, int32 apiVersion, int32 internalVersion ); + SPErr (*spAllocateBlockFunc)( SPAllocateProc allocateProc, size_t size, const char *debug, void **block ); + SPErr (*spFreeBlockFunc)( SPFreeProc freeProc, void *block ); + SPErr (*spReallocateBlockFunc)( SPReallocateProc reallocateProc, void *block, size_t newSize, const char *debug, void **newblock ); + SPHostProcs *gProcs; +} SPBasicFuncStruct; + +/** Internal */ +void SetUpBasicFuncs(SPBasicFuncStruct *inStruct); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/External/AE SDK/Headers/SP/SPSTSPrp.h b/External/AE SDK/Headers/SP/SPSTSPrp.h new file mode 100644 index 00000000..956173b3 --- /dev/null +++ b/External/AE SDK/Headers/SP/SPSTSPrp.h @@ -0,0 +1,52 @@ +/***********************************************************************/ +/* */ +/* SPSTSPrp.h */ +/* */ +/* Copyright 1995-2006 Adobe Systems Incorporated. */ +/* All Rights Reserved. */ +/* */ +/* Patents Pending */ +/* */ +/* NOTICE: All information contained herein is the property of Adobe */ +/* Systems Incorporated. Many of the intellectual and technical */ +/* concepts contained herein are proprietary to Adobe, are protected */ +/* as trade secrets, and are made available only to Adobe licensees */ +/* for their internal use. Any reproduction or dissemination of this */ +/* software is strictly forbidden unless prior written permission is */ +/* obtained from Adobe. */ +/* */ +/***********************************************************************/ + +#ifndef __SPSTSPrp__ +#define __SPSTSPrp__ + + +/******************************************************************************* + ** + ** Imports + ** + **/ + +#include "SPPiPL.h" + + +/******************************************************************************* + ** + ** Constants + ** + **/ + +/** Internal */ +#define PISuperTopSecretProperty 'StsP' +/** Internal */ +#define PISuperTopSecretValue 'clEn' + + +/******************************************************************************* + ** + ** Types + ** + **/ + + +#endif diff --git a/External/AE SDK/Headers/SP/SPStrngs.h b/External/AE SDK/Headers/SP/SPStrngs.h new file mode 100644 index 00000000..ebe9bed4 --- /dev/null +++ b/External/AE SDK/Headers/SP/SPStrngs.h @@ -0,0 +1,132 @@ +/***********************************************************************/ +/* */ +/* SPStrngs.h */ +/* */ +/* Copyright 1995-2006 Adobe Systems Incorporated. */ +/* All Rights Reserved. */ +/* */ +/* Patents Pending */ +/* */ +/* NOTICE: All information contained herein is the property of Adobe */ +/* Systems Incorporated. Many of the intellectual and technical */ +/* concepts contained herein are proprietary to Adobe, are protected */ +/* as trade secrets, and are made available only to Adobe licensees */ +/* for their internal use. Any reproduction or dissemination of this */ +/* software is strictly forbidden unless prior written permission is */ +/* obtained from Adobe. */ +/* */ +/***********************************************************************/ + +#ifndef __SPStrings__ +#define __SPStrings__ + + +/******************************************************************************* + ** + ** Imports + ** + **/ + +#include "SPTypes.h" + +#ifdef __cplusplus +extern "C" { +#endif + + +/******************************************************************************* + ** + ** Constants + ** + **/ +/** PICA strings suite name */ +#define kSPStringsSuite "SP Strings Suite" +/** PICA strings suite version */ +#define kSPStringsSuiteVersion 2 + +/** Globally available PICA strings resources. + @see \c #SPRuntimeSuite::GetRuntimeStringPool(). */ +#define kSPRuntimeStringPool ((SPStringPoolRef)NULL) + + +/******************************************************************************* + ** + ** Types + ** + **/ + +/* If you override the default string pool handler by defining host proc routines, + * how the string pool memory allocation and searching is done is up to you. As an example, + * the structure below is similar to what Sweet Pea uses for its default string pool + * routines. The pool is a sorted list of strings of number count, kept in memory referenced + * by the heap field. + * + * typedef struct SPStringPool { + * + * SPPoolHeapRef heap; + * int32 count; + * + * } SPStringPool; + */ + +/** Opaque reference to a string pool. Access with the \c #SPStringsSuite. */ +typedef struct SPStringPool *SPStringPoolRef; + + +/******************************************************************************* + ** + ** Suite + ** + **/ + +/** @ingroup Suites + This suite allows you to work with the PICA string pool. + + PICA manages a string pool, which provides an efficient central + storage space for C strings. When a string is placed in the pool, PICA + checks whether it already exists in the pool, and if so, returns a + pointer to the existing string. If not, it copies the string into the pool, + and returns a pointer to the copy. + + This mechanisms atomizes the strings. Because each string exists in + only one place, strings can be compared by address, rather than character + by character, and string searches are made much more efficient. + + \li Acquire this suite using \c #SPBasicSuite::AcquireSuite() with the constants + \c #kSPStringsSuite and \c #kSPStringsSuiteVersion. + */ +typedef struct SPStringsSuite { + + /** Creates a new string pool and allocates an initial block of memory for + its strings. You can also access PICA's global string pool, + using \c #SPRuntimeSuite::GetRuntimeStringPool(). + @param stringPool [out] A buffer in which to return the new string pool reference. + */ + SPAPI SPErr (*AllocateStringPool)( SPStringPoolRef *stringPool ); + /** Frees the memory used for a string pool created with \c #AllocateStringPool(). + Do not free the global string pool (\c #kSPRuntimeStringPool). + @param stringPool The string pool reference. + */ + SPAPI SPErr (*FreeStringPool)( SPStringPoolRef stringPool ); + /** Adds a string to a string pool, or, if the string has already been added + to the pool, retrieves a reference to the pooled string. + @param stringPool The string pool reference. + @param string The string. + @param wString [out] A buffer in which to return the address of + the atomized string in the pool. + */ + SPAPI SPErr (*MakeWString)( SPStringPoolRef stringPool, const char *string, const char **wString ); + +} SPStringsSuite; + + +SPAPI SPErr SPAllocateStringPool( SPStringPoolRef *stringPool ); +SPAPI SPErr SPFreeStringPool( SPStringPoolRef stringPool ); +SPAPI SPErr SPMakeWString( SPStringPoolRef stringPool, const char *string, const char **wString ); + + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/External/AE SDK/Headers/SP/SPSuites.h b/External/AE SDK/Headers/SP/SPSuites.h new file mode 100644 index 00000000..17b8dc93 --- /dev/null +++ b/External/AE SDK/Headers/SP/SPSuites.h @@ -0,0 +1,284 @@ +/***********************************************************************/ +/* */ +/* SPSuites.h */ +/* */ +/* Copyright 1995-2006 Adobe Systems Incorporated. */ +/* All Rights Reserved. */ +/* */ +/* Patents Pending */ +/* */ +/* NOTICE: All information contained herein is the property of Adobe */ +/* Systems Incorporated. Many of the intellectual and technical */ +/* concepts contained herein are proprietary to Adobe, are protected */ +/* as trade secrets, and are made available only to Adobe licensees */ +/* for their internal use. Any reproduction or dissemination of this */ +/* software is strictly forbidden unless prior written permission is */ +/* obtained from Adobe. */ +/* */ +/***********************************************************************/ + +#ifndef __SPSuites__ +#define __SPSuites__ + + +/******************************************************************************* + ** + ** Imports + ** + **/ + +#include "SPTypes.h" +#include "SPAccess.h" +#include "SPPlugs.h" +#include "SPStrngs.h" + +#ifdef __cplusplus +extern "C" { +#endif + + +/******************************************************************************* + ** + ** Constants + ** + **/ +/** PICA suite-management suite name */ +#define kSPSuitesSuite "SP Suites Suite" +/** PICA suite-management suite version */ +#define kSPSuitesSuiteVersion 2 + +/** Internal */ +#define kSPLatestInternalVersion 0 + +/** PICA global list of available suites. + @see \c #SPRuntimeSuite::GetRuntimeSuiteList(). */ +#define kSPRuntimeSuiteList ((SPSuiteListRef)NULL) + + +/******************************************************************************* + ** + ** Types + ** + **/ + +/** Opaque reference to a suite object. Access with the \c #SPSuitesSuite. */ +typedef struct SPSuite *SPSuiteRef; +/** A list of suite objects. Create with + \c #SPSuitesSuite::AllocateSuiteList(), or use + the global list, \c #kSPRuntimeSuiteList. */ +typedef struct SPSuiteList *SPSuiteListRef; +/** An iterator object for examining a suite list. + See \c #SPSuitesSuite::NewSuiteListIterator(). */ +typedef struct SPSuiteListIterator *SPSuiteListIteratorRef; + + +/******************************************************************************* + ** + ** Suite + ** + **/ + +/** @ingroup Suites + This suite allows you to create, manage, and access PICA function suites. + + A suite associates a name and version number with a pointer to an array of + function pointers. The functions generally haves some common purpose, such as + accessing a data type, and are used by plug-ins to interact with PICA, with + the application, and with each other. + + In order to use a function in a suite, you must first \e acquire it. + This suite provides the low-level function \c #AcquireSuite(), + but a plug-in more typically uses the \c #SPBasicSuite, which is provided + with every message to a plug-in. + + PICA creates a global suite list at application startup, which contains + references to every suite added by PICA, the application, or other plug-ins. + You can use this suite to create and manage additional suite lists. + + \li Acquire this suite using \c #SPBasicSuite::AcquireSuite() with the constants + \c #kSPSuitesSuite and \c #kSPSuitesSuiteVersion. + */ +typedef struct SPSuitesSuite { + + /** Creates a new suite list. You can also access PICA's global suite list, + using \c #SPRuntimeSuite::GetRuntimeSuiteList(). + @param stringPool The string pool in which to keep suite names. + @param plugins <> + @param suiteList [out] A buffer in which to return the new list object. + */ + SPAPI SPErr (*AllocateSuiteList)( SPStringPoolRef stringPool, SPPluginListRef plugins, + SPSuiteListRef *suiteList ); + + /** Frees a list of suites allocated with \c #AllocateSuiteList(), and + also frees any entries in the list. Do not free the global list (\c #kSPRuntimeSuiteList). + @param suiteList The suite list object. + */ + SPAPI SPErr (*FreeSuiteList)( SPSuiteListRef suiteList ); + + /** Creates a new plug-in function suite and adds it to a suite list. + Identifying constants for the suite name and version must be made + available in a public header file. + @param suiteList The suite list object, or \c NULL to use the + global list. + @param host The plug-in object providing the suite. + @param name The unique name of the suite. + @param apiVersion The public version number of the suite. + @param internalVersion The internal version number of the suite. + @param suiteProcs A pointer to a structure containing the function pointers + for the suite. + @param suite [out] A buffer in which to return the new suite object. + */ + SPAPI SPErr (*AddSuite)( SPSuiteListRef suiteList, SPPluginRef host, const char *name, + int32 apiVersion, int32 internalVersion, const void *suiteProcs, SPSuiteRef *suite ); + + /** Acquires a function suite from a suite list. Loads the suite if necessary, + and increments its reference count. This function differs from + \c #SPBasicSuite::AcquireSuite() in that you can specify a suite list + and internal version number. + @param suiteList The suite list object, or \c NULL to use the + global list. + @param name The suite name. + @param version The public suite version number. + @param internalVersion The internal suite version number. + @param suiteProcs [out] A buffer in which to return a pointer to the + suite function pointer array. + */ + SPAPI SPErr (*AcquireSuite)( SPSuiteListRef suiteList, const char *name, int32 apiVersion, + int32 internalVersion, const void **suiteProcs ); + + /** Decrements the reference count of a suite in a suite list and unloads it when the + reference count reaches 0. + @param suiteList The suite list object, or \c NULL to use the + global list. + @param name The suite name. + @param version The public suite version number. + @param internalVersion The internal suite version number. + */ + SPAPI SPErr (*ReleaseSuite)( SPSuiteListRef suiteList, const char *name, int32 apiVersion, + int32 internalVersion ); + + /** Retrieves a suite from a suite list. + @param suiteList The suite list object, or \c NULL to use the + global list. + @param name The suite name. + @param version The public suite version number. + @param internalVersion The internal suite version number. + @param suiteProcs [out] A buffer in which to return the suite object, or + \c NULL if no matching suite is found in the list. + */ + SPAPI SPErr (*FindSuite)( SPSuiteListRef suiteList, const char *name, int32 apiVersion, + int32 internalVersion, SPSuiteRef *suite ); + + /** Creates an iterator object with which to traverse a suite list. + The iterator is initially set to the first suite in the list. + @param suiteList The suite list object, or \c NULL to use the + global list. + @param iter [out] A buffer in which to return the new iterator object. + @see \c #NextSuite(), \c #DeleteSuiteListIterator() + */ + SPAPI SPErr (*NewSuiteListIterator)( SPSuiteListRef suiteList, SPSuiteListIteratorRef *iter ); + /** Retrieves the current suite and advances a suite-list iterator to the next suite in the list. + @param iter The suite-list iterator object. + @param suite [out] A buffer in which to return the current suite object, \c NULL + if the end of the list has been reached. + @see \c #NewSuiteListIterator(), + */ + SPAPI SPErr (*NextSuite)( SPSuiteListIteratorRef iter, SPSuiteRef *suite ); + /** Frees a suite-list iterator that is no longer needed. + @param iter The suite-list iterator object. + @see \c #NewSuiteListIterator(), + */ + SPAPI SPErr (*DeleteSuiteListIterator)( SPSuiteListIteratorRef iter ); + + /** Retrieves the plug-in that provides a suite. + @param suite The suite object. + @param plugin [out] A buffer in which to return the plug-in object. + */ + SPAPI SPErr (*GetSuiteHost)( SPSuiteRef suite, SPPluginRef *plugin ); + /** Retrieves the unique name of a suite. + @param suite The suite object. + @param name [out] A buffer in which to return the name string. + */ + SPAPI SPErr (*GetSuiteName)( SPSuiteRef suite, const char **name ); + /** Retrieves the public version number of a suite. + @param suite The suite object. + @param version [out] A buffer in which to return the public version number. + */ + SPAPI SPErr (*GetSuiteAPIVersion)( SPSuiteRef suite, int32 *version ); + /** Retrieves the internal version number of a suite. + @param suite The suite object. + @param version [out] A buffer in which to return the internal version number. + */ + SPAPI SPErr (*GetSuiteInternalVersion)( SPSuiteRef suite, int32 *version ); + /** Retrieves the function pointer array of a suite. + @param suite The suite object. + @param suiteProcs [out] A buffer in which to return a pointer + to the function pointer array. + */ + SPAPI SPErr (*GetSuiteProcs)( SPSuiteRef suite, const void **suiteProcs ); + /** Retrieves the current reference count of a suite. + @param suite The suite object. + @param count [out] A buffer in which to return the reference count. + */ + SPAPI SPErr (*GetSuiteAcquireCount)( SPSuiteRef suite, int32 *count ); + +} SPSuitesSuite; + + +/** Internal */ +SPAPI SPErr SPAllocateSuiteList( SPStringPoolRef stringPool, SPPluginListRef plugins, + SPSuiteListRef *suiteList ); + +/** Internal */ +SPAPI SPErr SPFreeSuiteList( SPSuiteListRef suiteList ); + +/** Internal */ +SPAPI SPErr SPAddSuite( SPSuiteListRef suiteList, SPPluginRef host, const char *name, + int32 apiVersion, int32 internalVersion, const void *suiteProcs, SPSuiteRef *suite ); + +/** Internal */ +SPAPI SPErr SPAcquireSuite( SPSuiteListRef suiteList, const char *name, int32 apiVersion, + int32 internalVersion, const void **suiteProcs ); + +/** Internal */ +SPAPI SPErr SPReleaseSuite( SPSuiteListRef suiteList, const char *name, int32 apiVersion, + int32 internalVersion ); + +/** Internal */ +SPAPI SPErr SPFindSuite( SPSuiteListRef suiteList, const char *name, int32 apiVersion, + int32 internalVersion, SPSuiteRef *suite ); + +/** Internal */ +SPAPI SPErr SPNewSuiteListIterator( SPSuiteListRef suiteList, SPSuiteListIteratorRef *iter ); +/** Internal */ +SPAPI SPErr SPNextSuite( SPSuiteListIteratorRef iter, SPSuiteRef *suite ); +/** Internal */ +SPAPI SPErr SPDeleteSuiteListIterator( SPSuiteListIteratorRef iter ); + +/** Internal */ +SPAPI SPErr SPGetSuiteHost( SPSuiteRef suite, SPPluginRef *plugin ); +/** Internal */ +SPAPI SPErr SPGetSuiteName( SPSuiteRef suite, const char **name ); +/** Internal */ +SPAPI SPErr SPGetSuiteAPIVersion( SPSuiteRef suite, int32 *version ); +/** Internal */ +SPAPI SPErr SPGetSuiteInternalVersion( SPSuiteRef suite, int32 *version ); +/** Internal */ +SPAPI SPErr SPGetSuiteProcs( SPSuiteRef suite, const void **suiteProcs ); +/** Internal */ +SPAPI SPErr SPGetSuiteAcquireCount( SPSuiteRef suite, int32 *count ); + + +/******************************************************************************* + ** + ** Errors + ** + **/ + +#include "SPErrorCodes.h" + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/External/AE SDK/Headers/SP/SPTypes.h b/External/AE SDK/Headers/SP/SPTypes.h new file mode 100644 index 00000000..182c0810 --- /dev/null +++ b/External/AE SDK/Headers/SP/SPTypes.h @@ -0,0 +1,175 @@ +/***********************************************************************/ +/* */ +/* SPTypes.h */ +/* */ +/* Copyright 1995-2006 Adobe Systems Incorporated. */ +/* All Rights Reserved. */ +/* */ +/* Patents Pending */ +/* */ +/* NOTICE: All information contained herein is the property of Adobe */ +/* Systems Incorporated. Many of the intellectual and technical */ +/* concepts contained herein are proprietary to Adobe, are protected */ +/* as trade secrets, and are made available only to Adobe licensees */ +/* for their internal use. Any reproduction or dissemination of this */ +/* software is strictly forbidden unless prior written permission is */ +/* obtained from Adobe. */ +/* */ +/***********************************************************************/ + + +/** + + These are the basic declarations used by Sweet Pea. + + **/ + + +#ifndef __SPTypes__ +#define __SPTypes__ + + +/******************************************************************************* + ** + ** Imports + ** + **/ + +#include "SPConfig.h" + + +/* + * You can replace SPTypes.h with your own. Define OTHER_SP_TYPES_H on the + * command line or in SPConfig.h to be the name of the replacement file. + * + * Example: + * + * #define OTHER_SP_TYPES_H "MySPTypes.h" + * #include "SPBasic.h" // for example + * + * Sweet Pea depends on TRUE, FALSE, SPErr, etc. Your replacement must + * define them. + */ + +#ifdef OTHER_SP_TYPES_H +#include OTHER_SP_TYPES_H +#else + + +/******************************************************************************* + ** + ** Constants + ** + **/ + +#ifndef TRUE +#define TRUE 1 +#endif + +#ifndef FALSE +#define FALSE 0 +#endif + +#ifndef NULL + +#ifdef MAC_ENV +#if !defined(__cplusplus) && (defined(__SC__) || defined(THINK_C)) +#define NULL ((void *) 0) +#else +#define NULL 0 +#endif +#endif + +#ifdef WIN_ENV +#ifdef __cplusplus +#define NULL 0 +#else +#define NULL ((void *)0) +#endif +#endif + +#endif + + +/* + * SPAPI is placed in front of procedure declarations in the API. On the Mac + * it used to be 'pascal', which forced consistent calling conventions across different + * compilers. No longer needed. On Windows it's nothing. + * + * Example: + * + * SPAPI void *SPAllocateBlock( int32 size, const char *debug, SPErr *error ); + * + */ + +#if defined(MAC_ENV) || defined(__ANDROID__) || defined(__LINUX__) || defined (__EMSCRIPTEN__) || defined(SIMULATED_WASM) +#if defined(__GNUC__) +#define SPAPI +#else +#define SPAPI pascal +#endif +#endif + +#ifdef WIN_ENV +#define SPAPI +#endif + +#include "PSIntTypes.h" + +typedef uint8 SPUInt8; +typedef uint16 SPUInt16; +typedef uint32 SPUInt32; + +typedef int32 SPInt32; + +#if defined(MAC_ENV) || defined(__ANDROID__) || defined(__LINUX__) || defined (__EMSCRIPTEN__) || defined(SIMULATED_WASM) + +/* SPBoolean is the same a Macintosh Boolean. */ +typedef uint8 SPBoolean; + +#endif + +#ifdef WIN_ENV + +/* SPBoolean is the same a Windows BOOL. */ +typedef int32 SPBoolean; + +#endif + + +/******************************************************************************* + ** + ** Error Handling + ** + **/ + +/* + * Error codes in Sweet Pea are C strings, with the exception of the code for + * no error, which is NULL. The error can first be compared with kSPNoError to + * test if the function succeeded. If it is not NULL then the error can be + * string-compared with predefined error strings. + * + * Example: + * + * SPErr error = kSPNoError; + * + * block = SPAllocateBlock( size, debug, &error ); + * if ( error != kSPNoError ) { + * if ( strcmp( error, kSPOutOfMemoryError ) == 0 ) + * FailOutOfMemory(); + * ... + * } + */ + +typedef int32 SPErr; + +/* + * kSPNoError and kSPUnimplementedError are universal. Other error codes should + * be defined in the appropriate header files. + */ + +#include "SPErrorCodes.h" + +#endif /* OTHER_SP_TYPES_H */ + +#endif diff --git a/External/AE SDK/Headers/SP/artemis/config/platform.hpp b/External/AE SDK/Headers/SP/artemis/config/platform.hpp new file mode 100755 index 00000000..5d128c4a --- /dev/null +++ b/External/AE SDK/Headers/SP/artemis/config/platform.hpp @@ -0,0 +1,114 @@ +// +// ADOBE CONFIDENTIAL +// __________________ +// +// Copyright 2016 Adobe +// All Rights Reserved. +// +// NOTICE: All information contained herein is, and remains +// the property of Adobe and its suppliers, if any. The intellectual +// and technical concepts contained herein are proprietary to Adobe +// and its suppliers and are protected by all applicable intellectual +// property laws, including trade secret and copyright laws. +// Dissemination of this information or reproduction of this material +// is strictly forbidden unless prior written permission is obtained +// from Adobe. +// + +#ifndef ARTEMIS_PLATFORM_HPP +#define ARTEMIS_PLATFORM_HPP + +/* + The ARTEMIS_PLATFORM() macro is used to conditionalize code based on platform or platform + attibutes. + + It is used as: + + #if ARTEMIS_PLATFORM(MACOS) + #endif + + The attributes currently create a hierarchy from general to specific, items lower in the + hierarchy imply their parent are defined as '1', all others are '0'. + + This graph may eventually become a DAG. Higher level nodes represent a set of services that the + lower level nodes have in common. As such, it should rarely be necessary to write an expression + using more than one of these terms. If you find yourself doing so, please name the common + service and add the flag. + + An unqualified else clause should only be written entirely in terms of standard constructs that + has no platform dependencies and should not assume that 'not X' implies some other 'Y'. + + POSIX - any Posix compliant platform + APPLE - any Apple platform + MACOS - compiled for macOS + IOS - compiled for iOS + LINUX - compiled for Linux + ANDROID - compiled for Android + MICROSOFT - any Microsoft platform + UWP - Compiled for UWP + WIN32 - Compiled for Win32 +*/ +#define ARTEMIS_PLATFORM(X) (ARTEMIS_PRIVATE_PLATFORM_##X()) + +/**************************************************************************************************/ + +// The *_PRIVATE_* macros are just that. Don't use them directly. + +#define ARTEMIS_PRIVATE_PLATFORM_ANDROID() 0 +#define ARTEMIS_PRIVATE_PLATFORM_WEB() 0 +#define ARTEMIS_PRIVATE_PLATFORM_APPLE() 0 +#define ARTEMIS_PRIVATE_PLATFORM_IOS() 0 +#define ARTEMIS_PRIVATE_PLATFORM_LINUX() 0 +#define ARTEMIS_PRIVATE_PLATFORM_MACOS() 0 +#define ARTEMIS_PRIVATE_PLATFORM_MICROSOFT() 0 +#define ARTEMIS_PRIVATE_PLATFORM_POSIX() 0 +#define ARTEMIS_PRIVATE_PLATFORM_UWP() 0 +#define ARTEMIS_PRIVATE_PLATFORM_WIN32() 0 + +#if defined(__ANDROID__) + #undef ARTEMIS_PRIVATE_PLATFORM_POSIX + #define ARTEMIS_PRIVATE_PLATFORM_POSIX() 1 + #undef ARTEMIS_PRIVATE_PLATFORM_ANDROID + #define ARTEMIS_PRIVATE_PLATFORM_ANDROID() 1 +#elif defined(_WIN32) + #include // for #define WINVER + #include + + #undef ARTEMIS_PRIVATE_PLATFORM_MICROSOFT + #define ARTEMIS_PRIVATE_PLATFORM_MICROSOFT() 1 + + #if defined(WINAPI_FAMILY) && !WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP) + #undef ARTEMIS_PRIVATE_PLATFORM_UWP + #define ARTEMIS_PRIVATE_PLATFORM_UWP() 1 + #else + #undef ARTEMIS_PRIVATE_PLATFORM_WIN32 + #define ARTEMIS_PRIVATE_PLATFORM_WIN32() 1 + #endif +#elif defined(__APPLE__) && !defined (__SIMULATED_WASM__) + #include "TargetConditionals.h" + + #undef ARTEMIS_PRIVATE_PLATFORM_POSIX + #define ARTEMIS_PRIVATE_PLATFORM_POSIX() 1 + #undef ARTEMIS_PRIVATE_PLATFORM_APPLE + #define ARTEMIS_PRIVATE_PLATFORM_APPLE() 1 + + #if TARGET_OS_SIMULATOR || TARGET_OS_IPHONE + #undef ARTEMIS_PRIVATE_PLATFORM_IOS + #define ARTEMIS_PRIVATE_PLATFORM_IOS() 1 + #elif TARGET_OS_MAC + #undef ARTEMIS_PRIVATE_PLATFORM_MACOS + #define ARTEMIS_PRIVATE_PLATFORM_MACOS() 1 + #endif +#elif defined(__LINUX__) + #undef ARTEMIS_PRIVATE_PLATFORM_POSIX + #define ARTEMIS_PRIVATE_PLATFORM_POSIX() 1 + #undef ARTEMIS_PRIVATE_PLATFORM_LINUX + #define ARTEMIS_PRIVATE_PLATFORM_LINUX() 1 +#elif defined(__EMSCRIPTEN__) || defined (__SIMULATED_WASM__) + #undef ARTEMIS_PRIVATE_PLATFORM_POSIX + #define ARTEMIS_PRIVATE_PLATFORM_POSIX() 1 + #undef ARTEMIS_PRIVATE_PLATFORM_WEB + #define ARTEMIS_PRIVATE_PLATFORM_WEB() 1 +#endif + +#endif // ARTEMIS_PLATFORM_HPP diff --git a/External/AE SDK/Headers/SP/photoshop/config/platform.hpp b/External/AE SDK/Headers/SP/photoshop/config/platform.hpp new file mode 100755 index 00000000..e9f9da0b --- /dev/null +++ b/External/AE SDK/Headers/SP/photoshop/config/platform.hpp @@ -0,0 +1,95 @@ +// +// ADOBE CONFIDENTIAL +// __________________ +// +// Copyright 2016 Adobe +// All Rights Reserved. +// +// NOTICE: All information contained herein is, and remains +// the property of Adobe and its suppliers, if any. The intellectual +// and technical concepts contained herein are proprietary to Adobe +// and its suppliers and are protected by all applicable intellectual +// property laws, including trade secret and copyright laws. +// Dissemination of this information or reproduction of this material +// is strictly forbidden unless prior written permission is obtained +// from Adobe. +// + +#ifndef PHOTOSHOP_PLATFORM_HPP +#define PHOTOSHOP_PLATFORM_HPP + +/**************************************************************************************************/ + +#ifdef RC_INVOKED // Windows Resource Compiler + + // #error Windows resource compiler - do not include this file! + +#else + +/**************************************************************************************************/ + +#include + +/**************************************************************************************************/ + +// alias to the private artemis macros via concatenation because calling PHOTOSHOP_PLATFORM(X) errors +// when PHOTOSHOP_PLATFORM(X) = (ARTEMIS_PLATFORM(X)) when the value of X is itself defined as a +// macro. This is especially problematic for WIN32. + +#define PHOTOSHOP_PLATFORM(X) (ARTEMIS_PRIVATE_PLATFORM_##X()) +#define PHOTOSHOP_ARCH(X) (ARTEMIS_PRIVATE_ARCH_##X()) +#define PHOTOSHOP_BITS(X) (ARTEMIS_PRIVATE_BITS_##X()) +#define PHOTOSHOP_CPU(A,B) (ARTEMIS_PRIVATE_ARCH_##A() && ARTEMIS_PRIVATE_BITS_##B()) +#define PHOTOSHOP_PLATFORM_ARCH(X, A) (ARTEMIS_PRIVATE_PLATFORM_##X() && ARTEMIS_PRIVATE_ARCH_##A()) +#define PHOTOSHOP_PLATFORM_ARCH_BITS(X, A, B) (ARTEMIS_PRIVATE_PLATFORM_##X() && ARTEMIS_PRIVATE_ARCH_##A() && ARTEMIS_PRIVATE_BITS_##B()) + +// Really, these need to die a horrible death. However, they are still required +// for rez_defines.h (See the comment in rez_platform.h for more details.) +#define PS_PLATFORM_ANDROID PHOTOSHOP_PLATFORM(ANDROID) +#define PS_PLATFORM_WEB PHOTOSHOP_PLATFORM(WEB) +#define PS_PLATFORM_APPLE PHOTOSHOP_PLATFORM(APPLE) +#define PS_PLATFORM_IOS PHOTOSHOP_PLATFORM(IOS) +#define PS_PLATFORM_LINUX PHOTOSHOP_PLATFORM(LINUX) +#define PS_PLATFORM_MACOS PHOTOSHOP_PLATFORM(MACOS) +#define PS_PLATFORM_MS PHOTOSHOP_PLATFORM(MICROSOFT) +#define PS_PLATFORM_POSIX PHOTOSHOP_PLATFORM(POSIX) +#define PS_PLATFORM_UWP PHOTOSHOP_PLATFORM(UWP) +#define PS_PLATFORM_WIN32 PHOTOSHOP_PLATFORM(WIN32) + +// Is there a reason why the above are replicated here? +#ifndef PS_OS_WIN // Some Windows projects define this in their props file + #define PS_OS_WIN PHOTOSHOP_PLATFORM(MICROSOFT) +#endif +#ifndef PS_OS_IOS // Some Windows projects define this in their props file + #define PS_OS_IOS PHOTOSHOP_PLATFORM(IOS) +#endif +#ifndef PS_OS_MAC // Some Windows projects define this in their props file + #define PS_OS_MAC PHOTOSHOP_PLATFORM(MACOS) +#endif +#ifndef PS_OS_ANDROID // Some Windows projects define this in their props file + #define PS_OS_ANDROID PHOTOSHOP_PLATFORM(ANDROID) +#endif + +#define PS_OS_WEB POISONED_MACRO_PS_OS_WEB() + +/**************************************************************************************************/ + +// Deprecated + +#define qPSIsWin (PHOTOSHOP_PLATFORM(MICROSOFT)) +#define qPSIsMac (PHOTOSHOP_PLATFORM(APPLE)) + +// REVISIT (sparent) : This also come from Switches.h... sometimes. Untangle + +// #ifndef MSWindows +// #define MSWindows (PHOTOSHOP_PLATFORM(MICROSOFT)) +// #endif + +// Macintosh is only defined for apple platforms +#if PHOTOSHOP_PLATFORM(APPLE) && !defined(Macintosh) + #define Macintosh 1 +#endif + +/**************************************************************************************************/ +#endif // RC_INVOKED +#endif // PHOTOSHOP_PLATFORM_HPP diff --git a/External/AE SDK/Headers/Smart_Utils.cpp b/External/AE SDK/Headers/Smart_Utils.cpp new file mode 100644 index 00000000..b67378b7 --- /dev/null +++ b/External/AE SDK/Headers/Smart_Utils.cpp @@ -0,0 +1,62 @@ +/*******************************************************************/ +/* */ +/* ADOBE CONFIDENTIAL */ +/* _ _ _ _ _ _ _ _ _ _ _ _ _ */ +/* */ +/* Copyright 2007 Adobe Systems Incorporated */ +/* All Rights Reserved. */ +/* */ +/* NOTICE: All information contained herein is, and remains the */ +/* property of Adobe Systems Incorporated and its suppliers, if */ +/* any. The intellectual and technical concepts contained */ +/* herein are proprietary to Adobe Systems Incorporated and its */ +/* suppliers and may be covered by U.S. and Foreign Patents, */ +/* patents in process, and are protected by trade secret or */ +/* copyright law. Dissemination of this information or */ +/* reproduction of this material is strictly forbidden unless */ +/* prior written permission is obtained from Adobe Systems */ +/* Incorporated. */ +/* */ +/*******************************************************************/ + +#include "Smart_Utils.h" + + +PF_Boolean IsEmptyRect(const PF_LRect *r){ + return (r->left >= r->right) || (r->top >= r->bottom); +} + +void UnionLRect(const PF_LRect *src, PF_LRect *dst) +{ + if (IsEmptyRect(dst)) { + *dst = *src; + } else if (!IsEmptyRect(src)) { + dst->left = mmin(dst->left, src->left); + dst->top = mmin(dst->top, src->top); + dst->right = mmax(dst->right, src->right); + dst->bottom = mmax(dst->bottom, src->bottom); + } +} + +PF_Boolean +IsEdgePixel( + PF_LRect *rectP, + A_long x, + A_long y) +{ + PF_Boolean x_hitB = FALSE, + y_hitB = FALSE; + + x_hitB = ((x == rectP->left) || (x == rectP->right)); + + y_hitB = ((y == rectP->top) || (y == rectP->bottom)); + + if (x_hitB){ + y_hitB = ((y >= rectP->top) && (y <= rectP->bottom)); + } else { + if (y_hitB){ + x_hitB = ((x >= rectP->left) && (x <= rectP->right)); + } + } + return (x_hitB && y_hitB); +} \ No newline at end of file diff --git a/External/AE SDK/Headers/Smart_Utils.h b/External/AE SDK/Headers/Smart_Utils.h new file mode 100644 index 00000000..3e1c03ce --- /dev/null +++ b/External/AE SDK/Headers/Smart_Utils.h @@ -0,0 +1,34 @@ +/*******************************************************************/ +/* */ +/* ADOBE CONFIDENTIAL */ +/* _ _ _ _ _ _ _ _ _ _ _ _ _ */ +/* */ +/* Copyright 2007 Adobe Systems Incorporated */ +/* All Rights Reserved. */ +/* */ +/* NOTICE: All information contained herein is, and remains the */ +/* property of Adobe Systems Incorporated and its suppliers, if */ +/* any. The intellectual and technical concepts contained */ +/* herein are proprietary to Adobe Systems Incorporated and its */ +/* suppliers and may be covered by U.S. and Foreign Patents, */ +/* patents in process, and are protected by trade secret or */ +/* copyright law. Dissemination of this information or */ +/* reproduction of this material is strictly forbidden unless */ +/* prior written permission is obtained from Adobe Systems */ +/* Incorporated. */ +/* */ +/*******************************************************************/ + +#include "AE_Effect.h" +#include "SPTypes.h" + +#ifndef mmin + #define mmin(a,b) ((a) < (b) ? (a) : (b)) + #define mmax(a,b) ((a) > (b) ? (a) : (b)) +#endif + +PF_Boolean IsEmptyRect(const PF_LRect *r); + +void UnionLRect(const PF_LRect *src, PF_LRect *dst); + +PF_Boolean IsEdgePixel(PF_LRect *rectP, A_long x, A_long y); \ No newline at end of file diff --git a/External/AE SDK/Headers/String_Utils.c b/External/AE SDK/Headers/String_Utils.c new file mode 100644 index 00000000..b897d050 --- /dev/null +++ b/External/AE SDK/Headers/String_Utils.c @@ -0,0 +1,6 @@ +#include "String_Utils.h" + +A_char *GetStringPtr(int strNum) +{ + return g_strs[strNum].str; +} \ No newline at end of file diff --git a/External/AE SDK/Headers/String_Utils.h b/External/AE SDK/Headers/String_Utils.h new file mode 100644 index 00000000..eadf62e7 --- /dev/null +++ b/External/AE SDK/Headers/String_Utils.h @@ -0,0 +1,48 @@ +/*******************************************************************/ +/* */ +/* ADOBE CONFIDENTIAL */ +/* _ _ _ _ _ _ _ _ _ _ _ _ _ */ +/* */ +/* Copyright 2007 Adobe Systems Incorporated */ +/* All Rights Reserved. */ +/* */ +/* NOTICE: All information contained herein is, and remains the */ +/* property of Adobe Systems Incorporated and its suppliers, if */ +/* any. The intellectual and technical concepts contained */ +/* herein are proprietary to Adobe Systems Incorporated and its */ +/* suppliers and may be covered by U.S. and Foreign Patents, */ +/* patents in process, and are protected by trade secret or */ +/* copyright law. Dissemination of this information or */ +/* reproduction of this material is strictly forbidden unless */ +/* prior written permission is obtained from Adobe Systems */ +/* Incorporated. */ +/* */ +/*******************************************************************/ + + + +/* String_Utils.h */ + + +#pragma once + +#ifndef STRING_UTILS_H +#define STRING_UTILS_H + +#ifdef __cplusplus +extern "C" { +#endif +A_char *GetStringPtr(int strNum); +#ifdef __cplusplus +} +#endif + +#define STR(_foo) GetStringPtr(_foo) + + + + + + + +#endif /* STRING_UTILS_H */ \ No newline at end of file diff --git a/External/AE SDK/Headers/SuiteHelper.h b/External/AE SDK/Headers/SuiteHelper.h new file mode 100644 index 00000000..ff050ccd --- /dev/null +++ b/External/AE SDK/Headers/SuiteHelper.h @@ -0,0 +1,97 @@ +#ifndef _H_SUITEHELPER +#define _H_SUITEHELPER + +#include "A.h" +#include "SPBasic.h" + +#include + +template +struct SuiteTraits +{ + static const A_char* i_name; + static const int32_t i_version; +}; + +template +class AssertAndThrowOnMissingSuite +{ +public: + void operator()() + { + assert( false ); + A_THROW(A_Err_MISSING_SUITE); + } +}; + + +class MissingSuiteErrFunc_NoOp +{ +public: + void operator()() + { + //swallow the error, not much we want to do or can do + } +}; + + +template > +class SuiteHelper +{ +public: + SuiteHelper(const SPBasicSuite* const basic_suiteP); + ~SuiteHelper(); + + const SuiteType* operator->() const; + SuiteType* get() const; + +private: + mutable SuiteType* i_SuiteP; + const SPBasicSuite* const i_basic_suiteP; +}; + + +template +SuiteHelper::SuiteHelper(const SPBasicSuite* const basic_suiteP) : i_basic_suiteP(basic_suiteP), i_SuiteP( NULL ) +{ + assert(basic_suiteP); + const void * acquired_suite = NULL; + + A_Err err = i_basic_suiteP->AcquireSuite(SuiteTraits::i_name, SuiteTraits::i_version, &acquired_suite); + if (err || !acquired_suite) { + MissingSuiteErrFunc error_func; + error_func(); + } else { + i_SuiteP = reinterpret_cast(const_cast(acquired_suite)); + } +} + +template +SuiteHelper::~SuiteHelper() +{ + if (i_SuiteP) { + + #ifdef DEBUG + A_Err err = + #endif + + i_basic_suiteP->ReleaseSuite(SuiteTraits::i_name, SuiteTraits::i_version); + + #ifdef DEBUG + assert( !err ); + #endif + } +} + +template +const SuiteType* SuiteHelper::operator->() const +{ + return i_SuiteP; +} + +template +SuiteType* SuiteHelper::get() const +{ + return i_SuiteP; +} +#endif diff --git a/External/AE SDK/Headers/adobesdk/DrawbotSuite.h b/External/AE SDK/Headers/adobesdk/DrawbotSuite.h new file mode 100644 index 00000000..409ed070 --- /dev/null +++ b/External/AE SDK/Headers/adobesdk/DrawbotSuite.h @@ -0,0 +1,660 @@ +/************************************************************************** +* +* ADOBE CONFIDENTIAL +* ___________________ +* +* Copyright 2009 Adobe Systems Incorporated +* All Rights Reserved. +* +* NOTICE: All information contained herein is, and remains the property of +* Adobe Systems Incorporated and its suppliers, if any. The intellectual +* and technical concepts contained herein are proprietary to Adobe Systems +* Incorporated and its suppliers and may be covered by U.S. and Foreign +* Patents,patents in process,and are protected by trade secret or copyright +* law. Dissemination of this information or reproduction of this material +* is strictly forbidden unless prior written permission is obtained from +* Adobe Systems Incorporated. +**************************************************************************/ + +#ifndef DRAWBOT_SUITE_H +#define DRAWBOT_SUITE_H + +#include + +#ifdef __cplusplus + #include // for std::exception +#endif +//Sweet pea header +#include + +#ifdef ADOBE_SDK_INTERNAL + #include +#else + #include +#endif + +#include + +#ifdef __cplusplus + extern "C" { +#endif + +/* +C STYLE +-------- +Drawbot suites can be used to draw paths, strings, images using application-provided DrawbotRef. Use C++ style (mentioned later in the file) +if you are creating cpp files as it is more elegant and you don't have to deal with retain/release of objects. + +Below function takes DrawbotRef and strokes a circle & a rectangle. + +void DrawSomething(DRAWBOT_DrawRef drawbot_ref) +{ + //Acquire drawbot (drawbot_suiteP), supplier (supplier_suiteP), surface (surface_suiteP) & path (path_suiteP) suites + ... + + //Get the supplier and surface reference from drawbot_ref + DRAWBOT_SupplierRef supplier_ref; + DRAWBOT_SurfaceRef surface_ref; + + drawbot_suiteP->GetSupplier(drawbot_ref, &supplier_ref); + drawbot_suiteP->GetSurface(drawbot_ref, &surface_ref); + + //Save the surface state by pushing it in stack. It is required to restore state if you are going to clip/transform surface + //or change interpolation/anti-aliasing policy. + surface_suiteP->PushStateStack(surface_ref); + + //Create a new red-color brush. + DRAWBOT_BrushRef brush_ref; + + supplier_suiteP->NewBrush(supplier_ref, DRAWBOT_ColorRGBA(1.0f, 0.0f, 0.0f, 1.0f), &brush_ref); + + //Create a new path + DRAWBOT_PathRef path_ref; + + supplier_suiteP->NewPath(supplier_ref, &path_ref); + + //Add a rectangle to the path + DRAWBOT_RectF32 rect1(0.0f, 0.0f, 50.0f, 50.0f); + + path_suiteP->AddRect(path_ref, rect1); + + //Add a circle to the path + path_suiteP->AddArc(path_ref, DRAWBOT_PointF32(25.0f, 25.0f), 10.0f, 0.0f, 360.0f); + + //Fill the path using red-colored brush. + surface_suiteP->FillPath(surface_ref, brush_ref, path_ref, kDRAWBOT_FillType_EvenOdd); + + //We are done. Release (delete) all the objects. There will be memory leak if you don't release. + surface_suiteP->ReleaseObject((DRAWBOT_ObjectRef)path_ref); + surface_suiteP->ReleaseObject((DRAWBOT_ObjectRef)brush_ref); + + //Don't forget to pop surface state (if pushed earlier) + surface_suiteP->PopStateStack(surface_ref); + + //DO NOT CALL ReleaseObject on surface_ref and supplier_ref as you did not create them. + + //Release drawbot (drawbot_suiteP), supplier (supplier_suiteP), surface (surface_suiteP) & path (path_suiteP) suites +} +*/ + + +#define kDRAWBOT_DrawSuite "DRAWBOT Draw Suite" +#define kDRAWBOT_DrawSuite_Version1 1 + +#define kDRAWBOT_DrawSuite_VersionCurrent kDRAWBOT_DrawSuite_Version1 +#define DRAWBOT_DrawbotSuiteCurrent DRAWBOT_DrawbotSuite1 + +typedef struct DRAWBOT_DrawbotSuite1 { + + //Get the supplier from the drawbot_ref + SPAPI SPErr (*GetSupplier)( DRAWBOT_DrawRef in_drawbot_ref, + DRAWBOT_SupplierRef *out_supplierP); + + //Get the surface from the drawbot_ref + SPAPI SPErr (*GetSurface)( DRAWBOT_DrawRef in_drawbot_ref, + DRAWBOT_SurfaceRef *out_surfaceP); + +} DRAWBOT_DrawbotSuite1; + + + +#define kDRAWBOT_SupplierSuite "DRAWBOT Supplier Suite" +#define kDRAWBOT_SupplierSuite_Version1 1 + +#define kDRAWBOT_SupplierSuite_VersionCurrent kDRAWBOT_SupplierSuite_Version1 +#define DRAWBOT_SupplierSuiteCurrent DRAWBOT_SupplierSuite1 + +typedef struct DRAWBOT_SupplierSuite1 { + + //Create a new pen. + //It should be released with ReleaseObject api. + SPErr (*NewPen)( DRAWBOT_SupplierRef in_supplier_ref, + const DRAWBOT_ColorRGBA *in_colorP, + float in_size, + DRAWBOT_PenRef *out_penP); + + //Create a new brush. + //It should be released with ReleaseObject api. + SPErr (*NewBrush)(DRAWBOT_SupplierRef in_supplier_ref, + const DRAWBOT_ColorRGBA *in_colorP, + DRAWBOT_BrushRef *out_brushP); + + //Check if current supplier supports text. + SPErr (*SupportsText)(DRAWBOT_SupplierRef in_supplier_ref, + DRAWBOT_Boolean *out_supports_textPB); + + //Get default font size. + SPErr (*GetDefaultFontSize)( DRAWBOT_SupplierRef in_supplier_ref, + float *out_font_sizeF); + + //Create a new font with default settings. + //You can pass default font size from GetDefaultFontSize. + //It should be released with ReleaseObject api. + SPErr (*NewDefaultFont)( DRAWBOT_SupplierRef in_supplier_ref, + float in_font_sizeF, + DRAWBOT_FontRef *out_fontP); + + //Create a new image from buffer. + //It should be released with ReleaseObject api. + SPErr (*NewImageFromBuffer)( DRAWBOT_SupplierRef in_supplier_ref, + int in_width, + int in_height, + int in_row_bytes, + DRAWBOT_PixelLayout in_pl, + const void *in_dataP, + DRAWBOT_ImageRef *out_imageP); + + //Create a new path. + //It should be released with ReleaseObject api. + SPErr (*NewPath)( DRAWBOT_SupplierRef in_supplier_ref, + DRAWBOT_PathRef *out_pathP); + + + //A given drawbot implementation can support multiple channel orders, but will likely + //prefer one over the other. Use below apis to get the preferred layout for any api that + //takes DRAWBOT_PixelLayout (ex- NewImageFromBuffer). + + SPErr (*SupportsPixelLayoutBGRA)( DRAWBOT_SupplierRef in_supplier_ref, + DRAWBOT_Boolean *out_supports_bgraPB); + + SPErr (*PrefersPixelLayoutBGRA) ( DRAWBOT_SupplierRef in_supplier_ref, + DRAWBOT_Boolean *out_prefers_bgraPB); + + SPErr (*SupportsPixelLayoutARGB)( DRAWBOT_SupplierRef in_supplier_ref, + DRAWBOT_Boolean *out_supports_argbPB); + + SPErr (*PrefersPixelLayoutARGB) ( DRAWBOT_SupplierRef in_supplier_ref, + DRAWBOT_Boolean *out_prefers_argbPB); + + //Retain (increase reference count) any object (pen, brush, path etc) + //Ex: It should be used when any object is copied and the copied object should be retained. + SPErr (*RetainObject)(DRAWBOT_ObjectRef in_obj_ref); + + //Release (decrease reference count) any object (pen, brush, path etc) + //This function MUST be called for any object created using NewXYZ() from this suite. + SPErr (*ReleaseObject)(DRAWBOT_ObjectRef in_obj_ref); + +} DRAWBOT_SupplierSuite1; + + +#define kDRAWBOT_SurfaceSuite "DRAWBOT Surface Suite" +#define kDRAWBOT_SurfaceSuite_Version1 1 +#define kDRAWBOT_SurfaceSuite_Version2 2 + +#define kDRAWBOT_SurfaceSuite_VersionCurrent kDRAWBOT_SurfaceSuite_Version2 +#define DRAWBOT_SurfaceSuiteCurrent DRAWBOT_SurfaceSuite2 + +typedef struct DRAWBOT_SurfaceSuite1 { + + //Push the current surface state in stack. It should be popped to retrieve old state. + SPErr (*PushStateStack)( DRAWBOT_SurfaceRef in_surface_ref); + + //Pop the last pushed surface state. + SPErr (*PopStateStack)( DRAWBOT_SurfaceRef in_surface_ref); + + //Paint a rectangle with a color on the surface. + SPErr (*PaintRect)( DRAWBOT_SurfaceRef in_surface_ref, + const DRAWBOT_ColorRGBA *in_colorP, + const DRAWBOT_RectF32 *in_rectPR); + + //Fill a path using a brush and fill type. + SPErr (*FillPath)( DRAWBOT_SurfaceRef in_surface_ref, + DRAWBOT_BrushRef in_brush_ref, + DRAWBOT_PathRef in_path_ref, + DRAWBOT_FillType in_fill_type); + + //Stroke a path using a pen. + SPErr (*StrokePath)( DRAWBOT_SurfaceRef in_surface_ref, + DRAWBOT_PenRef in_pen_ref, + DRAWBOT_PathRef in_path_ref); + + //Clip the surface + SPErr (*Clip)( DRAWBOT_SurfaceRef in_surface_ref, + DRAWBOT_SupplierRef in_supplier_ref, + const DRAWBOT_Rect32 *in_rectPR); + + //Get clip bounds + SPErr (*GetClipBounds)( + DRAWBOT_SurfaceRef in_surface_ref, + DRAWBOT_Rect32 *out_rectPR); + + //Checks whether a rect is within the clip bounds. + SPErr (*IsWithinClipBounds)( + DRAWBOT_SurfaceRef in_surface_ref, + const DRAWBOT_Rect32 *in_rectPR, + DRAWBOT_Boolean *out_withinPB); + + //Transform the last surface state. + SPErr (*Transform)( DRAWBOT_SurfaceRef in_surface_ref, + const DRAWBOT_MatrixF32 *in_matrixP); + + //Draw a string + SPErr (*DrawString)( DRAWBOT_SurfaceRef in_surface_ref, + DRAWBOT_BrushRef in_brush_ref, + DRAWBOT_FontRef in_font_ref, + const DRAWBOT_UTF16Char *in_stringP, + const DRAWBOT_PointF32 *in_originP, + DRAWBOT_TextAlignment in_alignment_style, + DRAWBOT_TextTruncation in_truncation_style, + float in_truncation_width); + + //Draw an image (created using NewImageFromBuffer())on the surface + //alpha = [0.0f, 1.0f] + SPErr (*DrawImage)( DRAWBOT_SurfaceRef in_surface_ref, + DRAWBOT_ImageRef in_image_ref, + const DRAWBOT_PointF32 *in_originP, + float in_alpha); + + SPErr (*SetInterpolationPolicy)( + DRAWBOT_SurfaceRef in_surface_ref, + DRAWBOT_InterpolationPolicy in_interp); + + SPErr (*GetInterpolationPolicy)( + DRAWBOT_SurfaceRef in_surface_ref, + DRAWBOT_InterpolationPolicy *out_interpP); + + SPErr (*SetAntiAliasPolicy)( + DRAWBOT_SurfaceRef in_surface_ref, + DRAWBOT_AntiAliasPolicy in_policy); + + SPErr (*GetAntiAliasPolicy)( + DRAWBOT_SurfaceRef in_surface_ref, + DRAWBOT_AntiAliasPolicy *out_policyP); + + //Flush drawing + SPErr (*Flush)( DRAWBOT_SurfaceRef in_surface_ref); + + //Get the transform of the surface state. + SPErr (*GetTransformToScreenScale)(DRAWBOT_SurfaceRef in_surface_ref, + float* out_scale); +} DRAWBOT_SurfaceSuite2; + +typedef DRAWBOT_SurfaceSuite2 DRAWBOT_SurfaceSuite1; // At the time, the last function was Flush. + + +#define kDRAWBOT_PathSuite "DRAWBOT Path Suite" +#define kDRAWBOT_PathSuite_Version1 1 + +#define kDRAWBOT_PathSuite_VersionCurrent kDRAWBOT_PathSuite_Version1 +#define DRAWBOT_PathSuiteCurrent DRAWBOT_PathSuite1 + +typedef struct DRAWBOT_PathSuite1 { + + //Move to a point + SPErr (*MoveTo)( DRAWBOT_PathRef in_path_ref, + float in_x, + float in_y); + + //Add a line to the path + SPErr (*LineTo)( DRAWBOT_PathRef in_path_ref, + float in_x, + float in_y); + + //Add a cubic bezier to the path + SPErr (*BezierTo)(DRAWBOT_PathRef in_path_ref, + const DRAWBOT_PointF32 *in_pt1P, + const DRAWBOT_PointF32 *in_pt2P, + const DRAWBOT_PointF32 *in_pt3P); + + //Add a rect to the path + SPErr (*AddRect)( DRAWBOT_PathRef in_path_ref, + const DRAWBOT_RectF32 *in_rectPR); + + //Add a arc to the path + //zero start degrees == 3 o'clock + //sweep is clockwise + //units in degrees + SPErr (*AddArc)( DRAWBOT_PathRef in_path_ref, + const DRAWBOT_PointF32 *in_centerP, + float in_radius, + float in_start_angle, + float in_sweep); + + SPErr (*Close)( DRAWBOT_PathRef in_path_ref); + +} DRAWBOT_PathSuite1; + + +#define kDRAWBOT_PenSuite "DRAWBOT Pen Suite" +#define kDRAWBOT_PenSuite_Version1 1 + +#define kDRAWBOT_PenSuite_VersionCurrent kDRAWBOT_PenSuite_Version1 +#define DRAWBOT_PenSuiteCurrent DRAWBOT_PenSuite1 + +typedef struct DRAWBOT_PenSuite1 { + + //Make the line dashed + SPErr (*SetDashPattern)( DRAWBOT_PenRef in_pen_ref, + const float *in_dashesP, + int in_pattern_size); + +} DRAWBOT_PenSuite1; + +#define kDRAWBOT_ImageSuite "DRAWBOT Image Suite" +#define kDRAWBOT_ImageSuite_Version1 1 + +#define kDRAWBOT_ImageSuite_VersionCurrent kDRAWBOT_ImageSuite_Version1 +#define DRAWBOT_ImageSuiteCurrent DRAWBOT_ImageSuite1 + +typedef struct DRAWBOT_ImageSuite1 { + + //Make the line dashed + SPErr (*SetScaleFactor)( DRAWBOT_ImageRef in_image_ref, + float in_scale_factor); + +} DRAWBOT_ImageSuite1; + +//Collection of latest drawbot suites +typedef struct { + DRAWBOT_DrawbotSuiteCurrent *drawbot_suiteP; + DRAWBOT_SupplierSuiteCurrent *supplier_suiteP; + DRAWBOT_SurfaceSuiteCurrent *surface_suiteP; + DRAWBOT_PathSuiteCurrent *path_suiteP; + DRAWBOT_PenSuiteCurrent *pen_suiteP; + DRAWBOT_ImageSuiteCurrent *image_suiteP; +} DRAWBOT_Suites; + + +#ifdef __cplusplus + } // end extern "C" +#endif + + + +#ifdef __cplusplus //C++ Style + +/* +Use C++ style as it will automatically deal with memory management of objects. Below example will make it clear. + +Below function takes DrawbotRef and strokes a circle & a rectangle. + +void DrawSomething(DRAWBOT_DrawRef drawbot_ref) +{ + //Acquire drawbot (drawbot_suiteP), supplier (supplier_suiteP), surface (surface_suiteP) & path (path_suiteP) suites + ... + + //Get the supplier and surface reference from drawbot_ref + DRAWBOT_SupplierRef supplier_ref; + DRAWBOT_SurfaceRef surface_ref; + + drawbot_suiteP->GetSupplier(drawbot_ref, &supplier_ref); + drawbot_suiteP->GetSurface(drawbot_ref, &surface_ref); + + //Save the surface state by pushing it in stack. It is required to restore if you are going to clip or transform surface. + //Below call acts like a a scoper: it will push the current surface state and automatically pop at the end of scope. + DRAWBOT_SaveAndRestoreStateStack sc_save_state(surface_suiteP, surface_ref); + + //Create a new red-color brush. + //Compare below call with C-style apis. It is compact and brush will be automatically released at the end of scope. + DRAWBOT_BrushP brushP(supplier_suiteP, supplier_ref, DRAWBOT_ColorRGBA(1.0f, 0.0f, 0.0f, 1.0f)); + + //Create a new path + DRAWBOT_PathP pathP(supplier_suiteP, supplier_ref); + + //Add a rectangle to the path + DRAWBOT_RectF32 rect1(0.0f, 0.0f, 50.0f, 50.0f); + + path_suiteP->AddRect(pathP, rect1); + + //Add a circle to the path + path_suiteP->AddArc(pathP, DRAWBOT_PointF32(25.0f, 25.0f), 10.0f, 0.0f, 360.0f); + + //Fill the path using red-colored brush. + surface_suiteP->FillPath(surface_ref, brushP, pathP, kDRAWBOT_FillType_EvenOdd); + + //Release drawbot (drawbot_suiteP), supplier (supplier_suiteP), surface (surface_suiteP) & path (path_suiteP) suites + + //We are DONE. You don't have to release brush & path objects as you did in C-style. +} +*/ +class DRAWBOT_Exception : public std::exception { +public: + DRAWBOT_Exception(SPErr err): mErr(err) + { + } + virtual ~DRAWBOT_Exception() throw () {} + + SPErr mErr; +}; + +#define DRAWBOT_ErrorToException(EXPR) { SPErr _err = (EXPR); if (_err) throw DRAWBOT_Exception(_err); } + + +//SharedRefImpl declaration + +template +class SharedRefImpl { +public: + SharedRefImpl(DRAWBOT_SupplierSuiteCurrent *suiteP, REF_T r = 0, bool retainB = true) + : + mRef(r), + mSuiteP(suiteP) + { + if (retainB) { + RetainObject(); + } + } + + virtual ~SharedRefImpl() + { + ReleaseObject(); + } + + //copy constructor + SharedRefImpl(SharedRefImpl const & rhs) + { + *this = rhs; + } + + //assignment operator + SharedRefImpl & operator=(SharedRefImpl const & rhs) + { + mSuiteP = rhs.mSuiteP; + mRef = rhs.mRef; + + RetainObject(); + + return *this; + } + + inline REF_T Get() const + { + return mRef; + } + + inline operator REF_T() const + { + return mRef; + } + + inline void Reset(REF_T rhs = 0, bool retainB = true) + { + if (mRef != rhs) { + ReleaseObject(); + + mRef = rhs; + + if (retainB) { + RetainObject(); + } + } + } + +private: + void ReleaseObject() + { + if (mRef) { + DRAWBOT_ErrorToException(mSuiteP->ReleaseObject(reinterpret_cast(mRef))); + mRef = NULL; + } + } + + void RetainObject() + { + if (mRef) { + DRAWBOT_ErrorToException(mSuiteP->RetainObject(reinterpret_cast(mRef))); + } + } + + REF_T mRef; + DRAWBOT_SupplierSuiteCurrent *mSuiteP; +}; + + +//DRAWBOT_PenP declaration + +class DRAWBOT_PenP : public SharedRefImpl { + typedef SharedRefImpl _inherited; +public: + + DRAWBOT_PenP( DRAWBOT_SupplierSuiteCurrent *suiteP, + const DRAWBOT_SupplierRef supplier_ref, + const DRAWBOT_ColorRGBA *colorP, + float sizeF) + : + _inherited(suiteP) + { + New(suiteP, supplier_ref, colorP, sizeF); + } + + void New( DRAWBOT_SupplierSuiteCurrent *suiteP, + const DRAWBOT_SupplierRef supplier_ref, + const DRAWBOT_ColorRGBA *colorP, + float sizeF) + { + DRAWBOT_PenRef pen_ref; + + DRAWBOT_ErrorToException(suiteP->NewPen(supplier_ref, colorP, sizeF, &pen_ref)); + + Reset(pen_ref, false); + } +}; + + +//DRAWBOT_PathP declaration + +class DRAWBOT_PathP : public SharedRefImpl { + typedef SharedRefImpl _inherited; +public: + DRAWBOT_PathP( DRAWBOT_SupplierSuiteCurrent *suiteP, + const DRAWBOT_SupplierRef supplier_ref) + : + _inherited(suiteP) + { + New(suiteP, supplier_ref); + } + + void New( DRAWBOT_SupplierSuiteCurrent *suiteP, + const DRAWBOT_SupplierRef supplier_ref) + { + DRAWBOT_PathRef path_ref; + + DRAWBOT_ErrorToException(suiteP->NewPath(supplier_ref, &path_ref)); + + Reset(path_ref, false); + } +}; + + +//DRAWBOT_BrushP declaration + +class DRAWBOT_BrushP : public SharedRefImpl { + typedef SharedRefImpl _inherited; +public: + DRAWBOT_BrushP( DRAWBOT_SupplierSuiteCurrent *suiteP, + const DRAWBOT_SupplierRef supplier_ref, + const DRAWBOT_ColorRGBA *colorP) + : + _inherited(suiteP) + { + New(suiteP, supplier_ref, colorP); + } + + void New( DRAWBOT_SupplierSuiteCurrent *suiteP, + const DRAWBOT_SupplierRef supplier_ref, + const DRAWBOT_ColorRGBA *colorP) + { + DRAWBOT_BrushRef brush_ref; + + DRAWBOT_ErrorToException(suiteP->NewBrush(supplier_ref, colorP, &brush_ref)); + + Reset(brush_ref, false); + } +}; + + +//DRAWBOT_FontP declaration + +class DRAWBOT_FontP : public SharedRefImpl { + typedef SharedRefImpl _inherited; +public: + DRAWBOT_FontP( DRAWBOT_SupplierSuiteCurrent *suiteP, + const DRAWBOT_SupplierRef supplier_ref, + float in_font_size) + : + _inherited(suiteP) + { + New(suiteP, supplier_ref, in_font_size); + } + + void New( DRAWBOT_SupplierSuiteCurrent *suiteP, + const DRAWBOT_SupplierRef supplier_ref, + float in_font_size) + { + DRAWBOT_FontRef font_ref; + + DRAWBOT_ErrorToException(suiteP->NewDefaultFont(supplier_ref, in_font_size, &font_ref)); + + Reset(font_ref, false); + } +}; + + +class DRAWBOT_SaveAndRestoreStateStack { +public: + DRAWBOT_SaveAndRestoreStateStack( DRAWBOT_SurfaceSuiteCurrent *suiteP, + const DRAWBOT_SurfaceRef surface_ref) + : + mSurfaceRef(surface_ref), + mSuiteP(suiteP) + { + DRAWBOT_ErrorToException(mSuiteP->PushStateStack(mSurfaceRef)); + } + + ~DRAWBOT_SaveAndRestoreStateStack() + { + (void)mSuiteP->PopStateStack(mSurfaceRef); + } + +private: + DRAWBOT_SurfaceRef mSurfaceRef; + DRAWBOT_SurfaceSuiteCurrent *mSuiteP; +}; + + +#endif //C++ Style + + +#include + +#endif //DRAWBOT_SUITE_H diff --git a/External/AE SDK/Headers/adobesdk/config/AdobesdkTypes.h b/External/AE SDK/Headers/adobesdk/config/AdobesdkTypes.h new file mode 100755 index 00000000..4dc90478 --- /dev/null +++ b/External/AE SDK/Headers/adobesdk/config/AdobesdkTypes.h @@ -0,0 +1,54 @@ +/************************************************************************** +* +* ADOBE CONFIDENTIAL +* ___________________ +* +* Copyright 2009 Adobe Systems Incorporated +* All Rights Reserved. +* +* NOTICE: All information contained herein is, and remains the property of +* Adobe Systems Incorporated and its suppliers, if any. The intellectual +* and technical concepts contained herein are proprietary to Adobe Systems +* Incorporated and its suppliers and may be covered by U.S. and Foreign +* Patents,patents in process,and are protected by trade secret or copyright +* law. Dissemination of this information or reproduction of this material +* is strictly forbidden unless prior written permission is obtained from +* Adobe Systems Incorporated. +**************************************************************************/ + +/** + Definition of common types used by adobesdk. +**/ + +#ifndef ADOBESDK_CONFIG_TYPES_H +#define ADOBESDK_CONFIG_TYPES_H + +#include + +#include "stdint.h" + + +typedef uint16_t ADOBESDK_UTF16Char; +typedef uint8_t ADOBESDK_UTF8Char; +typedef uint8_t ADOBESDK_Boolean; + +enum +{ + kAdobesdk_False = 0, + kAdobesdk_True = 1 +}; + + +typedef ADOBESDK_UTF16Char DRAWBOT_UTF16Char; +typedef ADOBESDK_Boolean DRAWBOT_Boolean; + + +typedef struct +{ + int64_t opaque[2]; +} ADOBESDK_String; + + +#include + +#endif //ADOBESDK_CONFIG_TYPES_H diff --git a/External/AE SDK/Headers/adobesdk/config/PostConfig.h b/External/AE SDK/Headers/adobesdk/config/PostConfig.h new file mode 100755 index 00000000..f10326ad --- /dev/null +++ b/External/AE SDK/Headers/adobesdk/config/PostConfig.h @@ -0,0 +1,2 @@ + +#pragma pack( pop, AdobeSDKExternalAlign ) \ No newline at end of file diff --git a/External/AE SDK/Headers/adobesdk/config/PreConfig.h b/External/AE SDK/Headers/adobesdk/config/PreConfig.h new file mode 100755 index 00000000..2675004d --- /dev/null +++ b/External/AE SDK/Headers/adobesdk/config/PreConfig.h @@ -0,0 +1,23 @@ + +//Must be balanced with PostConfig.h! + +#ifdef _WINDOWS + //disable warning in VS2008 about unbalanced struct alignment changes + #pragma warning( disable : 4103 ) + + // This is taken from PreConfig_Win.h in dvacore, there is a bug in the VS2010 xlocnum header in particular where it is + // incorrectly putting a declspec on a static member of a template class 'numpunct'. + #if defined(_MSC_VER) && (_MSC_VER >= 1600) && defined(PREMIERE_INTERNAL) + // Compilation problems due to locale id being marked as dllimport. -jacquave 2/18/2010 + // Also, opened a Technical Support Request with Microsoft, # 111021865918375. + + // http://connect.microsoft.com/VisualStudio/feedback/details/572376/msvc10-c-std-numpunct-has-a-hardcoded-dllimport-in-definition + // http://dotnetforum.net/topic/7346-vs2010-error-c2491-stdnumpunctid-while-using-stdbasic-fstream-in-ccli/ + #ifdef __cplusplus + #include "dvacore/config/win/xlocnum_hack.h" + #endif + #endif +#endif + +//8 byte alignment for adobesdk public files. +#pragma pack( push, AdobeSDKExternalAlign, 8 ) diff --git a/External/AE SDK/Headers/adobesdk/drawbotsuite/DrawbotSuiteTypes.h b/External/AE SDK/Headers/adobesdk/drawbotsuite/DrawbotSuiteTypes.h new file mode 100755 index 00000000..5c1ee028 --- /dev/null +++ b/External/AE SDK/Headers/adobesdk/drawbotsuite/DrawbotSuiteTypes.h @@ -0,0 +1,148 @@ +/************************************************************************** + * + * ADOBE CONFIDENTIAL + * ___________________ + * + * Copyright 2009 Adobe Systems Incorporated + * All Rights Reserved. + * + * NOTICE: All information contained herein is, and remains the property of + * Adobe Systems Incorporated and its suppliers, if any. The intellectual + * and technical concepts contained herein are proprietary to Adobe Systems + * Incorporated and its suppliers and may be covered by U.S. and Foreign + * Patents,patents in process,and are protected by trade secret or copyright + * law. Dissemination of this information or reproduction of this material + * is strictly forbidden unless prior written permission is obtained from + * Adobe Systems Incorporated. + **************************************************************************/ +// Author: pankajn@adobe.com + +#ifndef DRAWBOT_SUITE_TYPES_H +#define DRAWBOT_SUITE_TYPES_H + +#include + + +typedef struct _DRAWBOT_DrawRef *DRAWBOT_DrawRef; +typedef struct _DRAWBOT_SupplierRef *DRAWBOT_SupplierRef; +typedef struct _DRAWBOT_SurfaceRef *DRAWBOT_SurfaceRef; +typedef struct _DRAWBOT_PenRef *DRAWBOT_PenRef; +typedef struct _DRAWBOT_PathRef *DRAWBOT_PathRef; +typedef struct _DRAWBOT_BrushRef *DRAWBOT_BrushRef; +typedef struct _DRAWBOT_ImageRef *DRAWBOT_ImageRef; +typedef struct _DRAWBOT_FontRef *DRAWBOT_FontRef; +typedef struct _DRAWBOT_ObjectRef *DRAWBOT_ObjectRef; + + +// 0.0f to 1.0f +typedef struct { + float red; + float green; + float blue; + float alpha; +} DRAWBOT_ColorRGBA; + + +typedef struct { + float x; + float y; +} DRAWBOT_PointF32; + + +typedef struct { + float left; + float top; + float width; //not right + float height; //not bottom +} DRAWBOT_RectF32; + + +typedef struct { + int left; + int top; + int width; //not right + int height; //not bottom +} DRAWBOT_Rect32; + + +typedef struct { + float mat[3][3]; +} DRAWBOT_MatrixF32; + + +//Enum to fill a path +enum { + kDRAWBOT_FillType_EvenOdd = 0, + kDRAWBOT_FillType_Winding, + + kDRAWBOT_FillType_Default = kDRAWBOT_FillType_Winding +}; +typedef int DRAWBOT_FillType; + + +//Enum to specify pixel layout of buffer to create an image. +enum { + kDRAWBOT_PixelLayout_24RGB = 0, + kDRAWBOT_PixelLayout_24BGR, + kDRAWBOT_PixelLayout_32RGB, // ARGB (A is ignored). + kDRAWBOT_PixelLayout_32BGR, // BGRA (A is ignored). + kDRAWBOT_PixelLayout_32ARGB_Straight, + kDRAWBOT_PixelLayout_32ARGB_Premul, + kDRAWBOT_PixelLayout_32BGRA_Straight, + kDRAWBOT_PixelLayout_32BGRA_Premul +}; +typedef int DRAWBOT_PixelLayout; + + +//Enum to specify the text alignment (used in DrawString) +enum { + kDRAWBOT_TextAlignment_Left = 0, + kDRAWBOT_TextAlignment_Center, + kDRAWBOT_TextAlignment_Right, + + kDRAWBOT_TextAlignment_Default = kDRAWBOT_TextAlignment_Left +}; +typedef int DRAWBOT_TextAlignment; + + +//Enum to specify text truncation (used in DrawString) +enum { + kDRAWBOT_TextTruncation_None = 0, + kDRAWBOT_TextTruncation_End, + kDRAWBOT_TextTruncation_EndEllipsis, + kDRAWBOT_TextTruncation_PathEllipsis // tries to preserve the disk name ellipsis in middle of string +}; +typedef int DRAWBOT_TextTruncation; + + +//Enum to specify surface interpolation level +enum { + kDRAWBOT_InterpolationPolicy_None = 0, + kDRAWBOT_InterpolationPolicy_Med, + kDRAWBOT_InterpolationPolicy_High, + + kDRAWBOT_InterpolationPolicy_Default = kDRAWBOT_InterpolationPolicy_None +}; +typedef int DRAWBOT_InterpolationPolicy; + + +//Enum to specify drawing anti-aliasing level +enum { + kDRAWBOT_AntiAliasPolicy_None = 0, + kDRAWBOT_AntiAliasPolicy_Med, + kDRAWBOT_AntiAliasPolicy_High, + + kDRAWBOT_AntiAliasPolicy_Default = kDRAWBOT_AntiAliasPolicy_None +}; +typedef int DRAWBOT_AntiAliasPolicy; + + +#include + +#endif //DRAWBOT_SUITE_TYPES_H + + + + + + \ No newline at end of file diff --git a/External/AE SDK/Headers/entry.h b/External/AE SDK/Headers/entry.h new file mode 100644 index 00000000..6a0175db --- /dev/null +++ b/External/AE SDK/Headers/entry.h @@ -0,0 +1,53 @@ +/*******************************************************************/ +/* */ +/* ADOBE CONFIDENTIAL */ +/* _ _ _ _ _ _ _ _ _ _ _ _ _ */ +/* */ +/* Copyright 2007 Adobe Systems Incorporated */ +/* All Rights Reserved. */ +/* */ +/* NOTICE: All information contained herein is, and remains the */ +/* property of Adobe Systems Incorporated and its suppliers, if */ +/* any. The intellectual and technical concepts contained */ +/* herein are proprietary to Adobe Systems Incorporated and its */ +/* suppliers and may be covered by U.S. and Foreign Patents, */ +/* patents in process, and are protected by trade secret or */ +/* copyright law. Dissemination of this information or */ +/* reproduction of this material is strictly forbidden unless */ +/* prior written permission is obtained from Adobe Systems */ +/* Incorporated. */ +/* */ +/*******************************************************************/ + +/* + Entry.h + + Part of the Adobe After Effects SDK. +*/ + +#include "AE_PluginData.h" + +#ifdef AE_OS_WIN + #define DllExport __declspec( dllexport ) +#elif defined AE_OS_MAC + #define DllExport __attribute__ ((visibility ("default"))) +#endif + + +#define AE_ENTRY_POINT "EffectMain" +#define AE_RESERVED_INFO 8 + +#define PF_REGISTER_EFFECT(INPTR, CBPTR, NAME, MATCHNAME, CATEGORY,RESERVEDINFO) \ + result = (*(CBPTR))((INPTR),\ + reinterpret_cast(NAME),\ + reinterpret_cast(MATCHNAME),\ + reinterpret_cast(CATEGORY),\ + reinterpret_cast(AE_ENTRY_POINT),\ + 'eFKT',\ + PF_AE_PLUG_IN_VERSION,\ + PF_AE_PLUG_IN_SUBVERS,\ + RESERVEDINFO);\ + if(result == A_Err_NONE)\ + {\ + result = PF_Err_NONE;\ + } diff --git a/External/AE SDK/Resources/AE_General.r b/External/AE SDK/Resources/AE_General.r new file mode 100644 index 00000000..a0b146cf --- /dev/null +++ b/External/AE SDK/Resources/AE_General.r @@ -0,0 +1,548 @@ +/* + File: AE_General.r + + Copyright 1991-96 by Adobe Systems Inc.. + + Photoshop's Rinclude with AE extensions + +*/ + +#ifndef __AEPIGeneral_r__ +#define __AEPIGeneral_r__ + +#ifndef kPIPropertiesVersion +#define kPIPropertiesVersion 0 +#endif + +type 'PiPL' + { + longint = kPIPropertiesVersion; + longint = $$CountOf(properties); + array properties + { + switch + { + +/* Properties for all types of plug-ins. */ + + case Kind: + longint = '8BIM'; + key longint = 'kind'; + longint = 0; + longint = 4; + literal longint Filter = '8BFM', Parser = '8BYM', ImageFormat='8BIF', + Extension = '8BXM', Acquire = '8BAM', Export = '8BEM', + /* AE specific */ + AEEffect = 'eFKT', AEImageFormat = 'FXIF', AEAccelerator = 'eFST', + AEGeneral = 'AEgp', AEGP = 'AEgx', AEForeignProjectFormat = 'eFPF'; + + case Version: + longint = '8BIM'; + key longint = 'vers'; + longint = 0; + longint = 4; + longint; + + case Priority: + longint = '8BIM'; + key longint = 'prty'; + longint = 0; + longint = 4; + longint; + + case RequiredHost: + longint = '8BIM'; + key longint = 'host'; + longint = 0; + longint = 4; + literal longint; + + case Name: + longint = '8BIM'; + key longint = 'name'; + longint = 0; +#if DeRez + fill long; +#else + longint = (nameEnd[$$ArrayIndex(properties)] - nameStart[$$ArrayIndex(properties)]) / 8; +#endif + nameStart: + pstring; + nameEnd: + align long; + + case Category: + longint = '8BIM'; + key longint = 'catg'; + longint = 0; +#if DeRez + fill long; +#else + longint = (catgEnd[$$ArrayIndex(properties)] - catgStart[$$ArrayIndex(properties)]) / 8; +#endif + catgStart: + pstring; + catgEnd: + align long; + + case Code68k: + longint = '8BIM'; + key longint = 'm68k'; + longint = 0; + longint = 6; + literal longint; + integer; + align long; + + case Code68kFPU: + longint = '8BIM'; + key longint = '68fp'; + longint = 0; + longint = 6; + literal longint; + integer; + align long; + + case CodePowerPC: + longint = '8BIM'; + key longint = 'pwpc'; + longint = 0; +#if DeRez + fill long; +#else + longint = (pwpcEnd[$$ArrayIndex(properties)] - pwpcStart[$$ArrayIndex(properties)]) / 8; +#endif + pwpcStart: + longint; + longint; + pstring; + pwpcEnd: + align long; + + case CodeCarbonPowerPC: + longint = '8BIM'; + key longint = 'ppcb'; + longint = 0; + #if DeRez + fill long; + #else + longint = (pwpcCarbonEnd[$$ArrayIndex(properties)] - pwpcCarbonStart[$$ArrayIndex(properties)]) / 8; + #endif + pwpcCarbonStart: + longint; + longint; + pstring; + pwpcCarbonEnd: + align long; + + // Mach-O Support + case CodeMachOPowerPC: + longint = '8BIM'; + key longint = 'mach'; + longint = 0; + #if DeRez + fill long; + #else + longint = (pwpcMachEnd[$$ArrayIndex(properties)] - pwpcMachStart[$$ArrayIndex(properties)]) / 8; + #endif + pwpcMachStart: + pstring; + pwpcMachEnd: + align long; + + // Mach-O Intel 32bit Support + case CodeMacIntel32: + longint = '8BIM'; + key longint = 'mi32'; + longint = 0; + #if DeRez + fill long; + #else + longint = (pwpcMacIntel32End[$$ArrayIndex(properties)] - pwpcMacIntel32Start[$$ArrayIndex(properties)]) / 8; + #endif + pwpcMacIntel32Start: + pstring; + pwpcMacIntel32End: + align long; + + // Mach-O Intel 64bit Support + case CodeMacIntel64: + longint = '8BIM'; + key longint = 'mi64'; + longint = 0; + #if DeRez + fill long; + #else + longint = (pwpcMacIntel64End[$$ArrayIndex(properties)] - pwpcMacIntel64Start[$$ArrayIndex(properties)]) / 8; + #endif + pwpcMacIntel64Start: + pstring; + pwpcMacIntel64End: + align long; + + case CodeMacARM64: + longint = '8BIM'; + key longint = 'ma64'; + longint = 0; + #if DeRez + fill long; + #else + longint = (pwpcMacARM64End[$$ArrayIndex(properties)] - pwpcMacARM64Start[$$ArrayIndex(properties)]) / 8; + #endif + pwpcMacARM64Start: + pstring; + pwpcMacARM64End: + align long; + + +#ifdef AE_OS_WIN /* For documentation purposes only. */ + case CodeWin32X86: + longint = '8BIM'; + key longint = 'wx86'; + longint = 0; + longint = (win32x86End[$$ArrayIndex(properties)] - win32x86Start[$$ArrayIndex(properties)]) / 8; + win32x86Start: + cstring; + win32x86End: + align long; + + case CodeWin64X86: + longint = '8BIM'; + key longint = '8664'; + longint = 0; + longint = (win64x86End[$$ArrayIndex(properties)] - win64x86Start[$$ArrayIndex(properties)]) / 8; + win64x86Start: + cstring; + win64x86End: + align long; +#endif + + case SupportedModes: + longint = '8BIM'; + key longint = 'mode'; + longint = 0; +#if DeRez + fill long; +#else + longint = (modeEnd[$$ArrayIndex(properties)] - modeStart[$$ArrayIndex(properties)]) / 8; +#endif + modeStart: + boolean noBitmap, doesSupportBitmap; + boolean noGrayScale, doesSupportGrayScale; + boolean noIndexedColor, doesSupportIndexedColor; + boolean noRGBColor, doesSupportRGBColor; + boolean noCMYKColor, doesSupportCMYKColor; + boolean noHSLColor, doesSupportHSLColor; + boolean noHSBColor, doesSupportHSBColor; + boolean noMultichannel, doesSupportMultichannel; + boolean noDuotone, doesSupportDuotone; + boolean noLABColor, doesSupportLABColor; + boolean noGray16, doesSupportGray16; + boolean noRGB48, doesSupportRGB48; + boolean noLab48, doesSupportLab48; + boolean noCMYK64, doesSupportCMYK64; + boolean noDeepMultichannel, doesSupportDeepMultichannel; + boolean noDuotone16, doesSupportDuotone16; + modeEnd: + align long; + +/* Filter plug-in properties. */ + + case FilterCaseInfo: + longint = '8BIM'; + key longint = 'fici'; + longint = 0; + longint = 28; + array [7] + { + byte inCantFilter = 0, + inStraightData = 1, + inBlackMat = 2, + inGrayMat = 3, + inWhiteMat = 4, + inDefringe = 5, + inBlackZap = 6, + inGrayZap = 7, + inWhiteZap = 8, + inBackgroundZap = 10, + inForegroundZap = 11; + byte outCantFilter = 0, + outStraightData = 1, + outBlackMat = 2, + outGrayMat = 3, + outWhiteMat = 4, + outFillMask = 9; + fill bit [5]; + boolean doesNotFilterLayerMasks, filtersLayerMasks; + boolean doesNotWorkWithBlankData, worksWithBlankData; + boolean copySourceToDestination, doNotCopySourceToDestination; + fill byte; + } ; + +/* Export plug-in properties. */ + + case ExportFlags: + longint = '8BIM'; + key longint = 'expf'; + longint = 0; +#if DeRez + fill long; +#else + longint = (expFlagsEnd[$$ArrayIndex(properties)] - expFlagsStart[$$ArrayIndex(properties)]) / 8; +#endif + expFlagsStart: + boolean expDoesNotSupportTransparency, expSupportsTransparency; + fill bit[7]; + expFlagsEnd: + align long; + +/* Format plug-in properties. */ +// If this property is present, then its on. No parameters + case SupportsPOSIXIO: + longint = '8BIM'; + key longint = 'fxio'; + longint = 0; + longint = 4; + literal longint = 1; + + case FmtFileType: + longint = '8BIM'; + key longint = 'fmTC'; + longint = 0; + longint = 8; + literal longint; /* Default file type. */ + literal longint; /* Default file creator. */ + + case ReadTypes: + longint = '8BIM'; + key longint = 'RdTy'; + longint = 0; + longint = $$CountOf(ReadableTypes) * 8; + wide array ReadableTypes { literal longint; literal longint; } ; + + case WriteTypes: + longint = '8BIM'; + key longint = 'WrTy'; + longint = 0; + longint = $$CountOf(WritableTypes) * 8; + wide array WritableTypes { literal longint; literal longint; } ; + + case FilteredTypes: + longint = '8BIM'; + key longint = 'fftT'; + longint = 0; + longint = $$CountOf(FilteredTypes) * 8; + wide array FilteredTypes { literal longint; literal longint; } ; + + case ReadExtensions: + longint = '8BIM'; + key longint = 'RdEx'; + longint = 0; + longint = $$CountOf(ReadableExtensions) * 4; + wide array ReadableExtensions { literal longint; } ; + + case WriteExtensions: + longint = '8BIM'; + key longint = 'WrEx'; + longint = 0; + longint = $$CountOf(WriteableExtensions) * 4; + wide array WriteableExtensions { literal longint; } ; + + case FilteredExtensions: + longint = '8BIM'; + key longint = 'fftE'; + longint = 0; + longint = $$CountOf(FilteredExtensions) * 4; + wide array FilteredExtensions { literal longint; } ; + + case FormatFlags: + longint = '8BIM'; + key longint = 'fmtf'; + longint = 0; +/* longint = (fmtFlagsEnd[$$ArrayIndex(properties)] - fmtFlagsStart[$$ArrayIndex(properties)]) / 8; */ + longint = 1; + fmtFlagsStart: + boolean fmtReadsAllTypes, fmtDoesntReadAllTypes; + boolean fmtDoesNotSaveImageResources, fmtSavesImageResources; + boolean fmtCannotRead, fmtCanRead; + boolean fmtCannotWrite, fmtCanWrite; + boolean fmtWritesAll, fmtCanWriteIfRead; + fill bit[3]; + fmtFlagsEnd: + align long; + + case FormatICCFlags: + longint = '8BIM'; + key longint = 'fmip'; + longint = 0; + //longint = (iccFlagsEnd[$ArrayIndex(properties)] - iccFlagsStart[$ArrayIndex(properties)]) / 8; + longint = 1; + iccFlagsStart: + boolean iccCannotEmbedGray, iccCanEmbedGray; + boolean iccCannotEmbedIndexed, iccCanEmbedIndexed; + boolean iccCannotEmbedRGB, iccCanEmbedRGB; + boolean iccCannotEmbedCMYK, iccCanEmbedCMYK; + fill bit[4]; + iccFlagsEnd: + align long; + + case FormatMaxSize: + longint = '8BIM'; + key longint = 'mxsz'; + longint = 0; + longint = 4; + Point; + + case FormatMaxChannels: + longint = '8BIM'; + key longint = 'mxch'; + longint = 0; + longint = $$CountOf(ChannelsSupported) * 2; + wide array ChannelsSupported { integer; } ; + align long; + + /* after effects specific PiPL atoms */ + + case AE_PiPL_Version: + longint = '8BIM'; + key longint = 'ePVR'; + longint = 0; + longint = 4; + integer; + integer; + + case AE_Effect_Spec_Version: + longint = '8BIM'; + key longint = 'eSVR'; + longint = 0; + longint = 4; + integer; + integer; + + + case AE_Effect_Version: + longint = '8BIM'; + key longint = 'eVER'; + longint = 0; + longint = 4; + longint; + + + case AE_Effect_Info_Flags: + longint = '8BIM'; + key longint = 'eINF'; + longint = 0; + longint = 2; + integer; + align long; +/* + case AE_Effect_Global_OutFlags: + longint = '8BIM'; + key longint = 'eGLO'; + longint = 0; +#if DeRez + fill long; +#else + longint = (gloEnd[$$ArrayIndex(properties)] - gloStart[$$ArrayIndex(properties)]) / 8; +#endif + gloStart: + fill bit[6]; + boolean noReserved4, reserved4; + boolean noReserved3, reserved3; + boolean noReserved2, reserved2; + boolean noReserved1, reserved1; + boolean noObsolete, obsolete; + boolean noAudio, audio; + boolean noShutterAngle, shutterAngle; + boolean noNopRender, nopRender; + boolean noRefreshUI, refreshUI; + boolean noCustomNtrp, customNtrp; + boolean noCustomUI, customUI; + boolean noNonSquareOnly, nonSquareOnly; + boolean noWorksInPlace, worksInPlace; + boolean noShrinkBuf, shrinkBuf; + boolean noWriteInput, writeInput; + boolean noPixIndep, pixIndep; + boolean noExpandBuf, expandBuf; + boolean noErrMsg, errMsg; + boolean noSendDialog, sendDialog; + boolean noOutputExtent, outputExtent; + boolean noDialog, dialog; + boolean noSeqFlatten, seqFlatten; + boolean noSendParamsUpdate, sendParamsUpdate; + boolean noRandomness, randomness; + boolean noWideTimeInput, wideTimeInput; + boolean noKeepRsrcOpen, keepRsrcOpen; + gloEnd: + align long; +*/ + case AE_Effect_Global_OutFlags: + longint = '8BIM'; + key longint = 'eGLO'; + longint = 0; + longint = 4; + longint; + + case AE_Effect_Global_OutFlags_2: + longint = '8BIM'; + key longint = 'eGL2'; + longint = 0; + longint = 4; + longint; + + case AE_Effect_Match_Name: + longint = '8BIM'; + key longint = 'eMNA'; + longint = 0; +#if DeRez + fill long; +#else + longint = (matchNameEnd[$$ArrayIndex(properties)] - matchNameStart[$$ArrayIndex(properties)]) / 8; +#endif + matchNameStart: + pstring; + matchNameEnd: + align long; + + case AE_ImageFormat_Extension_Info: + longint = '8BIM'; + key longint = 'FXMF'; + longint = 0; + longint = 16; + integer; /* major version */ + integer; /* minor version */ + fill bit[21]; + boolean hasOptions, hasNoOptions; + boolean sequentialOnly, nonSequentialOk; + boolean noInteractRequired, mustInteract; + boolean noInteractPut, hasInteractPut; + boolean noInteractGet, hasInteractGet; + boolean hasTime, hasNoTime; + boolean noVideo, hasVideo; + boolean noStill, still; + boolean noFile, hasFile; + boolean noOutput, output; + boolean noInput, input; + longint = 0; /* reserved */ + literal longint;/* signature */ + + + case AE_Reserved: + longint = '8BIM'; + key longint = 'aeRD'; + longint = 0; + longint = 4; + longint; + + case AE_Reserved_Info: + longint = '8BIM'; + key longint = 'aeFL'; + longint = 0; + longint = 4; + longint; + }; + }; + }; + + +#endif diff --git a/External/AE SDK/Resources/Mach-O_prefix.h b/External/AE SDK/Resources/Mach-O_prefix.h new file mode 100644 index 00000000..e5da3715 --- /dev/null +++ b/External/AE SDK/Resources/Mach-O_prefix.h @@ -0,0 +1 @@ +#define __MACH__ 1 \ No newline at end of file diff --git a/External/AE SDK/Resources/PiPLtool.exe b/External/AE SDK/Resources/PiPLtool.exe new file mode 100755 index 00000000..a50f04f6 --- /dev/null +++ b/External/AE SDK/Resources/PiPLtool.exe @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:6c4d33fe38e8b8bd99c4dc98f4bebcd2f486c016ae6d9259775060b2ef9fac05 +size 201216 diff --git a/External/AE SDK/Util/AEFX_ArbParseHelper.c b/External/AE SDK/Util/AEFX_ArbParseHelper.c new file mode 100644 index 00000000..29d75396 --- /dev/null +++ b/External/AE SDK/Util/AEFX_ArbParseHelper.c @@ -0,0 +1,174 @@ +// AEFX_ArbParseHelper.c +// + + + +#include "AEFX_ArbParseHelper.h" + +#include +#include +#include +#include +#include + +PF_Err +AEFX_AppendText( A_char *srcAC, /* >> */ + const A_u_long dest_sizeL, /* >> */ + A_char *destAC, /* <> */ + A_u_long *current_indexPLu) /* <> */ +{ + PF_Err err = PF_Err_NONE; + + A_u_long new_strlenLu = (A_u_long) strlen(srcAC) + *current_indexPLu; + + + if (new_strlenLu <= dest_sizeL) { + destAC[*current_indexPLu] = 0x00; + + strcat(destAC, srcAC); + *current_indexPLu = new_strlenLu; + } else { + err = AEFX_ParseError_APPEND_ERROR; + } + + return err; +} + + + + +PF_Err +AEFX_ParseCell( PF_InData *in_data, /* >> */ + PF_OutData *out_data, /* >> */ + const A_char *startPC, /* >> */ + A_u_long *current_indexPL, /* << */ + A_char *bufAC) /* << AEFX_CELL_SIZE */ +{ + (void)out_data; + (void)in_data; + + PF_Err err = PF_Err_NONE; + A_char c; + A_char buf[AEFX_CELL_SIZE]; + A_char *scan; + A_short count; + + if (startPC[*current_indexPL] == AEFX_Char_EOL) { + err = AEFX_ParseError_EXPECTING_MORE_DATA; + } else if (startPC[*current_indexPL] == 0) { + err = AEFX_ParseError_EXPECTING_MORE_DATA; + } else { + count = 0; + scan = buf; + while ((c = startPC[(*current_indexPL)++]) != 0) { + if (c == AEFX_Char_TAB) + break; + if (c == AEFX_Char_EOL) { + (*current_indexPL)--; + break; + } + + *scan++ = c; + + if (++count >= AEFX_CELL_SIZE) + break; + } + *scan = 0; + + // trim spaces from head + scan = buf; + while (isspace(*scan)) + scan++; + + strcpy(bufAC, scan); + + // trim spaces from end (guaranteed not to scan past start of string, because + // if the string were all spaces, it would be trimmed down to nothing in the + // head-trim step above + if (*bufAC) { + scan = bufAC + strlen(bufAC) - 1; + while (*scan == AEFX_Char_SPACE) { + *scan-- = 0; + } + } + } + + return err; + +} + + +/** AEFX_ParseFpLong + + Reads in the next cell in the input stream and converts it to a double. + The first non-space character must be numeric. + +**/ +PF_Err +AEFX_ParseFpLong( PF_InData *in_data, /* >> */ + PF_OutData *out_data, /* >> */ + const A_char *startPC, /* >> */ + A_u_long *current_indexPL, /* << */ + PF_FpLong *dPF) /* << */ +{ + PF_Err err = PF_Err_NONE; + A_char c; + A_char *end_ptr; + A_char buf[AEFX_CELL_SIZE]; + + err = AEFX_ParseCell(in_data, out_data, startPC, current_indexPL, buf); + + if (!err) { + c = buf[0]; + + if (!isdigit(c) && c != '.' && c != '-') { + err = AEFX_ParseError_EXPECTING_A_NUMBER; + } else { + errno = 0; + *dPF = strtod(buf, &end_ptr); + } + } + + return err; +} + + + +PF_Err +AEFX_MatchCell( PF_InData *in_data, /* >> */ + PF_OutData *out_data, /* >> */ + const A_char *strPC, /* >> */ + const A_char *startPC, /* >> */ + A_u_long *current_indexPL, /* << */ + PF_Boolean *matchPB0) /* << */ +{ + PF_Err err = PF_Err_NONE; + A_char buf[AEFX_CELL_SIZE]; + A_u_long origLu = *current_indexPL; + PF_Boolean found = 0; + + if (startPC[*current_indexPL] == AEFX_Char_EOL) { + found = 0; + err = AEFX_ParseError_EXPECTING_MORE_DATA; + } else { + err = AEFX_ParseCell(in_data, out_data, startPC, current_indexPL, buf); + + if (!err) { + found = STR_EQUAL(buf, strPC); + + if (!found) + *current_indexPL = origLu; + } + } + + if (!err && !found && matchPB0 == NULL) { + err = AEFX_ParseError_MATCH_ERROR; + } + + if (matchPB0) + *matchPB0 = found; + + return err; +} + + diff --git a/External/AE SDK/Util/AEFX_ArbParseHelper.h b/External/AE SDK/Util/AEFX_ArbParseHelper.h new file mode 100644 index 00000000..fa79fa3e --- /dev/null +++ b/External/AE SDK/Util/AEFX_ArbParseHelper.h @@ -0,0 +1,75 @@ +// AEFX_ArbParseHelper.h +// + +// This file has no header, and is designed to by #included as necessary. -jja 9/30/98 + + +#ifndef _H_AEFX_ArbParseHelper +#define _H_AEFX_ArbParseHelper + +#include + +#define AEFX_Char_TAB '\t' +#define AEFX_Char_EOL '\r' +#define AEFX_Char_SPACE ' ' + +#ifndef AEFX_CELL_SIZE +#define AEFX_CELL_SIZE 256 +#endif + +#ifdef __cplusplus +extern "C" { +#endif + + +enum { + AEFX_ParseError_EXPECTING_MORE_DATA = 0x00FEBE00, + AEFX_ParseError_APPEND_ERROR, + AEFX_ParseError_EXPECTING_A_NUMBER, + AEFX_ParseError_MATCH_ERROR +}; +typedef A_long AEFX_ParseErrors; + + + +#ifndef STR_EQUAL + #define STR_EQUAL(A, B) (strcmp((A),(B)) == 0) +#endif + + +PF_Err +AEFX_AppendText( A_char *srcAC, /* >> */ + const A_u_long dest_sizeL, /* >> */ + A_char *destAC, /* <> */ + A_u_long *current_indexPLu); /* <> */ + + +PF_Err +AEFX_ParseFpLong( PF_InData *in_data, /* >> */ + PF_OutData *out_data, /* >> */ + const A_char *startPC, /* >> */ + A_u_long *current_indexPL, /* << */ + PF_FpLong *dPF); /* << */ + + +PF_Err +AEFX_MatchCell( PF_InData *in_data, /* >> */ + PF_OutData *out_data, /* >> */ + const A_char *strPC, /* >> */ + const A_char *startPC, /* >> */ + A_u_long *current_indexPL, /* << */ + PF_Boolean *matchPB0); /* << */ + +PF_Err +AEFX_ParseCell( PF_InData *in_data, /* >> */ + PF_OutData *out_data, /* >> */ + const A_char *startPC, /* >> */ + A_u_long *current_indexPL, /* << */ + A_char *bufAC); /* << AEFX_CELL_SIZE */ + + +#ifdef __cplusplus +} // extern "C" +#endif + +#endif diff --git a/External/AE SDK/Util/AEFX_ChannelDepthTpl.h b/External/AE SDK/Util/AEFX_ChannelDepthTpl.h new file mode 100644 index 00000000..55c0546d --- /dev/null +++ b/External/AE SDK/Util/AEFX_ChannelDepthTpl.h @@ -0,0 +1,59 @@ +#ifndef _H_AEFX_CHANNELDEPTHTPL +#define _H_AEFX_CHANNELDEPTHTPL + +/** AEFX_ChannelDepthTpl.h + + (c) 2005 Adobe Systems Incorporated + +**/ + +// Basic pixel traits structure. This structure is never used per se, merely overidden -- see below. +template +struct PixelTraits { + typedef int PixType; + typedef int DataType; + static DataType + LutFunc(DataType input, const DataType *map); + + enum {max_value = 0 }; +}; + + +// 8 bit pixel types, constants, and functions +template <> +struct PixelTraits{ + typedef PF_Pixel8 PixType; + typedef u_char DataType; + static DataType + LutFunc(DataType input, const DataType *map){return map[input];} + enum {max_value = PF_MAX_CHAN8}; +}; + +// 16 bit pixel types, constants, and functions +template <> +struct PixelTraits{ + typedef PF_Pixel16 PixType; + typedef u_short DataType; + static u_short + LutFunc(u_short input, const u_short *map); + enum {max_value = PF_MAX_CHAN16}; +}; + + +inline u_short +PixelTraits::LutFunc(u_short input, + const u_short *map) +{ + u_short index = input >> (15 - PF_TABLE_BITS); + uint32_t fract = input & ((1 << (15 - PF_TABLE_BITS)) - 1); + A_long result = map [index]; + + if (fract) { + result += ((((A_long) map [index + 1] - result) * fract) + + (1 << (14 - PF_TABLE_BITS))) >> (15 - PF_TABLE_BITS); + } + return (u_short) result; + +} + +#endif //_H_AEFX_CHANNELDEPTHTPL \ No newline at end of file diff --git a/External/AE SDK/Util/AEFX_SuiteHelper.c b/External/AE SDK/Util/AEFX_SuiteHelper.c new file mode 100644 index 00000000..9ddd9b2a --- /dev/null +++ b/External/AE SDK/Util/AEFX_SuiteHelper.c @@ -0,0 +1,139 @@ +/************************************************************************** +* +* ADOBE CONFIDENTIAL +* ___________________ +* +* Copyright 2009 Adobe Systems Incorporated +* All Rights Reserved. +* +* NOTICE: All information contained herein is, and remains the property of +* Adobe Systems Incorporated and its suppliers, if any. The intellectual +* and technical concepts contained herein are proprietary to Adobe Systems +* Incorporated and its suppliers and may be covered by U.S. and Foreign +* Patents,patents in process,and are protected by trade secret or copyright +* law. Dissemination of this information or reproduction of this material +* is strictly forbidden unless prior written permission is obtained from +* Adobe Systems Incorporated. +**************************************************************************/ + + +/** AEFX_SuiteHelper.c + + Contains helper routines for acquiring/releasing suites. + +**/ + +#include "AEFX_SuiteHelper.h" +#include + +PF_Err AEFX_AcquireSuite( PF_InData *in_data, /* >> */ + PF_OutData *out_data, /* >> */ + const char *name, /* >> */ + int32_t version, /* >> */ + const char *error_stringPC0, /* >> */ + void **suite) /* << */ +{ + PF_Err err = PF_Err_NONE; + SPBasicSuite *bsuite; + + bsuite = in_data->pica_basicP; + + if (bsuite) { + (*bsuite->AcquireSuite)((char*)name, version, (const void**)suite); + + if (!*suite) { + err = PF_Err_BAD_CALLBACK_PARAM; + } + } else { + err = PF_Err_BAD_CALLBACK_PARAM; + } + + if (err) { + const char *error_stringPC = error_stringPC0 ? error_stringPC0 : "Not able to acquire AEFX Suite."; + + out_data->out_flags |= PF_OutFlag_DISPLAY_ERROR_MESSAGE; + + PF_SPRINTF(out_data->return_msg, error_stringPC); + } + + return err; +} + + + +PF_Err AEFX_ReleaseSuite( PF_InData *in_data, /* >> */ + PF_OutData *out_data, /* >> */ + const char *name, /* >> */ + int32_t version, /* >> */ + const char *error_stringPC0) /* >> */ +{ + PF_Err err = PF_Err_NONE; + SPBasicSuite *bsuite; + + bsuite = in_data->pica_basicP; + + if (bsuite) { + (*bsuite->ReleaseSuite)((char*)name, version); + } else { + err = PF_Err_BAD_CALLBACK_PARAM; + } + + if (err) { + const char *error_stringPC = error_stringPC0 ? error_stringPC0 : "Not able to release AEFX Suite."; + + out_data->out_flags |= PF_OutFlag_DISPLAY_ERROR_MESSAGE; + + PF_SPRINTF(out_data->return_msg, error_stringPC); + } + + return err; +} + + +PF_Err AEFX_AcquireDrawbotSuites( PF_InData *in_data, /* >> */ + PF_OutData *out_data, /* >> */ + DRAWBOT_Suites *suitesP) /* << */ +{ + PF_Err err = PF_Err_NONE; + + if (suitesP == NULL) { + out_data->out_flags |= PF_OutFlag_DISPLAY_ERROR_MESSAGE; + + PF_SPRINTF(out_data->return_msg, "NULL suite pointer passed to AEFX_AcquireDrawbotSuites"); + + err = PF_Err_UNRECOGNIZED_PARAM_TYPE; + } + + if (!err) { + err = AEFX_AcquireSuite(in_data, out_data, kDRAWBOT_DrawSuite, kDRAWBOT_DrawSuite_VersionCurrent, NULL, (void **)&suitesP->drawbot_suiteP); + } + if (!err) { + err = AEFX_AcquireSuite(in_data, out_data, kDRAWBOT_SupplierSuite, kDRAWBOT_SupplierSuite_VersionCurrent, NULL, (void **)&suitesP->supplier_suiteP); + } + if (!err) { + err = AEFX_AcquireSuite(in_data, out_data, kDRAWBOT_SurfaceSuite, kDRAWBOT_SurfaceSuite_VersionCurrent, NULL, (void **)&suitesP->surface_suiteP); + } + if (!err) { + err = AEFX_AcquireSuite(in_data, out_data, kDRAWBOT_PathSuite, kDRAWBOT_PathSuite_VersionCurrent, NULL, (void **)&suitesP->path_suiteP); + } + + return err; +} + + +PF_Err AEFX_ReleaseDrawbotSuites( PF_InData *in_data, /* >> */ + PF_OutData *out_data) /* >> */ +{ + PF_Err err = PF_Err_NONE; + + AEFX_ReleaseSuite(in_data, out_data, kDRAWBOT_DrawSuite, kDRAWBOT_DrawSuite_VersionCurrent, NULL); + AEFX_ReleaseSuite(in_data, out_data, kDRAWBOT_SupplierSuite, kDRAWBOT_SupplierSuite_VersionCurrent, NULL); + AEFX_ReleaseSuite(in_data, out_data, kDRAWBOT_SurfaceSuite, kDRAWBOT_SurfaceSuite_VersionCurrent, NULL); + AEFX_ReleaseSuite(in_data, out_data, kDRAWBOT_PathSuite, kDRAWBOT_PathSuite_VersionCurrent, NULL); + + return err; +} + + + + diff --git a/External/AE SDK/Util/AEFX_SuiteHelper.h b/External/AE SDK/Util/AEFX_SuiteHelper.h new file mode 100644 index 00000000..2ede44c8 --- /dev/null +++ b/External/AE SDK/Util/AEFX_SuiteHelper.h @@ -0,0 +1,157 @@ +/************************************************************************** +* +* ADOBE CONFIDENTIAL +* ___________________ +* +* Copyright 2009 Adobe Systems Incorporated +* All Rights Reserved. +* +* NOTICE: All information contained herein is, and remains the property of +* Adobe Systems Incorporated and its suppliers, if any. The intellectual +* and technical concepts contained herein are proprietary to Adobe Systems +* Incorporated and its suppliers and may be covered by U.S. and Foreign +* Patents,patents in process,and are protected by trade secret or copyright +* law. Dissemination of this information or reproduction of this material +* is strictly forbidden unless prior written permission is obtained from +* Adobe Systems Incorporated. +**************************************************************************/ + +#ifndef AEFX_SUITE_HELPER_H +#define AEFX_SUITE_HELPER_H + + +/** AEFX_SuiteHelper.h + + Contains helper routines for acquiring/releasing suites. + + NOTE: If you're writing C++ plug-ins that support exceptions, use the AEGP_SuiteHandler class or AEFX_SuiteScoper. + +**/ + +#include +#include +#include +#include + + + +#ifdef __cplusplus + extern "C" { +#endif + +PF_Err AEFX_AcquireSuite( PF_InData *in_data, /* >> */ + PF_OutData *out_data, /* >> */ + const char *name, /* >> */ + int32_t version, /* >> */ + const char *error_stringPC0, /* >> */ + void **suite); /* << */ + + +PF_Err AEFX_ReleaseSuite( PF_InData *in_data, /* >> */ + PF_OutData *out_data, /* >> */ + const char *name, /* >> */ + int32_t version, /* >> */ + const char *error_stringPC0); /* >> */ + + +PF_Err AEFX_AcquireDrawbotSuites( PF_InData *in_data, /* >> */ + PF_OutData *out_data, /* >> */ + DRAWBOT_Suites *suiteP); /* << */ + + +PF_Err AEFX_ReleaseDrawbotSuites( PF_InData *in_data, /* >> */ + PF_OutData *out_data); /* >> */ + + +#ifdef __cplusplus + } +#endif + + +#ifdef __cplusplus + + template + class AEFX_SuiteHelperT + { + public: + AEFX_SuiteHelperT( PF_InData *in_data, /* >> */ + PF_OutData *out_data, /* >> */ + const char *name, /* >> */ + int32_t version) : /* >> */ + mInDataP(in_data), mOutDataP(out_data), mSuiteName(name), mSuiteVersion(version), mSuiteP(NULL) + { + void *suiteP(NULL); + + PF_Err err = AEFX_AcquireSuite(mInDataP, mOutDataP, mSuiteName, mSuiteVersion, NULL, &suiteP); + + if (err) { + A_THROW(err); + } + + mSuiteP = reinterpret_cast(suiteP); + } + + ~AEFX_SuiteHelperT() + { + (void)AEFX_ReleaseSuite(mInDataP, mOutDataP, mSuiteName, mSuiteVersion, NULL); + } + + const SuiteType* operator->() const + { + return mSuiteP; + } + + SuiteType* get() const + { + return mSuiteP; + } + + private: + + PF_InData *mInDataP; + PF_OutData *mOutDataP; + const char *mSuiteName; + int32_t mSuiteVersion; + SuiteType *mSuiteP; + }; + + + +// clients of this class probably should just be using the regular template +// instead + +class AEFX_DrawbotSuitesScoper +{ +public: + AEFX_DrawbotSuitesScoper(PF_InData *in_data, PF_OutData *out_data) + : + i_in_data(in_data), + i_out_data(out_data) + { + PF_Err err = AEFX_AcquireDrawbotSuites(in_data, out_data, &i_suites); + + if (err) { + A_THROW(err); + } + } + + inline DRAWBOT_Suites* Get() + { + return &i_suites; + } + + ~AEFX_DrawbotSuitesScoper() + { + AEFX_ReleaseDrawbotSuites(i_in_data, i_out_data); + } + +private: + DRAWBOT_Suites i_suites; + PF_InData *i_in_data; + PF_OutData *i_out_data; +}; + +#endif + + +#endif // AEFX_SUITE_HELPER_H diff --git a/External/AE SDK/Util/AEGP_SuiteHandler.cpp b/External/AE SDK/Util/AEGP_SuiteHandler.cpp new file mode 100644 index 00000000..146a5f5e --- /dev/null +++ b/External/AE SDK/Util/AEGP_SuiteHandler.cpp @@ -0,0 +1,66 @@ +/*******************************************************************/ +/* */ +/* ADOBE CONFIDENTIAL */ +/* _ _ _ _ _ _ _ _ _ _ _ _ _ */ +/* */ +/* Copyright 2007 Adobe Systems Incorporated */ +/* All Rights Reserved. */ +/* */ +/* NOTICE: All information contained herein is, and remains the */ +/* property of Adobe Systems Incorporated and its suppliers, if */ +/* any. The intellectual and technical concepts contained */ +/* herein are proprietary to Adobe Systems Incorporated and its */ +/* suppliers and may be covered by U.S. and Foreign Patents, */ +/* patents in process, and are protected by trade secret or */ +/* copyright law. Dissemination of this information or */ +/* reproduction of this material is strictly forbidden unless */ +/* prior written permission is obtained from Adobe Systems */ +/* Incorporated. */ +/* */ +/*******************************************************************/ + +/** AEGP_SuiteHandler.cpp + + Implementation of AEGP_SuiteHandler non-inlines. See AEGP_SuiteHandler.h for usage. + + created 9/11/2000 jms +**/ + + +#include +#include + +AEGP_SuiteHandler::AEGP_SuiteHandler(const SPBasicSuite *pica_basicP) : + i_pica_basicP(pica_basicP) +{ + AEFX_CLR_STRUCT(i_suites); + + if (!i_pica_basicP) { //can't construct w/out basic suite, everything else is demand loaded + MissingSuiteError(); + } +} + +AEGP_SuiteHandler::~AEGP_SuiteHandler() +{ + ReleaseAllSuites(); +} + +// Had to go to the header file to be inlined to please CW mach-o target +/*void *AEGP_SuiteHandler::pLoadSuite(A_char *nameZ, A_long versionL) const +{ + const void *suiteP; + A_long err = i_pica_basicP->AcquireSuite(nameZ, versionL, &suiteP); + + if (err || !suiteP) { + MissingSuiteError(); + } + + return (void*)suiteP; +}*/ + +// Free a particular suite. Ignore errors, because, what is there to be done if release fails? +void AEGP_SuiteHandler::ReleaseSuite(const A_char *nameZ, A_long versionL) +{ + i_pica_basicP->ReleaseSuite(nameZ, versionL); +} + diff --git a/External/AE SDK/Util/AEGP_SuiteHandler.h b/External/AE SDK/Util/AEGP_SuiteHandler.h new file mode 100644 index 00000000..59bc043b --- /dev/null +++ b/External/AE SDK/Util/AEGP_SuiteHandler.h @@ -0,0 +1,601 @@ +/*******************************************************************/ +/* */ +/* ADOBE CONFIDENTIAL */ +/* _ _ _ _ _ _ _ _ _ _ _ _ _ */ +/* */ +/* Copyright 2007 Adobe Systems Incorporated */ +/* All Rights Reserved. */ +/* */ +/* NOTICE: All information contained herein is, and remains the */ +/* property of Adobe Systems Incorporated and its suppliers, if */ +/* any. The intellectual and technical concepts contained */ +/* herein are proprietary to Adobe Systems Incorporated and its */ +/* suppliers and may be covered by U.S. and Foreign Patents, */ +/* patents in process, and are protected by trade secret or */ +/* copyright law. Dissemination of this information or */ +/* reproduction of this material is strictly forbidden unless */ +/* prior written permission is obtained from Adobe Systems */ +/* Incorporated. */ +/* */ +/*******************************************************************/ + + + +/** AEGP_SuiteHandler.h + + DEPRECATED: + This way of doing things is out of date. See AEFX_SuiteHandlerTemplate.h for the + new way of doing things. + + -kjw 2/28/2014 + + A very helpful class that manages demand loading and automatic, exception-safe freeing + of AEGP suites. + + USAGE INSTRUCTIONS: + + The accompanying file, AEGP_SuiteHandler.cpp, is designed to be compiled right into + the client application or plug-in. + + You'll get a link error. + + This is because AEGP_SuiteHandler.cpp lacks a definition for the MissingSuiteError() + method. You must provide one to define the error handling behaviour of the class. + This function may or may not display an error message etc. but it must end + by throwing an exception. It cannot return. + + Other than that, usage is pretty trivial. Construct with a pointer to the PICA + basic suite, and then call the public method to obtain lazily loaded pointers + to other AEGP suites. Upon desctruction, all loaded suites are freed (so this class + is really handy for writing exception-safe AEGP code.) + + NOTE!!! If you need to upgrade a suite, DO NOT SIMPLY UPDATE THE VERSION NUMBER. + You should: + 1. Add a new member to the Suites structure for that suite. + 2. Add the boiler plate macro to release the suite in ReleaseAllSuites (AEGP_SUITE_RELEASE_BOILERPLATE). + 3. Add the boiler plate macro to define the suite. (AEGP_SUITE_ACCESS_BOILERPLATE) + + If you have any questions, ask me. -jja 5/7/2004 + + If you'll be using ADM suites, #define I_NEED_ADM_SUPPORT before #including AEGP_SuiteHandler.h. + + -bbb 9/16/2004 +**/ + +#ifndef _H_AEGP_SUITEHANDLER +#define _H_AEGP_SUITEHANDLER + +#include +#include +#include +#include +#include +#include +#include + +#ifdef I_NEED_ADM_SUPPORT +#include +#include +#include +#include +#include +#include +#include +#endif + +// Suite registration and handling object +class AEGP_SuiteHandler { + +private: + // forbid copy construct + AEGP_SuiteHandler(const AEGP_SuiteHandler&) {} + AEGP_SuiteHandler& operator=(const AEGP_SuiteHandler&) { return *this; } + + // basic suite pointer + const SPBasicSuite *i_pica_basicP; + + // Suites we can register. These are mutable because they are demand loaded using a const object. + + struct Suites { + AEGP_KeyframeSuite4 *keyframe_suite4P; + AEGP_StreamSuite3 *stream_suite3P; + AEGP_StreamSuite4 *stream_suite4P; + AEGP_StreamSuite5 *stream_suite5P; + AEGP_MarkerSuite1 *marker_suite1P; + AEGP_MarkerSuite2 *marker_suite2P; + AEGP_MarkerSuite3 *marker_suite3P; + AEGP_CompSuite4 *comp_suite4P; + AEGP_CompSuite5 *comp_suite5P; + AEGP_CompSuite6 *comp_suite6P; + AEGP_CompSuite7 *comp_suite7P; + AEGP_CompSuite8 *comp_suite8P; + AEGP_CompSuite9 *comp_suite9P; + AEGP_CompSuite10 *comp_suite10P; + AEGP_CompSuite11 *comp_suite11P; + AEGP_LayerSuite3 *layer_suite3P; + AEGP_LayerSuite4 *layer_suite4P; + AEGP_StreamSuite2 *stream_suite2P; + AEGP_DynamicStreamSuite2 *dynamic_stream_suite2P; + AEGP_DynamicStreamSuite3 *dynamic_stream_suite3P; + AEGP_DynamicStreamSuite4 *dynamic_stream_suite4P; + AEGP_KeyframeSuite3 *keyframe_suite3P; + AEGP_CanvasSuite5 *canvas_suite5P; + AEGP_CanvasSuite6 *canvas_suite6P; + AEGP_CanvasSuite7 *canvas_suite7P; + AEGP_CanvasSuite8 *canvas_suite8P; + AEGP_CameraSuite2 *camera_suite2P; + AEGP_RegisterSuite5 *register_suite5P; + AEGP_MemorySuite1 *memory_suite1P; + AEGP_ItemViewSuite1 *item_view_suite1P; + AEGP_ItemSuite9 *item_suite9P; + AEGP_ItemSuite8 *item_suite8P; + AEGP_ItemSuite7 *item_suite7P; + AEGP_ItemSuite6 *item_suite6P; + AEGP_ItemSuite5 *item_suite5P; + AEGP_ItemSuite1 *item_suite1P; + AEGP_LightSuite1 *light_suite1P; + AEGP_LightSuite2 *light_suite2P; + AEGP_EffectSuite1 *effect_suite1P; + AEGP_EffectSuite2 *effect_suite2P; + AEGP_EffectSuite3 *effect_suite3P; + AEGP_EffectSuite4 *effect_suite4P; + AEGP_MaskSuite4 *mask_suite4P; + AEGP_MaskOutlineSuite1 *mask_outline_suite1P; + AEGP_MaskOutlineSuite2 *mask_outline_suite2P; + AEGP_MaskOutlineSuite3 *mask_outline_suite3P; + AEGP_CommandSuite1 *command_suite1P; + AEGP_UtilitySuite3 *utility_suite3P; + AEGP_RenderSuite1 *render_suite1P; + AEGP_RenderSuite2 *render_suite2P; + AEGP_RenderSuite3 *render_suite3P; + AEGP_RenderSuite4 *render_suite4P; + AEGP_RenderSuite5 *render_suite5P; + PF_ANSICallbacksSuite1 *ansi_callbacks_suite1P; + PF_HandleSuite1 *handle_suite1P; + PF_FillMatteSuite2 *fill_matte_suite2P; + PF_WorldTransformSuite1 *world_transform_suite1P; + AEGP_QueryXformSuite2 *query_xform_suite2P; + AEGP_CompositeSuite2 *composite_suite2P; + PF_WorldSuite1 *world_suite1P; + AEGP_PFInterfaceSuite1 *pf_interface_suite1P; + AEGP_MathSuite1 *math_suite1P; + PF_AdvTimeSuite4 *adv_time_suite4P; + PF_PathQuerySuite1 *path_query_suite1P; + PF_PathDataSuite1 *path_data_suite1P; + PF_ParamUtilsSuite3 *param_utils_suite3P; + PFAppSuite4 *app_suite4P; + PFAppSuite5 *app_suite5P; + PFAppSuite6 *app_suite6P; + PF_AdvAppSuite2 *adv_app_suite2P; + AEGP_IOInSuite4 *io_in_suite4P; + AEGP_IOOutSuite4 *io_out_suite4P; + AEGP_PersistentDataSuite3 *persistent_data_suite3P; + AEGP_PersistentDataSuite4 *persistent_data_suite4P; + AEGP_RenderQueueSuite1 *render_queue_suite1P; + AEGP_RQItemSuite2 *rq_item_suite2P; + AEGP_OutputModuleSuite4 *output_module_suite4P; + AEGP_FIMSuite3 *fim_suite3P; + PF_Sampling8Suite1 *sampling_8_suite1P; + PF_Sampling16Suite1 *sampling_16_suite1P; + PF_Iterate8Suite1 *iterate_8_suite1P; + PF_iterate16Suite1 *iterate_16_suite1P; + PF_iterateFloatSuite1 *iterate_float_suite1P; + PF_Iterate8Suite2 *iterate_8_suite2P; + PF_iterate16Suite2 *iterate_16_suite2P; + PF_iterateFloatSuite2 *iterate_float_suite2P; + AEGP_CollectionSuite2 *collection_suite2P; + AEGP_TextDocumentSuite1 *text_document_suite1P; + AEGP_SoundDataSuite1 *sound_data_suite1P; + AEGP_IterateSuite1 *aegp_iterate_suite1P; + AEGP_IterateSuite2 *aegp_iterate_suite2P; + AEGP_TextLayerSuite1 *text_layer_suite1P; + AEGP_ArtisanUtilSuite1 *artisan_util_suite1P; + AEGP_WorldSuite2 *aegp_world_suite_2P; + AEGP_WorldSuite3 *aegp_world_suite_3P; + AEGP_RenderOptionsSuite1 *render_options_suite_1P; + AEGP_LayerRenderOptionsSuite1 *layer_render_options_suite_1P; + AEGP_LayerRenderOptionsSuite2 *layer_render_options_suite_2P; + AEGP_RenderAsyncManagerSuite1 *async_manager_suite_1P; + AEGP_TrackerSuite1 *tracker_suite_1P; + AEGP_TrackerUtilitySuite1 *tracker_utility_suite_1P; + PF_HelperSuite2 *helper_suite_2P; + AEGP_LayerSuite5 *layer_suite_5P; + AEGP_LayerSuite6 *layer_suite_6P; + AEGP_LayerSuite7 *layer_suite_7P; + AEGP_LayerSuite8 *layer_suite_8P; + +#ifdef I_NEED_ADM_SUPPORT + ADMBasicSuite8 *adm_basic_suite_8P; + ADMDialogSuite8 *adm_dialog_suite_8P; + ADMDialogGroupSuite3 *adm_dialog_group_suite_3P; + ADMItemSuite8 *adm_item_suite_8P; + ADMListSuite3 *adm_list_suite_3P; + ADMEntrySuite5 *adm_entry_suite_5P; + ADMNotifierSuite2 *adm_notifier_suite_2P; +#endif + AEGP_LayerSuite1 *layer_suite_1P; + AEGP_MaskSuite1 *mask_suite_1P; + AEGP_MaskSuite5 *mask_suite_5P; + AEGP_MaskSuite6 *mask_suite_6P; + AEGP_StreamSuite1 *stream_suite_1P; + AEGP_CompSuite1 *comp_suite_1P; + AEGP_CollectionSuite1 *collection_suite_1P; + AEGP_KeyframeSuite1 *keyframe_suite_1P; + PF_AdvAppSuite1 *adv_app_suite_1P; + AEGP_UtilitySuite1 *utility_suite_1P; + AEGP_RenderOptionsSuite2 *render_options_suite_2P; + AEGP_ProjSuite5 *proj_suite_5P; + AEGP_ProjSuite6 *proj_suite_6P; + AEGP_FootageSuite5 *footage_suite_5P; + AEGP_RQItemSuite3 *rq_item_suite_3P; + AEGP_UtilitySuite4 *utility_suite_4P; + AEGP_ColorSettingsSuite3 *color_settings_suite_3P; + AEGP_ColorSettingsSuite2 *color_settings_suite_2P; + AEGP_ColorSettingsSuite1 *color_settings_suite_1P; + PF_AdvItemSuite1 *adv_item_suite_1P; + AEGP_RenderOptionsSuite3 *render_options_suite_3P; + PF_ColorParamSuite1 *color_param_suite_1P; + PF_SamplingFloatSuite1 *sampling_float_suite_1P; + AEGP_UtilitySuite5 *utility_suite_5P; + AEGP_UtilitySuite6 *utility_suite_6P; + PF_EffectCustomUISuite1 *custom_ui_suite1P; + PF_EffectCustomUISuite2 *custom_ui_suite2P; + PF_EffectCustomUIOverlayThemeSuite1 *custom_ui_theme_suite1P; + + //Drawbot Suites + DRAWBOT_DrawbotSuiteCurrent *drawing_suite_currentP; + DRAWBOT_SupplierSuiteCurrent *drawbot_supplier_suite_currentP; + DRAWBOT_SurfaceSuiteCurrent *drawbot_surface_suite_currentP; + DRAWBOT_PathSuiteCurrent *drawbot_path_suite_currentP; + + SPSuitesSuite *suites_suite_2P; + }; + + mutable Suites i_suites; + + // private methods + // I had to make this inline by moving the definition from the .cpp file + // CW mach-o target was freaking otherwise when seeing the call to this + // function in inlined public suite accessors below + + void *LoadSuite(const A_char *nameZ, A_long versionL) const + { + const void *suiteP; + A_long err = i_pica_basicP->AcquireSuite(nameZ, versionL, &suiteP); + + if (err || !suiteP) { + MissingSuiteError(); + } + + return (void*)suiteP; + } + + void ReleaseSuite(const A_char *nameZ, A_long versionL); + void ReleaseAllSuites() + { + #define AEGP_SUITE_RELEASE_BOILERPLATE(MEMBER_NAME, kSUITE_NAME, kVERSION_NAME) \ + if (i_suites.MEMBER_NAME) { \ + ReleaseSuite(kSUITE_NAME, kVERSION_NAME); \ + } + + AEGP_SUITE_RELEASE_BOILERPLATE(marker_suite1P, kAEGPMarkerSuite, kAEGPMarkerSuiteVersion1); + AEGP_SUITE_RELEASE_BOILERPLATE(marker_suite2P, kAEGPMarkerSuite, kAEGPMarkerSuiteVersion2); + AEGP_SUITE_RELEASE_BOILERPLATE(marker_suite3P, kAEGPMarkerSuite, kAEGPMarkerSuiteVersion3); + AEGP_SUITE_RELEASE_BOILERPLATE(layer_suite3P, kAEGPLayerSuite, kAEGPLayerSuiteVersion3); + AEGP_SUITE_RELEASE_BOILERPLATE(layer_suite4P, kAEGPLayerSuite, kAEGPLayerSuiteVersion4); + AEGP_SUITE_RELEASE_BOILERPLATE(stream_suite5P, kAEGPStreamSuite, kAEGPStreamSuiteVersion5); + AEGP_SUITE_RELEASE_BOILERPLATE(stream_suite4P, kAEGPStreamSuite, kAEGPStreamSuiteVersion4); + AEGP_SUITE_RELEASE_BOILERPLATE(stream_suite3P, kAEGPStreamSuite, kAEGPStreamSuiteVersion3); + AEGP_SUITE_RELEASE_BOILERPLATE(stream_suite2P, kAEGPStreamSuite, kAEGPStreamSuiteVersion2); + AEGP_SUITE_RELEASE_BOILERPLATE(stream_suite_1P, kAEGPStreamSuite, kAEGPStreamSuiteVersion1); + AEGP_SUITE_RELEASE_BOILERPLATE(dynamic_stream_suite2P, kAEGPDynamicStreamSuite, kAEGPDynamicStreamSuiteVersion2); + AEGP_SUITE_RELEASE_BOILERPLATE(dynamic_stream_suite3P, kAEGPDynamicStreamSuite, kAEGPDynamicStreamSuiteVersion3); + AEGP_SUITE_RELEASE_BOILERPLATE(dynamic_stream_suite4P, kAEGPDynamicStreamSuite, kAEGPDynamicStreamSuiteVersion4); + AEGP_SUITE_RELEASE_BOILERPLATE(keyframe_suite4P, kAEGPKeyframeSuite, kAEGPKeyframeSuiteVersion4); + AEGP_SUITE_RELEASE_BOILERPLATE(keyframe_suite3P, kAEGPKeyframeSuite, kAEGPKeyframeSuiteVersion3); + AEGP_SUITE_RELEASE_BOILERPLATE(keyframe_suite_1P, kAEGPKeyframeSuite, kAEGPKeyframeSuiteVersion1); + AEGP_SUITE_RELEASE_BOILERPLATE(comp_suite4P, kAEGPCompSuite, kAEGPCompSuiteVersion4); + AEGP_SUITE_RELEASE_BOILERPLATE(comp_suite5P, kAEGPCompSuite, kAEGPCompSuiteVersion5); + AEGP_SUITE_RELEASE_BOILERPLATE(comp_suite6P, kAEGPCompSuite, kAEGPCompSuiteVersion6); + AEGP_SUITE_RELEASE_BOILERPLATE(comp_suite7P, kAEGPCompSuite, kAEGPCompSuiteVersion7); + AEGP_SUITE_RELEASE_BOILERPLATE(comp_suite8P, kAEGPCompSuite, kAEGPCompSuiteVersion8); + AEGP_SUITE_RELEASE_BOILERPLATE(comp_suite9P, kAEGPCompSuite, kAEGPCompSuiteVersion9); + AEGP_SUITE_RELEASE_BOILERPLATE(comp_suite10P, kAEGPCompSuite, kAEGPCompSuiteVersion10); + AEGP_SUITE_RELEASE_BOILERPLATE(comp_suite11P, kAEGPCompSuite, kAEGPCompSuiteVersion11); + AEGP_SUITE_RELEASE_BOILERPLATE(canvas_suite5P, kAEGPCanvasSuite, kAEGPCanvasSuiteVersion5); + AEGP_SUITE_RELEASE_BOILERPLATE(canvas_suite6P, kAEGPCanvasSuite, kAEGPCanvasSuiteVersion6); + AEGP_SUITE_RELEASE_BOILERPLATE(canvas_suite7P, kAEGPCanvasSuite, kAEGPCanvasSuiteVersion7); + AEGP_SUITE_RELEASE_BOILERPLATE(canvas_suite8P, kAEGPCanvasSuite, kAEGPCanvasSuiteVersion8); + AEGP_SUITE_RELEASE_BOILERPLATE(camera_suite2P, kAEGPCameraSuite, kAEGPCameraSuiteVersion2); + AEGP_SUITE_RELEASE_BOILERPLATE(register_suite5P, kAEGPRegisterSuite, kAEGPRegisterSuiteVersion5); + AEGP_SUITE_RELEASE_BOILERPLATE(item_view_suite1P, kAEGPItemViewSuite, kAEGPItemViewSuiteVersion1); + AEGP_SUITE_RELEASE_BOILERPLATE(item_suite8P, kAEGPItemSuite, kAEGPItemSuiteVersion8); + AEGP_SUITE_RELEASE_BOILERPLATE(item_suite7P, kAEGPItemSuite, kAEGPItemSuiteVersion7); + AEGP_SUITE_RELEASE_BOILERPLATE(item_suite6P, kAEGPItemSuite, kAEGPItemSuiteVersion6); + AEGP_SUITE_RELEASE_BOILERPLATE(item_suite5P, kAEGPItemSuite, kAEGPItemSuiteVersion5); + AEGP_SUITE_RELEASE_BOILERPLATE(item_suite1P, kAEGPItemSuite, kAEGPItemSuiteVersion1); + AEGP_SUITE_RELEASE_BOILERPLATE(pf_interface_suite1P, kAEGPPFInterfaceSuite, kAEGPPFInterfaceSuiteVersion1); + AEGP_SUITE_RELEASE_BOILERPLATE(math_suite1P, kAEGPMathSuite, kAEGPMathSuiteVersion1); + AEGP_SUITE_RELEASE_BOILERPLATE(adv_time_suite4P, kPFAdvTimeSuite, kPFAdvTimeSuiteVersion4); + AEGP_SUITE_RELEASE_BOILERPLATE(path_query_suite1P, kPFPathQuerySuite, kPFPathQuerySuiteVersion1); + AEGP_SUITE_RELEASE_BOILERPLATE(memory_suite1P, kAEGPMemorySuite, kAEGPMemorySuiteVersion1); + AEGP_SUITE_RELEASE_BOILERPLATE(path_data_suite1P, kPFPathDataSuite, kPFPathDataSuiteVersion1); + AEGP_SUITE_RELEASE_BOILERPLATE(param_utils_suite3P, kPFParamUtilsSuite, kPFParamUtilsSuiteVersion3); + AEGP_SUITE_RELEASE_BOILERPLATE(app_suite4P, kPFAppSuite, kPFAppSuiteVersion4); + AEGP_SUITE_RELEASE_BOILERPLATE(app_suite5P, kPFAppSuite, kPFAppSuiteVersion5); + AEGP_SUITE_RELEASE_BOILERPLATE(app_suite6P, kPFAppSuite, kPFAppSuiteVersion6); + AEGP_SUITE_RELEASE_BOILERPLATE(adv_app_suite2P, kPFAdvAppSuite, kPFAdvAppSuiteVersion2); + AEGP_SUITE_RELEASE_BOILERPLATE(light_suite1P, kAEGPLightSuite, kAEGPLightSuiteVersion1); + AEGP_SUITE_RELEASE_BOILERPLATE(light_suite2P, kAEGPLightSuite, kAEGPLightSuiteVersion2); + AEGP_SUITE_RELEASE_BOILERPLATE(effect_suite1P, kAEGPEffectSuite, kAEGPEffectSuiteVersion1); + AEGP_SUITE_RELEASE_BOILERPLATE(effect_suite2P, kAEGPEffectSuite, kAEGPEffectSuiteVersion2); + AEGP_SUITE_RELEASE_BOILERPLATE(effect_suite3P, kAEGPEffectSuite, kAEGPEffectSuiteVersion3); + AEGP_SUITE_RELEASE_BOILERPLATE(effect_suite4P, kAEGPEffectSuite, kAEGPEffectSuiteVersion4); + AEGP_SUITE_RELEASE_BOILERPLATE(mask_suite4P, kAEGPMaskSuite, kAEGPMaskSuiteVersion4); + AEGP_SUITE_RELEASE_BOILERPLATE(mask_outline_suite1P, kAEGPMaskOutlineSuite, kAEGPMaskOutlineSuiteVersion1); + AEGP_SUITE_RELEASE_BOILERPLATE(mask_outline_suite2P, kAEGPMaskOutlineSuite, kAEGPMaskOutlineSuiteVersion2); + AEGP_SUITE_RELEASE_BOILERPLATE(mask_outline_suite3P, kAEGPMaskOutlineSuite, kAEGPMaskOutlineSuiteVersion3); + AEGP_SUITE_RELEASE_BOILERPLATE(command_suite1P, kAEGPCommandSuite, kAEGPCommandSuiteVersion1); + AEGP_SUITE_RELEASE_BOILERPLATE(utility_suite3P, kAEGPUtilitySuite, kAEGPUtilitySuiteVersion3); + AEGP_SUITE_RELEASE_BOILERPLATE(render_suite1P, kAEGPRenderSuite, kAEGPRenderSuiteVersion1); + AEGP_SUITE_RELEASE_BOILERPLATE(render_suite2P, kAEGPRenderSuite, kAEGPRenderSuiteVersion2); + AEGP_SUITE_RELEASE_BOILERPLATE(render_suite3P, kAEGPRenderSuite, kAEGPRenderSuiteVersion3); + AEGP_SUITE_RELEASE_BOILERPLATE(render_suite4P, kAEGPRenderSuite, kAEGPRenderSuiteVersion4); + AEGP_SUITE_RELEASE_BOILERPLATE(render_suite5P, kAEGPRenderSuite, kAEGPRenderSuiteVersion5); + AEGP_SUITE_RELEASE_BOILERPLATE(ansi_callbacks_suite1P, kPFANSISuite, kPFANSISuiteVersion1); + AEGP_SUITE_RELEASE_BOILERPLATE(handle_suite1P, kPFHandleSuite, kPFHandleSuiteVersion1); + AEGP_SUITE_RELEASE_BOILERPLATE(fill_matte_suite2P, kPFFillMatteSuite, kPFFillMatteSuiteVersion2); + AEGP_SUITE_RELEASE_BOILERPLATE(world_transform_suite1P, kPFWorldTransformSuite, kPFWorldTransformSuiteVersion1); + AEGP_SUITE_RELEASE_BOILERPLATE(query_xform_suite2P, kAEGPQueryXformSuite, kAEGPQueryXformSuiteVersion2); + AEGP_SUITE_RELEASE_BOILERPLATE(composite_suite2P, kAEGPCompositeSuite, kAEGPCompositeSuiteVersion2); + AEGP_SUITE_RELEASE_BOILERPLATE(world_suite1P, kPFWorldSuite, kPFWorldSuiteVersion1); + AEGP_SUITE_RELEASE_BOILERPLATE(io_in_suite4P, kAEGPIOInSuite, kAEGPIOInSuiteVersion4); + AEGP_SUITE_RELEASE_BOILERPLATE(io_out_suite4P, kAEGPIOOutSuite, kAEGPIOOutSuiteVersion4); + AEGP_SUITE_RELEASE_BOILERPLATE(render_queue_suite1P, kAEGPRenderQueueSuite, kAEGPRenderQueueSuiteVersion1); + AEGP_SUITE_RELEASE_BOILERPLATE(rq_item_suite2P, kAEGPRQItemSuite, kAEGPRQItemSuiteVersion2); + AEGP_SUITE_RELEASE_BOILERPLATE(output_module_suite4P, kAEGPOutputModuleSuite, kAEGPOutputModuleSuiteVersion4); + AEGP_SUITE_RELEASE_BOILERPLATE(fim_suite3P, kAEGPFIMSuite, kAEGPFIMSuiteVersion3); + AEGP_SUITE_RELEASE_BOILERPLATE(math_suite1P, kAEGPMathSuite, kAEGPMathSuiteVersion1); + AEGP_SUITE_RELEASE_BOILERPLATE(adv_time_suite4P, kPFAdvTimeSuite, kPFAdvTimeSuiteVersion4); + AEGP_SUITE_RELEASE_BOILERPLATE(sampling_8_suite1P, kPFSampling8Suite, kPFSampling8SuiteVersion1); + AEGP_SUITE_RELEASE_BOILERPLATE(sampling_16_suite1P, kPFSampling16Suite, kPFSampling16SuiteVersion1); + AEGP_SUITE_RELEASE_BOILERPLATE(iterate_8_suite1P, kPFIterate8Suite, kPFIterate8SuiteVersion1); + AEGP_SUITE_RELEASE_BOILERPLATE(iterate_16_suite1P, kPFIterate16Suite, kPFIterate16SuiteVersion1); + AEGP_SUITE_RELEASE_BOILERPLATE(iterate_float_suite1P, kPFIterateFloatSuite, kPFIterateFloatSuiteVersion1); + AEGP_SUITE_RELEASE_BOILERPLATE(iterate_8_suite2P, kPFIterate8Suite, kPFIterate8SuiteVersion2); + AEGP_SUITE_RELEASE_BOILERPLATE(iterate_16_suite2P, kPFIterate16Suite, kPFIterate16SuiteVersion2); + AEGP_SUITE_RELEASE_BOILERPLATE(iterate_float_suite2P, kPFIterateFloatSuite, kPFIterateFloatSuiteVersion2); + AEGP_SUITE_RELEASE_BOILERPLATE(collection_suite2P, kAEGPCollectionSuite, kAEGPCollectionSuiteVersion2); + AEGP_SUITE_RELEASE_BOILERPLATE(text_document_suite1P, kAEGPTextDocumentSuite, kAEGPTextDocumentSuiteVersion1); + AEGP_SUITE_RELEASE_BOILERPLATE(sound_data_suite1P, kAEGPSoundDataSuite, kAEGPSoundDataVersion1); + AEGP_SUITE_RELEASE_BOILERPLATE(text_layer_suite1P, kAEGPTextLayerSuite, kAEGPTextLayerSuiteVersion1); + AEGP_SUITE_RELEASE_BOILERPLATE(artisan_util_suite1P, kAEGPArtisanUtilSuite, kAEGPArtisanUtilSuiteVersion1); + AEGP_SUITE_RELEASE_BOILERPLATE(aegp_world_suite_2P, kAEGPWorldSuite, kAEGPWorldSuiteVersion2); + AEGP_SUITE_RELEASE_BOILERPLATE(aegp_world_suite_3P, kAEGPWorldSuite, kAEGPWorldSuiteVersion3); + AEGP_SUITE_RELEASE_BOILERPLATE(render_options_suite_1P, kAEGPRenderOptionsSuite, kAEGPRenderOptionsSuiteVersion1); + AEGP_SUITE_RELEASE_BOILERPLATE(tracker_suite_1P, kAEGPTrackerSuite, kAEGPTrackerSuiteVersion1); + AEGP_SUITE_RELEASE_BOILERPLATE(tracker_utility_suite_1P, kAEGPTrackerUtilitySuite, kAEGPTrackerUtilitySuiteVersion1); + AEGP_SUITE_RELEASE_BOILERPLATE(helper_suite_2P, kPFHelperSuite2, kPFHelperSuite2Version2); + AEGP_SUITE_RELEASE_BOILERPLATE(layer_suite_5P, kAEGPLayerSuite, kAEGPLayerSuiteVersion5); + AEGP_SUITE_RELEASE_BOILERPLATE(layer_suite_6P, kAEGPLayerSuite, kAEGPLayerSuiteVersion6); + AEGP_SUITE_RELEASE_BOILERPLATE(layer_suite_7P, kAEGPLayerSuite, kAEGPLayerSuiteVersion7); + AEGP_SUITE_RELEASE_BOILERPLATE(layer_suite_8P, kAEGPLayerSuite, kAEGPLayerSuiteVersion8); + AEGP_SUITE_RELEASE_BOILERPLATE(adv_item_suite_1P, kPFAdvItemSuite, kPFAdvItemSuiteVersion1); +#ifdef I_NEED_ADM_SUPPORT + AEGP_SUITE_RELEASE_BOILERPLATE(adm_basic_suite_8P, kADMBasicSuite, kADMBasicSuiteVersion8); + AEGP_SUITE_RELEASE_BOILERPLATE(adm_dialog_suite_8P, kADMDialogSuite, kADMDialogSuiteVersion8); + AEGP_SUITE_RELEASE_BOILERPLATE(adm_dialog_group_suite_3P, kADMDialogGroupSuite, kADMDialogGroupSuiteVersion3); + AEGP_SUITE_RELEASE_BOILERPLATE(adm_item_suite_8P, kADMItemSuite, kADMItemSuiteVersion8); + AEGP_SUITE_RELEASE_BOILERPLATE(adm_list_suite_3P, kADMListSuite, kADMListSuiteVersion3); + AEGP_SUITE_RELEASE_BOILERPLATE(adm_entry_suite_5P, kADMEntrySuite, kADMEntrySuiteVersion5); + AEGP_SUITE_RELEASE_BOILERPLATE(adm_notifier_suite_2P, kADMNotifierSuite, kADMNotifierSuiteVersion2); +#endif + AEGP_SUITE_RELEASE_BOILERPLATE(layer_suite_1P, kAEGPLayerSuite, kAEGPLayerSuiteVersion1); + AEGP_SUITE_RELEASE_BOILERPLATE(mask_suite_1P, kAEGPMaskSuite, kAEGPMaskSuiteVersion1); + AEGP_SUITE_RELEASE_BOILERPLATE(mask_suite_5P, kAEGPMaskSuite, kAEGPMaskSuiteVersion5); + AEGP_SUITE_RELEASE_BOILERPLATE(mask_suite_6P, kAEGPMaskSuite, kAEGPMaskSuiteVersion6); + AEGP_SUITE_RELEASE_BOILERPLATE(comp_suite_1P, kAEGPCompSuite, kAEGPCompSuiteVersion1); + AEGP_SUITE_RELEASE_BOILERPLATE(collection_suite_1P, kAEGPCollectionSuite, kAEGPCollectionSuiteVersion1); + AEGP_SUITE_RELEASE_BOILERPLATE(adv_app_suite_1P, kPFAdvAppSuite, kPFAdvAppSuiteVersion1); + AEGP_SUITE_RELEASE_BOILERPLATE(utility_suite_1P, kAEGPUtilitySuite, kAEGPUtilitySuiteVersion1); + AEGP_SUITE_RELEASE_BOILERPLATE(render_options_suite_2P, kAEGPRenderOptionsSuite, kAEGPRenderOptionsSuiteVersion2); + AEGP_SUITE_RELEASE_BOILERPLATE(layer_render_options_suite_1P, kAEGPLayerRenderOptionsSuite, kAEGPLayerRenderOptionsSuiteVersion1); + AEGP_SUITE_RELEASE_BOILERPLATE(layer_render_options_suite_2P, kAEGPLayerRenderOptionsSuite, kAEGPLayerRenderOptionsSuiteVersion2); + AEGP_SUITE_RELEASE_BOILERPLATE(async_manager_suite_1P, kAEGPRenderAsyncManagerSuite, kAEGPRenderAsyncManagerSuiteVersion1); + AEGP_SUITE_RELEASE_BOILERPLATE(proj_suite_5P, kAEGPProjSuite, kAEGPProjSuiteVersion5); + AEGP_SUITE_RELEASE_BOILERPLATE(proj_suite_6P, kAEGPProjSuite, kAEGPProjSuiteVersion6); + AEGP_SUITE_RELEASE_BOILERPLATE(footage_suite_5P, kAEGPFootageSuite, kAEGPFootageSuiteVersion5); + AEGP_SUITE_RELEASE_BOILERPLATE(rq_item_suite_3P, kAEGPRQItemSuite, kAEGPRQItemSuiteVersion3); + AEGP_SUITE_RELEASE_BOILERPLATE(utility_suite_4P, kAEGPUtilitySuite, kAEGPUtilitySuiteVersion4); + AEGP_SUITE_RELEASE_BOILERPLATE(persistent_data_suite4P, kAEGPPersistentDataSuite, kAEGPPersistentDataSuiteVersion4); + AEGP_SUITE_RELEASE_BOILERPLATE(persistent_data_suite3P, kAEGPPersistentDataSuite, kAEGPPersistentDataSuiteVersion3); + AEGP_SUITE_RELEASE_BOILERPLATE(color_settings_suite_3P, kAEGPColorSettingsSuite, kAEGPColorSettingsSuiteVersion3); + AEGP_SUITE_RELEASE_BOILERPLATE(color_settings_suite_2P, kAEGPColorSettingsSuite, kAEGPColorSettingsSuiteVersion2); + AEGP_SUITE_RELEASE_BOILERPLATE(color_settings_suite_1P, kAEGPColorSettingsSuite, kAEGPColorSettingsSuiteVersion1); + AEGP_SUITE_RELEASE_BOILERPLATE(color_param_suite_1P, kPFColorParamSuite, kPFColorParamSuiteVersion1); + AEGP_SUITE_RELEASE_BOILERPLATE(sampling_float_suite_1P, kPFSamplingFloatSuite, kPFSamplingFloatSuiteVersion1); + AEGP_SUITE_RELEASE_BOILERPLATE(utility_suite_5P, kAEGPUtilitySuite, kAEGPUtilitySuiteVersion5); + AEGP_SUITE_RELEASE_BOILERPLATE(utility_suite_6P, kAEGPUtilitySuite, kAEGPUtilitySuiteVersion6); + AEGP_SUITE_RELEASE_BOILERPLATE(custom_ui_suite1P, kPFEffectCustomUISuite, kPFEffectCustomUISuiteVersion1); + AEGP_SUITE_RELEASE_BOILERPLATE(custom_ui_suite2P, kPFEffectCustomUISuite, kPFEffectCustomUISuiteVersion2); + AEGP_SUITE_RELEASE_BOILERPLATE(custom_ui_theme_suite1P, kPFEffectCustomUIOverlayThemeSuite, kPFEffectCustomUIOverlayThemeSuiteVersion1); + AEGP_SUITE_RELEASE_BOILERPLATE(drawing_suite_currentP, kDRAWBOT_DrawSuite, kDRAWBOT_DrawSuite_VersionCurrent); + AEGP_SUITE_RELEASE_BOILERPLATE(drawbot_supplier_suite_currentP, kDRAWBOT_SupplierSuite, kDRAWBOT_SupplierSuite_VersionCurrent); + AEGP_SUITE_RELEASE_BOILERPLATE(drawbot_surface_suite_currentP, kDRAWBOT_SurfaceSuite, kDRAWBOT_SurfaceSuite_VersionCurrent); + AEGP_SUITE_RELEASE_BOILERPLATE(drawbot_path_suite_currentP, kDRAWBOT_PathSuite, kDRAWBOT_PathSuite_VersionCurrent); + AEGP_SUITE_RELEASE_BOILERPLATE(suites_suite_2P, kSPSuitesSuite, kSPSuitesSuiteVersion); +} + + // Here is the error handling function which must be defined. + // It must exit by throwing an exception, it cannot return. + void MissingSuiteError() const; + +public: + // To construct, pass pica_basicP + AEGP_SuiteHandler(const SPBasicSuite *pica_basicP); + ~AEGP_SuiteHandler(); + + const SPBasicSuite *Pica() const { return i_pica_basicP; } + + #define AEGP_SUITE_ACCESS_BOILERPLATE(SUITE_NAME, VERSION_NUMBER, SUITE_PREFIX, MEMBER_NAME, kSUITE_NAME, kVERSION_NAME) \ + SUITE_PREFIX##SUITE_NAME##VERSION_NUMBER *SUITE_NAME##VERSION_NUMBER() const \ + { \ + if (i_suites.MEMBER_NAME == NULL) { \ + i_suites.MEMBER_NAME = (SUITE_PREFIX##SUITE_NAME##VERSION_NUMBER*) \ + LoadSuite(kSUITE_NAME, kVERSION_NAME); \ + } \ + return i_suites.MEMBER_NAME; \ + } + + AEGP_SUITE_ACCESS_BOILERPLATE(MarkerSuite, 1, AEGP_, marker_suite1P, kAEGPMarkerSuite, kAEGPMarkerSuiteVersion1); + AEGP_SUITE_ACCESS_BOILERPLATE(MarkerSuite, 2, AEGP_, marker_suite2P, kAEGPMarkerSuite, kAEGPMarkerSuiteVersion2); + AEGP_SUITE_ACCESS_BOILERPLATE(MarkerSuite, 3, AEGP_, marker_suite3P, kAEGPMarkerSuite, kAEGPMarkerSuiteVersion3); + AEGP_SUITE_ACCESS_BOILERPLATE(LayerSuite, 3, AEGP_, layer_suite3P, kAEGPLayerSuite, kAEGPLayerSuiteVersion3); + AEGP_SUITE_ACCESS_BOILERPLATE(LayerSuite, 4, AEGP_, layer_suite4P, kAEGPLayerSuite, kAEGPLayerSuiteVersion4); + AEGP_SUITE_ACCESS_BOILERPLATE(StreamSuite, 5, AEGP_, stream_suite5P, kAEGPStreamSuite, kAEGPStreamSuiteVersion5); + AEGP_SUITE_ACCESS_BOILERPLATE(StreamSuite, 4, AEGP_, stream_suite4P, kAEGPStreamSuite, kAEGPStreamSuiteVersion4); + AEGP_SUITE_ACCESS_BOILERPLATE(StreamSuite, 3, AEGP_, stream_suite3P, kAEGPStreamSuite, kAEGPStreamSuiteVersion3); + AEGP_SUITE_ACCESS_BOILERPLATE(StreamSuite, 2, AEGP_, stream_suite2P, kAEGPStreamSuite, kAEGPStreamSuiteVersion2); + AEGP_SUITE_ACCESS_BOILERPLATE(StreamSuite, 1, AEGP_, stream_suite_1P, kAEGPStreamSuite, kAEGPStreamSuiteVersion1); + AEGP_SUITE_ACCESS_BOILERPLATE(DynamicStreamSuite, 2, AEGP_, dynamic_stream_suite2P, kAEGPDynamicStreamSuite, kAEGPDynamicStreamSuiteVersion2); + AEGP_SUITE_ACCESS_BOILERPLATE(DynamicStreamSuite, 3, AEGP_, dynamic_stream_suite3P, kAEGPDynamicStreamSuite, kAEGPDynamicStreamSuiteVersion3); + AEGP_SUITE_ACCESS_BOILERPLATE(DynamicStreamSuite, 4, AEGP_, dynamic_stream_suite4P, kAEGPDynamicStreamSuite, kAEGPDynamicStreamSuiteVersion4); + AEGP_SUITE_ACCESS_BOILERPLATE(KeyframeSuite, 4, AEGP_, keyframe_suite4P, kAEGPKeyframeSuite, kAEGPKeyframeSuiteVersion4); + AEGP_SUITE_ACCESS_BOILERPLATE(KeyframeSuite, 3, AEGP_, keyframe_suite3P, kAEGPKeyframeSuite, kAEGPKeyframeSuiteVersion3); + AEGP_SUITE_ACCESS_BOILERPLATE(KeyframeSuite, 1, AEGP_, keyframe_suite_1P, kAEGPKeyframeSuite, kAEGPKeyframeSuiteVersion1); + AEGP_SUITE_ACCESS_BOILERPLATE(CompSuite, 4, AEGP_, comp_suite4P, kAEGPCompSuite, kAEGPCompSuiteVersion4); + AEGP_SUITE_ACCESS_BOILERPLATE(CompSuite, 5, AEGP_, comp_suite5P, kAEGPCompSuite, kAEGPCompSuiteVersion5); + AEGP_SUITE_ACCESS_BOILERPLATE(CompSuite, 6, AEGP_, comp_suite6P, kAEGPCompSuite, kAEGPCompSuiteVersion6); + AEGP_SUITE_ACCESS_BOILERPLATE(CompSuite, 7, AEGP_, comp_suite7P, kAEGPCompSuite, kAEGPCompSuiteVersion7); + AEGP_SUITE_ACCESS_BOILERPLATE(CompSuite, 8, AEGP_, comp_suite8P, kAEGPCompSuite, kAEGPCompSuiteVersion8); + AEGP_SUITE_ACCESS_BOILERPLATE(CompSuite, 9, AEGP_, comp_suite9P, kAEGPCompSuite, kAEGPCompSuiteVersion9); + AEGP_SUITE_ACCESS_BOILERPLATE(CompSuite, 10, AEGP_, comp_suite10P, kAEGPCompSuite, kAEGPCompSuiteVersion10); + AEGP_SUITE_ACCESS_BOILERPLATE(CompSuite, 11, AEGP_, comp_suite11P, kAEGPCompSuite, kAEGPCompSuiteVersion11); + AEGP_SUITE_ACCESS_BOILERPLATE(CanvasSuite, 5, AEGP_, canvas_suite5P, kAEGPCanvasSuite, kAEGPCanvasSuiteVersion5); + AEGP_SUITE_ACCESS_BOILERPLATE(CanvasSuite, 6, AEGP_, canvas_suite6P, kAEGPCanvasSuite, kAEGPCanvasSuiteVersion6); + AEGP_SUITE_ACCESS_BOILERPLATE(CanvasSuite, 7, AEGP_, canvas_suite7P, kAEGPCanvasSuite, kAEGPCanvasSuiteVersion7); + AEGP_SUITE_ACCESS_BOILERPLATE(CanvasSuite, 8, AEGP_, canvas_suite8P, kAEGPCanvasSuite, kAEGPCanvasSuiteVersion8); + AEGP_SUITE_ACCESS_BOILERPLATE(CameraSuite, 2, AEGP_, camera_suite2P, kAEGPCameraSuite, kAEGPCameraSuiteVersion2); + AEGP_SUITE_ACCESS_BOILERPLATE(RegisterSuite, 5, AEGP_, register_suite5P, kAEGPRegisterSuite, kAEGPRegisterSuiteVersion5); + AEGP_SUITE_ACCESS_BOILERPLATE(MemorySuite, 1, AEGP_, memory_suite1P, kAEGPMemorySuite, kAEGPMemorySuiteVersion1); + AEGP_SUITE_ACCESS_BOILERPLATE(ItemViewSuite, 1, AEGP_, item_view_suite1P, kAEGPItemViewSuite, kAEGPItemViewSuiteVersion1); + AEGP_SUITE_ACCESS_BOILERPLATE(ItemSuite, 9, AEGP_, item_suite9P, kAEGPItemSuite, kAEGPItemSuiteVersion9); + AEGP_SUITE_ACCESS_BOILERPLATE(ItemSuite, 8, AEGP_, item_suite8P, kAEGPItemSuite, kAEGPItemSuiteVersion8); + AEGP_SUITE_ACCESS_BOILERPLATE(ItemSuite, 7, AEGP_, item_suite7P, kAEGPItemSuite, kAEGPItemSuiteVersion7); + AEGP_SUITE_ACCESS_BOILERPLATE(ItemSuite, 6, AEGP_, item_suite6P, kAEGPItemSuite, kAEGPItemSuiteVersion6); + AEGP_SUITE_ACCESS_BOILERPLATE(ItemSuite, 5, AEGP_, item_suite5P, kAEGPItemSuite, kAEGPItemSuiteVersion5); + AEGP_SUITE_ACCESS_BOILERPLATE(ItemSuite, 1, AEGP_, item_suite1P, kAEGPItemSuite, kAEGPItemSuiteVersion1); + AEGP_SUITE_ACCESS_BOILERPLATE(PFInterfaceSuite, 1, AEGP_, pf_interface_suite1P, kAEGPPFInterfaceSuite, kAEGPPFInterfaceSuiteVersion1); + AEGP_SUITE_ACCESS_BOILERPLATE(MathSuite, 1, AEGP_, math_suite1P, kAEGPMathSuite, kAEGPMathSuiteVersion1); + AEGP_SUITE_ACCESS_BOILERPLATE(AdvTimeSuite, 4, PF_, adv_time_suite4P, kPFAdvTimeSuite, kPFAdvTimeSuiteVersion4); + AEGP_SUITE_ACCESS_BOILERPLATE(PathQuerySuite, 1, PF_, path_query_suite1P, kPFPathQuerySuite, kPFPathQuerySuiteVersion1); + AEGP_SUITE_ACCESS_BOILERPLATE(PathDataSuite, 1, PF_, path_data_suite1P, kPFPathDataSuite, kPFPathDataSuiteVersion1); + AEGP_SUITE_ACCESS_BOILERPLATE(ParamUtilsSuite, 3, PF_, param_utils_suite3P, kPFParamUtilsSuite, kPFParamUtilsSuiteVersion3); + AEGP_SUITE_ACCESS_BOILERPLATE(AppSuite, 4, PF, app_suite4P, kPFAppSuite, kPFAppSuiteVersion4); + AEGP_SUITE_ACCESS_BOILERPLATE(AppSuite, 5, PF, app_suite5P, kPFAppSuite, kPFAppSuiteVersion5); + AEGP_SUITE_ACCESS_BOILERPLATE(AppSuite, 6, PF, app_suite6P, kPFAppSuite, kPFAppSuiteVersion6); + AEGP_SUITE_ACCESS_BOILERPLATE(AdvAppSuite, 2, PF_, adv_app_suite2P, kPFAdvAppSuite, kPFAdvAppSuiteVersion2); + AEGP_SUITE_ACCESS_BOILERPLATE(LightSuite, 1, AEGP_, light_suite1P, kAEGPLightSuite, kAEGPLightSuiteVersion1); + AEGP_SUITE_ACCESS_BOILERPLATE(LightSuite, 2, AEGP_, light_suite2P, kAEGPLightSuite, kAEGPLightSuiteVersion2); + AEGP_SUITE_ACCESS_BOILERPLATE(EffectSuite, 1, AEGP_, effect_suite1P, kAEGPEffectSuite, kAEGPEffectSuiteVersion1); + AEGP_SUITE_ACCESS_BOILERPLATE(EffectSuite, 2, AEGP_, effect_suite2P, kAEGPEffectSuite, kAEGPEffectSuiteVersion2); + AEGP_SUITE_ACCESS_BOILERPLATE(EffectSuite, 3, AEGP_, effect_suite3P, kAEGPEffectSuite, kAEGPEffectSuiteVersion3); + AEGP_SUITE_ACCESS_BOILERPLATE(EffectSuite, 4, AEGP_, effect_suite4P, kAEGPEffectSuite, kAEGPEffectSuiteVersion4); + AEGP_SUITE_ACCESS_BOILERPLATE(MaskSuite, 4, AEGP_, mask_suite4P, kAEGPMaskSuite, kAEGPMaskSuiteVersion4); + AEGP_SUITE_ACCESS_BOILERPLATE(MaskOutlineSuite, 1, AEGP_, mask_outline_suite1P, kAEGPMaskOutlineSuite, kAEGPMaskOutlineSuiteVersion1); + AEGP_SUITE_ACCESS_BOILERPLATE(MaskOutlineSuite, 2, AEGP_, mask_outline_suite2P, kAEGPMaskOutlineSuite, kAEGPMaskOutlineSuiteVersion2); + AEGP_SUITE_ACCESS_BOILERPLATE(MaskOutlineSuite, 3, AEGP_, mask_outline_suite3P, kAEGPMaskOutlineSuite, kAEGPMaskOutlineSuiteVersion3); + AEGP_SUITE_ACCESS_BOILERPLATE(CommandSuite, 1, AEGP_, command_suite1P, kAEGPCommandSuite, kAEGPCommandSuiteVersion1); + AEGP_SUITE_ACCESS_BOILERPLATE(UtilitySuite, 3, AEGP_, utility_suite3P, kAEGPUtilitySuite, kAEGPUtilitySuiteVersion3); + AEGP_SUITE_ACCESS_BOILERPLATE(RenderSuite, 1, AEGP_, render_suite1P, kAEGPRenderSuite, kAEGPRenderSuiteVersion1); + AEGP_SUITE_ACCESS_BOILERPLATE(RenderSuite, 2, AEGP_, render_suite2P, kAEGPRenderSuite, kAEGPRenderSuiteVersion2); + AEGP_SUITE_ACCESS_BOILERPLATE(RenderSuite, 3, AEGP_, render_suite3P, kAEGPRenderSuite, kAEGPRenderSuiteVersion3); + AEGP_SUITE_ACCESS_BOILERPLATE(RenderSuite, 4, AEGP_, render_suite4P, kAEGPRenderSuite, kAEGPRenderSuiteVersion4); + AEGP_SUITE_ACCESS_BOILERPLATE(RenderSuite, 5, AEGP_, render_suite5P, kAEGPRenderSuite, kAEGPRenderSuiteVersion5); + AEGP_SUITE_ACCESS_BOILERPLATE(ANSICallbacksSuite, 1, PF_, ansi_callbacks_suite1P, kPFANSISuite, kPFANSISuiteVersion1); + AEGP_SUITE_ACCESS_BOILERPLATE(HandleSuite, 1, PF_, handle_suite1P, kPFHandleSuite, kPFHandleSuiteVersion1); + AEGP_SUITE_ACCESS_BOILERPLATE(FillMatteSuite, 2, PF_, fill_matte_suite2P, kPFFillMatteSuite, kPFFillMatteSuiteVersion2); + AEGP_SUITE_ACCESS_BOILERPLATE(WorldTransformSuite, 1, PF_, world_transform_suite1P, kPFWorldTransformSuite, kPFWorldTransformSuiteVersion1); + AEGP_SUITE_ACCESS_BOILERPLATE(QueryXformSuite, 2, AEGP_, query_xform_suite2P, kAEGPQueryXformSuite, kAEGPQueryXformSuiteVersion2); + AEGP_SUITE_ACCESS_BOILERPLATE(CompositeSuite, 2, AEGP_, composite_suite2P, kAEGPCompositeSuite, kAEGPCompositeSuiteVersion2); + AEGP_SUITE_ACCESS_BOILERPLATE(WorldSuite, 1, PF_, world_suite1P, kPFWorldSuite, kPFWorldSuiteVersion1); + AEGP_SUITE_ACCESS_BOILERPLATE(IOInSuite, 4, AEGP_, io_in_suite4P, kAEGPIOInSuite, kAEGPIOInSuiteVersion4); + AEGP_SUITE_ACCESS_BOILERPLATE(IOOutSuite, 4, AEGP_, io_out_suite4P, kAEGPIOOutSuite, kAEGPIOOutSuiteVersion4); + AEGP_SUITE_ACCESS_BOILERPLATE(RenderQueueSuite, 1, AEGP_, render_queue_suite1P, kAEGPRenderQueueSuite, kAEGPRenderQueueSuiteVersion1); + AEGP_SUITE_ACCESS_BOILERPLATE(RQItemSuite, 2, AEGP_, rq_item_suite2P, kAEGPRQItemSuite, kAEGPRQItemSuiteVersion2); + AEGP_SUITE_ACCESS_BOILERPLATE(OutputModuleSuite, 4, AEGP_, output_module_suite4P, kAEGPOutputModuleSuite, kAEGPOutputModuleSuiteVersion4); + AEGP_SUITE_ACCESS_BOILERPLATE(FIMSuite, 3, AEGP_, fim_suite3P, kAEGPFIMSuite, kAEGPFIMSuiteVersion3); + AEGP_SUITE_ACCESS_BOILERPLATE(Sampling8Suite, 1, PF_, sampling_8_suite1P, kPFSampling8Suite, kPFSampling8SuiteVersion1); + AEGP_SUITE_ACCESS_BOILERPLATE(Sampling16Suite, 1, PF_, sampling_16_suite1P, kPFSampling16Suite, kPFSampling16SuiteVersion1); + AEGP_SUITE_ACCESS_BOILERPLATE(Iterate8Suite, 1, PF_, iterate_8_suite1P, kPFIterate8Suite, kPFIterate8SuiteVersion1); + AEGP_SUITE_ACCESS_BOILERPLATE(Iterate16Suite, 1, PF_, iterate_16_suite1P, kPFIterate16Suite, kPFIterate16SuiteVersion1); + AEGP_SUITE_ACCESS_BOILERPLATE(IterateFloatSuite, 1, PF_, iterate_float_suite1P, kPFIterateFloatSuite, kPFIterateFloatSuiteVersion1); + AEGP_SUITE_ACCESS_BOILERPLATE(Iterate8Suite, 2, PF_, iterate_8_suite2P, kPFIterate8Suite, kPFIterate8SuiteVersion2); + AEGP_SUITE_ACCESS_BOILERPLATE(Iterate16Suite, 2, PF_, iterate_16_suite2P, kPFIterate16Suite, kPFIterate16SuiteVersion2); + AEGP_SUITE_ACCESS_BOILERPLATE(IterateFloatSuite, 2, PF_, iterate_float_suite2P, kPFIterateFloatSuite, kPFIterateFloatSuiteVersion2); + AEGP_SUITE_ACCESS_BOILERPLATE(CollectionSuite, 2, AEGP_, collection_suite2P, kAEGPCollectionSuite, kAEGPCollectionSuiteVersion2); + AEGP_SUITE_ACCESS_BOILERPLATE(TextDocumentSuite, 1, AEGP_, text_document_suite1P, kAEGPTextDocumentSuite, kAEGPTextDocumentSuiteVersion1); + AEGP_SUITE_ACCESS_BOILERPLATE(SoundDataSuite, 1, AEGP_, sound_data_suite1P, kAEGPSoundDataSuite, kAEGPSoundDataVersion1); + AEGP_SUITE_ACCESS_BOILERPLATE(IterateSuite, 1, AEGP_, aegp_iterate_suite1P, kAEGPIterateSuite, kAEGPIterateSuiteVersion1); + AEGP_SUITE_ACCESS_BOILERPLATE(IterateSuite, 2, AEGP_, aegp_iterate_suite2P, kAEGPIterateSuite, kAEGPIterateSuiteVersion2); + AEGP_SUITE_ACCESS_BOILERPLATE(TextLayerSuite, 1, AEGP_, text_layer_suite1P, kAEGPTextLayerSuite, kAEGPTextLayerSuiteVersion1); + AEGP_SUITE_ACCESS_BOILERPLATE(ArtisanUtilSuite, 1, AEGP_, artisan_util_suite1P, kAEGPArtisanUtilSuite, kAEGPArtisanUtilSuiteVersion1); + AEGP_SUITE_ACCESS_BOILERPLATE(WorldSuite, 2, AEGP_, aegp_world_suite_2P, kAEGPWorldSuite, kAEGPWorldSuiteVersion2); + AEGP_SUITE_ACCESS_BOILERPLATE(WorldSuite, 3, AEGP_, aegp_world_suite_3P, kAEGPWorldSuite, kAEGPWorldSuiteVersion3); + AEGP_SUITE_ACCESS_BOILERPLATE(RenderOptionsSuite, 1, AEGP_, render_options_suite_1P, kAEGPRenderOptionsSuite, kAEGPRenderOptionsSuiteVersion1); + AEGP_SUITE_ACCESS_BOILERPLATE(TrackerSuite, 1, AEGP_, tracker_suite_1P, kAEGPTrackerSuite, kAEGPTrackerSuiteVersion1); + AEGP_SUITE_ACCESS_BOILERPLATE(TrackerUtilitySuite, 1, AEGP_, tracker_utility_suite_1P, kAEGPTrackerUtilitySuite, kAEGPTrackerUtilitySuiteVersion1); + AEGP_SUITE_ACCESS_BOILERPLATE(HelperSuite, 2, PF_, helper_suite_2P, kPFHelperSuite2, kPFHelperSuite2Version2); + AEGP_SUITE_ACCESS_BOILERPLATE(LayerSuite, 5, AEGP_, layer_suite_5P, kAEGPLayerSuite, kAEGPLayerSuiteVersion5); + AEGP_SUITE_ACCESS_BOILERPLATE(LayerSuite, 6, AEGP_, layer_suite_6P, kAEGPLayerSuite, kAEGPLayerSuiteVersion6); + AEGP_SUITE_ACCESS_BOILERPLATE(LayerSuite, 7, AEGP_, layer_suite_7P, kAEGPLayerSuite, kAEGPLayerSuiteVersion7); + AEGP_SUITE_ACCESS_BOILERPLATE(LayerSuite, 8, AEGP_, layer_suite_8P, kAEGPLayerSuite, kAEGPLayerSuiteVersion8); +#ifdef I_NEED_ADM_SUPPORT + AEGP_SUITE_ACCESS_BOILERPLATE(BasicSuite, 8, ADM, adm_basic_suite_8P, kADMBasicSuite, kADMBasicSuiteVersion8); + AEGP_SUITE_ACCESS_BOILERPLATE(DialogSuite, 8, ADM, adm_dialog_suite_8P, kADMDialogSuite, kADMDialogSuiteVersion8); + AEGP_SUITE_ACCESS_BOILERPLATE(DialogGroupSuite, 3, ADM, adm_dialog_group_suite_3P, kADMDialogGroupSuite, kADMDialogGroupSuiteVersion3); + AEGP_SUITE_ACCESS_BOILERPLATE(ItemSuite, 8, ADM, adm_item_suite_8P, kADMItemSuite, kADMItemSuiteVersion8); + AEGP_SUITE_ACCESS_BOILERPLATE(ListSuite, 3, ADM, adm_list_suite_3P, kADMListSuite, kADMListSuiteVersion3); + AEGP_SUITE_ACCESS_BOILERPLATE(EntrySuite, 5, ADM, adm_entry_suite_5P, kADMEntrySuite, kADMEntrySuiteVersion5); + AEGP_SUITE_ACCESS_BOILERPLATE(NotifierSuite, 2, ADM, adm_notifier_suite_2P, kADMNotifierSuite, kADMNotifierSuiteVersion2); +#endif + AEGP_SUITE_ACCESS_BOILERPLATE(LayerSuite, 1, AEGP_, layer_suite_1P, kAEGPLayerSuite, kAEGPLayerSuiteVersion1); + AEGP_SUITE_ACCESS_BOILERPLATE(AdvItemSuite, 1, PF_, adv_item_suite_1P, kPFAdvItemSuite, kPFAdvItemSuiteVersion1); + AEGP_SUITE_ACCESS_BOILERPLATE(MaskSuite, 1, AEGP_, mask_suite_1P, kAEGPMaskSuite, kAEGPMaskSuiteVersion1); + AEGP_SUITE_ACCESS_BOILERPLATE(MaskSuite, 5, AEGP_, mask_suite_5P, kAEGPMaskSuite, kAEGPMaskSuiteVersion5); + AEGP_SUITE_ACCESS_BOILERPLATE(MaskSuite, 6, AEGP_, mask_suite_6P, kAEGPMaskSuite, kAEGPMaskSuiteVersion6); + AEGP_SUITE_ACCESS_BOILERPLATE(CompSuite, 1, AEGP_, comp_suite_1P, kAEGPCompSuite, kAEGPCompSuiteVersion1); + AEGP_SUITE_ACCESS_BOILERPLATE(CollectionSuite, 1, AEGP_, collection_suite_1P, kAEGPCollectionSuite, kAEGPCollectionSuiteVersion1); + AEGP_SUITE_ACCESS_BOILERPLATE(AdvAppSuite, 1, PF_, adv_app_suite_1P, kPFAdvAppSuite, kPFAdvAppSuiteVersion1); + AEGP_SUITE_ACCESS_BOILERPLATE(UtilitySuite, 1, AEGP_, utility_suite_1P, kAEGPUtilitySuite, kAEGPUtilitySuiteVersion1); + AEGP_SUITE_ACCESS_BOILERPLATE(RenderOptionsSuite, 2, AEGP_, render_options_suite_2P, kAEGPRenderOptionsSuite, kAEGPRenderOptionsSuiteVersion2); + AEGP_SUITE_ACCESS_BOILERPLATE(RenderOptionsSuite, 3, AEGP_, render_options_suite_3P, kAEGPRenderOptionsSuite, kAEGPRenderOptionsSuiteVersion3); + AEGP_SUITE_ACCESS_BOILERPLATE(LayerRenderOptionsSuite, 1, AEGP_, layer_render_options_suite_1P, kAEGPLayerRenderOptionsSuite, kAEGPLayerRenderOptionsSuiteVersion1); + AEGP_SUITE_ACCESS_BOILERPLATE(LayerRenderOptionsSuite, 2, AEGP_, layer_render_options_suite_2P, kAEGPLayerRenderOptionsSuite, kAEGPLayerRenderOptionsSuiteVersion2); + AEGP_SUITE_ACCESS_BOILERPLATE(RenderAsyncManagerSuite, 1, AEGP_, async_manager_suite_1P, kAEGPRenderAsyncManagerSuite, kAEGPRenderAsyncManagerSuiteVersion1); + AEGP_SUITE_ACCESS_BOILERPLATE(ProjSuite, 5, AEGP_, proj_suite_5P, kAEGPProjSuite, kAEGPProjSuiteVersion5); + AEGP_SUITE_ACCESS_BOILERPLATE(ProjSuite, 6, AEGP_, proj_suite_6P, kAEGPProjSuite, kAEGPProjSuiteVersion6); + AEGP_SUITE_ACCESS_BOILERPLATE(FootageSuite, 5, AEGP_, footage_suite_5P, kAEGPFootageSuite, kAEGPFootageSuiteVersion5); + AEGP_SUITE_ACCESS_BOILERPLATE(RQItemSuite, 3, AEGP_, rq_item_suite_3P, kAEGPRQItemSuite, kAEGPRQItemSuiteVersion3); + AEGP_SUITE_ACCESS_BOILERPLATE(UtilitySuite, 4, AEGP_, utility_suite_4P, kAEGPUtilitySuite, kAEGPUtilitySuiteVersion4); + AEGP_SUITE_ACCESS_BOILERPLATE(ColorSettingsSuite, 3, AEGP_, color_settings_suite_3P, kAEGPColorSettingsSuite, kAEGPColorSettingsSuiteVersion3); + AEGP_SUITE_ACCESS_BOILERPLATE(ColorSettingsSuite, 2, AEGP_, color_settings_suite_2P, kAEGPColorSettingsSuite, kAEGPColorSettingsSuiteVersion2); + AEGP_SUITE_ACCESS_BOILERPLATE(ColorSettingsSuite, 1, AEGP_, color_settings_suite_1P, kAEGPColorSettingsSuite, kAEGPColorSettingsSuiteVersion1); + AEGP_SUITE_ACCESS_BOILERPLATE(ColorParamSuite, 1, PF_, color_param_suite_1P, kPFColorParamSuite, kPFColorParamSuiteVersion1); + AEGP_SUITE_ACCESS_BOILERPLATE(PersistentDataSuite, 4, AEGP_, persistent_data_suite4P, kAEGPPersistentDataSuite, kAEGPPersistentDataSuiteVersion4); + AEGP_SUITE_ACCESS_BOILERPLATE(PersistentDataSuite, 3, AEGP_, persistent_data_suite3P, kAEGPPersistentDataSuite, kAEGPPersistentDataSuiteVersion3); + AEGP_SUITE_ACCESS_BOILERPLATE(SamplingFloatSuite, 1, PF_, sampling_float_suite_1P, kPFSamplingFloatSuite, kPFSamplingFloatSuiteVersion1); + AEGP_SUITE_ACCESS_BOILERPLATE(UtilitySuite, 5, AEGP_, utility_suite_5P, kAEGPUtilitySuite, kAEGPUtilitySuiteVersion5); + AEGP_SUITE_ACCESS_BOILERPLATE(UtilitySuite, 6, AEGP_, utility_suite_6P, kAEGPUtilitySuite, kAEGPUtilitySuiteVersion6); + AEGP_SUITE_ACCESS_BOILERPLATE(EffectCustomUISuite, 1, PF_, custom_ui_suite1P, kPFEffectCustomUISuite, kPFEffectCustomUISuiteVersion1); + AEGP_SUITE_ACCESS_BOILERPLATE(EffectCustomUISuite, 2, PF_, custom_ui_suite2P, kPFEffectCustomUISuite, kPFEffectCustomUISuiteVersion2); + AEGP_SUITE_ACCESS_BOILERPLATE(EffectCustomUIOverlayThemeSuite, 1, PF_, custom_ui_theme_suite1P, kPFEffectCustomUIOverlayThemeSuite, kPFEffectCustomUIOverlayThemeSuiteVersion1); + AEGP_SUITE_ACCESS_BOILERPLATE(DrawbotSuite, Current, DRAWBOT_, drawing_suite_currentP, kDRAWBOT_DrawSuite, kDRAWBOT_DrawSuite_VersionCurrent); + AEGP_SUITE_ACCESS_BOILERPLATE(SupplierSuite, Current, DRAWBOT_, drawbot_supplier_suite_currentP, kDRAWBOT_SupplierSuite, kDRAWBOT_SupplierSuite_VersionCurrent); + AEGP_SUITE_ACCESS_BOILERPLATE(SurfaceSuite, Current, DRAWBOT_, drawbot_surface_suite_currentP, kDRAWBOT_SurfaceSuite, kDRAWBOT_SurfaceSuite_VersionCurrent); + AEGP_SUITE_ACCESS_BOILERPLATE(PathSuite, Current, DRAWBOT_, drawbot_path_suite_currentP, kDRAWBOT_PathSuite, kDRAWBOT_PathSuite_VersionCurrent); + + AEGP_SUITE_ACCESS_BOILERPLATE(SuitesSuite, , SP, suites_suite_2P, kSPSuitesSuite, kSPSuitesSuiteVersion); +}; + +#endif diff --git a/External/AE SDK/Util/AEGP_Utils.cpp b/External/AE SDK/Util/AEGP_Utils.cpp new file mode 100644 index 00000000..95f7cdb6 --- /dev/null +++ b/External/AE SDK/Util/AEGP_Utils.cpp @@ -0,0 +1,38 @@ +#include "AEGP_Utils.h" + + +A_Err GetNewFirstLayerInFirstComp( + SPBasicSuite *sP, + AEGP_LayerH *first_layerPH) +{ + A_Err err = A_Err_NONE; + + AEGP_ItemH itemH = NULL; + AEGP_ItemType type = AEGP_ItemType_NONE; + AEGP_CompH compH = NULL; + AEGP_ProjectH projH = NULL; + A_long num_projectsL = 0, + num_layersL = 0; + + AEGP_SuiteHandler suites(sP); + + (void)num_projectsL; + ERR(suites.ProjSuite5()->AEGP_GetProjectByIndex(0, &projH)); + ERR(suites.ItemSuite8()->AEGP_GetFirstProjItem(projH, &itemH)); + ERR(suites.ItemSuite6()->AEGP_GetItemType(itemH, &type)); + + while ((itemH != NULL) && (type != AEGP_ItemType_COMP)){ + ERR(suites.ItemSuite6()->AEGP_GetNextProjItem(projH, itemH, &itemH)); + ERR(suites.ItemSuite6()->AEGP_GetItemType(itemH, &type)); + } + if (!err && (type == AEGP_ItemType_COMP)){ + err = suites.CompSuite4()->AEGP_GetCompFromItem(itemH, &compH); + } + if (!err && compH) { + err = suites.LayerSuite5()->AEGP_GetCompNumLayers(compH, &num_layersL); + } + if (!err && num_layersL){ + err = suites.LayerSuite5()->AEGP_GetCompLayerByIndex(compH, 0, first_layerPH); + } + return err; +} diff --git a/External/AE SDK/Util/AEGP_Utils.h b/External/AE SDK/Util/AEGP_Utils.h new file mode 100644 index 00000000..a2f2b06f --- /dev/null +++ b/External/AE SDK/Util/AEGP_Utils.h @@ -0,0 +1,9 @@ +#include "A.h" +#include "AE_GeneralPlug.h" +#include "AEGP_SuiteHandler.h" +#include "AE_Macros.h" + +A_Err GetNewFirstLayerInFirstComp( + SPBasicSuite *sP, + AEGP_LayerH *first_layerPH); + diff --git a/External/AE SDK/Util/DuckSuite.h b/External/AE SDK/Util/DuckSuite.h new file mode 100644 index 00000000..59f9953c --- /dev/null +++ b/External/AE SDK/Util/DuckSuite.h @@ -0,0 +1,13 @@ +#include "A.h" +#include + +#ifdef AE_OS_WIN + #include +#endif + +#define kDuckSuite1 "AEGP Duck Suite" +#define kDuckSuiteVersion1 1 + +typedef struct DuckSuite1 { + SPAPI A_Err (*Quack)(A_u_short timesSu); +} DuckSuite1; \ No newline at end of file diff --git a/External/AE SDK/Util/MissingSuiteError.cpp b/External/AE SDK/Util/MissingSuiteError.cpp new file mode 100644 index 00000000..5be71f4f --- /dev/null +++ b/External/AE SDK/Util/MissingSuiteError.cpp @@ -0,0 +1,43 @@ +/*******************************************************************/ +/* */ +/* ADOBE CONFIDENTIAL */ +/* _ _ _ _ _ _ _ _ _ _ _ _ _ */ +/* */ +/* Copyright 2007 Adobe Systems Incorporated */ +/* All Rights Reserved. */ +/* */ +/* NOTICE: All information contained herein is, and remains the */ +/* property of Adobe Systems Incorporated and its suppliers, if */ +/* any. The intellectual and technical concepts contained */ +/* herein are proprietary to Adobe Systems Incorporated and its */ +/* suppliers and may be covered by U.S. and Foreign Patents, */ +/* patents in process, and are protected by trade secret or */ +/* copyright law. Dissemination of this information or */ +/* reproduction of this material is strictly forbidden unless */ +/* prior written permission is obtained from Adobe Systems */ +/* Incorporated. */ +/* */ +/*******************************************************************/ + +#include "AEGP_SuiteHandler.h" + +void AEGP_SuiteHandler::MissingSuiteError() const +{ + // Yes, we've read Scott Meyers, and know throwing + // a stack-based object can cause problems. Since + // the err is just a long, and since we aren't de- + // referencing it in any way, risk is mimimal. + + // As always, we expect those of you who use + // exception-based code to do a little less rudi- + // mentary job of it than we are here. + + // Also, excuse the Madagascar-inspired monkey + // joke; couldn't resist. + // -bbb 10/10/05 + + PF_Err poop = PF_Err_BAD_CALLBACK_PARAM; + + throw poop; +} + diff --git a/External/AE SDK/Util/Param_Utils.h b/External/AE SDK/Util/Param_Utils.h new file mode 100644 index 00000000..f4129069 --- /dev/null +++ b/External/AE SDK/Util/Param_Utils.h @@ -0,0 +1,343 @@ +#ifndef H_PARAM_UTILS +#define H_PARAM_UTILS + +// do not include DVA headers here +#include +#include + +// requires the explicit use of 'def' for the struct name + +#define PF_ParamDef_IS_PUI_FLAG_SET(_defP, _puiFlag) \ + (((_defP)->ui_flags & _puiFlag) != 0) + +#define PF_ParamDef_IS_PARAM_FLAG_SET(_defP, _paramFlag) \ + (((_defP)->flags & _paramFlag) != 0) + + +#define PF_ADD_COLOR(NAME, RED, GREEN, BLUE, ID)\ + do {\ + PF_Err priv_err = PF_Err_NONE; \ + def.param_type = PF_Param_COLOR; \ + PF_STRCPY(def.name, (NAME) ); \ + def.u.cd.value.red = (RED); \ + def.u.cd.value.green = (GREEN); \ + def.u.cd.value.blue = (BLUE); \ + def.u.cd.value.alpha = 255; \ + def.u.cd.dephault = def.u.cd.value; \ + def.uu.id = (ID); \ + if ((priv_err = PF_ADD_PARAM(in_data, -1, &def)) != PF_Err_NONE) return priv_err; \ + } while (0) + +#define PF_ADD_ARBITRARY2(NAME, WIDTH, HEIGHT, PARAM_FLAGS, PUI_FLAGS, DFLT, ID, REFCON)\ + do {\ + PF_Err priv_err = PF_Err_NONE; \ + def.param_type = PF_Param_ARBITRARY_DATA; \ + def.flags = (PARAM_FLAGS); \ + PF_STRCPY(def.name, (NAME) ); \ + def.ui_width = (WIDTH);\ + def.ui_height = (HEIGHT);\ + def.ui_flags = (PUI_FLAGS); \ + def.u.arb_d.value = NULL;\ + def.u.arb_d.pad = 0;\ + def.u.arb_d.dephault = (DFLT); \ + def.uu.id = def.u.arb_d.id = (ID); \ + def.u.arb_d.refconPV = REFCON; \ + if ((priv_err = PF_ADD_PARAM(in_data, -1, &def)) != PF_Err_NONE) return priv_err; \ + } while (0) + +#define PF_ADD_ARBITRARY(NAME, WIDTH, HEIGHT, PUI_FLAGS, DFLT, ID, REFCON)\ + PF_ADD_ARBITRARY2(NAME, WIDTH, HEIGHT, PF_ParamFlag_NONE, PUI_FLAGS, DFLT, ID, REFCON) + +#define PF_ADD_SLIDER(NAME, VALID_MIN, VALID_MAX, SLIDER_MIN, SLIDER_MAX, DFLT, ID) \ + do {\ + PF_Err priv_err = PF_Err_NONE; \ + def.param_type = PF_Param_SLIDER; \ + PF_STRCPY(def.name, (NAME) ); \ + def.u.sd.value_str[0] = '\0'; \ + def.u.sd.value_desc[0] = '\0'; \ + def.u.sd.valid_min = (VALID_MIN); \ + def.u.sd.slider_min = (SLIDER_MIN); \ + def.u.sd.valid_max = (VALID_MAX); \ + def.u.sd.slider_max = (SLIDER_MAX); \ + def.u.sd.value = def.u.sd.dephault = (DFLT); \ + def.uu.id = (ID); \ + if ((priv_err = PF_ADD_PARAM(in_data, -1, &def)) != PF_Err_NONE) return priv_err; \ + } while (0) + +#define PF_ADD_FIXED(NAME, VALID_MIN, VALID_MAX, SLIDER_MIN, SLIDER_MAX, DFLT, PREC, DISP, FLAGS, ID) \ + do {\ + PF_Err priv_err = PF_Err_NONE; \ + def.param_type = PF_Param_FIX_SLIDER; \ + PF_STRCPY(def.name, (NAME) ); \ + def.u.fd.value_str[0] = '\0'; \ + def.u.fd.value_desc[0] = '\0'; \ + def.u.fd.valid_min = (PF_Fixed)((VALID_MIN) * 65536.0); \ + def.u.fd.slider_min = (PF_Fixed)((SLIDER_MIN) * 65536.0); \ + def.u.fd.valid_max = (PF_Fixed)((VALID_MAX) * 65536.0); \ + def.u.fd.slider_max = (PF_Fixed)((SLIDER_MAX) * 65536.0); \ + def.u.fd.value = def.u.fd.dephault = (PF_Fixed)((DFLT) * 65536.0); \ + def.u.fd.precision = (A_short)(PREC); \ + def.u.fd.display_flags |= (A_short)(DISP); \ + def.flags |= (FLAGS); \ + def.uu.id = (ID); \ + if ((priv_err = PF_ADD_PARAM(in_data, -1, &def)) != PF_Err_NONE) return priv_err; \ + } while (0) + +// why does fs_flags get or-ed in? and why is CURVE_TOLERANCE param ignored? and .flags is never set. oy. +#define PF_ADD_FLOAT_SLIDER(NAME, VALID_MIN, VALID_MAX, SLIDER_MIN, SLIDER_MAX, CURVE_TOLERANCE, DFLT, PREC, DISP, WANT_PHASE, ID) \ + do {\ + PF_Err priv_err = PF_Err_NONE; \ + def.param_type = PF_Param_FLOAT_SLIDER; \ + PF_STRCPY(def.name, (NAME) ); \ + def.u.fs_d.valid_min = (VALID_MIN); \ + def.u.fs_d.slider_min = (SLIDER_MIN); \ + def.u.fs_d.valid_max = (VALID_MAX); \ + def.u.fs_d.slider_max = (SLIDER_MAX); \ + def.u.fs_d.value = (DFLT); \ + def.u.fs_d.dephault = (PF_FpShort)(def.u.fs_d.value); \ + def.u.fs_d.precision = (PREC); \ + def.u.fs_d.display_flags = (DISP); \ + def.u.fs_d.fs_flags |= (WANT_PHASE) ? PF_FSliderFlag_WANT_PHASE : 0; \ + def.u.fs_d.curve_tolerance = AEFX_AUDIO_DEFAULT_CURVE_TOLERANCE;\ + def.uu.id = (ID); \ + if ((priv_err = PF_ADD_PARAM(in_data, -1, &def)) != PF_Err_NONE) return priv_err; \ + } while (0) + +// safer newer version +#define PF_ADD_FLOAT_SLIDERX(NAME, VALID_MIN, VALID_MAX, SLIDER_MIN, SLIDER_MAX, DFLT, PREC, DISP, FLAGS, ID) \ + do { \ + AEFX_CLR_STRUCT(def); \ + def.flags = (FLAGS); \ + PF_ADD_FLOAT_SLIDER(NAME, VALID_MIN, VALID_MAX, SLIDER_MIN, SLIDER_MAX, 0, DFLT, PREC, DISP, 0, ID); \ + } while (0) + +// copied from Pr version of Param_Utils.h. It is used in some of Pr versions of AE effects +#define PF_ADD_FLOAT_EXPONENTIAL_SLIDER(NAME, VALID_MIN, VALID_MAX, SLIDER_MIN, SLIDER_MAX, CURVE_TOLERANCE, DFLT, PREC, DISP, WANT_PHASE, EXPONENT, ID) \ +do {\ +PF_Err priv_err = PF_Err_NONE; \ +def.param_type = PF_Param_FLOAT_SLIDER; \ +PF_STRCPY(def.name, (NAME) ); \ +def.u.fs_d.valid_min = (VALID_MIN); \ +def.u.fs_d.slider_min = (SLIDER_MIN); \ +def.u.fs_d.valid_max = (VALID_MAX); \ +def.u.fs_d.slider_max = (SLIDER_MAX); \ +def.u.fs_d.value = (DFLT); \ +def.u.fs_d.dephault = (DFLT); \ +def.u.fs_d.precision = (PREC); \ +def.u.fs_d.display_flags = (DISP); \ +def.u.fs_d.fs_flags |= (WANT_PHASE) ? PF_FSliderFlag_WANT_PHASE : 0; \ +def.u.fs_d.curve_tolerance = AEFX_AUDIO_DEFAULT_CURVE_TOLERANCE;\ +def.u.fs_d.useExponent = true;\ +def.u.fs_d.exponent = EXPONENT;\ +def.uu.id = (ID); \ +if ((priv_err = PF_ADD_PARAM(in_data, -1, &def)) != PF_Err_NONE) return priv_err; \ +} while (0) + +enum { PF_Precision_INTEGER, PF_Precision_TENTHS, PF_Precision_HUNDREDTHS, PF_Precision_THOUSANDTHS, PF_Precision_TEN_THOUSANDTHS }; + +#define PF_ADD_CHECKBOX(NAME_A, NAME_B, DFLT, FLAGS, ID)\ + do {\ + PF_Err priv_err = PF_Err_NONE; \ + def.param_type = PF_Param_CHECKBOX; \ + PF_STRCPY(def.name, NAME_A); \ + def.u.bd.u.nameptr = (NAME_B); \ + def.u.bd.value = (DFLT); \ + def.u.bd.dephault = (PF_Boolean)(def.u.bd.value); \ + def.flags |= (FLAGS); \ + def.uu.id = (ID); \ + if ((priv_err = PF_ADD_PARAM(in_data, -1, &def)) != PF_Err_NONE) return priv_err; \ + } while (0) + +// safer newer version +#define PF_ADD_CHECKBOXX(NAME, DFLT, FLAGS, ID)\ + do {\ + AEFX_CLR_STRUCT(def); \ + PF_ADD_CHECKBOX(NAME, "", DFLT, FLAGS, ID); \ + } while (0) + +#define PF_ADD_BUTTON(PARAM_NAME, BUTTON_NAME, PUI_FLAGS, PARAM_FLAGS, ID)\ + do {\ + AEFX_CLR_STRUCT(def); \ + PF_Err priv_err = PF_Err_NONE; \ + def.param_type = PF_Param_BUTTON; \ + PF_STRCPY(def.name, PARAM_NAME); \ + def.u.button_d.u.namesptr = (BUTTON_NAME); \ + def.flags = (PARAM_FLAGS); \ + def.ui_flags = (PUI_FLAGS); \ + def.uu.id = (ID); \ + if ((priv_err = PF_ADD_PARAM(in_data, -1, &def)) != PF_Err_NONE) return priv_err; \ + } while (0) + +#define PF_ADD_ANGLE(NAME, DFLT, ID) \ + do {\ + PF_Err priv_err = PF_Err_NONE; \ + def.param_type = PF_Param_ANGLE; \ + PF_STRCPY(def.name, (NAME) ); \ + def.u.ad.value = def.u.ad.dephault = (PF_Fixed)((DFLT) * 65536.0); \ + def.uu.id = (ID); \ + if ((priv_err = PF_ADD_PARAM(in_data, -1, &def)) != PF_Err_NONE) return priv_err; \ + } while (0) + + +#define PF_ADD_NULL(NAME, ID) \ + do {\ + PF_Err priv_err = PF_Err_NONE; \ + def.param_type = PF_Param_NO_DATA; \ + PF_STRCPY(def.name, (NAME) ); \ + def.uu.id = (ID); \ + if ((priv_err = PF_ADD_PARAM(in_data, -1, &def)) != PF_Err_NONE) return priv_err; \ + } while (0) + + +#define PF_ADD_POPUP(NAME, CHOICES, DFLT, STRING, ID) \ + do {\ + PF_Err priv_err = PF_Err_NONE; \ + def.param_type = PF_Param_POPUP; \ + PF_STRCPY(def.name, (NAME) ); \ + def.u.pd.num_choices = (CHOICES); \ + def.u.pd.dephault = (DFLT); \ + def.u.pd.value = def.u.pd.dephault; \ + def.u.pd.u.namesptr = (STRING); \ + def.uu.id = (ID); \ + if ((priv_err = PF_ADD_PARAM(in_data, -1, &def)) != PF_Err_NONE) return priv_err; \ + } while (0) + +#define PF_ADD_LAYER(NAME, DFLT, ID) \ + do {\ + PF_Err priv_err = PF_Err_NONE; \ + def.param_type = PF_Param_LAYER; \ + PF_STRCPY(def.name, (NAME) ); \ + def.u.ld.dephault = (DFLT); \ + def.uu.id = ID;\ + if ((priv_err = PF_ADD_PARAM(in_data, -1, &def)) != PF_Err_NONE) return priv_err; \ + } while (0) + +#define PF_ADD_255_SLIDER(NAME, DFLT, ID)\ + PF_ADD_SLIDER( (NAME), 0, 255, 0, 255, (DFLT), (ID)) + +#define PF_ADD_PERCENT(NAME, DFLT, ID)\ + PF_ADD_FIXED( (NAME), 0, 100, 0, 100, (DFLT), 1, 1, 0, (ID)) + +#define PF_ADD_POINT(NAME, X_DFLT, Y_DFLT, RESTRICT_BOUNDS, ID) \ + do {\ + PF_Err priv_err = PF_Err_NONE; \ + def.param_type = PF_Param_POINT; \ + PF_STRCPY(def.name, (NAME) ); \ + def.u.td.restrict_bounds = RESTRICT_BOUNDS;\ + def.u.td.x_value = def.u.td.x_dephault = (X_DFLT << 16); \ + def.u.td.y_value = def.u.td.y_dephault = (Y_DFLT << 16); \ + def.uu.id = (ID); \ + if ((priv_err = PF_ADD_PARAM(in_data, -1, &def)) != PF_Err_NONE) return priv_err; \ + } while (0) + +#define PF_ADD_POINT_3D(NAME, X_DFLT, Y_DFLT, Z_DFLT, ID) \ + do {\ + AEFX_CLR_STRUCT(def); \ + PF_Err priv_err = PF_Err_NONE; \ + def.param_type = PF_Param_POINT_3D; \ + PF_STRCPY(def.name, (NAME) ); \ + def.u.point3d_d.x_value = def.u.point3d_d.x_dephault = X_DFLT; \ + def.u.point3d_d.y_value = def.u.point3d_d.y_dephault = Y_DFLT; \ + def.u.point3d_d.z_value = def.u.point3d_d.z_dephault = Y_DFLT; \ + def.uu.id = (ID); \ + if ((priv_err = PF_ADD_PARAM(in_data, -1, &def)) != PF_Err_NONE) return priv_err; \ + } while (0) + +#define PF_ADD_TOPIC(NAME, ID) \ + do {\ + PF_Err priv_err = PF_Err_NONE; \ + def.param_type = PF_Param_GROUP_START; \ + PF_STRCPY(def.name, (NAME) ); \ + def.uu.id = (ID); \ + if ((priv_err = PF_ADD_PARAM(in_data, -1, &def)) != PF_Err_NONE) return priv_err; \ + } while (0) + +#define PF_END_TOPIC(ID) \ + do {\ + PF_Err priv_err = PF_Err_NONE; \ + def.param_type = PF_Param_GROUP_END; \ + def.uu.id = (ID); \ + if ((priv_err = PF_ADD_PARAM(in_data, -1, &def)) != PF_Err_NONE) return priv_err; \ + } while (0) + +#define PF_ADD_VERSIONED_FLAG(NAME) \ + do {\ + PF_Err priv_err = PF_Err_NONE; \ + def.param_type = PF_Param_CHECKBOX; \ + def.name[0] = 0; \ + def.u.bd.u.nameptr = (NAME); \ + def.u.bd.value = true; \ + def.u.bd.dephault = false; \ + def.flags = PF_ParamFlag_USE_VALUE_FOR_OLD_PROJECTS; \ + def.ui_flags = PF_PUI_INVISIBLE; \ + if ((priv_err = PF_ADD_PARAM(in_data, -1, &def)) != PF_Err_NONE) return priv_err; \ + } while (0) + +// newer safer version +#define PF_ADD_TOPICX(NAME, FLAGS, ID) \ + do {\ + AEFX_CLR_STRUCT(def); \ + def.flags = (FLAGS); \ + PF_ADD_TOPIC(NAME, ID); \ + } while (0) + +#define PF_ADD_POPUPX(NAME, NUM_CHOICES, DFLT, ITEMS_STRING, FLAGS, ID) \ + do { \ + AEFX_CLR_STRUCT(def); \ + def.flags = (FLAGS); \ + PF_ADD_POPUP(NAME, NUM_CHOICES, DFLT, ITEMS_STRING, ID); \ + } while (0) + +enum { PF_ParamFlag_NONE=0 }; // SBI:AE_Effect.h + +#define PF_ADD_FLOAT_SLIDERX_DISABLED(NAME, VALID_MIN, VALID_MAX, SLIDER_MIN, SLIDER_MAX, DFLT, PREC, DISP, FLAGS, ID) \ + do { \ + AEFX_CLR_STRUCT(def); \ + def.flags = (FLAGS);\ + def.ui_flags = PF_PUI_DISABLED;\ + PF_ADD_FLOAT_SLIDER(NAME, VALID_MIN, VALID_MAX, SLIDER_MIN, SLIDER_MAX, 0, DFLT, PREC, DISP, 0, ID); \ + } while (0) + +namespace fxparam_utility { + + template + inline int RoundF(T x) + { + int ret; + + if (x > 0) { + ret = (int)(x + (T)0.5); + } else { + if ((int)(x + (T)0.5) == (x + (T)0.5)) { + ret = (int)x; + } else { + ret = (int)(x - (T)0.5); + } + } + + return ret; + } +}; + +inline PF_Err PF_AddPointControl(PF_InData *in_data, + const char *nameZ, + float x_defaultF, // 0-1 + float y_defaultF, // 0-1 + bool restrict_boundsB, + PF_ParamFlags param_flags, + PF_ParamUIFlags pui_flags, + A_long param_id) +{ + PF_ParamDef def = {{0}}; + namespace du = fxparam_utility; + + def.flags = param_flags; + def.ui_flags = pui_flags; + + PF_ADD_POINT(nameZ, du::RoundF(x_defaultF*100), du::RoundF(y_defaultF*100), restrict_boundsB, param_id); // has error return in macro + + return PF_Err_NONE; +} + + +#endif // H_PARAM_UTILS diff --git a/External/AE SDK/Util/Smart_Utils.cpp b/External/AE SDK/Util/Smart_Utils.cpp new file mode 100644 index 00000000..b67378b7 --- /dev/null +++ b/External/AE SDK/Util/Smart_Utils.cpp @@ -0,0 +1,62 @@ +/*******************************************************************/ +/* */ +/* ADOBE CONFIDENTIAL */ +/* _ _ _ _ _ _ _ _ _ _ _ _ _ */ +/* */ +/* Copyright 2007 Adobe Systems Incorporated */ +/* All Rights Reserved. */ +/* */ +/* NOTICE: All information contained herein is, and remains the */ +/* property of Adobe Systems Incorporated and its suppliers, if */ +/* any. The intellectual and technical concepts contained */ +/* herein are proprietary to Adobe Systems Incorporated and its */ +/* suppliers and may be covered by U.S. and Foreign Patents, */ +/* patents in process, and are protected by trade secret or */ +/* copyright law. Dissemination of this information or */ +/* reproduction of this material is strictly forbidden unless */ +/* prior written permission is obtained from Adobe Systems */ +/* Incorporated. */ +/* */ +/*******************************************************************/ + +#include "Smart_Utils.h" + + +PF_Boolean IsEmptyRect(const PF_LRect *r){ + return (r->left >= r->right) || (r->top >= r->bottom); +} + +void UnionLRect(const PF_LRect *src, PF_LRect *dst) +{ + if (IsEmptyRect(dst)) { + *dst = *src; + } else if (!IsEmptyRect(src)) { + dst->left = mmin(dst->left, src->left); + dst->top = mmin(dst->top, src->top); + dst->right = mmax(dst->right, src->right); + dst->bottom = mmax(dst->bottom, src->bottom); + } +} + +PF_Boolean +IsEdgePixel( + PF_LRect *rectP, + A_long x, + A_long y) +{ + PF_Boolean x_hitB = FALSE, + y_hitB = FALSE; + + x_hitB = ((x == rectP->left) || (x == rectP->right)); + + y_hitB = ((y == rectP->top) || (y == rectP->bottom)); + + if (x_hitB){ + y_hitB = ((y >= rectP->top) && (y <= rectP->bottom)); + } else { + if (y_hitB){ + x_hitB = ((x >= rectP->left) && (x <= rectP->right)); + } + } + return (x_hitB && y_hitB); +} \ No newline at end of file diff --git a/External/AE SDK/Util/Smart_Utils.h b/External/AE SDK/Util/Smart_Utils.h new file mode 100644 index 00000000..3e1c03ce --- /dev/null +++ b/External/AE SDK/Util/Smart_Utils.h @@ -0,0 +1,34 @@ +/*******************************************************************/ +/* */ +/* ADOBE CONFIDENTIAL */ +/* _ _ _ _ _ _ _ _ _ _ _ _ _ */ +/* */ +/* Copyright 2007 Adobe Systems Incorporated */ +/* All Rights Reserved. */ +/* */ +/* NOTICE: All information contained herein is, and remains the */ +/* property of Adobe Systems Incorporated and its suppliers, if */ +/* any. The intellectual and technical concepts contained */ +/* herein are proprietary to Adobe Systems Incorporated and its */ +/* suppliers and may be covered by U.S. and Foreign Patents, */ +/* patents in process, and are protected by trade secret or */ +/* copyright law. Dissemination of this information or */ +/* reproduction of this material is strictly forbidden unless */ +/* prior written permission is obtained from Adobe Systems */ +/* Incorporated. */ +/* */ +/*******************************************************************/ + +#include "AE_Effect.h" +#include "SPTypes.h" + +#ifndef mmin + #define mmin(a,b) ((a) < (b) ? (a) : (b)) + #define mmax(a,b) ((a) > (b) ? (a) : (b)) +#endif + +PF_Boolean IsEmptyRect(const PF_LRect *r); + +void UnionLRect(const PF_LRect *src, PF_LRect *dst); + +PF_Boolean IsEdgePixel(PF_LRect *rectP, A_long x, A_long y); \ No newline at end of file diff --git a/External/AE SDK/Util/String_Utils.h b/External/AE SDK/Util/String_Utils.h new file mode 100644 index 00000000..00f9f9ad --- /dev/null +++ b/External/AE SDK/Util/String_Utils.h @@ -0,0 +1,48 @@ +/*******************************************************************/ +/* */ +/* ADOBE CONFIDENTIAL */ +/* _ _ _ _ _ _ _ _ _ _ _ _ _ */ +/* */ +/* Copyright 2007 Adobe Systems Incorporated */ +/* All Rights Reserved. */ +/* */ +/* NOTICE: All information contained herein is, and remains the */ +/* property of Adobe Systems Incorporated and its suppliers, if */ +/* any. The intellectual and technical concepts contained */ +/* herein are proprietary to Adobe Systems Incorporated and its */ +/* suppliers and may be covered by U.S. and Foreign Patents, */ +/* patents in process, and are protected by trade secret or */ +/* copyright law. Dissemination of this information or */ +/* reproduction of this material is strictly forbidden unless */ +/* prior written permission is obtained from Adobe Systems */ +/* Incorporated. */ +/* */ +/*******************************************************************/ + + + +/* String_Utils.h */ + + +#pragma once + +#ifndef STRING_UTILS_H +#define STRING_UTILS_H + +#if defined(__cplusplus) +extern "C" { +#endif +A_char *GetStringPtr(int strNum); +#if defined(__cplusplus) +} +#endif + +#define STR(_foo) GetStringPtr(_foo) + + + + + + + +#endif /* STRING_UTILS_H */ \ No newline at end of file diff --git a/External/AE SDK/Util/entry.h b/External/AE SDK/Util/entry.h new file mode 100644 index 00000000..6a0175db --- /dev/null +++ b/External/AE SDK/Util/entry.h @@ -0,0 +1,53 @@ +/*******************************************************************/ +/* */ +/* ADOBE CONFIDENTIAL */ +/* _ _ _ _ _ _ _ _ _ _ _ _ _ */ +/* */ +/* Copyright 2007 Adobe Systems Incorporated */ +/* All Rights Reserved. */ +/* */ +/* NOTICE: All information contained herein is, and remains the */ +/* property of Adobe Systems Incorporated and its suppliers, if */ +/* any. The intellectual and technical concepts contained */ +/* herein are proprietary to Adobe Systems Incorporated and its */ +/* suppliers and may be covered by U.S. and Foreign Patents, */ +/* patents in process, and are protected by trade secret or */ +/* copyright law. Dissemination of this information or */ +/* reproduction of this material is strictly forbidden unless */ +/* prior written permission is obtained from Adobe Systems */ +/* Incorporated. */ +/* */ +/*******************************************************************/ + +/* + Entry.h + + Part of the Adobe After Effects SDK. +*/ + +#include "AE_PluginData.h" + +#ifdef AE_OS_WIN + #define DllExport __declspec( dllexport ) +#elif defined AE_OS_MAC + #define DllExport __attribute__ ((visibility ("default"))) +#endif + + +#define AE_ENTRY_POINT "EffectMain" +#define AE_RESERVED_INFO 8 + +#define PF_REGISTER_EFFECT(INPTR, CBPTR, NAME, MATCHNAME, CATEGORY,RESERVEDINFO) \ + result = (*(CBPTR))((INPTR),\ + reinterpret_cast(NAME),\ + reinterpret_cast(MATCHNAME),\ + reinterpret_cast(CATEGORY),\ + reinterpret_cast(AE_ENTRY_POINT),\ + 'eFKT',\ + PF_AE_PLUG_IN_VERSION,\ + PF_AE_PLUG_IN_SUBVERS,\ + RESERVEDINFO);\ + if(result == A_Err_NONE)\ + {\ + result = PF_Err_NONE;\ + } diff --git a/External/popcornfx.qt/Qt5Core.dll b/External/popcornfx.qt/Qt5Core.dll new file mode 100644 index 00000000..c0a7b6b7 --- /dev/null +++ b/External/popcornfx.qt/Qt5Core.dll @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:dae3aefe8afc6ecce88184c8908722af6a1382bcf2a67ea66fe5c97dfa59322a +size 6453232 diff --git a/External/popcornfx.qt/Qt5Gui.dll b/External/popcornfx.qt/Qt5Gui.dll new file mode 100644 index 00000000..b3b7f0cb --- /dev/null +++ b/External/popcornfx.qt/Qt5Gui.dll @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:38a6c697833268f5c5013e68e8bb7f7b7ef00bd9946ebfc9d563f533fa55bf66 +size 7208960 diff --git a/External/popcornfx.qt/Qt5Widgets.dll b/External/popcornfx.qt/Qt5Widgets.dll new file mode 100644 index 00000000..fb41e8cd --- /dev/null +++ b/External/popcornfx.qt/Qt5Widgets.dll @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:da032d6457d5f6993c3aa3388d62739d9c3387a5d34edd0b7f79a81cb9af6f74 +size 5562880 diff --git a/External/popcornfx.qt/popcornfx.qt.manifest b/External/popcornfx.qt/popcornfx.qt.manifest new file mode 100644 index 00000000..f2161de7 --- /dev/null +++ b/External/popcornfx.qt/popcornfx.qt.manifest @@ -0,0 +1,9 @@ + +" + + + + + + + \ No newline at end of file diff --git a/External/popcornfx.qt/qwindows.dll b/External/popcornfx.qt/qwindows.dll new file mode 100644 index 00000000..4a3eaf74 --- /dev/null +++ b/External/popcornfx.qt/qwindows.dll @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:9f083147f27e7f6ac7d8d97b02e165cfb00af89b2b79ab4524971d0cfc5eaca9 +size 1469952 diff --git a/Native/debugger/PopcornFX.natvis b/Native/debugger/PopcornFX.natvis new file mode 100644 index 00000000..94eba7ef --- /dev/null +++ b/Native/debugger/PopcornFX.natvis @@ -0,0 +1,409 @@ + + + + + + + + + + + + null + {*((char**)((ptrdiff_t)m_Container.m_Ptr + (((sizeof(PopcornFX::CStringContainer) + 4) + (sizeof(void*) - 1)) & ~((ptrdiff_t)(sizeof(void*) - 1))))),s} [Len={m_Container.m_Ptr->m_Length & 0x7FFFFFFF}] + {(char*)((ptrdiff_t)m_Container.m_Ptr + sizeof(PopcornFX::CStringContainer) + (0xF - ((sizeof(PopcornFX::CStringContainer) + 0xF) & ((ptrdiff_t)0xF)))),s} [Len={m_Container.m_Ptr->m_Length & 0x7FFFFFFF}] + null + *((char**)((ptrdiff_t)m_Container.m_Ptr + (((sizeof(PopcornFX::CStringContainer) + 4) + (sizeof(void*) - 1)) & ~((ptrdiff_t)(sizeof(void*) - 1))))),s + (char*)((ptrdiff_t)m_Container.m_Ptr + sizeof(PopcornFX::CStringContainer) + (0xF - ((sizeof(PopcornFX::CStringContainer) + 0xF) & ((ptrdiff_t)0xF)))),s + + + + null + {*((wchar_t**)((ptrdiff_t)m_Container.m_Ptr + sizeof(PopcornFX::CStringUnicodeContainer) + 4)),su} [Len={m_Container.m_Ptr->m_Length & 0x7FFFFFFF}] + {(wchar_t*)(((ptrdiff_t)m_Container.m_Ptr + sizeof(PopcornFX::CStringUnicodeContainer) + 0xF) & ~((ptrdiff_t)0xF)),su} [Len={m_Container.m_Ptr->m_Length & 0x7FFFFFFF}] + null + *((wchar_t**)((ptrdiff_t)m_Container.m_Ptr + sizeof(PopcornFX::CStringUnicodeContainer) + 4)),su + (wchar_t*)(((ptrdiff_t)m_Container.m_Ptr + sizeof(PopcornFX::CStringUnicodeContainer) + 0xF) & ~((ptrdiff_t)0xF)),su + + + + Id=0 null + Id={m_Id} {PopcornFX::CStringInternals::m_StringIdDictionnary->m_StringIdPool.m_Chunks[m_Id / PopcornFX::CStringIdDictionary::kPoolChunkSize][m_Id % PopcornFX::CStringIdDictionary::kPoolChunkSize]} + + PopcornFX::CStringInternals::m_StringIdDictionnary->m_StringIdPool.m_Chunks[m_Id / PopcornFX::CStringIdDictionary::kPoolChunkSize][m_Id % PopcornFX::CStringIdDictionary::kPoolChunkSize] + + + + + null + {m_Data,[m_Length]s} [Len={m_Length}] + + + + null + {m_DataFeed.m_Ptr} + + m_DataFeed.m_Ptr + + + + + {{RefPtr={(void*)m_Ptr}}} + + m_Ptr + + + + {{WeakPtr={(void*)m_Ptr}}} + + m_Ptr + + + + {{ScopedPtr={(void*)m_Ptr}}} + + m_Ptr + + + + + {{A Count={m_Count}}} + + + m_Count + ($T1*)m_Data + + + + + + {{A Count={m_Count}}} + + + m_Count + ($T1*)m_Data + + + + + + {{SDA Count={m_Count & 0x7FFFFFFF} Data={(void*)m_Allocated.m_Data}} + {{SDA Count={m_Count & 0x7FFFFFFF} Data={(void*)(((unsigned long long)m_StaticData + kAlignment - 1) & - kAlignment)}} + + + m_Count & 0x7FFFFFFF + ($T1*)m_Allocated.m_Data + + + m_Count + ($T1*)(((unsigned long long)m_StaticData + kAlignment - 1) & - kAlignment) + + + + + + {{SFA Count={m_Count}, Data={(void*)m_Data}, Cap={m_Capacity}}} + + + m_Count + ($T1*)m_Data + + + + + + {{SA _Count={$T2}, Data={(void*)(((unsigned long long)_m_Data + kAlignment - 1) & - kAlignment)} + + + $T2 + ($T1*)(((unsigned long long)_m_Data + kAlignment - 1) & - kAlignment) + + + + + + {{SCA Count={m_Count}, Data={(void*)(((unsigned long long)_m_Data + kAlignment - 1) & - kAlignment)}}} + + + m_Count + ($T1*)(((unsigned long long)_m_Data + kAlignment - 1) & - kAlignment) + + + + + + {{CA Count={$T2 * m_ChunksCount}({$T2}*{m_ChunksCount}), ChuncksCap={m_ChunksCapacity}}} + + + $T2 * m_ChunksCount + m_Chunks[$i / $T2][$i % $T2] + + + + + + {{SlotA UsedCount={m_UsedSlots} _Count={$T2}}} + + + $T2 + ($T1*)m_Data + + + + + + {{SlotA UsedCount={m_UsedSlots} Count={m_DataSizeInBytes / sizeof($T1)}}} + + + m_DataSizeInBytes / sizeof($T1) + ($T1*)m_Data + + + + + + {{MV Count={m_Count}, Data={(void*)m_Data}, sizeof={sizeof($T1)}}} + + + m_Count + ($T1*)m_Data + + + + + + {{SMV Count={m_Storage.m_Count}, Data={(void*)m_Storage.m_RawDataPtr}, Stride={m_Storage.m_Stride}, sizeof={sizeof($T1)}}} + + + m_Storage.m_Count + *(($T1*)(m_Storage.m_RawDataPtr + $i * m_Storage.m_Stride)) + + + + + + {{SMVF Count={m_Storage.m_Count}, Data={(void*)m_Storage.m_RawDataPtr}, Stride={m_Storage.m_Stride}, Footp={m_ElementFootprintInBytes}, sizeof={sizeof($T1)}} + + + m_Storage.m_Count + *(($T1*)(m_Storage.m_RawDataPtr + $i * m_Storage.m_Stride)) + + + + + + {{First={m_First}, Second={m_Second}}} + + m_First + m_Second + + + + + {{FHM Count={m_Count}, Data={(void*)m_Slots}, Size={m_Size}}} + + + m_Size + m_Slots + + + + + + + empty + + void (error) + + + const class cr{m_RawBits & 0xFFFF,d} + variable class vr{m_RawBits & 0xFFFF,d} + instance class ir{m_RawBits & 0xFFFF,d} + stream class sr{m_RawBits & 0xFFFF,d} + + + const bool1 cr{m_RawBits & 0xFFFF,d} + variable bool1 vr{m_RawBits & 0xFFFF,d} + instance bool1 ir{m_RawBits & 0xFFFF,d} + stream bool1 sr{m_RawBits & 0xFFFF,d} + + const bool2 cr{m_RawBits & 0xFFFF,d} + variable bool2 vr{m_RawBits & 0xFFFF,d} + instance bool2 ir{m_RawBits & 0xFFFF,d} + stream bool2 sr{m_RawBits & 0xFFFF,d} + + const bool3 cr{m_RawBits & 0xFFFF,d} + variable bool3 vr{m_RawBits & 0xFFFF,d} + instance bool3 ir{m_RawBits & 0xFFFF,d} + stream bool3 sr{m_RawBits & 0xFFFF,d} + + const bool4 cr{m_RawBits & 0xFFFF,d} + variable bool4 vr{m_RawBits & 0xFFFF,d} + instance bool4 ir{m_RawBits & 0xFFFF,d} + stream bool4 sr{m_RawBits & 0xFFFF,d} + + + const int1 cr{m_RawBits & 0xFFFF,d} + variable int1 vr{m_RawBits & 0xFFFF,d} + instance int1 ir{m_RawBits & 0xFFFF,d} + stream int1 sr{m_RawBits & 0xFFFF,d} + + const int2 cr{m_RawBits & 0xFFFF,d} + variable int2 vr{m_RawBits & 0xFFFF,d} + instance int2 ir{m_RawBits & 0xFFFF,d} + stream int2 sr{m_RawBits & 0xFFFF,d} + + const int3 cr{m_RawBits & 0xFFFF,d} + variable int3 vr{m_RawBits & 0xFFFF,d} + instance int3 ir{m_RawBits & 0xFFFF,d} + stream int3 sr{m_RawBits & 0xFFFF,d} + + const int4 cr{m_RawBits & 0xFFFF,d} + variable int4 vr{m_RawBits & 0xFFFF,d} + instance int4 ir{m_RawBits & 0xFFFF,d} + stream int4 sr{m_RawBits & 0xFFFF,d} + + + const float1 cr{m_RawBits & 0xFFFF,d} + variable float1 vr{m_RawBits & 0xFFFF,d} + instance float1 ir{m_RawBits & 0xFFFF,d} + stream float1 sr{m_RawBits & 0xFFFF,d} + + const float2 cr{m_RawBits & 0xFFFF,d} + variable float2 vr{m_RawBits & 0xFFFF,d} + instance float2 ir{m_RawBits & 0xFFFF,d} + stream float2 sr{m_RawBits & 0xFFFF,d} + + const float3 cr{m_RawBits & 0xFFFF,d} + variable float3 vr{m_RawBits & 0xFFFF,d} + instance float3 ir{m_RawBits & 0xFFFF,d} + stream float3 sr{m_RawBits & 0xFFFF,d} + + const float4 cr{m_RawBits & 0xFFFF,d} + variable float4 vr{m_RawBits & 0xFFFF,d} + instance float4 ir{m_RawBits & 0xFFFF,d} + stream float4 sr{m_RawBits & 0xFFFF,d} + + + const orientation cr{m_RawBits & 0xFFFF,d} + variable orientation vr{m_RawBits & 0xFFFF,d} + instance orientation ir{m_RawBits & 0xFFFF,d} + stream orientation sr{m_RawBits & 0xFFFF,d} + + + + + + Range = ]{m_BoundMin.m_Value.m_Data32u,X}, {m_BoundMax.m_Value.m_Data32u,X}[ - ]{m_BoundMin.m_Value.m_Data32f}, {m_BoundMax.m_Value.m_Data32f}[ - ]{m_BoundMin.m_Value.m_Data32s}, {m_BoundMax.m_Value.m_Data32s}[ + Range = ]{m_BoundMin.m_Value.m_Data32u,X}, {m_BoundMax.m_Value.m_Data32u,X}] - ]{m_BoundMin.m_Value.m_Data32f}, {m_BoundMax.m_Value.m_Data32f}] - ]{m_BoundMin.m_Value.m_Data32s}, {m_BoundMax.m_Value.m_Data32s}] + Range = [{m_BoundMin.m_Value.m_Data32u,X}, {m_BoundMax.m_Value.m_Data32u,X}[ - [{m_BoundMin.m_Value.m_Data32f}, {m_BoundMax.m_Value.m_Data32f}[ - [{m_BoundMin.m_Value.m_Data32s}, {m_BoundMax.m_Value.m_Data32s}[ + Range = [{m_BoundMin.m_Value.m_Data32u,X}, {m_BoundMax.m_Value.m_Data32u,X}] - [{m_BoundMin.m_Value.m_Data32f}, {m_BoundMax.m_Value.m_Data32f}] - [{m_BoundMin.m_Value.m_Data32s}, {m_BoundMax.m_Value.m_Data32s}] + + + + X + O + + + + {*(PopcornFX::Range::Internal::_SConstantRange_Natvis*)(m_BoundMin.m_Value.m_Data32u + 0)} + + + 4 + (PopcornFX::Range::Internal::_SConstantRange_Natvis*)(m_BoundMin.m_Value.m_Data32u + $i) + + + + + + {*(PopcornFX::Range::Internal::_SConstantEdge_Natvis*)(m_Edge.m_Data+0)}{*(PopcornFX::Range::Internal::_SConstantEdge_Natvis*)(m_Edge.m_Data+1)}{*(PopcornFX::Range::Internal::_SConstantEdge_Natvis*)(m_Edge.m_Data+2)}{*(PopcornFX::Range::Internal::_SConstantEdge_Natvis*)(m_Edge.m_Data+3)}: |{m_Value.m_Data32u[0],X}, {m_Value.m_Data32u[1],X}, {m_Value.m_Data32u[2],X}, {m_Value.m_Data32u[3],X}| - |{m_Value.m_Data32f[0]}, {m_Value.m_Data32f[1]}, {m_Value.m_Data32f[2]}, {m_Value.m_Data32f[3]}| - |{m_Value.m_Data32s[0]}, {m_Value.m_Data32s[1]}, {m_Value.m_Data32s[2]}, {m_Value.m_Data32s[3]}| + + + + INVALID + void + auto + byte + float + float2 + float3 + float4 + int + int2 + int3 + int4 + bool + bool2 + bool3 + bool4 + orientation + + m_Index + + + + + (PopcornFX::CVStreamSemanticDictionnary::EDefaultOrdinals)(m_Code >> 8) + (m_Code >> 8) + + (PopcornFX::CVStreamSemanticDictionnary::EDefaultOrdinals)(m_Code >> 8) + (m_Code >> 8) + (PopcornFX::SVStreamCode::EElementType)(m_Code & 0x1F) + (m_Code & 0x80) != 0 + (m_Code & 0x40) != 0 + m_Code + + + + + v{(m_Key >> 29) & 0x7,d}.{(m_Key >> 24) & 0x1F,d}.{(m_Key >> 18) & 0x3F,d}.{m_Key & 0x3FFFF,d} + + m_Key + + + + + {m_Data} + + + $T2 + m_Data + + + + + + {m_Axes} + + + $T2 + m_Axes + + + + + + {{{m_Imag[0]}, {m_Imag[1]}, {m_Imag[2]}, {m_Real}}} + + + 4 + m_Imag + + + + + diff --git a/Native/debugger/qt5.natvis b/Native/debugger/qt5.natvis new file mode 100644 index 00000000..65bf3a65 --- /dev/null +++ b/Native/debugger/qt5.natvis @@ -0,0 +1,683 @@ + + + + + + {{ x = {xp}, y = {yp} }} + + xp + yp + + + + + {{ x = {x1}, y = {y1}, width = {x2 - x1 + 1}, height = {y2 - y1 + 1} }} + + x1 + y1 + x2 - x1 + 1 + y2 - y1 + 1 + + + + + {{ x = {xp}, y = {yp}, width = {w}, height = {h} }} + + xp + yp + w + h + + + + + + {{ width = {wd}, height = {ht} }} + + wd + ht + + + + + + {{ start point = {pt1}, end point = {pt2} }} + + + {pt1} + + pt1 + + + + {pt2} + + pt2 + + + + + + + + {{ size = {d->size} }} + + d->ref.atomic._q_value + + d->size + (QPoint*)((reinterpret_cast<char*>(d)) + d->offset) + + + + + + {{ size = {d->size} }} + + + d->size > 0 + && ((((QPointF*)((reinterpret_cast<char*>(d)) + d->offset)[0]).xp + == (((QPointF*)((reinterpret_cast<char*>(d)) + d->offset)[d->size - 1]).xp) + && ((((QPointF*)((reinterpret_cast<char*>(d)) + d->offset)[0]).yp + == (((QPointF*)((reinterpret_cast<char*>(d)) + d->offset)[d->size - 1]).yp) + + d->ref.atomic._q_value + + d->size + (QPointF*)((reinterpret_cast<char*>(d)) + d->offset) + + + + + + {{ x = {xp}, y = {yp} }} + + xp + yp + + + + + {{ x = {xp}, y = {yp}, z = {zp} }} + + xp + yp + zp + + + + + {{ x = {xp}, y = {yp}, z = {zp}, w = {wp} }} + + xp + yp + zp + wp + + + + + + {{ m11 = {_m11}, m12 = {_m12}, m21 = {_m21}, m22 = {_m22}, ... }} + + + _m11 + _m12 + _m21 + _m22 + _dx + _dy + + + + + + {{ m11 = {m[0][0]}, m12 = {m[1][0]}, m13 = {m[2][0]}, m14 = {m[3][0]}, ... }} + + + m[0][0] + m[1][0] + m[2][0] + m[3][0] + m[0][1] + m[1][1] + m[2][1] + m[3][1] + m[0][2] + m[1][2] + m[2][2] + m[3][2] + m[0][3] + m[1][3] + m[2][3] + m[3][3] + + + + + + {{ horizontal = {static_cast<Policy>(bits.horPolicy)}, vertical = {static_cast<Policy>(bits.verPolicy)}, type = {ControlType(1 << bits.ctype)} }} + + + + QSizePolicy::Policy::{static_cast<Policy>(bits.verPolicy)} + + + QSizePolicy::Policy::{static_cast<Policy>(bits.horPolicy)} + + + QSizePolicy::ControlType::{ControlType(1 << bits.ctype)} + + + + Qt::Vertical (2) + + + Qt::Horizontal (1) + + + static_cast<int>(bits.verStretch) + static_cast<int>(bits.horStretch) + bits.hfw == 1 + bits.wfh == 1 + + + + + {ucs,c} + ucs,c + + ucs > 0xff ? '\0' : char(ucs),c + ucs,c + + + + + {((reinterpret_cast<unsigned short*>(d)) + d->offset / 2),sub} + ((reinterpret_cast<unsigned short*>(d)) + d->offset / 2),sub + + d->size + d->ref.atomic._q_value + + d->size + ((reinterpret_cast<unsigned short*>(d)) + d->offset / 2),c + + + + + + {((reinterpret_cast<char*>(d)) + d->offset),sb} + ((reinterpret_cast<char*>(d)) + d->offset),sb + + d->size + d->ref.atomic._q_value + + d->size + ((reinterpret_cast<char*>(d)) + d->offset),c + + + + + + {{ size = {(d.d->size << 3) - *((reinterpret_cast<char*>(d.d)) + d.d->offset)} }} + + d.d->ref.atomic._q_value + + (d.d->size << 3) - *((reinterpret_cast<char*>(d.d)) + d.d->offset) + + (*(reinterpret_cast<const unsigned char*>((reinterpret_cast<char*>(d.d)) + d.d->offset) + 1 + + ($i >> 3)) & (1 << ($i & 7))) != 0 + + + + + + + + {{ size = {s} }} + + a + + s + ptr + + + + + + {{ julian day = {jd} }} + + + + + {{ millisecond = {mds} }} + {{ milliseconds = {mds} }} + + mds / 3600000, d + mds / 3600000, d + (mds % 3600000) / 60000, d + (mds % 3600000) / 60000, d + (mds / 1000) % 60, d + (mds / 1000) % 60, d + mds % 1000, d + mds % 1000, d + + + + + {d.pattern} + + + + + ref._q_value + + + + + strong reference to shared pointer of type {"$T1"} + + value == 0 + d->weakref._q_value + d->strongref._q_value + + + + + pointer to implicit shared object of type {"$T1"} + + d + + + + + pointer to explicit shared object of type {"$T1"} + + d + + + + + guarded pointer to subclass of QObject of type {"$T1"} + + wp.d == 0 || wp.d->strongref._q_value == 0 || wp.value == 0 + + + + + weak reference to shared pointer of type {"$T1"} + + d == 0 || d->strongref._q_value == 0 || value == 0 + d->weakref._q_value + d->strongref._q_value + + + + + scoped pointer to a dynamically allocated object of type {"$T1"} + + !d + + + + + scoped pointer to dynamically allocated array of objects of type {"$T1"} + + !d + + + + + ({first}, {second}) + + first + second + + + + + + {{ size = {d->size} }} + + d->ref.atomic._q_value + + d->size + ($T1*)((reinterpret_cast<char*>(d)) + d->offset) + + + + + + + + {{ size = {d->end - d->begin} }} + + d->ref.atomic._q_value + + d->end - d->begin + + *reinterpret_cast<$T1*>((sizeof($T1) > sizeof(void*)) + ? reinterpret_cast<Node*>(d->array + d->begin + $i)->v + : reinterpret_cast<$T1*>(d->array + d->begin + $i)) + + + + + + + {{ size = {d->size} }} + + d->ref.atomic._q_value + + d->size + d->n + n + (*(QLinkedListNode<$T1>*)this).t + + + + + + ({key}, {value}) + + key + value + + + + + + {{ size = {d->size} }} + + d->ref.atomic._q_value + + d->size + d->header.left + left + right + *((QMapNode<$T1,$T2>*)this) + + + + + + (empty) + ({key}, {value}) + + key + value + + + + + + {{ size = {d->size} }} + + d->ref.atomic._q_value + + d->numBuckets + *((QHashNode<$T1,$T2>*)d->buckets[$i]) + + + + + + (empty) + ({key}) + + key + + + + + {{ size = {q_hash.d->size} }} + + q_hash + + + + + ({*keyPtr}, {*t}) + + *keyPtr + *t + + + + + {{ size = {hash.d->size} }} + + mx + total + hash.d->ref.atomic._q_value + + hash.d->size + f + n + *((Node*)this) + + + + + + + + Invalid + {d.data.b} + {d.data.i} + {d.data.u} + {d.data.ll} + {d.data.ull} + {d.data.d} + {d.data.c} + + {*((QMap<QString,QVariant>*)(d.is_shared ? d.data.shared->ptr + : reinterpret_cast<const void *>(&d.data.ptr)))} + + + {*((QList<QVariant>*)(d.is_shared ? d.data.shared->ptr + : reinterpret_cast<const void *>(&d.data.ptr)))} + + + {*((QString*)(d.is_shared ? d.data.shared->ptr + : reinterpret_cast<const void *>(&d.data.ptr)))} + + + {*((QStringList*)(d.is_shared ? d.data.shared->ptr + : reinterpret_cast<const void *>(&d.data.ptr)))} + + + {*((QByteArray*)(d.is_shared ? d.data.shared->ptr + : reinterpret_cast<const void *>(&d.data.ptr)))} + + + {*((QBitArray*)(d.is_shared ? d.data.shared->ptr + : reinterpret_cast<const void *>(&d.data.ptr)))} + + + {*((QDate*)(d.is_shared ? d.data.shared->ptr + : reinterpret_cast<const void *>(&d.data.ptr)))} + + + {*((QTime*)(d.is_shared ? d.data.shared->ptr + : reinterpret_cast<const void *>(&d.data.ptr)))} + + DateTime + Url + Locale + + {*((QRect*)(d.is_shared ? d.data.shared->ptr + : reinterpret_cast<const void *>(&d.data.ptr)))} + + + {*((QRectF*)(d.is_shared ? d.data.shared->ptr + : reinterpret_cast<const void *>(&d.data.ptr)))} + + + {*((QSize*)(d.is_shared ? d.data.shared->ptr + : reinterpret_cast<const void *>(&d.data.ptr)))} + + + {*((QSizeF*)(d.is_shared ? d.data.shared->ptr + : reinterpret_cast<const void *>(&d.data.ptr)))} + + + {*((QLine*)(d.is_shared ? d.data.shared->ptr + : reinterpret_cast<const void *>(&d.data.ptr)))} + + + {*((QLineF*)(d.is_shared ? d.data.shared->ptr + : reinterpret_cast<const void *>(&d.data.ptr)))} + + + {*((QPoint*)(d.is_shared ? d.data.shared->ptr + : reinterpret_cast<const void *>(&d.data.ptr)))} + + + {*((QPointF*)(d.is_shared ? d.data.shared->ptr + : reinterpret_cast<const void *>(&d.data.ptr)))} + + RegExp + RegularExpression + + {*((QHash<QString,QVariant>*)(d.is_shared ? d.data.shared->ptr + : reinterpret_cast<const void *>(&d.data.ptr)))} + + EasingCurve + Uuid + ModelIndex + LastCoreType + Font + Pixmap + Brush + Color + Palette + Image + Polygon + Region + Bitmap + Cursor + KeySequence + Pen + TextLength + TextFormat + Matrix + Transform + Matrix4x4 + Vector2D + Vector3D + Vector4D + Quaternion + PolygonF + Icon + LastGuiType + SizePolicy + UserType + LastType + + + + + + d.data.c + + + *((QString*)(d.is_shared ? d.data.shared->ptr + : reinterpret_cast<const void *>(&d.data.ptr))) + + + + *((QByteArray*)(d.is_shared ? d.data.shared->ptr + : reinterpret_cast<const void *>(&d.data.ptr))) + + + + + + + + + *((QMap<QString,QVariant>*)(d.is_shared ? d.data.shared->ptr + : reinterpret_cast<const void *>(&d.data.ptr))) + + + *((QList<QVariant>*)(d.is_shared ? d.data.shared->ptr + : reinterpret_cast<const void *>(&d.data.ptr))) + + + *((QString*)(d.is_shared ? d.data.shared->ptr + : reinterpret_cast<const void *>(&d.data.ptr))) + + + *((QStringList*)(d.is_shared ? d.data.shared->ptr + : reinterpret_cast<const void *>(&d.data.ptr))) + + + *((QByteArray*)(d.is_shared ? d.data.shared->ptr + : reinterpret_cast<const void *>(&d.data.ptr))) + + + *((QBitArray*)(d.is_shared ? d.data.shared->ptr + : reinterpret_cast<const void *>(&d.data.ptr))) + + + *((QDate*)(d.is_shared ? d.data.shared->ptr + : reinterpret_cast<const void *>(&d.data.ptr))) + + + *((QTime*)(d.is_shared ? d.data.shared->ptr + : reinterpret_cast<const void *>(&d.data.ptr))) + + + *((QRect*)(d.is_shared ? d.data.shared->ptr + : reinterpret_cast<const void *>(&d.data.ptr))) + + + *((QRectF*)(d.is_shared ? d.data.shared->ptr + : reinterpret_cast<const void *>(&d.data.ptr))) + + + *((QSize*)(d.is_shared ? d.data.shared->ptr + : reinterpret_cast<const void *>(&d.data.ptr))) + + + *((QSizeF*)(d.is_shared ? d.data.shared->ptr + : reinterpret_cast<const void *>(&d.data.ptr))) + + + *((QLine*)(d.is_shared ? d.data.shared->ptr + : reinterpret_cast<const void *>(&d.data.ptr))) + + + *((QLineF*)(d.is_shared ? d.data.shared->ptr + : reinterpret_cast<const void *>(&d.data.ptr))) + + + *((QPoint*)(d.is_shared ? d.data.shared->ptr + : reinterpret_cast<const void *>(&d.data.ptr))) + + + *((QPointF*)(d.is_shared ? d.data.shared->ptr + : reinterpret_cast<const void *>(&d.data.ptr))) + + + *((QHash<QString,QVariant>*)(d.is_shared ? d.data.shared->ptr + : reinterpret_cast<const void *>(&d.data.ptr))) + + + + + + + diff --git a/PopcornFX/CHANGELOG.md b/PopcornFX/CHANGELOG.md new file mode 100644 index 00000000..be56853b --- /dev/null +++ b/PopcornFX/CHANGELOG.md @@ -0,0 +1,3 @@ +# Changelog +For each PopcornFX **Editor** / **Runtime SDK** there is one matching After Effects plugin version. +Official changelog for each version can be found [here](https://www.popcornfx.com/category/news/) \ No newline at end of file diff --git a/PopcornFX/LICENSE.md b/PopcornFX/LICENSE.md new file mode 100644 index 00000000..1814cd64 --- /dev/null +++ b/PopcornFX/LICENSE.md @@ -0,0 +1,14 @@ +# After Effects PopcornFX Plugin and its PopcornFX Runtime SDK License + +[PopcornFX store terms & conditions](http://www.popcornfx.com/terms-and-conditions/) +governs the After Effects PopcornFX Plugin, its PopcornFX Runtime SDK, and +related products licenses. + +* After Effects PopcornFX Plugin **source code** AND its PopcornFX Runtime SDK + **source code and binaries**: + * You cannot lease, rent or sell them in any form + * You will only use them in Adobe After Effects + * You cannot use them in a different way + * http://www.popcornfx.com/terms-and-conditions/ +* Any other form of the After Effects PopcornFX Plugin and PopcornFX Runtime SDK: + * http://www.popcornfx.com/terms-and-conditions/ diff --git a/PopcornFX/PK-ShaderTool_r.exe b/PopcornFX/PK-ShaderTool_r.exe new file mode 100755 index 00000000..f12f8ac1 --- /dev/null +++ b/PopcornFX/PK-ShaderTool_r.exe @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:a7b0fedfe562427e13f1240e29fc6b853faa8d0f9bdada8761cf58ba551ad5f1 +size 7867904 diff --git a/PopcornFX/PopcornFXInternals/Meshes/default.pkmm b/PopcornFX/PopcornFXInternals/Meshes/default.pkmm new file mode 100644 index 00000000..d47df868 --- /dev/null +++ b/PopcornFX/PopcornFXInternals/Meshes/default.pkmm @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:82104142fed2d9e31deb8f93ca50471e9e943fa52c582d2e30bacc6c1b24e9b6 +size 67558 diff --git a/PopcornFX/PopcornFXInternals/Shaders/BlurCubemap.comp.0C443080A9914F8E3821857B39F3B3F6.metallib b/PopcornFX/PopcornFXInternals/Shaders/BlurCubemap.comp.0C443080A9914F8E3821857B39F3B3F6.metallib new file mode 100644 index 0000000000000000000000000000000000000000..a22914093bd1a55f4caf81f5c7211a3a83a88fd2 GIT binary patch literal 69574 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 literal 0 HcmV?d00001 diff --git a/PopcornFX/PopcornFXInternals/Shaders/BrushBackdrop.frag.3777E0C4C3850AF4730B699288C64A32.cso.pdb b/PopcornFX/PopcornFXInternals/Shaders/BrushBackdrop.frag.3777E0C4C3850AF4730B699288C64A32.cso.pdb new file mode 100644 index 00000000..4840e78e --- /dev/null +++ b/PopcornFX/PopcornFXInternals/Shaders/BrushBackdrop.frag.3777E0C4C3850AF4730B699288C64A32.cso.pdb @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:88dde5563655c93391976dacd279d11933216eb2e923ad451b3a6b58c29b8cf4 +size 17920 diff --git a/PopcornFX/PopcornFXInternals/Shaders/BrushBackdrop.frag.DBCFC7E098405CD8ABAFBFE666F38717.metallib b/PopcornFX/PopcornFXInternals/Shaders/BrushBackdrop.frag.DBCFC7E098405CD8ABAFBFE666F38717.metallib new file mode 100644 index 0000000000000000000000000000000000000000..ee7ad13c28a4410a68827dade06d8fded53cdfa7 GIT binary patch literal 68478 zcmeFYcQl+`*El>FX7nz)QKK83Akl*my+;^*qK{6<=p{PQ$q*z65d=Z>XhF1y-Xc+= zMFc_Oca1yu^WM+cG(bRbs)|vA30U)QCWiD1?)>8v^MLGBVdw z!vW!FC>d(NKs5HW8mSXw7;EQ9|1yy1t#58k1NNC^S%^Ehk}Fl`gu3eLM)ZHt`+vwy z)C>%vAY2g6WztbKw19&Cp571`3I%2SVM^_`s*#4FfeHm^@DI8AgTDwG8*8dkfY85g z+OwpF-_f4=Q8~3f?S#e03W_bU0;;MhYgU4k0EmdOw*$&s#M8sm&I9G{81Q#Z$krF> zYH#b|BjWFYa&bWYU0j0gkth*IUsqQll*46P#K^dNYBQc_at;xf{r z(!y>IJ_uJ=r0ri7fMGp#Es%&G0+`st^^)qn01<0he|tx1H+u<3ak!tey^EWVop+Fz zs0{(WX4aeG@a2T5TB5_PGF#f~e)Sf$YbDFImJ3*b>!=~$Em0NCAQO9JOY zQ{eYw``JlAAQ(OfM2yQ0EDi`n4J1eyXR1;^Sd)N4Og0TCl7t%{%D@VKXp5#-!&Ocr zR_>t?qmhBq-y#yTjnzn@fvKp+mVy|>l);*0DU_T&dP@3X2`dqwCDx51 z(jgqySqw{880#nwJjT-|CXg3`hQ;_~$9Pge{CH!eFfpDQ5I^S#FDS$h=mib2GfyK} z2XSE2Ma*9itg|52wIb$Tc9t&y%?{?}B7hV#$QwY;jzNK-{sA#ka7Z9D21^PZei|`;pbaI~ts-W0C(9zhi4tp95zAl^>GBH8cqhw75%XFR>0lVkcoEBN z2g_n7%Pg8@kezu52R6ULG7Dpw?_~b+Z~S8*fzSS)R4*pT84}=(7X*cP*~Fl-Asx(J zVOSA%OvqAl?`+OpHGuJ4H+o z9OBIj3B*nW3E_o+$U()d06$%w%z*g+Sdl*x#RdV&1dszD-WV(=egQF_n14xxCVi*~ zBCG)!rx5fC^0HB#rHzTK{I+XH&X~M z4TvU?6JYmsv?4tZ1&%&Fb+}y@nrjeji(rHR@HiL<z#g=LD2!gJKPASe z142XN4Yo;v_K1$t=y$Ev*&52o5QYOZmK6yosaANA@w|uw^AThTp)*fr_B|Tj2~NW2N001~f@~WDtTOp$H2I+( z`GFqUCq432Ju+TT;k2??DxQlh&=>RAjmN!Ev=Ue&yF3?y-8l4+AkPRtUSPo?exrB_ zz}o}tK49OaKxkC?;6wJqcnbY03JG`$O-gbZcnXntavNc+^(r!>5%MK?*PC#dF*et9 zayhiJ?@zh#bD>KF=XaG%kJwG#(yH0qq9VngC~xfX2Y_;juP^5zq*D0t{%U!ec?u2xt

uH2;l)&A<2B{I_26 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

PbXAAtMfMhpV87 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 literal 0 HcmV?d00001 diff --git a/PopcornFX/PopcornFXInternals/Shaders/ColorRemap.frag.1CFFFE56845EBA06EDCF9E5C8278FEE3.cso b/PopcornFX/PopcornFXInternals/Shaders/ColorRemap.frag.1CFFFE56845EBA06EDCF9E5C8278FEE3.cso new file mode 100644 index 0000000000000000000000000000000000000000..2143fb240345d866311d55e866743f0e5f406890 GIT binary patch literal 24300 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 literal 0 HcmV?d00001 diff --git a/PopcornFX/PopcornFXInternals/Shaders/ComputeCubemap.comp.08B780C3B4A4A9B95239BE4725C155E3.metallib b/PopcornFX/PopcornFXInternals/Shaders/ComputeCubemap.comp.08B780C3B4A4A9B95239BE4725C155E3.metallib new file mode 100644 index 0000000000000000000000000000000000000000..802845712934ceff616f1293c8b5972c21082700 GIT binary patch literal 68274 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%0A-(#7Y>LDhEw#zR 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