From ad2a66501e627ec33ffc83d4809cbec01e0c85e0 Mon Sep 17 00:00:00 2001 From: Devon R Date: Sun, 31 Mar 2019 19:03:19 +0900 Subject: [PATCH] Merge commits from 'indev'. --- .gitignore | 11 ++ InvEqui.cpp | 291 +++++++++++++++++++++++++++ InvEqui.hpp | 63 ++++++ InvEquiPiPL.r | 67 +++++++ InvEqui_Strings.cpp | 25 +++ InvEqui_Strings.hpp | 14 ++ LICENSE | 4 +- Math3D.hpp | 90 +++++++++ README.md | 36 +++- Win/InvEqui.sln | 25 +++ Win/InvEqui.vcxproj | 380 ++++++++++++++++++++++++++++++++++++ Win/InvEqui.vcxproj.filters | 104 ++++++++++ Win/InvEqui.vcxproj.user | 19 ++ demo.png | Bin 0 -> 7449 bytes 14 files changed, 1126 insertions(+), 3 deletions(-) create mode 100644 InvEqui.cpp create mode 100644 InvEqui.hpp create mode 100644 InvEquiPiPL.r create mode 100644 InvEqui_Strings.cpp create mode 100644 InvEqui_Strings.hpp create mode 100644 Math3D.hpp create mode 100644 Win/InvEqui.sln create mode 100644 Win/InvEqui.vcxproj create mode 100644 Win/InvEqui.vcxproj.filters create mode 100644 Win/InvEqui.vcxproj.user create mode 100644 demo.png diff --git a/.gitignore b/.gitignore index 259148f..3cccfe7 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,14 @@ +# Visual Studio & Code +.code/ +.vs/ +.vscode/ + +# Build artifacts +Win/x64/ +Win/enc_temp_folder/ +Win/*.aps +Win/*.rc + # Prerequisites *.d diff --git a/InvEqui.cpp b/InvEqui.cpp new file mode 100644 index 0000000..9262a7b --- /dev/null +++ b/InvEqui.cpp @@ -0,0 +1,291 @@ + +#include "Math3D.hpp" +#include "InvEqui.hpp" + +static PF_Err About (PF_InData *in_data, PF_OutData *out_data, PF_ParamDef *params[], PF_LayerDef *output) { + AEGP_SuiteHandler suites(in_data->pica_basicP); + + suites.ANSICallbacksSuite1()->sprintf( + out_data->return_msg, + "%s v%d.%d\r%s", + STR(StrID_Name), + MAJOR_VERSION, + MINOR_VERSION, + STR(StrID_Description) + ); + + return PF_Err_NONE; +} + +static PF_Err GlobalSetup (PF_InData *in_data, PF_OutData *out_data, PF_ParamDef *params[], PF_LayerDef *output) { + out_data->my_version = PF_VERSION( + MAJOR_VERSION, + MINOR_VERSION, + BUG_VERSION, + STAGE_VERSION, + BUILD_VERSION + ); + + out_data->out_flags = PF_OutFlag_DEEP_COLOR_AWARE; + + return PF_Err_NONE; +} + +static PF_Err ParamsSetup (PF_InData *in_data, PF_OutData *out_data, PF_ParamDef *params[], PF_LayerDef *output) { + PF_ParamDef def; + + AEFX_CLR_STRUCT(def); + + PF_ADD_LAYER( + STR(StrID_Layer_Param_Name), + PF_LayerDefault_MYSELF, + LAYER_PARAM_ID + ); + + AEFX_CLR_STRUCT(def); + + PF_ADD_ANGLE( + STR(StrID_FOV_Param_Name), + 90.0f, + FOV_PARAM_ID + ); + + AEFX_CLR_STRUCT(def); + + PF_ADD_ANGLE( + STR(StrID_Yaw_Param_Name), + 0.0f, + YAW_PARAM_ID + ); + + AEFX_CLR_STRUCT(def); + + PF_ADD_ANGLE( + STR(StrID_Pitch_Param_Name), + 0.0f, + PITCH_PARAM_ID + ); + + AEFX_CLR_STRUCT(def); + + PF_ADD_CHECKBOX( + STR(StrID_KeepLayer_Param_Name), + STR(StrID_KeepLayer_Param_Desc), + TRUE, + 0, + KEEPLAYER_PARAM_ID + ); + + out_data->num_params = INVEQUI_NUM_PARAMS; + + return PF_Err_NONE; +} + +struct RenderArgs { + PF_InData *in_data; + PF_ParamDef **params; + PF_ParamDef *scanLayer; +}; + +inline PF_Pixel *sampleIntegral8(PF_EffectWorld &def, int x, int y) { + return (PF_Pixel8*)((char*)def.data + (y * def.rowbytes) + (x * sizeof(PF_Pixel8))); +} + +static PF_Err SubSample_Pixel8(void *refcon, A_long x, A_long y, PF_Pixel8 *inP, PF_Pixel8 *outP) { + PF_Err err = PF_Err_NONE; + RenderArgs* rArgs = reinterpret_cast(refcon); + + float yawDeg = (static_cast(x) * 360.0f / static_cast(rArgs->in_data->width)) - 180.0f; + float pitchDeg = (static_cast(y) * 180.0f / static_cast(rArgs->in_data->height)) - 90.0f; + + PF_EffectWorld sample = rArgs->scanLayer->u.ld; + PF_ParamDefUnion aa = rArgs->scanLayer->u; + + float yaw = static_cast(FIX_2_FLOAT(rArgs->params[INVEQUI_YAW]->u.ad.value)); + float pitch = static_cast(FIX_2_FLOAT(rArgs->params[INVEQUI_PITCH]->u.ad.value)); + + float fov = static_cast(FIX_2_FLOAT(rArgs->params[INVEQUI_FOV]->u.ad.value)); + fov = fminf(fmaxf(fov, 0.1f), 179.9f); + + bool keepLayer = static_cast(rArgs->params[INVEQUI_KEEPLAYER]->u.bd.value); + + Math3D::Vector3D model = + Math3D::rotate( + Math3D::rotate( + Math3D::Vector3D(0.0f, 0.0f, -1.0f), + Math3D::radians(pitchDeg), + Math3D::Vector3D(1.0f, 0.0f, 0.0f) + ), + Math3D::radians(yawDeg), + Math3D::Vector3D(0.0f, 1.0f, 0.0f) + ); + + Math3D::Vector3D view = + Math3D::rotate( + Math3D::rotate( + model, + Math3D::radians(-yaw), + Math3D::Vector3D(0.0f, 1.0f, 0.0f) + ), + Math3D::radians(-pitch), + Math3D::Vector3D(1.0f, 0.0f, 0.0f) + ); + + Math3D::Vector3D screen = + Math3D::perspective( + view, + Math3D::radians(fov), + static_cast(sample.width) / static_cast(sample.height) + ); + + if (screen.z < -1.0f || screen.z > 1.0f || screen.x < -1.0f || screen.x > 1.0f || screen.y < -1.0f || screen.y > 1.0f) { + if (keepLayer) { + outP->red = inP->red; + outP->green = inP->green; + outP->blue = inP->blue; + outP->alpha = inP->alpha; + } + else { + outP->red = 0; + outP->green = 0; + outP->blue = 0; + outP->alpha = 0; + } + } + else { + float samplePosX = (screen.x + 1.0f) * 0.5f * static_cast(sample.width); + float samplePosY = (1.0f - ((screen.y + 1.0f) * 0.5f)) * static_cast(sample.height); + + int sX = static_cast(samplePosX); + int sY = static_cast(samplePosY); + + PF_Pixel* sampleP = sampleIntegral8(sample, sX, sY); + + if (sampleP != nullptr) { + outP->red = sampleP->red; + outP->green = sampleP->green; + outP->blue = sampleP->blue; + outP->alpha = sampleP->alpha; + } + else { + outP->red = 255; + outP->green = 255; + outP->blue = 0; + outP->alpha = 255; + } + } + + return err; +} + +static PF_Err Render (PF_InData *in_data, PF_OutData *out_data, PF_ParamDef *params[], PF_LayerDef *output) { + PF_Err err = PF_Err_NONE; + AEGP_SuiteHandler suites(in_data->pica_basicP); + + PF_ParamDef scanLayer; + + RenderArgs rArgs = { + in_data, + params, + &scanLayer + }; + + A_long progress_baseL = 0, progress_finalL = 1; + + ERR(PF_CHECKOUT_PARAM( + in_data, + INVEQUI_LAYER, + in_data->current_time, + in_data->time_step, + in_data->time_scale, + &scanLayer + )); + + ERR(suites.Iterate8Suite1()->iterate( + in_data, + progress_baseL, + progress_finalL, + ¶ms[INVEQUI_INPUT]->u.ld, + NULL, + reinterpret_cast(&rArgs), + SubSample_Pixel8, + output + )); + + progress_baseL++; + + return err; +} + + +extern "C" DllExport +PF_Err PluginDataEntryFunction( + PF_PluginDataPtr inPtr, + PF_PluginDataCB inPluginDataCallBackPtr, + SPBasicSuite* inSPBasicSuitePtr, + const char* inHostName, + const char* inHostVersion) +{ + PF_Err result = PF_Err_INVALID_CALLBACK; + + result = PF_REGISTER_EFFECT( + inPtr, + inPluginDataCallBackPtr, + "Inverse Equirectangular", + "GORIALIS InvEquirectangular", + "Devon's Plug-ins", + AE_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 err = PF_Err_NONE; + + try { + switch (cmd) { + case PF_Cmd_ABOUT: + err = About( + in_data, + out_data, + params, + output + ); + break; + + case PF_Cmd_GLOBAL_SETUP: + err = GlobalSetup( + in_data, + out_data, + params, + output + ); + break; + + case PF_Cmd_PARAMS_SETUP: + err = ParamsSetup( + in_data, + out_data, + params, + output + ); + break; + + case PF_Cmd_RENDER: + err = Render( + in_data, + out_data, + params, + output + ); + break; + } + } + catch(PF_Err &thrown_err){ + err = thrown_err; + } + return err; +} + diff --git a/InvEqui.hpp b/InvEqui.hpp new file mode 100644 index 0000000..91b7651 --- /dev/null +++ b/InvEqui.hpp @@ -0,0 +1,63 @@ +#pragma once + +#define PF_TABLE_BITS 12 +#define PF_TABLE_SZ_16 4096 +#define PF_DEEP_COLOR_AWARE 1 + +#include "AEConfig.h" + +#ifdef AE_OS_WIN + typedef unsigned short PixelType; + #include +#endif + +#include "entry.h" +#include "AE_Effect.h" +#include "AE_EffectCB.h" +#include "AE_Macros.h" +#include "Param_Utils.h" +#include "AE_EffectCBSuites.h" +#include "String_Utils.h" +#include "AE_GeneralPlug.h" +#include "AEFX_ChannelDepthTpl.h" +#include "AEGP_SuiteHandler.h" + +#include "InvEqui_Strings.hpp" + +/* Versioning information */ + +#define MAJOR_VERSION 1 +#define MINOR_VERSION 0 +#define BUG_VERSION 0 +#define STAGE_VERSION PF_Stage_DEVELOP +#define BUILD_VERSION 1 + +enum { + INVEQUI_INPUT = 0, + INVEQUI_LAYER, + INVEQUI_FOV, + INVEQUI_YAW, + INVEQUI_PITCH, + INVEQUI_KEEPLAYER, + INVEQUI_NUM_PARAMS +}; + +enum { + LAYER_PARAM_ID = 1, + FOV_PARAM_ID, + YAW_PARAM_ID, + PITCH_PARAM_ID, + KEEPLAYER_PARAM_ID, +}; + + +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 + ); +} diff --git a/InvEquiPiPL.r b/InvEquiPiPL.r new file mode 100644 index 0000000..0d7807a --- /dev/null +++ b/InvEquiPiPL.r @@ -0,0 +1,67 @@ +#include "AEConfig.h" +#include "AE_EffectVers.h" + +#ifndef AE_OS_WIN + #include +#endif + +resource 'PiPL' (16000) { + { /* array properties: 12 elements */ + /* [1] */ + Kind { + AEEffect + }, + /* [2] */ + Name { + "Inverse Equirectangular" + }, + /* [3] */ + Category { + "Devon's Plug-ins" + }, +#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 { + 524289 /* 1.0 */ + }, + /* [9] */ + AE_Effect_Info_Flags { + 0 + }, + /* [10] */ + AE_Effect_Global_OutFlags { + 0x02000000 //50332160 + + }, + AE_Effect_Global_OutFlags_2 { + 0x00000000 + }, + /* [11] */ + AE_Effect_Match_Name { + "GORIALIS InvEquirectangular" + }, + /* [12] */ + AE_Reserved_Info { + 0 + } + } +}; + diff --git a/InvEqui_Strings.cpp b/InvEqui_Strings.cpp new file mode 100644 index 0000000..39d9476 --- /dev/null +++ b/InvEqui_Strings.cpp @@ -0,0 +1,25 @@ +#include "InvEqui.hpp" + +typedef struct { + A_u_long index; + A_char str[256]; +} TableString; + + +TableString g_strs[StrID_NUMTYPES] = { + StrID_NONE, "", + StrID_Name, "Inverse Equirectangular", + StrID_Description, "A plugin that takes standard perspective footage with an FOV, yaw and pitch to convert into an equirectangular projection patch.", + StrID_Layer_Param_Name, "Source Layer", + StrID_FOV_Param_Name, "FOV", + StrID_Yaw_Param_Name, "Yaw", + StrID_Pitch_Param_Name, "Pitch", + StrID_KeepLayer_Param_Name, "Preserve layer", + StrID_KeepLayer_Param_Desc, "Keep", +}; + + +char *GetStringPtr(int strNum) +{ + return g_strs[strNum].str; +} diff --git a/InvEqui_Strings.hpp b/InvEqui_Strings.hpp new file mode 100644 index 0000000..6ffaab9 --- /dev/null +++ b/InvEqui_Strings.hpp @@ -0,0 +1,14 @@ +#pragma once + +typedef enum { + StrID_NONE, + StrID_Name, + StrID_Description, + StrID_Layer_Param_Name, + StrID_FOV_Param_Name, + StrID_Yaw_Param_Name, + StrID_Pitch_Param_Name, + StrID_KeepLayer_Param_Name, + StrID_KeepLayer_Param_Desc, + StrID_NUMTYPES +} StrIDType; diff --git a/LICENSE b/LICENSE index 67ba6ab..57bf172 100644 --- a/LICENSE +++ b/LICENSE @@ -1,6 +1,6 @@ MIT License -Copyright (c) 2019 Devon R +Copyright (c) 2019 Devon (Gorialis) R Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal @@ -18,4 +18,4 @@ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. \ No newline at end of file +SOFTWARE. diff --git a/Math3D.hpp b/Math3D.hpp new file mode 100644 index 0000000..9ab21ad --- /dev/null +++ b/Math3D.hpp @@ -0,0 +1,90 @@ +#pragma once + +#include + + +namespace Math3D { + + template + class Vector3D { + public: + Vector3D(T X, T Y, T Z) : x(X), y(Y), z(Z) {}; + + const Vector3D operator*(T coefficient) const { + return Vector3D(x * coefficient, y * coefficient, z * coefficient); + }; + + const Vector3D operator*(const Vector3D& other) const { + return Vector3D(x * other.x, y * other.y, z * other.z); + } + + const Vector3D operator/(T coefficient) const { + return Vector3D(x / coefficient, y / coefficient, z / coefficient); + }; + + const Vector3D operator/(const Vector3D& other) const { + return Vector3D(x / other.x, y / other.y, z / other.z); + } + + T x, y, z; + }; + + template + T magnitude(const Vector3D& src) { + return sqrt(pow(src.x, static_cast(2)) + pow(src.y, static_cast(2)) + pow(src.z, static_cast(2))); + }; + + template + Vector3D normalize(const Vector3D& src) { + return src / magnitude(src); + }; + + template + T radians(T degrees) { + return degrees * static_cast(0.01745329251994329576923690768489); + }; + + template + Vector3D rotate(const Vector3D& src, T angle, const Vector3D& axis) { + Vector3D n = normalize(axis); + + T c = cos(angle); + T s = sin(angle); + T ic = static_cast(1) - c; + + Vector3D v = n * ic; + + T x = ( + (c + v.x * n.x) * src.x + + (v.x * n.y + s * n.z) * src.y + + (v.x * n.z - s * n.y) * src.z + ); + + T y = ( + (v.y * n.x - s * n.z) * src.x + + (c + v.y * n.y) * src.y + + (v.y * n.z + s * n.x) * src.z + ); + + T z = ( + (v.z * n.x + s * n.y) * src.x + + (v.z * n.y - s * n.x) * src.y + + (c + v.z * n.z) * src.z + ); + + return Vector3D(x, y, z); + }; + + template + Vector3D perspective(const Vector3D& src, T fovy, T aspect, T zNear = 0.5f, T zFar = 1.5f) { + T halfFov = tan(fovy / static_cast(2)); + + T x = src.x / (aspect * halfFov); + T y = src.y / halfFov; + T z = (((-zFar - zNear) / (zFar - zNear)) * src.z) + (-static_cast(2) * zFar * zNear / (zFar - zNear)); + T w = -static_cast(1) * src.z; + + return Vector3D(x / w, y / w, z / w); + } + +} diff --git a/README.md b/README.md index 74d1c2c..9a04b75 100644 --- a/README.md +++ b/README.md @@ -1 +1,35 @@ -# aftereffects_inverse_equirectangular +# After Effects Inverse Equirectangular Plug-in + +This is a plug-in that can convert regular perspective footage (from e.g. a camera) to equirectangular patches that can be used to produce a full equirectangular image/video: + +![Example of an equirectangular projection](demo.png) + +## Installing + +Check the [releases page](https://github.com/Gorialis/jishaku/releases) and place the .aex file into the `Plug-ins` folder of your install, e.g. at `C:\Program Files\Adobe\Adobe After Effects CC 2018\Support Files\Plug-ins\`. + +The effect is called "Inverse Equirectangular" and will appear in the "Devon's Plug-ins" subcategory. + +## Using + +This plugin works by mapping the individual bits of footage onto a larger 2-by-1 equirectangular master layer. The effect itself should be applied to this master layer. + +For example, create a 2000x1000 solid, apply the effect to it, and select the footage to use for a patch as the "Source Layer" attribute. + +The FOV is the vertical FOV of the footage, and the yaw and pitch are relative to the center of the equirectangular image. + +If you don't want the color of the solid to show through as the background, untick "Preserve layer" and anything not drawn by the patch will become transparent. + +You can apply all of your footage patches to the master solid by adding the effect multiple times, and keeping "Preserve layer" ticked on all but the first effect. + +## Building + +Building this plug-in relies on proprietary Adobe code that I cannot distribute under a free software license. + +To make the plug-in build properly, download the [Adobe After Effects SDK](https://www.adobe.io/apis/creativecloud/aftereffects.html) and clone this repository into the `Templates` folder. + +From there, the project can be built from the `InvEqui.sln` in the `Win` folder. + +If you do not use CC 2018, or your After Effects is installed in a non-default location, you may need to open the `InvEqui` solution properties and edit the `General > Output directory` and `Debug > Command` entries to suit your install. + +From there, building the solution should build and install the plug-in and launch After Effects for debugging. diff --git a/Win/InvEqui.sln b/Win/InvEqui.sln new file mode 100644 index 0000000..56531a9 --- /dev/null +++ b/Win/InvEqui.sln @@ -0,0 +1,25 @@ +Microsoft Visual Studio Solution File, Format Version 11.00 +# Visual Studio 2010 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "InvEqui", "InvEqui.vcxproj", "{2C8DED3E-111D-4272-A54A-F1865F02A90E}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|x64 = Debug|x64 + Debug|x86 = Debug|x86 + Release|x64 = Release|x64 + Release|x86 = Release|x86 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {2C8DED3E-111D-4272-A54A-F1865F02A90E}.Debug|x64.ActiveCfg = Debug|x64 + {2C8DED3E-111D-4272-A54A-F1865F02A90E}.Debug|x64.Build.0 = Debug|x64 + {2C8DED3E-111D-4272-A54A-F1865F02A90E}.Debug|x86.ActiveCfg = Debug|Win32 + {2C8DED3E-111D-4272-A54A-F1865F02A90E}.Debug|x86.Build.0 = Debug|Win32 + {2C8DED3E-111D-4272-A54A-F1865F02A90E}.Release|x64.ActiveCfg = Release|x64 + {2C8DED3E-111D-4272-A54A-F1865F02A90E}.Release|x64.Build.0 = Release|x64 + {2C8DED3E-111D-4272-A54A-F1865F02A90E}.Release|x86.ActiveCfg = Release|Win32 + {2C8DED3E-111D-4272-A54A-F1865F02A90E}.Release|x86.Build.0 = Release|Win32 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/Win/InvEqui.vcxproj b/Win/InvEqui.vcxproj new file mode 100644 index 0000000..a4b7f8a --- /dev/null +++ b/Win/InvEqui.vcxproj @@ -0,0 +1,380 @@ + + + + + Debug + Win32 + + + Debug + x64 + + + Release + Win32 + + + Release + x64 + + + + {2C8DED3E-111D-4272-A54A-F1865F02A90E} + InvEqui + 10.0.17763.0 + + + + DynamicLibrary + false + v141 + + + DynamicLibrary + false + v141 + + + DynamicLibrary + false + v141 + + + DynamicLibrary + false + v141 + + + + + + + + + + + + + + + + + + + + + + + <_ProjectFileVersion>10.0.40219.1 + C:\Program Files\Adobe\Adobe After Effects CC 2018\Support Files\Plug-ins\Build + C:\Program Files\Adobe\Adobe After Effects CC 2018\Support Files\Plug-ins\Build + $(Platform)\$(Configuration)\ + $(Platform)\$(Configuration)\ + true + true + C:\Program Files\Adobe\Adobe After Effects CC 2018\Support Files\Plug-ins\Build + C:\Program Files\Adobe\Adobe After Effects CC 2018\Support Files\Plug-ins\Build + $(Platform)\$(Configuration)\ + $(Platform)\$(Configuration)\ + true + true + AllRules.ruleset + AllRules.ruleset + + + + + AllRules.ruleset + AllRules.ruleset + + + + + .aex + .aex + .aex + .aex + + + + _DEBUG;%(PreprocessorDefinitions) + true + true + X64 + .\Debug/InvEqui.tlb + + + + + Disabled + ..\..\..\Headers;..\..\..\Headers\SP;..\..\..\Headers\Win;..\..\..\Resources;..\..\..\Util;%(AdditionalIncludeDirectories) + MSWindows;WIN32;_DEBUG;_WINDOWS;%(PreprocessorDefinitions) + MultiThreadedDebugDLL + 4Bytes + true + + + AE_Effect.h + $(IntDir)$(TargetName).pch + NoListing + $(IntDir) + $(IntDir) + $(IntDir)vc$(PlatformToolsetVersion).pdb + true + Level3 + true + true + ProgramDatabase + Default + + + _DEBUG;%(PreprocessorDefinitions) + 0x0409 + + + NotSet + $(OutDir)$(TargetName)$(TargetExt) + true + true + $(IntDir)$(TargetName).pdb + + + false + + + $(IntDir)/$(TargetName).lib + MachineX64 + + + $(IntDir)$(TargetName).bsc + + + + + _DEBUG;%(PreprocessorDefinitions) + true + true + X64 + .\Debug/InvEqui.tlb + + + + + MaxSpeed + ..\..\..\Headers;..\..\..\Headers\SP;..\..\..\Headers\Win;..\..\..\Resources;..\..\..\Util;%(AdditionalIncludeDirectories) + MultiThreadedDLL + 4Bytes + true + + + AE_Effect.h + $(IntDir)$(TargetName).pch + NoListing + $(IntDir) + $(IntDir) + $(IntDir)vc$(PlatformToolsetVersion).pdb + true + Level3 + true + true + ProgramDatabase + Default + MSWindows;WIN32;_WINDOWS;%(PreprocessorDefinitions) + + + %(PreprocessorDefinitions) + 0x0409 + + + NotSet + $(OutDir)$(TargetName)$(TargetExt) + true + + + $(IntDir)$(TargetName).pdb + + + false + + + $(IntDir)/$(TargetName).lib + MachineX64 + + + $(IntDir)$(TargetName).bsc + + + + + _DEBUG;%(PreprocessorDefinitions) + true + true + X64 + .\Debug/InvEqui.tlb + + + + + Disabled + ..\..\..\Headers;..\..\..\Headers\SP;..\..\..\Headers\Win;..\..\..\Resources;..\..\..\Util;%(AdditionalIncludeDirectories) + MSWindows;WIN32;_DEBUG;_WINDOWS;%(PreprocessorDefinitions) + MultiThreadedDebugDLL + 4Bytes + true + + + AE_Effect.h + $(IntDir)$(TargetName).pch + NoListing + $(IntDir) + $(IntDir) + $(IntDir)vc$(PlatformToolsetVersion).pdb + true + Level3 + true + true + ProgramDatabase + Default + + + _DEBUG;%(PreprocessorDefinitions) + 0x0409 + + + NotSet + $(OutDir)$(TargetName)$(TargetExt) + true + true + $(IntDir)$(TargetName).pdb + + + false + + + $(IntDir)/$(TargetName).lib + MachineX86 + + + $(IntDir)$(TargetName).bsc + + + + + _DEBUG;%(PreprocessorDefinitions) + true + true + X64 + .\Debug/InvEqui.tlb + + + + + MaxSpeed + ..\..\..\Headers;..\..\..\Headers\SP;..\..\..\Headers\Win;..\..\..\Resources;..\..\..\Util;%(AdditionalIncludeDirectories) + MultiThreadedDLL + 4Bytes + true + + + AE_Effect.h + $(IntDir)$(TargetName).pch + NoListing + $(IntDir) + $(IntDir) + $(IntDir)vc$(PlatformToolsetVersion).pdb + true + Level3 + true + true + ProgramDatabase + Default + MSWindows;WIN32;_WINDOWS;%(PreprocessorDefinitions) + + + %(PreprocessorDefinitions) + 0x0409 + + + NotSet + $(OutDir)$(TargetName)$(TargetExt) + true + + + $(IntDir)$(TargetName).pdb + + + false + + + $(IntDir)/$(TargetName).lib + MachineX86 + + + $(IntDir)$(TargetName).bsc + + + + + Compiling the PiPL + Compiling the PiPL + cl /I "$(ProjectDir)..\..\..\Headers" /EP ".."\\"%(Filename).r" > "$(IntDir)"\\"%(Filename).rr" +"$(ProjectDir)..\..\..\Resources\PiPLTool" "$(IntDir)%(Filename).rr" "$(IntDir)%(Filename).rrc" +cl /D "MSWindows" /EP $(IntDir)%(Filename).rrc > "$(ProjectDir)"\\"%(Filename)".rc + + cl /I "$(ProjectDir)..\..\..\Headers" /EP ".."\\"%(Filename).r" > "$(IntDir)"\\"%(Filename).rr" +"$(ProjectDir)..\..\..\Resources\PiPLTool" "$(IntDir)%(Filename).rr" "$(IntDir)%(Filename).rrc" +cl /D "MSWindows" /EP $(IntDir)%(Filename).rrc > "$(ProjectDir)"\\"%(Filename)".rc + + $(ProjectDir)%(Filename).rc;%(Outputs) + $(ProjectDir)%(Filename).rc;%(Outputs) + Compiling the PiPL + Compiling the PiPL + cl /I "$(ProjectDir)..\..\..\Headers" /EP ".."\\"%(Filename).r" > "$(IntDir)"\\"%(Filename).rr" +"$(ProjectDir)..\..\..\Resources\PiPLTool" "$(IntDir)%(Filename).rr" "$(IntDir)%(Filename).rrc" +cl /D "MSWindows" /EP $(IntDir)%(Filename).rrc > "$(ProjectDir)"\\"%(Filename)".rc + + cl /I "$(ProjectDir)..\..\..\Headers" /EP ".."\\"%(Filename).r" > "$(IntDir)"\\"%(Filename).rr" +"$(ProjectDir)..\..\..\Resources\PiPLTool" "$(IntDir)%(Filename).rr" "$(IntDir)%(Filename).rrc" +cl /D "MSWindows" /EP $(IntDir)%(Filename).rrc > "$(ProjectDir)"\\"%(Filename)".rc + + $(ProjectDir)%(Filename).rc;%(Outputs) + $(ProjectDir)%(Filename).rc;%(Outputs) + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Win/InvEqui.vcxproj.filters b/Win/InvEqui.vcxproj.filters new file mode 100644 index 0000000..33a2e20 --- /dev/null +++ b/Win/InvEqui.vcxproj.filters @@ -0,0 +1,104 @@ + + + + + {b69af876-1d29-49fa-9917-fd2efa165225} + ico;cur;bmp;dlg;rc2;rct;bin;cnt;rtf;gif;jpg;jpeg;jpe + + + {e1cf207c-552f-4fd4-96ed-76ccc9ebdf72} + + + {728b7ff5-0e0a-45d2-999a-696b548f9a28} + + + {f2f05dcb-eed5-4aa5-b2d0-504449ce3cf4} + + + + + Resources + + + + + Headers\AE + + + Headers\AE + + + Headers\AE + + + Headers\AE + + + Headers\AE + + + Headers\AE + + + Headers\AE + + + Headers\AE + + + Headers\AE + + + Headers\AE + + + Headers\AE + + + Headers\AE + + + Headers\AE + + + Headers\AE + + + Headers\AE + + + Headers\AE + + + Headers\AE + + + Headers\AE + + + Headers\AE + + + + Headers + + + Headers + + + + + Supporting code + + + Supporting code + + + + + + + Resources + + + \ No newline at end of file diff --git a/Win/InvEqui.vcxproj.user b/Win/InvEqui.vcxproj.user new file mode 100644 index 0000000..8d23967 --- /dev/null +++ b/Win/InvEqui.vcxproj.user @@ -0,0 +1,19 @@ + + + + C:\Program Files\Adobe\Adobe After Effects CC 2018\Support Files\AfterFX.exe + WindowsLocalDebugger + + + C:\Program Files\Adobe\Adobe After Effects CC 2018\Support Files\AfterFX.exe + WindowsLocalDebugger + + + C:\Program Files\Adobe\Adobe After Effects CC 2018\Support Files\AfterFX.exe + WindowsLocalDebugger + + + C:\Program Files\Adobe\Adobe After Effects CC 2018\Support Files\AfterFX.exe + WindowsLocalDebugger + + \ No newline at end of file diff --git a/demo.png b/demo.png new file mode 100644 index 0000000000000000000000000000000000000000..b368eaafa191fc5ae46f703b06222296e28b6b96 GIT binary patch literal 7449 zcmeHMdsLFyyGF|_)6Acmm+9s-MpUNW(~hKXQWrZ!gESn8At zHfkUUc+K(xmKItWQ-Y*M-ZB+M5ycy~gVSo(to2)Go%7#W=bZldzHh(JexAMdde^(Z zz4!b6>h5|%N6S7BHwzPtOSg??4OVfY~msB`pW z>+Og&A#Si4DLN#0n4sLGr~5we%^|03j75L|%T^ZLsP9nnmjM6`cZ}5mfLm)F0DvUD zfRzBi?xWgj0KoAZW&l9bO6%nSfU#MsYO-5e)&c;(T>nn~f9;K?2>Xw{@-Om1*${8; zGILQJm?)bS2~N*1>(gjdbjkTWnvD5z#l&mECI%RzyvdS^Ugrb-2{y8-SIvZ>cIUrQPsYcV9bbI`Qa{Okdw84Le^%HpqT{xB<&sjE;<3HfrRot!Qf~j@9U@IpQnH+E0 z7vboa9N{W>;I%*wo3S`^h=$bZopePR(>t!4z72D?m**a!(4HLtqEC}?Tu?kZi?)eJ zO`T+7YIO$D58RtEI)cz7rXgBKA;}Yd9VJa6e{ve+t8A;k*h#zi=t1LH;pX-sEAvze zX>~O{f%}4zle24QZjpjTPaUc2VbUG=@ojPBx>#wqw_gX?+=Z8a)1x^?=N-B>(Lb$D zk~QUp7S7ht>mH$9?$LhEElM3W{bMX#$ykFPGaoD!bPL1$(Wl4mZS#xS<-~8G`#gPo zdlpUVG9OH9i42yay!}3ctt;Nv&`fX4>EAZZv5JBU-j7rKpc8_Y7BH_8wfU3VJ`|kM z0xdmRMURC(rReLAof#uvjkAA8I=k>M?~+~ZjBe-<&Gl4SjAdDP>m<+=q@Q^v+tfTY z_q>(4#Au-S^N}GwwqpanESw#3h{Qhz&}ejELO7(Z7d>-An zZVknYM|3SS$RhNe?SIk&B@@&8EkCSwmY4W;Eiw?LWb}rV!TrLNVi#gIb+R;@jNo}3 z4DUcXkuM?solpoP3!<+2?pQw@5O-7XI|Xl6YFj^Z?WqQOxPBsuH?1DJZ77!ez|YnJ z!d@umz11Nd>P2fd;EfJyh?M`pEx+MT4%=%fo#O(NtoXOU#@O(q7e8@UxY{=VcJ5DK zgJxfE;uh|yu}h!3nRkm_e@2yGdi5-jJL*($Yw2~bgvZS$d1jdIEQl7t(O?KL5DktN z_Bum|>p^hvP+x`MQnBkx!KKfFzvP0KvzCNt*&SnXMFMmT@v4=97`jW2TO%cRX3GLA z>9B=j3w$$!jJ6C8@~4WOp*CqM9%_k)wj_9gAljpTC=(BG+$tl)@q25K&r5RjN|JLU zD}s-W#yv0=AHxJNcB;-9+lv$ zSbe2Bf?CfhIOo5zRX{f8)ebS2NOdRwNxHd2>ft?l4N5fY+iCq7!%2q;S3EM3#E>%E zYXV-BkPWHv`?ohfCLBq)Kr`I23raoDt#Tf%k*^m7#!%r=r6@-V{xD z3rc+4tP+m5vD3%du?K~5KGs1Es1KP7%c-U>QBZT8ut=)l`lKGA5ZVl&U@VTFm6T0S8djXsV8wTK4L|p-x)x|V zCc`?G`8=z@OB$EDYEq5GV!;SKy>(L2dSc}HQ-rOJ;cu6TiB7odyKrSNUCIrwDUn{C zr~+XtOVC^39@_MD3wCV3H+l|V zJPsF@BptTW@oPG+=5tE>{t30KIqK?-`!1>dpb=zk9kfwnIYMjY%=*ryiWi70N;J^KNtrEx@VgDl?-;WQDM?fVCtKqq{CylKJ_)Ki2XZS zmpDh%uHw}ze>dKfsjg0)zPkG0w#|QfehXi;U8I_(#`1Wr)_{Ok8?BYqZ#8%I6(${a z`?erD7n(HI8>}7KzWL^_X45Juc+-=lWOa4hzgNicGNVZM!-d48om;<8;=3pQ`fGlV ziEsPI{}E3}`rFyA5m`34XH=@?p#+CIfr z%4hbsH5+}bo?|{y673hqXO1tKm2*I)7`?HfuT$P5t(STy%H1%t0U5^PN^+cRs;9&M zCI5?rJu%5pyco6APu=|lL>!2ko1MYW)8|-Ycj<1fO0{sLVP-8*Djjt5-|=HPWngNo zmL(mW&_(w4%7=KEb%Vh#?&NwzT#MgpGtU~_LU(1z7UcZPOq<5r&wp9LD|3m-(?I;wP7Nv$VQm>sl;@IV+H<2O(}?C z(KQNEu0k2Uh+oHh)LBLjBJyNJ64YSK=S-f8omGIGCa5mY)R4w}W3i3k{G=6Qu^&Vs zl2es0LVuwgdKp@n%;lo`z3r9Hmf%Az{`s5@gPs5*B5XAiyzuZVn5cXa%Q~oYsk{zh zDPz&E1horFQ4T|F#)ti|_ZL{xH_YtYV+vwzay<2Rwe9`Z_#3JE3;8W7pq1D|5E@5y zPr=a^13r4NYWp7RzUsjWfmch_k7ef*9|yLCvI4oKH$oiY?-UnUcRDgyWKTVIx(!`* zkE{uRw$F3(CYkUM$`SesyB&x(kR34ep1E_#(GgCe_cDT^<+)Nr3iv)YCJR}#m-|mh zs>)=6z)=2q+7EAG)mI)EzwbH8A~Z-9H>05-Kqswn&-3%x(YU$j9WZ;SPEt)6{nqYo zB=}Q7F>fFp1t{~w248?Rt zbKzj{tCeiwk0(!@Fj?4V9fVc$J2^Ts9^A5b3yy42?hOHhu_jY*Ruafs<2Cm(-Xf3N z?0rrot7AbWMOC?a>{~MdaTGxc1e>tKuEQE(yBD%)OxhkwI<*Yw<@CJ%T9{KnoTWjAwL#WcVWjrMJ7+Xg0<}{%LD8%QknDtRh2f2tY^6)Z&FRi2eHBO>^g35(r^5;{MY9DpRpn@rQ zT~fqTyOfS5MNh>Ob*v+aA|u@sq_GPq3fn#UGUR<5BibX z708m$L(ndgJ{io9!)7TmekV?lc!j>p=n%1(e1WqHS`aQVva~Ld}0xYK1~t%l+?k|yafC0rQA)Ml+q5a z))~Wwx<}CYGKe3oZj3>=#}Q;^D&?an4Vo6xufqZdE8PXZC?5x!OGciV<75%q{s>!& zhk23fKEVLj@e(=e5b8Xweg<@G61Wv_`7@`=6n$E7tcd23eUNB+peXfA-AR9knJWPU zU0Dt)A+J~^G==^e^Ir&y!@GGlepQky0hO<+%&l?Z+!jGD4F)qh>z@bNGjEOkxwKvi z!tvH3o997PG}qZ(Zilw;Vh%F)mjsEn%tk{l&xOs?%oDh0x!}PR>DP> zwm#PQQ1QeBPvqwir!&Z_?t}u5NTi%ncX@`i`(DzP-1eI88r^ZMM;F(fX_T`kT9s2xiyu)X#mnLF?12;xif30o=@{(o zAV<6=ESe-L*To6Cc_D;?)IVm@)QLZC*wZ&Bld9SJH)+~$`(Ek!UibQMRsn6Q>ZMA} Z7{_ZerhaO?szL~Gc62>PJNnDD{{SP(H2eSn literal 0 HcmV?d00001