├── .gitignore ├── CHANGELOG.md ├── README.md ├── icons ├── CrossProductVector3.png ├── DeterminantMatrix3.png ├── DeterminantMatrix4.png ├── DotProductVector3.png ├── IdentityMatrix4.png ├── InvertMatrix4.png ├── MagnitudeVector3.png ├── Math.png ├── Matrix3.png ├── Matrix4.png ├── NormalizeVector3.png ├── ProductMatrix4.png ├── ProductVector3.png ├── RotateMatrix4.png ├── ScaleMatrix4.png ├── TransformMatrix4.png ├── TranslateMatrix4.png ├── TransposeMatrix4.png ├── Vector2.png └── Vector3.png ├── init.py ├── menu.py ├── nuke ├── Convert │ ├── LumaToVector3.nk │ ├── STMapToVector2.nk │ ├── Vector2ToSTMap.nk │ └── Vector3ToMatrix4.nk ├── Generate │ ├── GenerateMatrix4.nk │ └── GenerateSTMap.nk ├── Gizmos │ └── IIDistort.gizmo └── Math │ ├── Axis │ ├── InvertAxis.nk │ ├── TransformAxis.nk │ └── ZeroAxis.nk │ ├── Matrix4 │ ├── InvertMatrix4.nk │ ├── ProductMatrix4.nk │ ├── RotateMatrix4.nk │ ├── ScaleMatrix4.nk │ ├── TransformMatrix4.nk │ ├── TranslateMatrix4.nk │ └── TransposeMatrix4.nk │ ├── Vector2 │ ├── CrossProductVector2.nk │ ├── DotProductVector2.nk │ ├── MagnitudeVector2.nk │ ├── NormalizeVector2.nk │ ├── RotateVector2.nk │ └── TransformVector2.nk │ └── Vector3 │ ├── CrossProductVector3.nk │ ├── DotProductVector3.nk │ ├── MagnitudeVector3.nk │ ├── MultiplyVector3Matrix3.nk │ ├── NormalizeVector3.nk │ ├── RotateVector3.nk │ └── TransformVector3.nk └── transform_utils ├── __init__.py ├── matrix_utils.py ├── rotation_filters.py └── tracker4_api.py /.gitignore: -------------------------------------------------------------------------------- 1 | # Byte-compiled / optimized / DLL files 2 | __pycache__/ 3 | *.py[cod] 4 | *$py.class 5 | 6 | # C extensions 7 | *.so 8 | 9 | # Distribution / packaging 10 | .Python 11 | build/ 12 | develop-eggs/ 13 | dist/ 14 | downloads/ 15 | eggs/ 16 | .eggs/ 17 | lib/ 18 | lib64/ 19 | parts/ 20 | sdist/ 21 | var/ 22 | wheels/ 23 | share/python-wheels/ 24 | *.egg-info/ 25 | .installed.cfg 26 | *.egg 27 | MANIFEST 28 | 29 | # PyInstaller 30 | # Usually these files are written by a python script from a template 31 | # before PyInstaller builds the exe, so as to inject date/other infos into it. 32 | *.manifest 33 | *.spec 34 | 35 | # Installer logs 36 | pip-log.txt 37 | pip-delete-this-directory.txt 38 | 39 | # Unit test / coverage reports 40 | htmlcov/ 41 | .tox/ 42 | .nox/ 43 | .coverage 44 | .coverage.* 45 | .cache 46 | nosetests.xml 47 | coverage.xml 48 | *.cover 49 | *.py,cover 50 | .hypothesis/ 51 | .pytest_cache/ 52 | cover/ 53 | 54 | # Translations 55 | *.mo 56 | *.pot 57 | 58 | # Django stuff: 59 | *.log 60 | local_settings.py 61 | db.sqlite3 62 | db.sqlite3-journal 63 | 64 | # Flask stuff: 65 | instance/ 66 | .webassets-cache 67 | 68 | # Scrapy stuff: 69 | .scrapy 70 | 71 | # Sphinx documentation 72 | docs/_build/ 73 | 74 | # PyBuilder 75 | .pybuilder/ 76 | target/ 77 | 78 | # Jupyter Notebook 79 | .ipynb_checkpoints 80 | 81 | # IPython 82 | profile_default/ 83 | ipython_config.py 84 | 85 | # pyenv 86 | # For a library or package, you might want to ignore these files since the code is 87 | # intended to run in multiple environments; otherwise, check them in: 88 | # .python-version 89 | 90 | # pipenv 91 | # According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control. 92 | # However, in case of collaboration, if having platform-specific dependencies or dependencies 93 | # having no cross-platform support, pipenv may install dependencies that don't work, or not 94 | # install all needed dependencies. 95 | #Pipfile.lock 96 | 97 | # poetry 98 | # Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control. 99 | # This is especially recommended for binary packages to ensure reproducibility, and is more 100 | # commonly ignored for libraries. 101 | # https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control 102 | #poetry.lock 103 | 104 | # pdm 105 | # Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control. 106 | #pdm.lock 107 | # pdm stores project-wide configurations in .pdm.toml, but it is recommended to not include it 108 | # in version control. 109 | # https://pdm.fming.dev/#use-with-ide 110 | .pdm.toml 111 | 112 | # PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm 113 | __pypackages__/ 114 | 115 | # Celery stuff 116 | celerybeat-schedule 117 | celerybeat.pid 118 | 119 | # SageMath parsed files 120 | *.sage.py 121 | 122 | # Environments 123 | .env 124 | .venv 125 | env/ 126 | venv/ 127 | ENV/ 128 | env.bak/ 129 | venv.bak/ 130 | 131 | # Spyder project settings 132 | .spyderproject 133 | .spyproject 134 | 135 | # Rope project settings 136 | .ropeproject 137 | 138 | # mkdocs documentation 139 | /site 140 | 141 | # mypy 142 | .mypy_cache/ 143 | .dmypy.json 144 | dmypy.json 145 | 146 | # Pyre type checker 147 | .pyre/ 148 | 149 | # pytype static type analyzer 150 | .pytype/ 151 | 152 | # Cython debug symbols 153 | cython_debug/ 154 | 155 | # PyCharm 156 | # JetBrains specific template is maintained in a separate JetBrains.gitignore that can 157 | # be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore 158 | # and can be added to the global gitignore or merged into this file. For a more nuclear 159 | # option (not recommended) you can uncomment the following to ignore the entire idea folder. 160 | #.idea/ 161 | 162 | 163 | .DS_Store 164 | Thumbs.db 165 | temp/ -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Changelog 2 | All notable changes to this project will be documented in this file. 3 | 4 | The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/) 5 | 6 | ## [Unreleased] 7 | 8 | ### Added 9 | - Added ApplyAxis node 10 | 11 | 12 | ## [1.0.0] 13 | 14 | ### Added 15 | - Initial structure of the collection. 16 | - Added initial vector2 and vector3 tools: 17 | >- CrossProductVector2 18 | >- CrossProductVector3 19 | >- DotProductVector2 20 | >- DotProductVector3 21 | >- MagnitudeVector2 22 | >- MagnitudeVector3 23 | >- MultiplyVector3Matrix3 24 | >- NormalizeVector2 25 | >- NormalizeVector3 26 | >- RotateVector2 27 | >- RotateVector3 28 | >- TransformVector2 29 | >- TransformVector3 30 | >- MultiplyVector3Matrix3 31 | - Added initial axis and matrix tools: 32 | >- InvertAxis 33 | >- ZeroAxis 34 | >- InvertMatrix4 35 | >- ProductMatrix4 36 | >- RotateMatrix4 37 | >- ScaleMatrix4 38 | >- TransformMatrix4 39 | >- TranslateMatrix4 40 | >- TransposeMatrix4 41 | - Added initial Convert, Generate, Gizmo tools: 42 | >- GenerateMatrix4 43 | >- GenerateSTMap 44 | >- LumaToVector3 45 | >- Vector2ToSTMap 46 | >- Vector3ToMatrix 47 | >- IIDistort 48 | - Setup menu.py and init.py 49 | - Initial installation documentation in README 50 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # nuke-vector-matrix 2 | Suite of mathematical nodes for Nuke to deal with Vectors and Matrices, by @mapoga (Mathieu Goulet-Aubin) 3 | and @herronelou (Erwan Leroy). 4 | 5 | ### Table of Contents 6 | **[Installation Instructions](#installation-instructions)**
7 | **[Manual Installation](#manual-installation)**
8 | **[Resources to learn about Vectors and Matrices](#resources-to-learn-about-vectors-and-matrices)** 9 | 10 | ## Installation Instructions 11 | For easy installation of the toolset, we provide a script that will make menu entries for each of our tools and ensure 12 | they are all part of the Nuke plugin path. 13 | 14 | Installation instructions are similar for any OS. However, the paths we are using in the example are formatted for an 15 | UNIX system (Mac or Linux). 16 | 17 | 1. Download the full content of the nuke-vector-matrix repository. If downloaded 18 | as a .ZIP, uncompress the zip in the desired location. For the following steps, we will assume the folder is present 19 | on disk as: `/my_nuke_gizmos/nuke-vector-matrix/`. 20 | 2. Add the path to the folder in your NUKE_PATH, either via an environment variable ([Defining Nuke plugin path]( 21 | https://learn.foundry.com/nuke/content/comp_environment/configuring_nuke/defining_nuke_plugin_path.html)) or 22 | via an existing / new `init.py` file, in which you would add the line: 23 | 24 | ```python 25 | nuke.pluginAddPath('/my_nuke_gizmos/nuke-vector-matrix/') 26 | ``` 27 | 28 | This should be enough to Install the suite of tools. 29 | 30 | 31 | ## Manual Installation 32 | While the default installation is probably ideal for many users, it may not be the best for Studio Environments 33 | where tools need to be installed in a specific location or for users who already have their own Gizmo loader. 34 | 35 | For manual installation of the tools, only the content of the `nuke` folder is necessary and contains all the .nk and 36 | .gizmo files. 37 | It can be reorganized as required. 38 | 39 | .gizmo files need to be added to the nuke plugin path. See instructions by the foundry: 40 | - [Loading Gizmos, Plugins, Scripts]( 41 | https://learn.foundry.com/nuke/content/comp_environment/configuring_nuke/loading_gizmos_plugins_scripts.html) 42 | - [Custom Menus]( 43 | https://learn.foundry.com/nuke/content/comp_environment/configuring_nuke/custom_menus_toolbars.html) 44 | 45 | 46 | All the icons are located in the `icons` folder. 47 | 48 | ## Resources to learn about Vectors and Matrices 49 | 50 | Most tools in this toolset are mathematical tools and require some basic knowledge about Vectors and Matrices for 51 | optimal use. 52 | 53 | - [Math is Fun: Scalar, Vector, Matrix](https://www.mathsisfun.com/algebra/scalar-vector-matrix.html) 54 | - [Wikipedia: Transformation Matrices](https://en.wikipedia.org/wiki/Transformation_matrix) 55 | - [Nukepedia: Python Vector and Matrix Math](http://www.nukepedia.com/written-tutorials/using-the-nukemath-python-module-to-do-vector-and-matrix-operations/) 56 | - [Nukepedia: The Matrix Knob](http://www.nukepedia.com/expressions/enter-the-matrix-knob) 57 | 58 | 59 | -------------------------------------------------------------------------------- /icons/CrossProductVector3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mapoga/nuke-vector-matrix/b55276cd253bab70a09b5ef63ef04c5718d09bab/icons/CrossProductVector3.png -------------------------------------------------------------------------------- /icons/DeterminantMatrix3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mapoga/nuke-vector-matrix/b55276cd253bab70a09b5ef63ef04c5718d09bab/icons/DeterminantMatrix3.png -------------------------------------------------------------------------------- /icons/DeterminantMatrix4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mapoga/nuke-vector-matrix/b55276cd253bab70a09b5ef63ef04c5718d09bab/icons/DeterminantMatrix4.png -------------------------------------------------------------------------------- /icons/DotProductVector3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mapoga/nuke-vector-matrix/b55276cd253bab70a09b5ef63ef04c5718d09bab/icons/DotProductVector3.png -------------------------------------------------------------------------------- /icons/IdentityMatrix4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mapoga/nuke-vector-matrix/b55276cd253bab70a09b5ef63ef04c5718d09bab/icons/IdentityMatrix4.png -------------------------------------------------------------------------------- /icons/InvertMatrix4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mapoga/nuke-vector-matrix/b55276cd253bab70a09b5ef63ef04c5718d09bab/icons/InvertMatrix4.png -------------------------------------------------------------------------------- /icons/MagnitudeVector3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mapoga/nuke-vector-matrix/b55276cd253bab70a09b5ef63ef04c5718d09bab/icons/MagnitudeVector3.png -------------------------------------------------------------------------------- /icons/Math.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mapoga/nuke-vector-matrix/b55276cd253bab70a09b5ef63ef04c5718d09bab/icons/Math.png -------------------------------------------------------------------------------- /icons/Matrix3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mapoga/nuke-vector-matrix/b55276cd253bab70a09b5ef63ef04c5718d09bab/icons/Matrix3.png -------------------------------------------------------------------------------- /icons/Matrix4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mapoga/nuke-vector-matrix/b55276cd253bab70a09b5ef63ef04c5718d09bab/icons/Matrix4.png -------------------------------------------------------------------------------- /icons/NormalizeVector3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mapoga/nuke-vector-matrix/b55276cd253bab70a09b5ef63ef04c5718d09bab/icons/NormalizeVector3.png -------------------------------------------------------------------------------- /icons/ProductMatrix4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mapoga/nuke-vector-matrix/b55276cd253bab70a09b5ef63ef04c5718d09bab/icons/ProductMatrix4.png -------------------------------------------------------------------------------- /icons/ProductVector3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mapoga/nuke-vector-matrix/b55276cd253bab70a09b5ef63ef04c5718d09bab/icons/ProductVector3.png -------------------------------------------------------------------------------- /icons/RotateMatrix4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mapoga/nuke-vector-matrix/b55276cd253bab70a09b5ef63ef04c5718d09bab/icons/RotateMatrix4.png -------------------------------------------------------------------------------- /icons/ScaleMatrix4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mapoga/nuke-vector-matrix/b55276cd253bab70a09b5ef63ef04c5718d09bab/icons/ScaleMatrix4.png -------------------------------------------------------------------------------- /icons/TransformMatrix4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mapoga/nuke-vector-matrix/b55276cd253bab70a09b5ef63ef04c5718d09bab/icons/TransformMatrix4.png -------------------------------------------------------------------------------- /icons/TranslateMatrix4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mapoga/nuke-vector-matrix/b55276cd253bab70a09b5ef63ef04c5718d09bab/icons/TranslateMatrix4.png -------------------------------------------------------------------------------- /icons/TransposeMatrix4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mapoga/nuke-vector-matrix/b55276cd253bab70a09b5ef63ef04c5718d09bab/icons/TransposeMatrix4.png -------------------------------------------------------------------------------- /icons/Vector2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mapoga/nuke-vector-matrix/b55276cd253bab70a09b5ef63ef04c5718d09bab/icons/Vector2.png -------------------------------------------------------------------------------- /icons/Vector3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mapoga/nuke-vector-matrix/b55276cd253bab70a09b5ef63ef04c5718d09bab/icons/Vector3.png -------------------------------------------------------------------------------- /init.py: -------------------------------------------------------------------------------- 1 | """ 2 | recursively adding all subfolders to plugin path 3 | """ 4 | 5 | import os 6 | import nuke 7 | try: 8 | import scandir as walk_module 9 | except ImportError: 10 | import os as walk_module 11 | 12 | 13 | CWD = os.path.dirname((os.path.abspath(__file__))) 14 | 15 | # add Nuke Directory Recursively 16 | nuke_dir = os.path.join(CWD, 'nuke') 17 | 18 | for root, dirs, files in walk_module.walk(nuke_dir): 19 | nuke.pluginAddPath(root) 20 | -------------------------------------------------------------------------------- /menu.py: -------------------------------------------------------------------------------- 1 | """ 2 | Creates a menu and dynamically populate it with .gizmo, .so and .nk files 3 | Supports icons by adding them either at the same level as the tool/subdir or in a /icons directory 4 | All subdirectories are added to the nuke.pluginPath() (see init.py) 5 | """ 6 | 7 | import os 8 | import re 9 | import nuke 10 | from transform_utils import matrix_utils 11 | 12 | try: 13 | import scandir as walk_module 14 | except ImportError: 15 | walk_module = os 16 | 17 | CWD = os.path.dirname((os.path.abspath(__file__))) 18 | 19 | 20 | # Functions 21 | def find_icon(name): 22 | path = os.path.join(CWD, 'icons') 23 | img = None 24 | for icon_ext in ['.jpg', '.png']: 25 | icon_path = os.path.join(path, name + icon_ext) 26 | if os.path.isfile(icon_path): 27 | img = icon_path 28 | 29 | return str(img) if img else None 30 | 31 | 32 | def populate_menu_recursive(tool_path, menu): 33 | if not tool_path.endswith(os.sep): 34 | tool_path += os.sep 35 | 36 | for root, dirs, files in os.walk(tool_path): 37 | category = root.replace(tool_path, '').replace('\\', '/') 38 | # build the dynamic menus, ignoring empty dirs: 39 | for dir_name in natural_sort(dirs): 40 | if os.listdir(os.path.join(root, dir_name)): 41 | img = find_icon(dir_name) 42 | menu.addMenu(category + '/' + dir_name, icon=img) 43 | 44 | # if we have both dirs and files, add a separator 45 | if files and dirs: 46 | submenu = menu.addMenu(category) # menu() and findItem() do not return a menu object. 47 | submenu.addSeparator() 48 | 49 | # Populate the menus 50 | for nuke_file in natural_sort(files): 51 | file_name, extension = os.path.splitext(nuke_file) 52 | if extension.lower() in ['.gizmo', '.so', '.nk']: 53 | img = find_icon(file_name) 54 | # Adding the menu command 55 | if extension.lower() in ['.nk']: 56 | menu.addCommand(category + '/' + file_name, 57 | 'nuke.nodePaste( "{}" )'.format(os.path.join(root, nuke_file).replace('\\', '/')), 58 | icon=img) 59 | if extension.lower() in ['.gizmo', '.so']: 60 | menu.addCommand(category + '/' + file_name, 61 | 'nuke.createNode( "{}" )'.format(file_name), 62 | icon=img) 63 | return menu 64 | 65 | 66 | def natural_sort(values, case_sensitive=False): 67 | """ 68 | Returns a human-readable list with integers accounted for in the sort. 69 | items = ['xyz.1001.exr', 'xyz.1000.exr', 'abc11.txt', 'xyz.0999.exr', 'abc10.txt', 'abc9.txt'] 70 | natural_sort(items) = ['abc9.txt', 'abc10.txt', 'abc11.txt', 'xyz.0999.exr', 'xyz.1000.exr', 'xyz.1001.exr'] 71 | :param values: string list 72 | :param case_sensitive: Bool. If True capitals precede lowercase, so ['a', 'b', 'C'] sorts to ['C', 'a', 'b'] 73 | :return: list 74 | """ 75 | def alpha_to_int(a, _case_sensitive=False): 76 | return int(a) if a.isdigit() else (a if _case_sensitive else a.lower()) 77 | 78 | def natural_sort_key(_values): 79 | try: 80 | return tuple(alpha_to_int(c, case_sensitive) for c in re.split(r'(\d+)', _values) if c) 81 | except (TypeError, ValueError): 82 | return _values 83 | 84 | return sorted(values, key=natural_sort_key) 85 | 86 | 87 | # Nodes Menu 88 | toolbar = nuke.toolbar("Nodes") 89 | toolbar_math_tools = toolbar.addMenu("Math Tools", icon=find_icon("Math")) 90 | 91 | nuke_dir = os.path.join(CWD, 'nuke') 92 | 93 | populate_menu_recursive(nuke_dir, toolbar_math_tools) 94 | 95 | # Utilities Menu 96 | # By default in the main Nuke menu, change the next line to have the menu somewhere else. 97 | target_menu = nuke.menu('Nuke') 98 | transform_menu = target_menu.addMenu("Transform Utils", icon="transforms.png") 99 | transform_menu.addCommand("Convert Transforms", matrix_utils.run_convert_matrix) 100 | transform_menu.addCommand("Merge Transforms", matrix_utils.run_merge_transforms) 101 | transform_menu.addCommand("Convert Tracker to SplineWarp", matrix_utils.run_convert_tracker_to_splinewarp) 102 | 103 | # Menus in the animation menu must call a string for some reason 104 | nuke.menu('Animation').addCommand('Edit/Filter Rotations', 105 | "from transform_utils import rotation_filters;" 106 | "rotation_filters.setup_filter_rotations()") 107 | -------------------------------------------------------------------------------- /nuke/Convert/LumaToVector3.nk: -------------------------------------------------------------------------------- 1 | Group { 2 | name LumaToVector3 3 | help "Performs a Sobel filter on the Luminance channel of an image to extract an approximation of a Normal map.\n\nFor a mathematical conversion of a displacement map to normals, do not use Details separation." 4 | addUserKnob {20 luma_to_normals l "Luma to Normals"} 5 | addUserKnob {26 div_pre l Pre-Process} 6 | addUserKnob {7 blur t "High quality blur, may be slower than a regular blur node but will avoid loss of quality in the vectors." R 0 10} 7 | addUserKnob {7 gain l "height (gain)" t "Increasing this value would result in vectors as per a stronger displacement." R 0 10} 8 | gain 1 9 | addUserKnob {26 div_details l "Details Separation"} 10 | addUserKnob {7 size t "Bigger sizes will separate high and low frequencies more." R 0 100} 11 | addUserKnob {7 details_weight t "How much the details affect the final output"} 12 | addUserKnob {26 div_out l Output} 13 | addUserKnob {6 zerotoone l "Use 0-1 range" t "Pack the vectors in a 0 to 1 range, so that it can be exported as an 8bit image. May cause clamped vectors, make sure to also use normalize if exporting a normal map to avoid clamped values." +STARTLINE} 14 | addUserKnob {6 normalize t "Normal maps should generally be represented with a vector magnitude of 1.\nTurning on normalization will scale all vectors to ensure they all have a magnitude of 1.\n\nYou may want to disable it for more interesting effects when generating normals for a fake refraction through an iDistort, where having vectors of different length adds depth." -STARTLINE} 15 | normalize true 16 | addUserKnob {26 ""} 17 | addUserKnob {26 copyright l "" +STARTLINE T "v1.0 - Mathieu Goulet-Aubin & Erwan Leroy - Github"} 18 | } 19 | Input { 20 | inputs 0 21 | name Input1 22 | xpos -576 23 | ypos -320 24 | } 25 | Saturation { 26 | saturation 0 27 | name Saturation1 28 | xpos -576 29 | ypos -264 30 | } 31 | Blur { 32 | size {{parent.blur}} 33 | quality {{"int(max(parent.blur, 15))"}} 34 | name Blur2 35 | xpos -576 36 | ypos -223 37 | } 38 | Multiply { 39 | value {{parent.gain}} 40 | name Multiply1 41 | xpos -576 42 | ypos -185 43 | } 44 | set N8fdf0400 [stack 0] 45 | Blur { 46 | size {{parent.size}} 47 | name Blur1 48 | xpos -576 49 | ypos -134 50 | } 51 | Dot { 52 | name Dot2 53 | xpos -542 54 | ypos -45 55 | } 56 | set Nc5a5fc00 [stack 0] 57 | Matrix { 58 | matrix { 59 | {1 0 -1} 60 | {2 0 -2} 61 | {1 0 -1} 62 | } 63 | name Matrix1 64 | xpos -576 65 | ypos 38 66 | } 67 | push $Nc5a5fc00 68 | Dot { 69 | name Dot3 70 | xpos -432 71 | ypos -45 72 | } 73 | set Nc5a5f400 [stack 0] 74 | Matrix { 75 | matrix { 76 | {-1 -2 -1} 77 | {0 0 0} 78 | {1 2 1} 79 | } 80 | name Matrix2 81 | xpos -466 82 | ypos 36 83 | } 84 | Dot { 85 | name Dot4 86 | xpos -432 87 | ypos 92 88 | } 89 | ShuffleCopy { 90 | inputs 2 91 | red red 92 | blue black 93 | alpha black 94 | name ShuffleCopy1 95 | xpos -575 96 | ypos 88 97 | } 98 | Multiply { 99 | value {{(1-parent.details_weight)*(parent.size/10+1)}} 100 | name Multiply2 101 | xpos -577 102 | ypos 128 103 | } 104 | push $Nc5a5f400 105 | push $N8fdf0400 106 | Dot { 107 | name Dot1 108 | xpos -319 109 | ypos -175 110 | } 111 | Merge2 { 112 | inputs 2 113 | operation from 114 | name Merge1 115 | xpos -353 116 | ypos -49 117 | } 118 | Dot { 119 | name Dot5 120 | xpos -319 121 | ypos -23 122 | } 123 | set Nb4693800 [stack 0] 124 | Matrix { 125 | matrix { 126 | {1 0 -1} 127 | {2 0 -2} 128 | {1 0 -1} 129 | } 130 | name Matrix3 131 | xpos -353 132 | ypos 25 133 | } 134 | push $Nb4693800 135 | Dot { 136 | name Dot6 137 | xpos -181 138 | ypos -23 139 | } 140 | Matrix { 141 | matrix { 142 | {-1 -2 -1} 143 | {0 0 0} 144 | {1 2 1} 145 | } 146 | name Matrix4 147 | xpos -215 148 | ypos 30 149 | } 150 | Dot { 151 | name Dot7 152 | xpos -181 153 | ypos 87 154 | } 155 | ShuffleCopy { 156 | inputs 2 157 | red red 158 | blue black 159 | alpha black 160 | name ShuffleCopy2 161 | xpos -353 162 | ypos 83 163 | } 164 | Multiply { 165 | value {{parent.details_weight}} 166 | name Multiply3 167 | xpos -353 168 | ypos 119 169 | } 170 | Dot { 171 | name Dot8 172 | xpos -319 173 | ypos 188 174 | } 175 | Merge2 { 176 | inputs 2 177 | operation plus 178 | name Merge2 179 | xpos -577 180 | ypos 184 181 | } 182 | Multiply { 183 | value 0.5 184 | name Multiply4 185 | xpos -577 186 | ypos 229 187 | disable {{!proxy}} 188 | } 189 | Expression { 190 | temp_name0 mag 191 | temp_expr0 sqrt(pow(r,2)+pow(g,2)+pow(b,2)) 192 | expr0 mag>1?r/mag:r 193 | expr1 mag>1?g/mag:g 194 | name Expression3 195 | xpos -577 196 | ypos 283 197 | disable {{!parent.normalize}} 198 | } 199 | Expression { 200 | temp_name0 facing 201 | temp_expr0 sqrt(-pow(r,2)-pow(g,2)+1) 202 | expr2 isnan(facing)?0:facing 203 | name Expression2 204 | xpos -577 205 | ypos 322 206 | } 207 | Remove { 208 | operation keep 209 | channels rgb 210 | name Remove1 211 | xpos -577 212 | ypos 354 213 | } 214 | Grade { 215 | white 0.5 216 | add 0.5 217 | white_clamp true 218 | name Grade1 219 | xpos -577 220 | ypos 397 221 | disable {{!parent.zerotoone}} 222 | } 223 | Output { 224 | name Output1 225 | xpos -577 226 | ypos 479 227 | } 228 | end_group 229 | -------------------------------------------------------------------------------- /nuke/Convert/STMapToVector2.nk: -------------------------------------------------------------------------------- 1 | Group { 2 | name STMapToVector2_ 3 | help "Transforms a distorted UV Map to Motion Vectors corresponding to the distortion." 4 | xpos -587 5 | ypos 59 6 | addUserKnob {20 UV_to_Vectors l "STMap to Vector2"} 7 | addUserKnob {41 in l UV_Layer t "Select the layer containing your UV_map" T UV_Channel.in} 8 | addUserKnob {26 ""} 9 | addUserKnob {26 copyright l "" +STARTLINE T "v1.0 - Mathieu Goulet-Aubin & Erwan Leroy - Github"} 10 | } 11 | Input { 12 | inputs 0 13 | name Input 14 | xpos -291 15 | ypos -63 16 | } 17 | set Na0950a0 [stack 0] 18 | Shuffle { 19 | name UV_Channel 20 | xpos -151 21 | ypos -17 22 | } 23 | Expression { 24 | expr0 -x+r*width-0.5 25 | expr1 -y+g*height-0.5 26 | channel2 {-rgba.red -rgba.green -rgba.blue none} 27 | channel3 {none none none -rgba.alpha} 28 | name UV_to_Vectors1 29 | xpos -151 30 | ypos 97 31 | } 32 | push $Na0950a0 33 | ShuffleCopy { 34 | inputs 2 35 | in2 none 36 | red red 37 | green green 38 | alpha black 39 | out {{{parent.UV_Channel.in}}} 40 | name ShuffleCopy1 41 | xpos -291 42 | ypos 97 43 | } 44 | Output { 45 | name Output1 46 | xpos -291 47 | ypos 167 48 | } 49 | end_group 50 | -------------------------------------------------------------------------------- /nuke/Convert/Vector2ToSTMap.nk: -------------------------------------------------------------------------------- 1 | Group { 2 | name Vector2ToSTMap 3 | xpos -588 4 | ypos -1 5 | addUserKnob {20 VtoU l "Vector2 to STMap"} 6 | addUserKnob {41 in l Vector_Layer t "Pick the layer containing your motion vectors." T UV_Channel.in} 7 | addUserKnob {26 ""} 8 | addUserKnob {26 copyright l "" +STARTLINE T "v1.0 - Mathieu Goulet-Aubin & Erwan Leroy - Github"} 9 | } 10 | Input { 11 | inputs 0 12 | name Input 13 | xpos -303 14 | ypos 114 15 | } 16 | set Ne43e7b0 [stack 0] 17 | Shuffle { 18 | name UV_Channel 19 | xpos -163 20 | ypos 114 21 | } 22 | Expression { 23 | expr0 (r+x+0.5)/width 24 | expr1 (g+y+0.5)/height 25 | channel2 {-rgba.red -rgba.green -rgba.blue none} 26 | channel3 {none none none -rgba.alpha} 27 | name Vectors_to_UV 28 | xpos -163 29 | ypos 228 30 | } 31 | push $Ne43e7b0 32 | ShuffleCopy { 33 | inputs 2 34 | in2 none 35 | red red 36 | green green 37 | alpha black 38 | out {{{parent.UV_Channel.in}}} 39 | name ShuffleCopy1 40 | xpos -303 41 | ypos 228 42 | } 43 | Output { 44 | name Output1 45 | xpos -303 46 | ypos 299 47 | } 48 | end_group 49 | -------------------------------------------------------------------------------- /nuke/Convert/Vector3ToMatrix4.nk: -------------------------------------------------------------------------------- 1 | Group { 2 | name Vector3ToMatrix4_ 3 | knobChanged "# Knobchanged code:\nnode = nuke.thisNode()\nknob = nuke.thisKnob()\nif knob.name() == 'vector_representation':\n if knob.value() == 'Rotation (orientation vector)':\n node\['lookat'].setVisible(True)\n node\['minus_axis'].setVisible(True)\n else:\n node\['lookat'].setVisible(False)\n node\['minus_axis'].setVisible(False)\n" 4 | addUserKnob {20 main_tab l "Vector3 to Matrix4"} 5 | addUserKnob {4 vector_representation l "Use Vector as" t "A vector3 by itself cannot represent all the parts required for a matrix, however we are able to infer some transformation matrices from a vector3.\nFor a translation matrix, the x, y and z values are used as is for translate values.\nFor a rotation matrix, we calculate a rotation matrix so that a specified axis looks at the 3d point defined by the vector. If you are looking to rotate in x, y and z angles by the amount of each dimention of the vector, look at the RotateMatrix4 node instead.\nFor the scale vector, we use the magnitude here, so this will always result in an uniform scale. For non-uniform scaling, look at ScaleMatrix4." M {Translation "Rotation (orientation vector)" "Scale (magnitude)"}} 6 | addUserKnob {4 lookat l "Aim Axis" t "Aim the selected Axis in the direction of the 3d vector." +HIDDEN M {X Y Z "" ""}} 7 | addUserKnob {6 minus_axis l "Negative Axis" t "Use the negative axis rather than the positive axis" -STARTLINE +HIDDEN} 8 | addUserKnob {26 ""} 9 | addUserKnob {26 copyright l "" +STARTLINE T "v1.0 - Mathieu Goulet-Aubin & Erwan Leroy - Github"} 10 | } 11 | BackdropNode { 12 | inputs 0 13 | name BackdropNode1 14 | tile_color 0x545454ff 15 | label "- Identity in\n matrix layers\n- Bypass other channels" 16 | note_font_size 20 17 | xpos -39 18 | ypos 277 19 | bdwidth 280 20 | bdheight 262 21 | } 22 | Input { 23 | inputs 0 24 | name vector3 25 | xpos -335 26 | ypos -120 27 | } 28 | Dot { 29 | name Dot12 30 | tile_color 0xcccccc00 31 | xpos -301 32 | ypos 97 33 | } 34 | set N260f03c0 [stack 0] 35 | Group { 36 | name NormalizeVector3_1 37 | help "Normalize the magnitude of a Vector3 (to be of magnitude 1)" 38 | xpos -145 39 | ypos 94 40 | addUserKnob {20 main_tab l "Normalize Vector3"} 41 | addUserKnob {41 in l "Vector B Layer" t "Layer containing the vector information for input B" T vector_layer.in} 42 | addUserKnob {26 ""} 43 | addUserKnob {26 copyright l "" +STARTLINE T "v1.0 - Mathieu Goulet-Aubin & Erwan Leroy - Github"} 44 | } 45 | Input { 46 | inputs 0 47 | name vectorB 48 | xpos 0 49 | } 50 | Dot { 51 | name Dot1 52 | tile_color 0xcccccc00 53 | xpos 34 54 | ypos 108 55 | } 56 | set N168e4560 [stack 0] 57 | Shuffle { 58 | name vector_layer 59 | xpos 140 60 | ypos 104 61 | } 62 | Remove { 63 | operation keep 64 | channels rgba 65 | name Remove1 66 | xpos 140 67 | ypos 130 68 | } 69 | Dot { 70 | name Dot3 71 | tile_color 0x9e3c6300 72 | xpos 174 73 | ypos 156 74 | } 75 | set N1b5e0b90 [stack 0] 76 | push $N1b5e0b90 77 | Dot { 78 | name Dot4 79 | tile_color 0x9e3c6300 80 | xpos 377 81 | ypos 156 82 | } 83 | Expression { 84 | channel0 rgba 85 | expr0 sqrt((r*r)+(g*g)+(b*b)) 86 | channel2 {-rgba.red -rgba.green -rgba.blue none} 87 | channel3 {none none none -rgba.alpha} 88 | name Mag3 89 | xpos 343 90 | ypos 209 91 | } 92 | Dot { 93 | name Dot5 94 | tile_color 0xcccccc00 95 | xpos 377 96 | ypos 271 97 | } 98 | Merge2 { 99 | inputs 2 100 | operation divide 101 | bbox B 102 | name Merge1 103 | xpos 140 104 | ypos 267 105 | } 106 | Dot { 107 | name Dot2 108 | tile_color 0x4b5ec600 109 | xpos 174 110 | ypos 364 111 | } 112 | push $N168e4560 113 | ShuffleCopy { 114 | inputs 2 115 | in2 none 116 | red red 117 | green green 118 | blue blue 119 | out {{{parent.UV_Channel.in}}} 120 | name ShuffleCopy1 121 | xpos 0 122 | ypos 360 123 | } 124 | Output { 125 | name Output1 126 | xpos 0 127 | ypos 506 128 | } 129 | end_group 130 | Multiply { 131 | value -1 132 | name Multiply1 133 | xpos 269 134 | ypos 88 135 | disable {{!parent.minus_axis}} 136 | } 137 | Dot { 138 | name Dot1 139 | tile_color 0x7aa9ff00 140 | xpos 303 141 | ypos 173 142 | } 143 | set N1556f230 [stack 0] 144 | Dot { 145 | name Dot5 146 | tile_color 0x7aa9ff00 147 | xpos 376 148 | ypos 173 149 | } 150 | set N1cfd1db0 [stack 0] 151 | Constant { 152 | inputs 0 153 | channels rgb 154 | color {1 0 0 1} 155 | name Pole_Vector1 156 | xpos 609 157 | ypos -35 158 | } 159 | Constant { 160 | inputs 0 161 | channels rgb 162 | color {0 0 1 1} 163 | name Pole_Vector2 164 | xpos 506 165 | ypos -36 166 | } 167 | Constant { 168 | inputs 0 169 | channels rgb 170 | color {0 1 0 1} 171 | name Pole_Vector 172 | xpos 407 173 | ypos -38 174 | } 175 | Switch { 176 | inputs 3 177 | which {{parent.lookat}} 178 | name Pole_Picker 179 | xpos 407 180 | ypos 88 181 | } 182 | Group { 183 | inputs 2 184 | name CrossProductVector3_ 185 | help "Calculates the cross product of 2 Vector3 inputs." 186 | xpos 407 187 | ypos 225 188 | addUserKnob {20 main_tab l "Cross Product Vector3"} 189 | addUserKnob {41 in l "Vector B Layer" t "Layer containing the vector information for input B" T vector_layer.in} 190 | addUserKnob {41 in_1 l "Vector A Layer" t "Layer containing the vector information for input A" T vector_layer1.in} 191 | addUserKnob {26 ""} 192 | addUserKnob {26 copyright l "" +STARTLINE T "v1.0 - Mathieu Goulet-Aubin & Erwan Leroy - Github"} 193 | } 194 | Input { 195 | inputs 0 196 | name vectorA 197 | xpos 457 198 | ypos -6 199 | number 1 200 | } 201 | Shuffle { 202 | name vector_layer1 203 | xpos 457 204 | ypos 103 205 | } 206 | Remove { 207 | operation keep 208 | channels rgba 209 | name Remove2 210 | xpos 457 211 | ypos 129 212 | } 213 | Dot { 214 | name Dot3 215 | tile_color 0x9e3c6300 216 | xpos 491 217 | ypos 210 218 | } 219 | Input { 220 | inputs 0 221 | name vectorB 222 | xpos 0 223 | } 224 | Dot { 225 | name Dot1 226 | tile_color 0xcccccc00 227 | xpos 34 228 | ypos 108 229 | } 230 | set N12b61dd0 [stack 0] 231 | Shuffle { 232 | name vector_layer 233 | xpos 140 234 | ypos 104 235 | } 236 | Remove { 237 | operation keep 238 | channels rgba 239 | name Remove1 240 | xpos 140 241 | ypos 130 242 | } 243 | MergeExpression { 244 | inputs 2 245 | expr0 "Ag*Bb - Ab*Bg" 246 | expr1 "Ab*Br - Ar*Bb" 247 | expr2 "Ar*Bg - Ag*Br" 248 | name MergeExpression2 249 | xpos 140 250 | ypos 206 251 | } 252 | Dot { 253 | name Dot2 254 | tile_color 0x4b5ec600 255 | xpos 174 256 | ypos 364 257 | } 258 | push $N12b61dd0 259 | ShuffleCopy { 260 | inputs 2 261 | in2 none 262 | red red 263 | green green 264 | blue blue 265 | out {{{parent.UV_Channel.in}}} 266 | name ShuffleCopy1 267 | xpos 0 268 | ypos 360 269 | } 270 | Output { 271 | name Output1 272 | xpos 0 273 | ypos 506 274 | } 275 | end_group 276 | set N122b60e0 [stack 0] 277 | push $N260f03c0 278 | Group { 279 | name Magnitude_Vector3_ 280 | help "Calculate the magnitude (scalar) of an input Vector3." 281 | xpos -560 282 | ypos 94 283 | addUserKnob {20 main_tab l "Magnitude Vector3"} 284 | addUserKnob {41 in l "Vector B Layer" t "Layer containing the vector information for input B" T vector_layer.in} 285 | addUserKnob {26 ""} 286 | addUserKnob {26 copyright l "" +STARTLINE T "v1.0 - Mathieu Goulet-Aubin & Erwan Leroy - Github"} 287 | } 288 | Input { 289 | inputs 0 290 | name vectorB 291 | xpos 0 292 | } 293 | Dot { 294 | name Dot1 295 | tile_color 0xcccccc00 296 | xpos 34 297 | ypos 108 298 | } 299 | set N355da1b0 [stack 0] 300 | Shuffle { 301 | name vector_layer 302 | xpos 140 303 | ypos 104 304 | } 305 | Remove { 306 | operation keep 307 | channels rgba 308 | name Remove1 309 | xpos 140 310 | ypos 130 311 | } 312 | Expression { 313 | channel0 rgba 314 | expr0 sqrt((r*r)+(g*g)+(b*b)) 315 | channel2 {-rgba.red -rgba.green -rgba.blue none} 316 | channel3 {none none none -rgba.alpha} 317 | name Mag3 318 | xpos 140 319 | ypos 227 320 | } 321 | Dot { 322 | name Dot2 323 | tile_color 0xcccccc00 324 | xpos 174 325 | ypos 364 326 | } 327 | push $N355da1b0 328 | ShuffleCopy { 329 | inputs 2 330 | in2 none 331 | red red 332 | green green 333 | blue blue 334 | out {{{parent.UV_Channel.in}}} 335 | name ShuffleCopy1 336 | xpos 0 337 | ypos 360 338 | } 339 | Output { 340 | name Output1 341 | xpos 0 342 | ypos 506 343 | } 344 | end_group 345 | push $N1556f230 346 | Dot { 347 | name Dot8 348 | tile_color 0x7aa9ff00 349 | xpos 93 350 | ypos 173 351 | } 352 | Remove { 353 | name Remove1 354 | xpos 59 355 | ypos 229 356 | } 357 | add_layer {matrix0 matrix0.0 matrix0.1 matrix0.2 matrix0.3} 358 | Expression { 359 | channel0 {matrix0.0 -matrix0.1 -matrix0.2 -matrix0.3} 360 | expr0 1 361 | channel1 {-matrix0.0 matrix0.1 -matrix0.2 -matrix0.3} 362 | expr1 0 363 | channel2 {-matrix0.0 -matrix0.1 matrix0.2 -matrix0.3} 364 | expr2 0 365 | channel3 {-matrix0.0 -matrix0.1 -matrix0.2 matrix0.3} 366 | expr3 0 367 | name Expression1 368 | xpos 59 369 | ypos 402 370 | } 371 | add_layer {matrix1 matrix1.0 matrix1.1 matrix1.2 matrix1.3} 372 | Expression { 373 | channel0 {matrix1.0 -matrix1.1 -matrix1.2 -matrix1.3} 374 | expr0 0 375 | channel1 {-matrix1.0 matrix1.1 -matrix1.2 -matrix1.3} 376 | expr1 1 377 | channel2 {-matrix1.0 -matrix1.1 matrix1.2 -matrix1.3} 378 | expr2 0 379 | channel3 {-matrix1.0 -matrix1.1 -matrix1.2 matrix1.3} 380 | expr3 0 381 | name Expression2 382 | xpos 59 383 | ypos 426 384 | } 385 | add_layer {matrix2 matrix2.0 matrix2.1 matrix2.2 matrix2.3} 386 | Expression { 387 | channel0 {matrix2.0 -matrix2.1 -matrix2.2 -matrix2.3} 388 | expr0 0 389 | channel1 {-matrix2.0 matrix2.1 -matrix2.2 -matrix2.3} 390 | expr1 0 391 | channel2 {-matrix2.0 -matrix2.1 matrix2.2 -matrix2.3} 392 | expr2 1 393 | channel3 {-matrix2.0 -matrix2.1 -matrix2.2 matrix2.3} 394 | expr3 0 395 | name Expression3 396 | xpos 59 397 | ypos 450 398 | } 399 | add_layer {matrix3 matrix3.0 matrix3.1 matrix3.2 matrix3.3} 400 | Expression { 401 | channel0 {matrix3.0 -matrix3.1 -matrix3.2 -matrix3.3} 402 | expr0 0 403 | channel1 {-matrix3.0 matrix3.1 -matrix3.2 -matrix3.3} 404 | expr1 0 405 | channel2 {-matrix3.0 -matrix3.1 matrix3.2 -matrix3.3} 406 | expr2 0 407 | channel3 {-matrix3.0 -matrix3.1 -matrix3.2 matrix3.3} 408 | expr3 1 409 | name Expression4 410 | xpos 59 411 | ypos 474 412 | } 413 | Dot { 414 | name Dot13 415 | tile_color 0xcccccc00 416 | xpos 93 417 | ypos 530 418 | } 419 | set N2c4e4bb0 [stack 0] 420 | Dot { 421 | name Dot14 422 | tile_color 0xcccccc00 423 | xpos -202 424 | ypos 530 425 | } 426 | set N13be2b70 [stack 0] 427 | Group { 428 | inputs 2 429 | name ScaleMatrix4_ 430 | help "Scale a matrix4 using a control channel (rgb from vector input) for which each channel is considered as a scalar for x, y and z" 431 | xpos -560 432 | ypos 527 433 | addUserKnob {20 ScaleMatrix4} 434 | addUserKnob {26 Description l "" +STARTLINE T "Scale a matrix4 using a control channel (rgb) for which each channel is considered as a scalar for x, y and z"} 435 | addUserKnob {26 divider_copyright l "" +STARTLINE} 436 | addUserKnob {26 copyright l "" +STARTLINE T "v1.0 - Mathieu Goulet-Aubin & Erwan Leroy - Github"} 437 | } 438 | Input { 439 | inputs 0 440 | name vector 441 | xpos 491 442 | ypos 162 443 | number 1 444 | } 445 | Dot { 446 | name Dot1 447 | xpos 525 448 | ypos 252 449 | } 450 | Input { 451 | inputs 0 452 | name matrix 453 | xpos 344 454 | ypos 161 455 | } 456 | MergeExpression { 457 | inputs 2 458 | channel0 {matrix0.0 -matrix0.1 -matrix0.2 -matrix0.3} 459 | expr0 matrix0.0*Ar 460 | channel1 {-matrix1.0 matrix1.1 -matrix1.2 -matrix1.3} 461 | expr1 matrix1.1*Ag 462 | channel2 {-matrix2.0 -matrix2.1 matrix2.2 -matrix2.3} 463 | expr2 matrix2.2*Ab 464 | channel3 none 465 | name MergeExpression1 466 | xpos 344 467 | ypos 249 468 | } 469 | Output { 470 | name Output1 471 | xpos 344 472 | ypos 349 473 | } 474 | end_group 475 | Dot { 476 | name Dot16 477 | tile_color 0xcccccc00 478 | xpos -526 479 | ypos 914 480 | } 481 | push $N1556f230 482 | Dot { 483 | name Dot3 484 | tile_color 0x7aa9ff00 485 | label "Aim Vector" 486 | xpos 303 487 | ypos 358 488 | } 489 | set N13f4f5e0 [stack 0] 490 | push $N122b60e0 491 | Dot { 492 | name Dot2 493 | tile_color 0xcccccc00 494 | xpos 441 495 | ypos 262 496 | } 497 | set N1280eb70 [stack 0] 498 | push $N1cfd1db0 499 | Dot { 500 | name Dot6 501 | tile_color 0x7aa9ff00 502 | xpos 595 503 | ypos 173 504 | } 505 | Group { 506 | inputs 2 507 | name CrossProductVector3_1 508 | help "Calculates the cross product of 2 Vector3 inputs." 509 | xpos 561 510 | ypos 259 511 | addUserKnob {20 main_tab l "Cross Product Vector3"} 512 | addUserKnob {41 in l "Vector B Layer" t "Layer containing the vector information for input B" T vector_layer.in} 513 | addUserKnob {41 in_1 l "Vector A Layer" t "Layer containing the vector information for input A" T vector_layer1.in} 514 | addUserKnob {26 ""} 515 | addUserKnob {26 copyright l "" +STARTLINE T "v1.0 - Mathieu Goulet-Aubin & Erwan Leroy - Github"} 516 | } 517 | Input { 518 | inputs 0 519 | name vectorA 520 | xpos 457 521 | ypos -6 522 | number 1 523 | } 524 | Shuffle { 525 | name vector_layer1 526 | xpos 457 527 | ypos 103 528 | } 529 | Remove { 530 | operation keep 531 | channels rgba 532 | name Remove2 533 | xpos 457 534 | ypos 129 535 | } 536 | Dot { 537 | name Dot3 538 | tile_color 0x9e3c6300 539 | xpos 491 540 | ypos 210 541 | } 542 | Input { 543 | inputs 0 544 | name vectorB 545 | xpos 0 546 | } 547 | Dot { 548 | name Dot1 549 | tile_color 0xcccccc00 550 | xpos 34 551 | ypos 108 552 | } 553 | set N1300e9c0 [stack 0] 554 | Shuffle { 555 | name vector_layer 556 | xpos 140 557 | ypos 104 558 | } 559 | Remove { 560 | operation keep 561 | channels rgba 562 | name Remove1 563 | xpos 140 564 | ypos 130 565 | } 566 | MergeExpression { 567 | inputs 2 568 | expr0 "Ag*Bb - Ab*Bg" 569 | expr1 "Ab*Br - Ar*Bb" 570 | expr2 "Ar*Bg - Ag*Br" 571 | name MergeExpression2 572 | xpos 140 573 | ypos 206 574 | } 575 | Dot { 576 | name Dot2 577 | tile_color 0x4b5ec600 578 | xpos 174 579 | ypos 364 580 | } 581 | push $N1300e9c0 582 | ShuffleCopy { 583 | inputs 2 584 | in2 none 585 | red red 586 | green green 587 | blue blue 588 | out {{{parent.UV_Channel.in}}} 589 | name ShuffleCopy1 590 | xpos 0 591 | ypos 360 592 | } 593 | Output { 594 | name Output1 595 | xpos 0 596 | ypos 506 597 | } 598 | end_group 599 | Group { 600 | name NormalizeVector3_3 601 | help "Normalize the magnitude of a Vector3 (to be of magnitude 1)" 602 | xpos 561 603 | ypos 302 604 | addUserKnob {20 main_tab l "Normalize Vector3"} 605 | addUserKnob {41 in l "Vector B Layer" t "Layer containing the vector information for input B" T vector_layer.in} 606 | addUserKnob {26 ""} 607 | addUserKnob {26 copyright l "" +STARTLINE T "v1.0 - Mathieu Goulet-Aubin & Erwan Leroy - Github"} 608 | } 609 | Input { 610 | inputs 0 611 | name vectorB 612 | xpos 0 613 | } 614 | Dot { 615 | name Dot1 616 | tile_color 0xcccccc00 617 | xpos 34 618 | ypos 108 619 | } 620 | set N1cbbba10 [stack 0] 621 | Shuffle { 622 | name vector_layer 623 | xpos 140 624 | ypos 104 625 | } 626 | Remove { 627 | operation keep 628 | channels rgba 629 | name Remove1 630 | xpos 140 631 | ypos 130 632 | } 633 | Dot { 634 | name Dot3 635 | tile_color 0x9e3c6300 636 | xpos 174 637 | ypos 156 638 | } 639 | set N1c785c30 [stack 0] 640 | push $N1c785c30 641 | Dot { 642 | name Dot4 643 | tile_color 0x9e3c6300 644 | xpos 377 645 | ypos 156 646 | } 647 | Expression { 648 | channel0 rgba 649 | expr0 sqrt((r*r)+(g*g)+(b*b)) 650 | channel2 {-rgba.red -rgba.green -rgba.blue none} 651 | channel3 {none none none -rgba.alpha} 652 | name Mag3 653 | xpos 343 654 | ypos 209 655 | } 656 | Dot { 657 | name Dot5 658 | tile_color 0xcccccc00 659 | xpos 377 660 | ypos 271 661 | } 662 | Merge2 { 663 | inputs 2 664 | operation divide 665 | bbox B 666 | name Merge1 667 | xpos 140 668 | ypos 267 669 | } 670 | Dot { 671 | name Dot2 672 | tile_color 0x4b5ec600 673 | xpos 174 674 | ypos 364 675 | } 676 | push $N1cbbba10 677 | ShuffleCopy { 678 | inputs 2 679 | in2 none 680 | red red 681 | green green 682 | blue blue 683 | out {{{parent.UV_Channel.in}}} 684 | name ShuffleCopy1 685 | xpos 0 686 | ypos 360 687 | } 688 | Output { 689 | name Output1 690 | xpos 0 691 | ypos 506 692 | } 693 | end_group 694 | Dot { 695 | name Dot7 696 | tile_color 0xcccccc00 697 | label "Modified Pole Vector" 698 | xpos 595 699 | ypos 355 700 | } 701 | set N15c8e370 [stack 0] 702 | push $N1280eb70 703 | Group { 704 | name NormalizeVector3_2 705 | help "Normalize the magnitude of a Vector3 (to be of magnitude 1)" 706 | xpos 408 707 | ypos 302 708 | addUserKnob {20 main_tab l "Normalize Vector3"} 709 | addUserKnob {41 in l "Vector B Layer" t "Layer containing the vector information for input B" T vector_layer.in} 710 | addUserKnob {26 ""} 711 | addUserKnob {26 copyright l "" +STARTLINE T "v1.0 - Mathieu Goulet-Aubin & Erwan Leroy - Github"} 712 | } 713 | Input { 714 | inputs 0 715 | name vectorB 716 | xpos 0 717 | } 718 | Dot { 719 | name Dot1 720 | tile_color 0xcccccc00 721 | xpos 34 722 | ypos 108 723 | } 724 | set N1b5f6750 [stack 0] 725 | Shuffle { 726 | name vector_layer 727 | xpos 140 728 | ypos 104 729 | } 730 | Remove { 731 | operation keep 732 | channels rgba 733 | name Remove1 734 | xpos 140 735 | ypos 130 736 | } 737 | Dot { 738 | name Dot3 739 | tile_color 0x9e3c6300 740 | xpos 174 741 | ypos 156 742 | } 743 | set N1dfc20b0 [stack 0] 744 | push $N1dfc20b0 745 | Dot { 746 | name Dot4 747 | tile_color 0x9e3c6300 748 | xpos 377 749 | ypos 156 750 | } 751 | Expression { 752 | channel0 rgba 753 | expr0 sqrt((r*r)+(g*g)+(b*b)) 754 | channel2 {-rgba.red -rgba.green -rgba.blue none} 755 | channel3 {none none none -rgba.alpha} 756 | name Mag3 757 | xpos 343 758 | ypos 209 759 | } 760 | Dot { 761 | name Dot5 762 | tile_color 0xcccccc00 763 | xpos 377 764 | ypos 271 765 | } 766 | Merge2 { 767 | inputs 2 768 | operation divide 769 | bbox B 770 | name Merge1 771 | xpos 140 772 | ypos 267 773 | } 774 | Dot { 775 | name Dot2 776 | tile_color 0x4b5ec600 777 | xpos 174 778 | ypos 364 779 | } 780 | push $N1b5f6750 781 | ShuffleCopy { 782 | inputs 2 783 | in2 none 784 | red red 785 | green green 786 | blue blue 787 | out {{{parent.UV_Channel.in}}} 788 | name ShuffleCopy1 789 | xpos 0 790 | ypos 360 791 | } 792 | Output { 793 | name Output1 794 | xpos 0 795 | ypos 506 796 | } 797 | end_group 798 | Dot { 799 | name Dot4 800 | tile_color 0xcccccc00 801 | label "Unconstrained Vector" 802 | xpos 441 803 | ypos 354 804 | } 805 | set N12ce8110 [stack 0] 806 | Switch { 807 | inputs 3 808 | which {{parent.lookat}} 809 | name Z 810 | xpos 561 811 | ypos 438 812 | } 813 | Dot { 814 | name Dot9 815 | tile_color 0xcccccc00 816 | xpos 595 817 | ypos 728 818 | } 819 | push $N12ce8110 820 | push $N13f4f5e0 821 | push $N15c8e370 822 | Switch { 823 | inputs 3 824 | which {{parent.lookat}} 825 | name Y 826 | xpos 407 827 | ypos 433 828 | } 829 | Dot { 830 | name Dot10 831 | tile_color 0xcccccc00 832 | xpos 441 833 | ypos 666 834 | } 835 | push $N15c8e370 836 | push $N12ce8110 837 | push $N13f4f5e0 838 | Switch { 839 | inputs 3 840 | which {{parent.lookat}} 841 | name X 842 | xpos 269 843 | ypos 432 844 | } 845 | Dot { 846 | name Dot11 847 | tile_color 0xcccccc00 848 | xpos 303 849 | ypos 604 850 | } 851 | push $N2c4e4bb0 852 | Copy { 853 | inputs 2 854 | from0 rgba.red 855 | to0 matrix0.0 856 | from1 rgba.green 857 | to1 matrix1.0 858 | from2 rgba.blue 859 | to2 matrix2.0 860 | bbox B 861 | name Copy1 862 | xpos 59 863 | ypos 582 864 | } 865 | Copy { 866 | inputs 2 867 | from0 rgba.red 868 | to0 matrix0.1 869 | from1 rgba.green 870 | to1 matrix1.1 871 | from2 rgba.blue 872 | to2 matrix2.1 873 | bbox B 874 | name Copy2 875 | xpos 59 876 | ypos 644 877 | } 878 | Copy { 879 | inputs 2 880 | from0 rgba.red 881 | to0 matrix0.2 882 | from1 rgba.green 883 | to1 matrix1.2 884 | from2 rgba.blue 885 | to2 matrix2.2 886 | bbox B 887 | name Copy3 888 | xpos 59 889 | ypos 706 890 | } 891 | Dot { 892 | name Dot17 893 | tile_color 0x9e3c6300 894 | xpos 93 895 | ypos 914 896 | } 897 | push $N260f03c0 898 | Dot { 899 | name Dot15 900 | tile_color 0xcccccc00 901 | xpos -301 902 | ypos 606 903 | } 904 | push $N13be2b70 905 | Copy { 906 | inputs 2 907 | from0 rgba.red 908 | to0 matrix0.3 909 | from1 rgba.green 910 | to1 matrix1.3 911 | from2 rgba.blue 912 | to2 matrix2.3 913 | bbox B 914 | name Copy4 915 | xpos -236 916 | ypos 584 917 | } 918 | Switch { 919 | inputs 3 920 | which {{parent.vector_representation}} 921 | name Switch1 922 | xpos -236 923 | ypos 911 924 | } 925 | Output { 926 | name Output1 927 | xpos -236 928 | ypos 1009 929 | } 930 | end_group 931 | -------------------------------------------------------------------------------- /nuke/Generate/GenerateMatrix4.nk: -------------------------------------------------------------------------------- 1 | Group { 2 | name GenerateMatrix4_ 3 | help "Generate a Matrix4 based on a Matrix Knob. (Defaults to an identity matrix)" 4 | knobChanged "node = nuke.thisNode()\nknob = nuke.thisKnob()\n\nif knob.name() == \"inputChange\":\n with node:\n format_knob = nuke.toNode('Constant1')\['format']\n if node.input(0):\n format_knob.setEnabled(False)\n else:\n format_knob.setEnabled(True)\n" 5 | addUserKnob {20 Matrix4} 6 | addUserKnob {41 format T Constant1.format} 7 | addUserKnob {26 ""} 8 | addUserKnob {41 matrix T MatrixKnob.matrix} 9 | 10 | addUserKnob {26 divider_copyright l "" +STARTLINE} 11 | addUserKnob {26 copyright l "" +STARTLINE T "v1.0 - Mathieu Goulet-Aubin & Erwan Leroy - Github"} 12 | } 13 | BackdropNode { 14 | inputs 0 15 | name BackdropNode1 16 | tile_color 0x545454ff 17 | label "- Identity in\n matrix layers\n- Bypass other channels" 18 | note_font_size 20 19 | xpos 411 20 | ypos 441 21 | bdwidth 280 22 | bdheight 262 23 | } 24 | BackdropNode { 25 | inputs 0 26 | name BackdropNode2 27 | tile_color 0x545454ff 28 | label "Use input format" 29 | note_font_size 20 30 | xpos 408 31 | ypos -57 32 | bdwidth 281 33 | bdheight 195 34 | } 35 | BackdropNode { 36 | inputs 0 37 | name BackdropNode3 38 | tile_color 0x545454ff 39 | label "Custom format" 40 | note_font_size 20 41 | xpos 793 42 | ypos -58 43 | bdwidth 281 44 | bdheight 195 45 | } 46 | BackdropNode { 47 | inputs 0 48 | name BackdropNode4 49 | tile_color 0x464646ff 50 | label "Used for\nmatrix knob" 51 | note_font_size 20 52 | xpos 6 53 | ypos -57 54 | bdwidth 284 55 | bdheight 231 56 | } 57 | Axis2 { 58 | inputs 0 59 | useMatrix true 60 | name MatrixKnob 61 | xpos 111 62 | ypos 49 63 | } 64 | Constant { 65 | inputs 0 66 | channels rgb 67 | name Constant1 68 | xpos 889 69 | ypos 13 70 | } 71 | Dot { 72 | name Dot1 73 | xpos 923 74 | ypos 224 75 | } 76 | Input { 77 | inputs 0 78 | name Input 79 | xpos 509 80 | ypos 4 81 | } 82 | Switch { 83 | inputs 2 84 | which {{"!\[exists parent.input0]"}} 85 | name format 86 | xpos 509 87 | ypos 220 88 | } 89 | add_layer {matrix0 matrix0.0 matrix0.1 matrix0.2 matrix0.3} 90 | add_layer {matrix1 matrix1.0 matrix1.1 matrix1.2 matrix1.3} 91 | add_layer {matrix2 matrix2.0 matrix2.1 matrix2.2 matrix2.3} 92 | add_layer {matrix3 matrix3.0 matrix3.1 matrix3.2 matrix3.3} 93 | AddChannels { 94 | channels matrix0 95 | channels2 matrix1 96 | channels3 matrix2 97 | channels4 matrix3 98 | name AddChannels1 99 | xpos 509 100 | ypos 303 101 | } 102 | Expression { 103 | channel0 {matrix0.0 -matrix0.1 -matrix0.2 -matrix0.3} 104 | expr0 MatrixKnob.world_matrix.0 105 | channel1 {-matrix0.0 matrix0.1 -matrix0.2 -matrix0.3} 106 | expr1 MatrixKnob.world_matrix.1 107 | channel2 {-matrix0.0 -matrix0.1 matrix0.2 -matrix0.3} 108 | expr2 MatrixKnob.world_matrix.2 109 | channel3 {-matrix0.0 -matrix0.1 -matrix0.2 matrix0.3} 110 | expr3 MatrixKnob.world_matrix.3 111 | name Expression1 112 | xpos 509 113 | ypos 568 114 | } 115 | Expression { 116 | channel0 {matrix1.0 -matrix1.1 -matrix1.2 -matrix1.3} 117 | expr0 MatrixKnob.world_matrix.4 118 | channel1 {-matrix1.0 matrix1.1 -matrix1.2 -matrix1.3} 119 | expr1 MatrixKnob.world_matrix.5 120 | channel2 {-matrix1.0 -matrix1.1 matrix1.2 -matrix1.3} 121 | expr2 MatrixKnob.world_matrix.6 122 | channel3 {-matrix1.0 -matrix1.1 -matrix1.2 matrix1.3} 123 | expr3 MatrixKnob.world_matrix.7 124 | name Expression2 125 | xpos 509 126 | ypos 594 127 | } 128 | Expression { 129 | channel0 {matrix2.0 -matrix2.1 -matrix2.2 -matrix2.3} 130 | expr0 MatrixKnob.world_matrix.8 131 | channel1 {-matrix2.0 matrix2.1 -matrix2.2 -matrix2.3} 132 | expr1 MatrixKnob.world_matrix.9 133 | channel2 {-matrix2.0 -matrix2.1 matrix2.2 -matrix2.3} 134 | expr2 MatrixKnob.world_matrix.10 135 | channel3 {-matrix2.0 -matrix2.1 -matrix2.2 matrix2.3} 136 | expr3 MatrixKnob.world_matrix.11 137 | name Expression3 138 | xpos 509 139 | ypos 620 140 | } 141 | Expression { 142 | channel0 {matrix3.0 -matrix3.1 -matrix3.2 -matrix3.3} 143 | expr0 MatrixKnob.world_matrix.12 144 | channel1 {-matrix3.0 matrix3.1 -matrix3.2 -matrix3.3} 145 | expr1 MatrixKnob.world_matrix.13 146 | channel2 {-matrix3.0 -matrix3.1 matrix3.2 -matrix3.3} 147 | expr2 MatrixKnob.world_matrix.14 148 | channel3 {-matrix3.0 -matrix3.1 -matrix3.2 matrix3.3} 149 | expr3 MatrixKnob.world_matrix.15 150 | name Expression4 151 | xpos 509 152 | ypos 646 153 | } 154 | Output { 155 | name Output1 156 | xpos 509 157 | ypos 756 158 | } 159 | end_group 160 | -------------------------------------------------------------------------------- /nuke/Generate/GenerateSTMap.nk: -------------------------------------------------------------------------------- 1 | Group { 2 | inputs 0 3 | name GenerateSTMap 4 | postage_stamp true 5 | addUserKnob {20 STMap l "ST Map"} 6 | addUserKnob {41 format l Format T Reformat1.format} 7 | addUserKnob {26 ""} 8 | addUserKnob {7 overscan l "Overscan (%)" t "Add overscan to your ST map" R 0 100} 9 | overscan 10 10 | addUserKnob {6 reformat l "Reformat to Overscan" t "Reformats the image to overscan size" +STARTLINE} 11 | addUserKnob {26 ""} 12 | addUserKnob {26 copyright l "" +STARTLINE T "v1.0 - Mathieu Goulet-Aubin & Erwan Leroy - Github"} 13 | } 14 | Reformat { 15 | inputs 0 16 | name Reformat1 17 | xpos 555 18 | ypos 395 19 | } 20 | Crop { 21 | box {{-width*(parent.overscan/100)/2} {-height*(parent.overscan/100)/2} {width+(width*(parent.overscan/100)/2)} {height+(height*(parent.overscan/100)/2)}} 22 | reformat {{parent.reformat}} 23 | crop false 24 | name Crop1 25 | xpos 555 26 | ypos 446 27 | } 28 | Expression { 29 | expr0 (x+0.5)/width 30 | expr1 (y+.5)/height 31 | name Expression1 32 | xpos 555 33 | ypos 497 34 | } 35 | Output { 36 | name Output1 37 | xpos 555 38 | ypos 583 39 | } 40 | end_group 41 | -------------------------------------------------------------------------------- /nuke/Gizmos/IIDistort.gizmo: -------------------------------------------------------------------------------- 1 | version 11.3 v4 2 | Gizmo { 3 | inputs 2 4 | name IIDistort 5 | help "Recursuve IDistort Node, the vectors advect themselves multiple times, creating more different patterns than a regular IDistort node." 6 | addUserKnob {20 iidistort_tab l IIDistort} 7 | addUserKnob {7 scale l Scale t "Amount of vector advection" R 0 10} 8 | scale 1 9 | addUserKnob {3 samples l "Number of Samples" t "Add samples for a smoother curve, reduce for faster results."} 10 | samples 10 11 | addUserKnob {26 ""} 12 | addUserKnob {4 output l Output t "Choose the desired output.\n\nDistorted image: Image from img input distorted by vectors.\nModified Vectors: Vectors modified so that feeding these in a regular IDistort would produce the same result as this node's distorted image.\nSTMap: An STMap whch would match this node's distortion." M {"Distorted image" "Modified Vectors" STMap}} 13 | addUserKnob {26 ""} 14 | addUserKnob {26 copyright l "" +STARTLINE T "v1.1 - Erwan Leroy - Github"} 15 | } 16 | Input { 17 | inputs 0 18 | name vectors 19 | xpos 223 20 | ypos -56 21 | number 1 22 | } 23 | BlinkScript { 24 | ProgramGroup 1 25 | KernelDescription "2 \"FlowKernel\" iterate pixelWise 831e6c85b5efa3aa8b859b0c422c683ec13d73f561e57321e66c972e8e807f77 2 \"vectors\" Read Random \"dst\" Write Point 2 \"samples\" Int 1 AAAAAA== \"strength\" Float 1 AAAAAA== 2 \"samples\" 1 1 \"strength\" 1 1 0" 26 | kernelSource "kernel FlowKernel : ImageComputationKernel\n\{\n Image vectors; // the input image\n Image dst; // the output image\n\n param:\n int samples;\n float strength;\n\n void process(int2 pos) \{\n float2 fpos = float2(pos.x, pos.y);\n float4 disp;\n\n for (int i=0; iGithub"} 44 | } 45 | Input { 46 | inputs 0 47 | name Input 48 | xpos -303 49 | ypos 114 50 | } 51 | set Ne07e7c00 [stack 0] 52 | Shuffle { 53 | name UV_Channel 54 | xpos -163 55 | ypos 114 56 | } 57 | Expression { 58 | expr0 (r+x+0.5)/width 59 | expr1 (g+y+0.5)/height 60 | channel2 {-rgba.red -rgba.green -rgba.blue none} 61 | channel3 {none none none -rgba.alpha} 62 | name Vectors_to_UV 63 | xpos -163 64 | ypos 228 65 | } 66 | push $Ne07e7c00 67 | ShuffleCopy { 68 | inputs 2 69 | in2 none 70 | red red 71 | green green 72 | alpha black 73 | out {{{parent.UV_Channel.in}}} 74 | name ShuffleCopy1 75 | xpos -303 76 | ypos 228 77 | } 78 | Output { 79 | name Output1 80 | xpos -303 81 | ypos 299 82 | } 83 | end_group 84 | set Nf9650480 [stack 0] 85 | push $Ne07e6000 86 | Dot { 87 | name Dot1 88 | xpos 257 89 | ypos 171 90 | } 91 | push $Nf9650480 92 | Input { 93 | inputs 0 94 | name img 95 | xpos 515 96 | ypos -53 97 | } 98 | STMap { 99 | inputs 2 100 | uv rgb 101 | name STMap1 102 | xpos 515 103 | ypos 59 104 | } 105 | Switch { 106 | inputs 3 107 | which {{parent.output}} 108 | name Switch1 109 | xpos 515 110 | ypos 167 111 | } 112 | Output { 113 | name Output1 114 | xpos 515 115 | ypos 249 116 | } 117 | end_group 118 | -------------------------------------------------------------------------------- /nuke/Math/Axis/InvertAxis.nk: -------------------------------------------------------------------------------- 1 | Group { 2 | name InvertAxis 3 | help "Inverts an input Axis" 4 | tile_color 0x9c0000ff 5 | addUserKnob {20 InvertAxis l "Invert Axis"} 6 | addUserKnob {41 world_matrix l "" -STARTLINE T Out_Axis.world_matrix} 7 | addUserKnob {26 divider_copyright l "" +STARTLINE} 8 | addUserKnob {26 copyright l "" +STARTLINE T "v1.1 - Mathieu Goulet-Aubin & Erwan Leroy - Github"} 9 | } 10 | Axis2 { 11 | inputs 0 12 | useMatrix true 13 | matrix { 14 | {{Mid_Axis.matrix/Mid_Axis.matrix.15} {Mid_Axis.matrix/Mid_Axis.matrix.15} {Mid_Axis.matrix/Mid_Axis.matrix.15} {Mid_Axis.matrix/Mid_Axis.matrix.15}} 15 | {{Mid_Axis.matrix/Mid_Axis.matrix.15} {Mid_Axis.matrix/Mid_Axis.matrix.15} {Mid_Axis.matrix/Mid_Axis.matrix.15} {Mid_Axis.matrix/Mid_Axis.matrix.15}} 16 | {{Mid_Axis.matrix/Mid_Axis.matrix.15} {Mid_Axis.matrix/Mid_Axis.matrix.15} {Mid_Axis.matrix/Mid_Axis.matrix.15} {Mid_Axis.matrix/Mid_Axis.matrix.15}} 17 | {{Mid_Axis.matrix/Mid_Axis.matrix.15} {Mid_Axis.matrix/Mid_Axis.matrix.15} {Mid_Axis.matrix/Mid_Axis.matrix.15} 1} 18 | } 19 | name Out_Axis 20 | xpos 816 21 | ypos 668 22 | } 23 | Output { 24 | name Output1 25 | xpos 806 26 | ypos 780 27 | } 28 | Input { 29 | inputs 0 30 | name Inputaxis 31 | xpos 806 32 | ypos 434 33 | } 34 | Axis2 { 35 | name In_Axis 36 | xpos 816 37 | ypos 499 38 | } 39 | Axis2 { 40 | inputs 0 41 | useMatrix true 42 | matrix { 43 | {{In_Axis.world_matrix.5*In_Axis.world_matrix.10*In_Axis.world_matrix.15+In_Axis.world_matrix.6*In_Axis.world_matrix.11*In_Axis.world_matrix.13+In_Axis.world_matrix.7*In_Axis.world_matrix.9*In_Axis.world_matrix.14-In_Axis.world_matrix.5*In_Axis.world_matrix.11*In_Axis.world_matrix.14-In_Axis.world_matrix.6*In_Axis.world_matrix.9*In_Axis.world_matrix.15-In_Axis.world_matrix.7*In_Axis.world_matrix.10*In_Axis.world_matrix.13} {In_Axis.world_matrix.1*In_Axis.world_matrix.11*In_Axis.world_matrix.14+In_Axis.world_matrix.2*In_Axis.world_matrix.9*In_Axis.world_matrix.15+In_Axis.world_matrix.3*In_Axis.world_matrix.10*In_Axis.world_matrix.13-In_Axis.world_matrix.1*In_Axis.world_matrix.10*In_Axis.world_matrix.15-In_Axis.world_matrix.2*In_Axis.world_matrix.11*In_Axis.world_matrix.13-In_Axis.world_matrix.3*In_Axis.world_matrix.9*In_Axis.world_matrix.14} {In_Axis.world_matrix.1*In_Axis.world_matrix.6*In_Axis.world_matrix.15+In_Axis.world_matrix.2*In_Axis.world_matrix.7*In_Axis.world_matrix.13+In_Axis.world_matrix.3*In_Axis.world_matrix.5*In_Axis.world_matrix.14-In_Axis.world_matrix.1*In_Axis.world_matrix.7*In_Axis.world_matrix.14-In_Axis.world_matrix.2*In_Axis.world_matrix.5*In_Axis.world_matrix.15-In_Axis.world_matrix.3*In_Axis.world_matrix.6*In_Axis.world_matrix.13} {In_Axis.world_matrix.1*In_Axis.world_matrix.7*In_Axis.world_matrix.10+In_Axis.world_matrix.2*In_Axis.world_matrix.5*In_Axis.world_matrix.11+In_Axis.world_matrix.3*In_Axis.world_matrix.6*In_Axis.world_matrix.9-In_Axis.world_matrix.1*In_Axis.world_matrix.6*In_Axis.world_matrix.11-In_Axis.world_matrix.2*In_Axis.world_matrix.7*In_Axis.world_matrix.9-In_Axis.world_matrix.3*In_Axis.world_matrix.5*In_Axis.world_matrix.10}} 44 | {{In_Axis.world_matrix.4*In_Axis.world_matrix.11*In_Axis.world_matrix.14+In_Axis.world_matrix.6*In_Axis.world_matrix.8*In_Axis.world_matrix.15+In_Axis.world_matrix.7*In_Axis.world_matrix.10*In_Axis.world_matrix.12-In_Axis.world_matrix.4*In_Axis.world_matrix.10*In_Axis.world_matrix.15-In_Axis.world_matrix.6*In_Axis.world_matrix.11*In_Axis.world_matrix.12-In_Axis.world_matrix.7*In_Axis.world_matrix.8*In_Axis.world_matrix.14} {In_Axis.world_matrix.0*In_Axis.world_matrix.10*In_Axis.world_matrix.15+In_Axis.world_matrix.2*In_Axis.world_matrix.11*In_Axis.world_matrix.12+In_Axis.world_matrix.3*In_Axis.world_matrix.8*In_Axis.world_matrix.14-In_Axis.world_matrix.0*In_Axis.world_matrix.11*In_Axis.world_matrix.14-In_Axis.world_matrix.2*In_Axis.world_matrix.8*In_Axis.world_matrix.15-In_Axis.world_matrix.3*In_Axis.world_matrix.10*In_Axis.world_matrix.12} {In_Axis.world_matrix.0*In_Axis.world_matrix.7*In_Axis.world_matrix.14+In_Axis.world_matrix.2*In_Axis.world_matrix.4*In_Axis.world_matrix.15+In_Axis.world_matrix.3*In_Axis.world_matrix.6*In_Axis.world_matrix.12-In_Axis.world_matrix.0*In_Axis.world_matrix.6*In_Axis.world_matrix.15-In_Axis.world_matrix.2*In_Axis.world_matrix.7*In_Axis.world_matrix.12-In_Axis.world_matrix.3*In_Axis.world_matrix.4*In_Axis.world_matrix.14} {In_Axis.world_matrix.0*In_Axis.world_matrix.6*In_Axis.world_matrix.11+In_Axis.world_matrix.2*In_Axis.world_matrix.7*In_Axis.world_matrix.8+In_Axis.world_matrix.3*In_Axis.world_matrix.4*In_Axis.world_matrix.10-In_Axis.world_matrix.0*In_Axis.world_matrix.7*In_Axis.world_matrix.10-In_Axis.world_matrix.2*In_Axis.world_matrix.4*In_Axis.world_matrix.11-In_Axis.world_matrix.3*In_Axis.world_matrix.6*In_Axis.world_matrix.8}} 45 | {{In_Axis.world_matrix.4*In_Axis.world_matrix.9*In_Axis.world_matrix.15+In_Axis.world_matrix.5*In_Axis.world_matrix.11*In_Axis.world_matrix.12+In_Axis.world_matrix.7*In_Axis.world_matrix.8*In_Axis.world_matrix.13-In_Axis.world_matrix.4*In_Axis.world_matrix.11*In_Axis.world_matrix.13-In_Axis.world_matrix.5*In_Axis.world_matrix.8*In_Axis.world_matrix.15-In_Axis.world_matrix.7*In_Axis.world_matrix.9*In_Axis.world_matrix.12} {In_Axis.world_matrix.0*In_Axis.world_matrix.11*In_Axis.world_matrix.13+In_Axis.world_matrix.1*In_Axis.world_matrix.8*In_Axis.world_matrix.15+In_Axis.world_matrix.3*In_Axis.world_matrix.9*In_Axis.world_matrix.12-In_Axis.world_matrix.0*In_Axis.world_matrix.9*In_Axis.world_matrix.15-In_Axis.world_matrix.1*In_Axis.world_matrix.11*In_Axis.world_matrix.12-In_Axis.world_matrix.3*In_Axis.world_matrix.8*In_Axis.world_matrix.13} {In_Axis.world_matrix.0*In_Axis.world_matrix.5*In_Axis.world_matrix.15+In_Axis.world_matrix.1*In_Axis.world_matrix.7*In_Axis.world_matrix.12+In_Axis.world_matrix.3*In_Axis.world_matrix.4*In_Axis.world_matrix.13-In_Axis.world_matrix.0*In_Axis.world_matrix.7*In_Axis.world_matrix.13-In_Axis.world_matrix.1*In_Axis.world_matrix.4*In_Axis.world_matrix.15-In_Axis.world_matrix.3*In_Axis.world_matrix.5*In_Axis.world_matrix.12} {In_Axis.world_matrix.0*In_Axis.world_matrix.7*In_Axis.world_matrix.9+In_Axis.world_matrix.1*In_Axis.world_matrix.4*In_Axis.world_matrix.11+In_Axis.world_matrix.3*In_Axis.world_matrix.5*In_Axis.world_matrix.8-In_Axis.world_matrix.0*In_Axis.world_matrix.5*In_Axis.world_matrix.11-In_Axis.world_matrix.1*In_Axis.world_matrix.7*In_Axis.world_matrix.8-In_Axis.world_matrix.3*In_Axis.world_matrix.4*In_Axis.world_matrix.9}} 46 | {{In_Axis.world_matrix.4*In_Axis.world_matrix.10*In_Axis.world_matrix.13+In_Axis.world_matrix.5*In_Axis.world_matrix.8*In_Axis.world_matrix.14+In_Axis.world_matrix.6*In_Axis.world_matrix.9*In_Axis.world_matrix.12-In_Axis.world_matrix.4*In_Axis.world_matrix.9*In_Axis.world_matrix.14-In_Axis.world_matrix.5*In_Axis.world_matrix.10*In_Axis.world_matrix.12-In_Axis.world_matrix.6*In_Axis.world_matrix.8*In_Axis.world_matrix.13} {In_Axis.world_matrix.0*In_Axis.world_matrix.9*In_Axis.world_matrix.14+In_Axis.world_matrix.1*In_Axis.world_matrix.10*In_Axis.world_matrix.12+In_Axis.world_matrix.2*In_Axis.world_matrix.8*In_Axis.world_matrix.13-In_Axis.world_matrix.0*In_Axis.world_matrix.10*In_Axis.world_matrix.13-In_Axis.world_matrix.1*In_Axis.world_matrix.8*In_Axis.world_matrix.14-In_Axis.world_matrix.2*In_Axis.world_matrix.9*In_Axis.world_matrix.12} {In_Axis.world_matrix.0*In_Axis.world_matrix.6*In_Axis.world_matrix.13+In_Axis.world_matrix.1*In_Axis.world_matrix.4*In_Axis.world_matrix.14+In_Axis.world_matrix.2*In_Axis.world_matrix.5*In_Axis.world_matrix.12-In_Axis.world_matrix.0*In_Axis.world_matrix.5*In_Axis.world_matrix.14-In_Axis.world_matrix.1*In_Axis.world_matrix.6*In_Axis.world_matrix.12-In_Axis.world_matrix.2*In_Axis.world_matrix.4*In_Axis.world_matrix.13} {In_Axis.world_matrix.0*In_Axis.world_matrix.5*In_Axis.world_matrix.10+In_Axis.world_matrix.1*In_Axis.world_matrix.6*In_Axis.world_matrix.8+In_Axis.world_matrix.2*In_Axis.world_matrix.4*In_Axis.world_matrix.9-In_Axis.world_matrix.0*In_Axis.world_matrix.6*In_Axis.world_matrix.9-In_Axis.world_matrix.1*In_Axis.world_matrix.4*In_Axis.world_matrix.10-In_Axis.world_matrix.2*In_Axis.world_matrix.5*In_Axis.world_matrix.8}} 47 | } 48 | name Mid_Axis 49 | xpos 700 50 | ypos 601 51 | } 52 | end_group 53 | -------------------------------------------------------------------------------- /nuke/Math/Axis/TransformAxis.nk: -------------------------------------------------------------------------------- 1 | Group { 2 | name TransformAxis 3 | help "Transforms AxisB by AxisA (similar to adding axis A above axis B)" 4 | tile_color 0x9c0000ff 5 | addUserKnob {20 TransformAxis l "Transform Axis"} 6 | addUserKnob {26 tip l "" +STARTLINE T "Results are similar to connecting Axis A to Axis B's axis input"} 7 | addUserKnob {26 divider_matrix l "" +STARTLINE} 8 | addUserKnob {41 world_matrix l "" -STARTLINE T Out_Axis.world_matrix} 9 | addUserKnob {26 divider_copyright l "" +STARTLINE} 10 | addUserKnob {26 copyright l "" +STARTLINE T "v1.0 - Mathieu Goulet-Aubin & Erwan Leroy - Github"} 11 | } 12 | Input { 13 | inputs 0 14 | name InputaxisB 15 | xpos 806 16 | ypos 436 17 | } 18 | Axis2 { 19 | name In_Axis 20 | xpos 816 21 | ypos 498 22 | } 23 | Input { 24 | inputs 0 25 | name InputaxisA 26 | xpos 954 27 | ypos 433 28 | number 1 29 | } 30 | Axis2 { 31 | useMatrix true 32 | matrix { 33 | {{parent.In_Axis.world_matrix} {parent.In_Axis.world_matrix} {parent.In_Axis.world_matrix} {parent.In_Axis.world_matrix}} 34 | {{parent.In_Axis.world_matrix} {parent.In_Axis.world_matrix} {parent.In_Axis.world_matrix} {parent.In_Axis.world_matrix}} 35 | {{parent.In_Axis.world_matrix} {parent.In_Axis.world_matrix} {parent.In_Axis.world_matrix} {parent.In_Axis.world_matrix}} 36 | {{parent.In_Axis.world_matrix} {parent.In_Axis.world_matrix} {parent.In_Axis.world_matrix} {parent.In_Axis.world_matrix}} 37 | } 38 | name Out_Axis 39 | xpos 964 40 | ypos 655 41 | } 42 | Output { 43 | name Output1 44 | xpos 954 45 | ypos 778 46 | } 47 | end_group 48 | -------------------------------------------------------------------------------- /nuke/Math/Axis/ZeroAxis.nk: -------------------------------------------------------------------------------- 1 | Group { 2 | name ZeroAxis 3 | help "Inverts an input Axis at a specified frame" 4 | tile_color 0x9c0000ff 5 | addUserKnob {20 ZeroAxis l "Zero Axis"} 6 | addUserKnob {3 ref_frame l "Reference Frame" t "Select a new reference frame, and the curves will be zero'd out at that frame."} 7 | ref_frame 50 8 | addUserKnob {4 mode l Mode t "Pin mode results in a transformation that looks like it was parented to another, but with the reference frame at origin.\n\nZero-out will re-apply the same curve, relative to the origin. You generally want this for cameras.\n\nThere may be use cases for both modes, but generally try one, and if the result is not what you expected, switch to the other one." M {"Pin to original axis" Zero-out ""}} 9 | mode Zero-out 10 | addUserKnob {26 ""} 11 | addUserKnob {41 world_matrix l "" -STARTLINE T Hold_Axis.world_matrix} 12 | addUserKnob {26 divider_copyright l "" +STARTLINE} 13 | addUserKnob {26 copyright l "" +STARTLINE T "v1.1 - Mathieu Goulet-Aubin & Erwan Leroy - Github"} 14 | } 15 | Input { 16 | inputs 0 17 | name Inputaxis 18 | xpos 806 19 | ypos 434 20 | } 21 | Dot { 22 | name Dot2 23 | xpos 840 24 | ypos 519 25 | } 26 | set N8c91400 [stack 0] 27 | Group { 28 | name InvertAxis 29 | help "Inverts an input Axis" 30 | tile_color 0x9c0000ff 31 | xpos 944 32 | ypos 515 33 | addUserKnob {20 InvertAxis l "Invert Axis"} 34 | addUserKnob {41 world_matrix l "" -STARTLINE T Out_Axis.world_matrix} 35 | addUserKnob {26 divider_copyright l "" +STARTLINE} 36 | addUserKnob {26 copyright l "" +STARTLINE T "v1.1 - Mathieu Goulet-Aubin & Erwan Leroy - Github"} 37 | } 38 | Axis2 { 39 | inputs 0 40 | useMatrix true 41 | matrix { 42 | {{Mid_Axis.matrix/Mid_Axis.matrix.15} {Mid_Axis.matrix/Mid_Axis.matrix.15} {Mid_Axis.matrix/Mid_Axis.matrix.15} {Mid_Axis.matrix/Mid_Axis.matrix.15}} 43 | {{Mid_Axis.matrix/Mid_Axis.matrix.15} {Mid_Axis.matrix/Mid_Axis.matrix.15} {Mid_Axis.matrix/Mid_Axis.matrix.15} {Mid_Axis.matrix/Mid_Axis.matrix.15}} 44 | {{Mid_Axis.matrix/Mid_Axis.matrix.15} {Mid_Axis.matrix/Mid_Axis.matrix.15} {Mid_Axis.matrix/Mid_Axis.matrix.15} {Mid_Axis.matrix/Mid_Axis.matrix.15}} 45 | {{Mid_Axis.matrix/Mid_Axis.matrix.15} {Mid_Axis.matrix/Mid_Axis.matrix.15} {Mid_Axis.matrix/Mid_Axis.matrix.15} 1} 46 | } 47 | name Out_Axis 48 | xpos 816 49 | ypos 668 50 | } 51 | Output { 52 | name Output1 53 | xpos 806 54 | ypos 780 55 | } 56 | Input { 57 | inputs 0 58 | name Inputaxis 59 | xpos 806 60 | ypos 434 61 | } 62 | Axis2 { 63 | name In_Axis 64 | xpos 816 65 | ypos 499 66 | } 67 | Axis2 { 68 | inputs 0 69 | useMatrix true 70 | matrix { 71 | {{In_Axis.world_matrix.5*In_Axis.world_matrix.10*In_Axis.world_matrix.15+In_Axis.world_matrix.6*In_Axis.world_matrix.11*In_Axis.world_matrix.13+In_Axis.world_matrix.7*In_Axis.world_matrix.9*In_Axis.world_matrix.14-In_Axis.world_matrix.5*In_Axis.world_matrix.11*In_Axis.world_matrix.14-In_Axis.world_matrix.6*In_Axis.world_matrix.9*In_Axis.world_matrix.15-In_Axis.world_matrix.7*In_Axis.world_matrix.10*In_Axis.world_matrix.13} {In_Axis.world_matrix.1*In_Axis.world_matrix.11*In_Axis.world_matrix.14+In_Axis.world_matrix.2*In_Axis.world_matrix.9*In_Axis.world_matrix.15+In_Axis.world_matrix.3*In_Axis.world_matrix.10*In_Axis.world_matrix.13-In_Axis.world_matrix.1*In_Axis.world_matrix.10*In_Axis.world_matrix.15-In_Axis.world_matrix.2*In_Axis.world_matrix.11*In_Axis.world_matrix.13-In_Axis.world_matrix.3*In_Axis.world_matrix.9*In_Axis.world_matrix.14} {In_Axis.world_matrix.1*In_Axis.world_matrix.6*In_Axis.world_matrix.15+In_Axis.world_matrix.2*In_Axis.world_matrix.7*In_Axis.world_matrix.13+In_Axis.world_matrix.3*In_Axis.world_matrix.5*In_Axis.world_matrix.14-In_Axis.world_matrix.1*In_Axis.world_matrix.7*In_Axis.world_matrix.14-In_Axis.world_matrix.2*In_Axis.world_matrix.5*In_Axis.world_matrix.15-In_Axis.world_matrix.3*In_Axis.world_matrix.6*In_Axis.world_matrix.13} {In_Axis.world_matrix.1*In_Axis.world_matrix.7*In_Axis.world_matrix.10+In_Axis.world_matrix.2*In_Axis.world_matrix.5*In_Axis.world_matrix.11+In_Axis.world_matrix.3*In_Axis.world_matrix.6*In_Axis.world_matrix.9-In_Axis.world_matrix.1*In_Axis.world_matrix.6*In_Axis.world_matrix.11-In_Axis.world_matrix.2*In_Axis.world_matrix.7*In_Axis.world_matrix.9-In_Axis.world_matrix.3*In_Axis.world_matrix.5*In_Axis.world_matrix.10}} 72 | {{In_Axis.world_matrix.4*In_Axis.world_matrix.11*In_Axis.world_matrix.14+In_Axis.world_matrix.6*In_Axis.world_matrix.8*In_Axis.world_matrix.15+In_Axis.world_matrix.7*In_Axis.world_matrix.10*In_Axis.world_matrix.12-In_Axis.world_matrix.4*In_Axis.world_matrix.10*In_Axis.world_matrix.15-In_Axis.world_matrix.6*In_Axis.world_matrix.11*In_Axis.world_matrix.12-In_Axis.world_matrix.7*In_Axis.world_matrix.8*In_Axis.world_matrix.14} {In_Axis.world_matrix.0*In_Axis.world_matrix.10*In_Axis.world_matrix.15+In_Axis.world_matrix.2*In_Axis.world_matrix.11*In_Axis.world_matrix.12+In_Axis.world_matrix.3*In_Axis.world_matrix.8*In_Axis.world_matrix.14-In_Axis.world_matrix.0*In_Axis.world_matrix.11*In_Axis.world_matrix.14-In_Axis.world_matrix.2*In_Axis.world_matrix.8*In_Axis.world_matrix.15-In_Axis.world_matrix.3*In_Axis.world_matrix.10*In_Axis.world_matrix.12} {In_Axis.world_matrix.0*In_Axis.world_matrix.7*In_Axis.world_matrix.14+In_Axis.world_matrix.2*In_Axis.world_matrix.4*In_Axis.world_matrix.15+In_Axis.world_matrix.3*In_Axis.world_matrix.6*In_Axis.world_matrix.12-In_Axis.world_matrix.0*In_Axis.world_matrix.6*In_Axis.world_matrix.15-In_Axis.world_matrix.2*In_Axis.world_matrix.7*In_Axis.world_matrix.12-In_Axis.world_matrix.3*In_Axis.world_matrix.4*In_Axis.world_matrix.14} {In_Axis.world_matrix.0*In_Axis.world_matrix.6*In_Axis.world_matrix.11+In_Axis.world_matrix.2*In_Axis.world_matrix.7*In_Axis.world_matrix.8+In_Axis.world_matrix.3*In_Axis.world_matrix.4*In_Axis.world_matrix.10-In_Axis.world_matrix.0*In_Axis.world_matrix.7*In_Axis.world_matrix.10-In_Axis.world_matrix.2*In_Axis.world_matrix.4*In_Axis.world_matrix.11-In_Axis.world_matrix.3*In_Axis.world_matrix.6*In_Axis.world_matrix.8}} 73 | {{In_Axis.world_matrix.4*In_Axis.world_matrix.9*In_Axis.world_matrix.15+In_Axis.world_matrix.5*In_Axis.world_matrix.11*In_Axis.world_matrix.12+In_Axis.world_matrix.7*In_Axis.world_matrix.8*In_Axis.world_matrix.13-In_Axis.world_matrix.4*In_Axis.world_matrix.11*In_Axis.world_matrix.13-In_Axis.world_matrix.5*In_Axis.world_matrix.8*In_Axis.world_matrix.15-In_Axis.world_matrix.7*In_Axis.world_matrix.9*In_Axis.world_matrix.12} {In_Axis.world_matrix.0*In_Axis.world_matrix.11*In_Axis.world_matrix.13+In_Axis.world_matrix.1*In_Axis.world_matrix.8*In_Axis.world_matrix.15+In_Axis.world_matrix.3*In_Axis.world_matrix.9*In_Axis.world_matrix.12-In_Axis.world_matrix.0*In_Axis.world_matrix.9*In_Axis.world_matrix.15-In_Axis.world_matrix.1*In_Axis.world_matrix.11*In_Axis.world_matrix.12-In_Axis.world_matrix.3*In_Axis.world_matrix.8*In_Axis.world_matrix.13} {In_Axis.world_matrix.0*In_Axis.world_matrix.5*In_Axis.world_matrix.15+In_Axis.world_matrix.1*In_Axis.world_matrix.7*In_Axis.world_matrix.12+In_Axis.world_matrix.3*In_Axis.world_matrix.4*In_Axis.world_matrix.13-In_Axis.world_matrix.0*In_Axis.world_matrix.7*In_Axis.world_matrix.13-In_Axis.world_matrix.1*In_Axis.world_matrix.4*In_Axis.world_matrix.15-In_Axis.world_matrix.3*In_Axis.world_matrix.5*In_Axis.world_matrix.12} {In_Axis.world_matrix.0*In_Axis.world_matrix.7*In_Axis.world_matrix.9+In_Axis.world_matrix.1*In_Axis.world_matrix.4*In_Axis.world_matrix.11+In_Axis.world_matrix.3*In_Axis.world_matrix.5*In_Axis.world_matrix.8-In_Axis.world_matrix.0*In_Axis.world_matrix.5*In_Axis.world_matrix.11-In_Axis.world_matrix.1*In_Axis.world_matrix.7*In_Axis.world_matrix.8-In_Axis.world_matrix.3*In_Axis.world_matrix.4*In_Axis.world_matrix.9}} 74 | {{In_Axis.world_matrix.4*In_Axis.world_matrix.10*In_Axis.world_matrix.13+In_Axis.world_matrix.5*In_Axis.world_matrix.8*In_Axis.world_matrix.14+In_Axis.world_matrix.6*In_Axis.world_matrix.9*In_Axis.world_matrix.12-In_Axis.world_matrix.4*In_Axis.world_matrix.9*In_Axis.world_matrix.14-In_Axis.world_matrix.5*In_Axis.world_matrix.10*In_Axis.world_matrix.12-In_Axis.world_matrix.6*In_Axis.world_matrix.8*In_Axis.world_matrix.13} {In_Axis.world_matrix.0*In_Axis.world_matrix.9*In_Axis.world_matrix.14+In_Axis.world_matrix.1*In_Axis.world_matrix.10*In_Axis.world_matrix.12+In_Axis.world_matrix.2*In_Axis.world_matrix.8*In_Axis.world_matrix.13-In_Axis.world_matrix.0*In_Axis.world_matrix.10*In_Axis.world_matrix.13-In_Axis.world_matrix.1*In_Axis.world_matrix.8*In_Axis.world_matrix.14-In_Axis.world_matrix.2*In_Axis.world_matrix.9*In_Axis.world_matrix.12} {In_Axis.world_matrix.0*In_Axis.world_matrix.6*In_Axis.world_matrix.13+In_Axis.world_matrix.1*In_Axis.world_matrix.4*In_Axis.world_matrix.14+In_Axis.world_matrix.2*In_Axis.world_matrix.5*In_Axis.world_matrix.12-In_Axis.world_matrix.0*In_Axis.world_matrix.5*In_Axis.world_matrix.14-In_Axis.world_matrix.1*In_Axis.world_matrix.6*In_Axis.world_matrix.12-In_Axis.world_matrix.2*In_Axis.world_matrix.4*In_Axis.world_matrix.13} {In_Axis.world_matrix.0*In_Axis.world_matrix.5*In_Axis.world_matrix.10+In_Axis.world_matrix.1*In_Axis.world_matrix.6*In_Axis.world_matrix.8+In_Axis.world_matrix.2*In_Axis.world_matrix.4*In_Axis.world_matrix.9-In_Axis.world_matrix.0*In_Axis.world_matrix.6*In_Axis.world_matrix.9-In_Axis.world_matrix.1*In_Axis.world_matrix.4*In_Axis.world_matrix.10-In_Axis.world_matrix.2*In_Axis.world_matrix.5*In_Axis.world_matrix.8}} 75 | } 76 | name Mid_Axis 77 | xpos 700 78 | ypos 601 79 | } 80 | end_group 81 | Axis2 { 82 | inputs 0 83 | useMatrix true 84 | matrix { 85 | {{InvertAxis.world_matrix(parent.ref_frame)} {InvertAxis.world_matrix(parent.ref_frame)} {InvertAxis.world_matrix(parent.ref_frame)} {InvertAxis.world_matrix(parent.ref_frame)}} 86 | {{InvertAxis.world_matrix(parent.ref_frame)} {InvertAxis.world_matrix(parent.ref_frame)} {InvertAxis.world_matrix(parent.ref_frame)} {InvertAxis.world_matrix(parent.ref_frame)}} 87 | {{InvertAxis.world_matrix(parent.ref_frame)} {InvertAxis.world_matrix(parent.ref_frame)} {InvertAxis.world_matrix(parent.ref_frame)} {InvertAxis.world_matrix(parent.ref_frame)}} 88 | {{InvertAxis.world_matrix(parent.ref_frame)} {InvertAxis.world_matrix(parent.ref_frame)} {InvertAxis.world_matrix(parent.ref_frame)} 1} 89 | } 90 | name Hold_Axis 91 | xpos 954 92 | ypos 586 93 | } 94 | Dot { 95 | name Dot1 96 | xpos 978 97 | ypos 687 98 | } 99 | set N179e0800 [stack 0] 100 | push $N8c91400 101 | Group { 102 | inputs 2 103 | name TransformAxis 104 | help "Transforms AxisB by AxisA (similar to adding axis A above axis B)" 105 | tile_color 0x9c0000ff 106 | xpos 806 107 | ypos 721 108 | addUserKnob {20 InvertAxis l "Invert Axis"} 109 | addUserKnob {26 tip l "" +STARTLINE T "Results are similar to connecting Axis A to Axis B's axis input"} 110 | addUserKnob {26 divider_matrix l "" +STARTLINE} 111 | addUserKnob {41 world_matrix l "" -STARTLINE T Out_Axis.world_matrix} 112 | addUserKnob {26 divider_copyright l "" +STARTLINE} 113 | addUserKnob {26 copyright l "" +STARTLINE T "v1.0 - Mathieu Goulet-Aubin & Erwan Leroy - Github"} 114 | } 115 | Input { 116 | inputs 0 117 | name InputaxisB 118 | xpos 806 119 | ypos 436 120 | } 121 | Axis2 { 122 | name In_Axis 123 | xpos 816 124 | ypos 498 125 | } 126 | Input { 127 | inputs 0 128 | name InputaxisA 129 | xpos 954 130 | ypos 433 131 | number 1 132 | } 133 | Axis2 { 134 | useMatrix true 135 | matrix { 136 | {{parent.In_Axis.world_matrix} {parent.In_Axis.world_matrix} {parent.In_Axis.world_matrix} {parent.In_Axis.world_matrix}} 137 | {{parent.In_Axis.world_matrix} {parent.In_Axis.world_matrix} {parent.In_Axis.world_matrix} {parent.In_Axis.world_matrix}} 138 | {{parent.In_Axis.world_matrix} {parent.In_Axis.world_matrix} {parent.In_Axis.world_matrix} {parent.In_Axis.world_matrix}} 139 | {{parent.In_Axis.world_matrix} {parent.In_Axis.world_matrix} {parent.In_Axis.world_matrix} {parent.In_Axis.world_matrix}} 140 | } 141 | name Out_Axis 142 | xpos 964 143 | ypos 655 144 | } 145 | Output { 146 | name Output1 147 | xpos 954 148 | ypos 778 149 | } 150 | end_group 151 | push $N8c91400 152 | Dot { 153 | name Dot3 154 | xpos 703 155 | ypos 519 156 | } 157 | push $N179e0800 158 | Dot { 159 | name Dot4 160 | xpos 791 161 | ypos 687 162 | } 163 | Group { 164 | inputs 2 165 | name TransformAxis1 166 | help "Transforms AxisB by AxisA (similar to adding axis A above axis B)" 167 | tile_color 0x9c0000ff 168 | xpos 669 169 | ypos 721 170 | addUserKnob {20 InvertAxis l "Invert Axis"} 171 | addUserKnob {26 tip l "" +STARTLINE T "Results are similar to connecting Axis A to Axis B's axis input"} 172 | addUserKnob {26 divider_matrix l "" +STARTLINE} 173 | addUserKnob {41 world_matrix l "" -STARTLINE T Out_Axis.world_matrix} 174 | addUserKnob {26 divider_copyright l "" +STARTLINE} 175 | addUserKnob {26 copyright l "" +STARTLINE T "v1.0 - Mathieu Goulet-Aubin & Erwan Leroy - Github"} 176 | } 177 | Input { 178 | inputs 0 179 | name InputaxisB 180 | xpos 806 181 | ypos 436 182 | } 183 | Axis2 { 184 | name In_Axis 185 | xpos 816 186 | ypos 498 187 | } 188 | Input { 189 | inputs 0 190 | name InputaxisA 191 | xpos 954 192 | ypos 433 193 | number 1 194 | } 195 | Axis2 { 196 | useMatrix true 197 | matrix { 198 | {{parent.In_Axis.world_matrix} {parent.In_Axis.world_matrix} {parent.In_Axis.world_matrix} {parent.In_Axis.world_matrix}} 199 | {{parent.In_Axis.world_matrix} {parent.In_Axis.world_matrix} {parent.In_Axis.world_matrix} {parent.In_Axis.world_matrix}} 200 | {{parent.In_Axis.world_matrix} {parent.In_Axis.world_matrix} {parent.In_Axis.world_matrix} {parent.In_Axis.world_matrix}} 201 | {{parent.In_Axis.world_matrix} {parent.In_Axis.world_matrix} {parent.In_Axis.world_matrix} {parent.In_Axis.world_matrix}} 202 | } 203 | name Out_Axis 204 | xpos 964 205 | ypos 655 206 | } 207 | Output { 208 | name Output1 209 | xpos 954 210 | ypos 778 211 | } 212 | end_group 213 | Dot { 214 | name Dot5 215 | xpos 703 216 | ypos 782 217 | } 218 | Switch { 219 | inputs 2 220 | which {{parent.mode}} 221 | name Switch1 222 | xpos 806 223 | ypos 778 224 | } 225 | Output { 226 | name Output1 227 | xpos 806 228 | ypos 834 229 | } 230 | end_group 231 | -------------------------------------------------------------------------------- /nuke/Math/Matrix4/InvertMatrix4.nk: -------------------------------------------------------------------------------- 1 | Group { 2 | name InvertMatrix4_1 3 | help "Invert a pixel based Matrix4 (Defined as layers matrix0, matrix1, matrix2 and matrix3)" 4 | knobChanged "node = nuke.thisNode()\nknob = nuke.thisKnob()\n\nif knob.name() == \"inputChange\":\n with node:\n format_knob = nuke.toNode('Constant1')\['format']\n if node.input(0):\n format_knob.setEnabled(False)\n else:\n format_knob.setEnabled(True)\n" 5 | selected true 6 | xpos -2208 7 | ypos 688 8 | addUserKnob {20 Matrix4 l InvertMatrix4} 9 | addUserKnob {26 Description l "" +STARTLINE T "Invert matrix channels"} 10 | addUserKnob {26 divider_copyright l "" +STARTLINE} 11 | addUserKnob {26 copyright l "" +STARTLINE T "v1.0 - Mathieu Goulet-Aubin & Erwan Leroy - Github"} 12 | } 13 | Input { 14 | inputs 0 15 | name Inputmatrix 16 | xpos 276 17 | ypos 144 18 | } 19 | Dot { 20 | name Dot3 21 | tile_color 0xcccccc00 22 | xpos 310 23 | ypos 296 24 | } 25 | set N120b6ee0 [stack 0] 26 | Dot { 27 | name Dot20 28 | tile_color 0xcccccc00 29 | xpos 456 30 | ypos 296 31 | } 32 | add_layer {matrix0 matrix0.0 matrix0.1 matrix0.2 matrix0.3} 33 | Shuffle { 34 | in matrix0 35 | name Shuffle1 36 | label "in \[value in]-->out \[value out]" 37 | xpos 422 38 | ypos 343 39 | } 40 | set N14561c90 [stack 0] 41 | add_layer {matrix1 matrix1.0 matrix1.1 matrix1.2 matrix1.3} 42 | Shuffle { 43 | in matrix1 44 | name Shuffle2 45 | label "in \[value in]-->out \[value out]" 46 | xpos 422 47 | ypos 383 48 | } 49 | set N1c218280 [stack 0] 50 | add_layer {matrix2 matrix2.0 matrix2.1 matrix2.2 matrix2.3} 51 | Shuffle { 52 | in matrix2 53 | name Shuffle3 54 | label "in \[value in]-->out \[value out]" 55 | xpos 422 56 | ypos 419 57 | } 58 | set N1c736ac0 [stack 0] 59 | add_layer {matrix3 matrix3.0 matrix3.1 matrix3.2 matrix3.3} 60 | Shuffle { 61 | in matrix3 62 | name Shuffle4 63 | label "in \[value in]-->out \[value out]" 64 | xpos 422 65 | ypos 456 66 | } 67 | Dot { 68 | name Dot8 69 | tile_color 0x9e3c6300 70 | xpos 707 71 | ypos 465 72 | } 73 | set N142755e0 [stack 0] 74 | Dot { 75 | name Dot11 76 | tile_color 0x9e3c6300 77 | xpos 831 78 | ypos 465 79 | } 80 | set N11330380 [stack 0] 81 | Dot { 82 | name Dot12 83 | tile_color 0x9e3c6300 84 | xpos 965 85 | ypos 465 86 | } 87 | set N1b902700 [stack 0] 88 | Dot { 89 | name Dot16 90 | tile_color 0x9e3c6300 91 | xpos 1113 92 | ypos 465 93 | } 94 | push $N1c736ac0 95 | Dot { 96 | name Dot7 97 | tile_color 0x9e3c6300 98 | xpos 666 99 | ypos 428 100 | } 101 | set N1c6f5ac0 [stack 0] 102 | Dot { 103 | name Dot10 104 | tile_color 0x9e3c6300 105 | xpos 821 106 | ypos 428 107 | } 108 | set N1e8d5010 [stack 0] 109 | Dot { 110 | name Dot13 111 | tile_color 0x9e3c6300 112 | xpos 949 113 | ypos 428 114 | } 115 | set N1133ec50 [stack 0] 116 | Dot { 117 | name Dot17 118 | tile_color 0x9e3c6300 119 | xpos 1100 120 | ypos 428 121 | } 122 | push $N1c218280 123 | Dot { 124 | name Dot6 125 | tile_color 0x9e3c6300 126 | xpos 637 127 | ypos 392 128 | } 129 | set N1c7017f0 [stack 0] 130 | Dot { 131 | name Dot9 132 | tile_color 0x9e3c6300 133 | xpos 808 134 | ypos 392 135 | } 136 | set N11323810 [stack 0] 137 | Dot { 138 | name Dot14 139 | tile_color 0x9e3c6300 140 | xpos 927 141 | ypos 392 142 | } 143 | set N1eabc3d0 [stack 0] 144 | Dot { 145 | name Dot18 146 | tile_color 0x9e3c6300 147 | xpos 1084 148 | ypos 392 149 | } 150 | push $N14561c90 151 | Dot { 152 | name Dot5 153 | tile_color 0x9e3c6300 154 | xpos 592 155 | ypos 352 156 | } 157 | set N1e9a4770 [stack 0] 158 | Dot { 159 | name Dot4 160 | tile_color 0x9e3c6300 161 | xpos 776 162 | ypos 352 163 | } 164 | set N1c087c20 [stack 0] 165 | Dot { 166 | name Dot15 167 | tile_color 0x9e3c6300 168 | xpos 905 169 | ypos 352 170 | } 171 | set N1ec479e0 [stack 0] 172 | Dot { 173 | name Dot19 174 | tile_color 0x9e3c6300 175 | xpos 1068 176 | ypos 352 177 | } 178 | BlinkScript { 179 | inputs 4 180 | recompileCount 14 181 | ProgramGroup 1 182 | KernelDescription "2 \"InvertMatrix4\" iterate pixelWise 24c0b57d50e6fc4d3de1ddabffc2c534b1cd8bf00f432f09e06cab24b7b23d50 5 \"matrix0\" Read Point \"matrix1\" Read Point \"matrix2\" Read Point \"matrix3\" Read Point \"dst\" Write Point 0 0 0" 183 | kernelSource "kernel InvertMatrix4 : ImageComputationKernel\n\{\n Image matrix0; // the input image\n Image matrix1; // the input image\n Image matrix2; // the input image\n Image matrix3; // the input image\n Image dst; // the output image\n\n void process() \{\n // Read the input image\n SampleType(matrix0) m0 = matrix0();\n SampleType(matrix1) m1 = matrix1();\n SampleType(matrix2) m2 = matrix2();\n SampleType(matrix3) m3 = matrix3();\n\n // Create the matrix object (matrix3 in this case)\n float4x4 matrix;\n matrix\[0]\[0] = m0.x;\n matrix\[0]\[1] = m0.y;\n matrix\[0]\[2] = m0.z;\n matrix\[0]\[3] = m0.w;\n matrix\[1]\[0] = m1.x;\n matrix\[1]\[1] = m1.y;\n matrix\[1]\[2] = m1.z;\n matrix\[1]\[3] = m1.w;\n matrix\[2]\[0] = m2.x;\n matrix\[2]\[1] = m2.y;\n matrix\[2]\[2] = m2.z;\n matrix\[2]\[3] = m2.w;\n matrix\[3]\[0] = m3.x;\n matrix\[3]\[1] = m3.y;\n matrix\[3]\[2] = m3.z;\n matrix\[3]\[3] = m3.w;\n\n // Inverse the matrix\n matrix = matrix.invert();\n\n // Write the result to the output image\n dst() = float4(matrix\[3]\[0], matrix\[3]\[1], matrix\[3]\[2], matrix\[3]\[3]);\n \}\n\};\n" 184 | rebuild "" 185 | rebuild_finalise "" 186 | name BlinkScript4 187 | xpos 1034 188 | ypos 579 189 | } 190 | Dot { 191 | name Dot2 192 | tile_color 0xcccccc00 193 | xpos 1068 194 | ypos 866 195 | } 196 | push $N1b902700 197 | push $N1133ec50 198 | push $N1eabc3d0 199 | push $N1ec479e0 200 | BlinkScript { 201 | inputs 4 202 | recompileCount 14 203 | ProgramGroup 1 204 | KernelDescription "2 \"InvertMatrix4\" iterate pixelWise 18ad5fdc0440a3820ed7a9939c0cfbbf7fad1323aed420c38542f1e186aa8c86 5 \"matrix0\" Read Point \"matrix1\" Read Point \"matrix2\" Read Point \"matrix3\" Read Point \"dst\" Write Point 0 0 0" 205 | kernelSource "kernel InvertMatrix4 : ImageComputationKernel\n\{\n Image matrix0; // the input image\n Image matrix1; // the input image\n Image matrix2; // the input image\n Image matrix3; // the input image\n Image dst; // the output image\n\n void process() \{\n // Read the input image\n SampleType(matrix0) m0 = matrix0();\n SampleType(matrix1) m1 = matrix1();\n SampleType(matrix2) m2 = matrix2();\n SampleType(matrix3) m3 = matrix3();\n\n // Create the matrix object (matrix3 in this case)\n float4x4 matrix;\n matrix\[0]\[0] = m0.x;\n matrix\[0]\[1] = m0.y;\n matrix\[0]\[2] = m0.z;\n matrix\[0]\[3] = m0.w;\n matrix\[1]\[0] = m1.x;\n matrix\[1]\[1] = m1.y;\n matrix\[1]\[2] = m1.z;\n matrix\[1]\[3] = m1.w;\n matrix\[2]\[0] = m2.x;\n matrix\[2]\[1] = m2.y;\n matrix\[2]\[2] = m2.z;\n matrix\[2]\[3] = m2.w;\n matrix\[3]\[0] = m3.x;\n matrix\[3]\[1] = m3.y;\n matrix\[3]\[2] = m3.z;\n matrix\[3]\[3] = m3.w;\n\n // Inverse the matrix\n matrix = matrix.invert();\n\n // Write the result to the output image\n dst() = float4(matrix\[2]\[0], matrix\[2]\[1], matrix\[2]\[2], matrix\[2]\[3]);\n \}\n\};\n" 206 | rebuild "" 207 | rebuild_finalise "" 208 | name BlinkScript3 209 | xpos 871 210 | ypos 585 211 | } 212 | Dot { 213 | name Dot1 214 | tile_color 0xcccccc00 215 | xpos 905 216 | ypos 776 217 | } 218 | push $N11330380 219 | push $N1e8d5010 220 | push $N11323810 221 | push $N1c087c20 222 | BlinkScript { 223 | inputs 4 224 | recompileCount 14 225 | ProgramGroup 1 226 | KernelDescription "2 \"InvertMatrix4\" iterate pixelWise e9f630cc235826bda0787271e2c79d1689a8462ddf208e8692d52b548c8b67e3 5 \"matrix0\" Read Point \"matrix1\" Read Point \"matrix2\" Read Point \"matrix3\" Read Point \"dst\" Write Point 0 0 0" 227 | kernelSource "kernel InvertMatrix4 : ImageComputationKernel\n\{\n Image matrix0; // the input image\n Image matrix1; // the input image\n Image matrix2; // the input image\n Image matrix3; // the input image\n Image dst; // the output image\n\n void process() \{\n // Read the input image\n SampleType(matrix0) m0 = matrix0();\n SampleType(matrix1) m1 = matrix1();\n SampleType(matrix2) m2 = matrix2();\n SampleType(matrix3) m3 = matrix3();\n\n // Create the matrix object (matrix3 in this case)\n float4x4 matrix;\n matrix\[0]\[0] = m0.x;\n matrix\[0]\[1] = m0.y;\n matrix\[0]\[2] = m0.z;\n matrix\[0]\[3] = m0.w;\n matrix\[1]\[0] = m1.x;\n matrix\[1]\[1] = m1.y;\n matrix\[1]\[2] = m1.z;\n matrix\[1]\[3] = m1.w;\n matrix\[2]\[0] = m2.x;\n matrix\[2]\[1] = m2.y;\n matrix\[2]\[2] = m2.z;\n matrix\[2]\[3] = m2.w;\n matrix\[3]\[0] = m3.x;\n matrix\[3]\[1] = m3.y;\n matrix\[3]\[2] = m3.z;\n matrix\[3]\[3] = m3.w;\n\n // Inverse the matrix\n matrix = matrix.invert();\n\n // Write the result to the output image\n dst() = float4(matrix\[1]\[0], matrix\[1]\[1], matrix\[1]\[2], matrix\[1]\[3]);\n \}\n\};\n" 228 | rebuild "" 229 | rebuild_finalise "" 230 | name BlinkScript2 231 | xpos 742 232 | ypos 581 233 | } 234 | Dot { 235 | name Dot37 236 | tile_color 0xcccccc00 237 | xpos 776 238 | ypos 692 239 | } 240 | push $N142755e0 241 | push $N1c6f5ac0 242 | push $N1c7017f0 243 | push $N1e9a4770 244 | BlinkScript { 245 | inputs 4 246 | recompileCount 15 247 | ProgramGroup 1 248 | KernelDescription "2 \"InvertMatrix4\" iterate pixelWise 13aa95e9193320b60408dcef52f07d536b6bc8570746ebe3a513989e032825a7 5 \"matrix0\" Read Point \"matrix1\" Read Point \"matrix2\" Read Point \"matrix3\" Read Point \"dst\" Write Point 0 0 0" 249 | kernelSource "kernel InvertMatrix4 : ImageComputationKernel\n\{\n Image matrix0; // the input image\n Image matrix1; // the input image\n Image matrix2; // the input image\n Image matrix3; // the input image\n Image dst; // the output image\n\n void process() \{\n // Read the input image\n SampleType(matrix0) m0 = matrix0();\n SampleType(matrix1) m1 = matrix1();\n SampleType(matrix2) m2 = matrix2();\n SampleType(matrix3) m3 = matrix3();\n\n // Create the matrix object (matrix3 in this case)\n float4x4 matrix;\n matrix\[0]\[0] = m0.x;\n matrix\[0]\[1] = m0.y;\n matrix\[0]\[2] = m0.z;\n matrix\[0]\[3] = m0.w;\n matrix\[1]\[0] = m1.x;\n matrix\[1]\[1] = m1.y;\n matrix\[1]\[2] = m1.z;\n matrix\[1]\[3] = m1.w;\n matrix\[2]\[0] = m2.x;\n matrix\[2]\[1] = m2.y;\n matrix\[2]\[2] = m2.z;\n matrix\[2]\[3] = m2.w;\n matrix\[3]\[0] = m3.x;\n matrix\[3]\[1] = m3.y;\n matrix\[3]\[2] = m3.z;\n matrix\[3]\[3] = m3.w;\n\n // Inverse the matrix\n matrix = matrix.invert();\n\n // Write the result to the output image\n dst() = float4(matrix\[0]\[0], matrix\[0]\[1], matrix\[0]\[2], matrix\[0]\[3]);\n \}\n\};\n" 250 | rebuild "" 251 | rebuild_finalise "" 252 | name BlinkScript1 253 | selected true 254 | xpos 558 255 | ypos 588 256 | } 257 | push $N120b6ee0 258 | Copy { 259 | inputs 2 260 | from0 rgba.red 261 | to0 matrix0.0 262 | from1 rgba.green 263 | to1 matrix0.1 264 | from2 rgba.blue 265 | to2 matrix0.2 266 | from3 rgba.alpha 267 | to3 matrix0.3 268 | bbox B 269 | name Copy2 270 | xpos 276 271 | ypos 569 272 | } 273 | Copy { 274 | inputs 2 275 | from0 rgba.red 276 | to0 matrix1.0 277 | from1 rgba.green 278 | to1 matrix1.1 279 | from2 rgba.blue 280 | to2 matrix1.2 281 | from3 rgba.alpha 282 | to3 matrix1.3 283 | bbox B 284 | name Copy1 285 | xpos 276 286 | ypos 664 287 | } 288 | Copy { 289 | inputs 2 290 | from0 rgba.red 291 | to0 matrix2.0 292 | from1 rgba.green 293 | to1 matrix2.1 294 | from2 rgba.blue 295 | to2 matrix2.2 296 | from3 rgba.alpha 297 | to3 matrix2.3 298 | bbox B 299 | name Copy4 300 | xpos 276 301 | ypos 748 302 | } 303 | Copy { 304 | inputs 2 305 | from0 rgba.red 306 | to0 matrix3.0 307 | from1 rgba.green 308 | to1 matrix3.1 309 | from2 rgba.blue 310 | to2 matrix3.2 311 | from3 rgba.alpha 312 | to3 matrix3.3 313 | bbox B 314 | name Copy5 315 | xpos 276 316 | ypos 838 317 | } 318 | Output { 319 | name Output1 320 | xpos 276 321 | ypos 1059 322 | } 323 | end_group 324 | -------------------------------------------------------------------------------- /nuke/Math/Matrix4/ProductMatrix4.nk: -------------------------------------------------------------------------------- 1 | Group { 2 | name ProductMatrix4_ 3 | help "Multiply two pixel based Matrix4 (Defined as layers matrix0, matrix1, matrix2 and matrix3)" 4 | addUserKnob {20 Matrix4Product l "Product Matrix4"} 5 | addUserKnob {26 Description l "" +STARTLINE T "Multiply two matrix4: matrixA*matrixB"} 6 | addUserKnob {26 divider_copyright l "" +STARTLINE} 7 | addUserKnob {26 copyright l "" +STARTLINE T "v1.0 - Mathieu Goulet-Aubin & Erwan Leroy - Github"} 8 | } 9 | Input { 10 | inputs 0 11 | name matrixA 12 | xpos 344 13 | ypos 139 14 | } 15 | Dot { 16 | name Dot3 17 | xpos 378 18 | ypos 252 19 | } 20 | set N1dd52c30 [stack 0] 21 | push $N1dd52c30 22 | push $N1dd52c30 23 | push $N1dd52c30 24 | Input { 25 | inputs 0 26 | name matrixB 27 | xpos 21 28 | ypos 142 29 | number 1 30 | } 31 | add_layer {matrix0 matrix0.0 matrix0.1 matrix0.2 matrix0.3} 32 | MergeExpression { 33 | inputs 2 34 | channel0 {matrix0.0 -matrix0.1 -matrix0.2 -matrix0.3} 35 | expr0 (Bmatrix0.0*Amatrix0.0)+(Bmatrix0.1*Amatrix1.0)+(Bmatrix0.2*Amatrix2.0)+(Bmatrix0.3*Amatrix3.0) 36 | channel1 {-matrix0.0 matrix0.1 -matrix0.2 -matrix0.3} 37 | expr1 (Bmatrix0.0*Amatrix0.1)+(Bmatrix0.1*Amatrix1.1)+(Bmatrix0.2*Amatrix2.1)+(Bmatrix0.3*Amatrix3.1) 38 | channel2 {-matrix0.0 -matrix0.1 matrix0.2 -matrix0.3} 39 | expr2 (Bmatrix0.0*Amatrix0.2)+(Bmatrix0.1*Amatrix1.2)+(Bmatrix0.2*Amatrix2.2)+(Bmatrix0.3*Amatrix3.2) 40 | channel3 {-matrix0.0 -matrix0.1 -matrix0.2 matrix0.3} 41 | expr3 (Bmatrix0.0*Amatrix0.3)+(Bmatrix0.1*Amatrix1.3)+(Bmatrix0.2*Amatrix2.3)+(Bmatrix0.3*Amatrix3.3) 42 | name MergeExpression1 43 | xpos 21 44 | ypos 249 45 | } 46 | add_layer {matrix1 matrix1.0 matrix1.1 matrix1.2 matrix1.3} 47 | MergeExpression { 48 | inputs 2 49 | channel0 {matrix1.0 -matrix1.1 -matrix1.2 -matrix1.3} 50 | expr0 (Bmatrix1.0*Amatrix0.0)+(Bmatrix1.1*Amatrix1.0)+(Bmatrix1.2*Amatrix2.0)+(Bmatrix1.3*Amatrix3.0) 51 | channel1 {-matrix1.0 matrix1.1 -matrix1.2 -matrix1.3} 52 | expr1 (Bmatrix1.0*Amatrix0.1)+(Bmatrix1.1*Amatrix1.1)+(Bmatrix1.2*Amatrix2.1)+(Bmatrix1.3*Amatrix3.1) 53 | channel2 {-matrix1.0 -matrix1.1 matrix1.2 -matrix1.3} 54 | expr2 (Bmatrix1.0*Amatrix0.2)+(Bmatrix1.1*Amatrix1.2)+(Bmatrix1.2*Amatrix2.2)+(Bmatrix1.3*Amatrix3.2) 55 | channel3 {-matrix1.0 -matrix1.1 -matrix1.2 matrix1.3} 56 | expr3 (Bmatrix1.0*Amatrix0.3)+(Bmatrix1.1*Amatrix1.3)+(Bmatrix1.2*Amatrix2.3)+(Bmatrix1.3*Amatrix3.3) 57 | name MergeExpression2 58 | xpos 21 59 | ypos 273 60 | } 61 | add_layer {matrix2 matrix2.0 matrix2.1 matrix2.2 matrix2.3} 62 | MergeExpression { 63 | inputs 2 64 | channel0 {matrix2.0 -matrix2.1 -matrix2.2 -matrix2.3} 65 | expr0 (Bmatrix2.0*Amatrix0.0)+(Bmatrix2.1*Amatrix1.0)+(Bmatrix2.2*Amatrix2.0)+(Bmatrix2.3*Amatrix3.0) 66 | channel1 {-matrix2.0 matrix2.1 -matrix2.2 -matrix2.3} 67 | expr1 (Bmatrix2.0*Amatrix0.1)+(Bmatrix2.1*Amatrix1.1)+(Bmatrix2.2*Amatrix2.1)+(Bmatrix2.3*Amatrix3.1) 68 | channel2 {-matrix2.0 -matrix2.1 matrix2.2 -matrix2.3} 69 | expr2 (Bmatrix2.0*Amatrix0.2)+(Bmatrix2.1*Amatrix1.2)+(Bmatrix2.2*Amatrix2.2)+(Bmatrix2.3*Amatrix3.2) 70 | channel3 {-matrix2.0 -matrix2.1 -matrix2.2 matrix2.3} 71 | expr3 (Bmatrix2.0*Amatrix0.3)+(Bmatrix2.1*Amatrix1.3)+(Bmatrix2.2*Amatrix2.3)+(Bmatrix2.3*Amatrix3.3) 72 | name MergeExpression3 73 | xpos 21 74 | ypos 297 75 | } 76 | add_layer {matrix3 matrix3.0 matrix3.1 matrix3.2 matrix3.3} 77 | MergeExpression { 78 | inputs 2 79 | channel0 {matrix3.0 -matrix3.1 -matrix3.2 -matrix3.3} 80 | expr0 (Bmatrix3.0*Amatrix0.0)+(Bmatrix3.1*Amatrix1.0)+(Bmatrix3.2*Amatrix2.0)+(Bmatrix3.3*Amatrix3.0) 81 | channel1 {-matrix3.0 matrix3.1 -matrix3.2 -matrix3.3} 82 | expr1 (Bmatrix3.0*Amatrix0.1)+(Bmatrix3.1*Amatrix1.1)+(Bmatrix3.2*Amatrix2.1)+(Bmatrix3.3*Amatrix3.1) 83 | channel2 {-matrix3.0 -matrix3.1 matrix3.2 -matrix3.3} 84 | expr2 (Bmatrix3.0*Amatrix0.2)+(Bmatrix3.1*Amatrix1.2)+(Bmatrix3.2*Amatrix2.2)+(Bmatrix3.3*Amatrix3.2) 85 | channel3 {-matrix3.0 -matrix3.1 -matrix3.2 matrix3.3} 86 | expr3 (Bmatrix3.0*Amatrix0.3)+(Bmatrix3.1*Amatrix1.3)+(Bmatrix3.2*Amatrix2.3)+(Bmatrix3.3*Amatrix3.3) 87 | name MergeExpression4 88 | selected true 89 | xpos 21 90 | ypos 321 91 | } 92 | Output { 93 | name Output1 94 | xpos 21 95 | ypos 421 96 | } 97 | end_group 98 | -------------------------------------------------------------------------------- /nuke/Math/Matrix4/ScaleMatrix4.nk: -------------------------------------------------------------------------------- 1 | Group { 2 | name ScaleMatrix4_ 3 | help "Scale a matrix4 using a control channel (rgb from vector input) for which each channel is considered as a scalar for x, y and z" 4 | addUserKnob {20 ScaleMatrix4} 5 | addUserKnob {26 Description l "" +STARTLINE T "Scale a matrix4 using a control channel (rgb) for which each channel is considered as a scalar for x, y and z"} 6 | addUserKnob {26 divider_copyright l "" +STARTLINE} 7 | addUserKnob {26 copyright l "" +STARTLINE T "v1.0 - Mathieu Goulet-Aubin & Erwan Leroy - Github"} 8 | } 9 | Input { 10 | inputs 0 11 | name vector 12 | xpos 491 13 | ypos 162 14 | number 1 15 | } 16 | Dot { 17 | name Dot1 18 | xpos 525 19 | ypos 252 20 | } 21 | Input { 22 | inputs 0 23 | name matrix 24 | xpos 344 25 | ypos 161 26 | } 27 | add_layer {matrix0 matrix0.0 matrix0.1 matrix0.2 matrix0.3} 28 | add_layer {matrix1 matrix1.0 matrix1.1 matrix1.2 matrix1.3} 29 | add_layer {matrix2 matrix2.0 matrix2.1 matrix2.2 matrix2.3} 30 | MergeExpression { 31 | inputs 2 32 | channel0 {matrix0.0 -matrix0.1 -matrix0.2 -matrix0.3} 33 | expr0 matrix0.0*Ar 34 | channel1 {-matrix1.0 matrix1.1 -matrix1.2 -matrix1.3} 35 | expr1 matrix1.1*Ag 36 | channel2 {-matrix2.0 -matrix2.1 matrix2.2 -matrix2.3} 37 | expr2 matrix2.2*Ab 38 | channel3 none 39 | name MergeExpression1 40 | xpos 344 41 | ypos 249 42 | } 43 | Output { 44 | name Output1 45 | xpos 344 46 | ypos 349 47 | } 48 | end_group 49 | -------------------------------------------------------------------------------- /nuke/Math/Matrix4/TransformMatrix4.nk: -------------------------------------------------------------------------------- 1 | set cut_paste_input [stack 0] 2 | version 11.2 v4 3 | push $cut_paste_input 4 | Group { 5 | name TransformMatrix4 6 | selected true 7 | xpos -2220 8 | ypos 808 9 | addUserKnob {20 Matrix4x4_Transform} 10 | addUserKnob {41 xform_order l "transform order" T Axis1.xform_order} 11 | addUserKnob {41 rot_order l "rotation order" T Axis1.rot_order} 12 | addUserKnob {41 translate T Axis1.translate} 13 | addUserKnob {41 rotate T Axis1.rotate} 14 | addUserKnob {41 scaling l scale T Axis1.scaling} 15 | addUserKnob {41 uniform_scale l "uniform scale" T Axis1.uniform_scale} 16 | addUserKnob {41 skew T Axis1.skew} 17 | addUserKnob {41 pivot T Axis1.pivot} 18 | addUserKnob {20 "" l "Local matrix" n 2} 19 | addUserKnob {41 useMatrix l "specify matrix" T Axis1.useMatrix} 20 | addUserKnob {41 matrix l "" +STARTLINE T Axis1.matrix} 21 | } 22 | BackdropNode { 23 | inputs 0 24 | name BackdropNode1 25 | tile_color 0xaaaaaa00 26 | label "Transform\nTo Matrix" 27 | note_font_size 20 28 | xpos 764 29 | ypos 251 30 | bdwidth 218 31 | bdheight 180 32 | } 33 | Input { 34 | inputs 0 35 | name matrix 36 | xpos 451 37 | ypos 137 38 | } 39 | Dot { 40 | name Dot1 41 | xpos 485 42 | ypos 195 43 | } 44 | set N1e536770 [stack 0] 45 | Dot { 46 | name Dot2 47 | xpos 808 48 | ypos 195 49 | } 50 | add_layer {matrix0 matrix0.0 matrix0.1 matrix0.2 matrix0.3} 51 | Expression { 52 | channel0 {matrix0.0 -matrix0.1 -matrix0.2 -matrix0.3} 53 | expr0 Axis1.world_matrix.0 54 | channel1 {-matrix0.0 matrix0.1 -matrix0.2 -matrix0.3} 55 | expr1 Axis1.world_matrix.1 56 | channel2 {-matrix0.0 -matrix0.1 matrix0.2 -matrix0.3} 57 | expr2 Axis1.world_matrix.2 58 | channel3 {-matrix0.0 -matrix0.1 -matrix0.2 matrix0.3} 59 | expr3 Axis1.world_matrix.3 60 | name Expression1 61 | xpos 774 62 | ypos 331 63 | } 64 | add_layer {matrix1 matrix1.0 matrix1.1 matrix1.2 matrix1.3} 65 | Expression { 66 | channel0 {matrix1.0 -matrix1.1 -matrix1.2 -matrix1.3} 67 | expr0 Axis1.world_matrix.4 68 | channel1 {-matrix1.0 matrix1.1 -matrix1.2 -matrix1.3} 69 | expr1 Axis1.world_matrix.5 70 | channel2 {-matrix1.0 -matrix1.1 matrix1.2 -matrix1.3} 71 | expr2 Axis1.world_matrix.6 72 | channel3 {-matrix1.0 -matrix1.1 -matrix1.2 matrix1.3} 73 | expr3 Axis1.world_matrix.7 74 | name Expression2 75 | xpos 774 76 | ypos 355 77 | } 78 | add_layer {matrix2 matrix2.0 matrix2.1 matrix2.2 matrix2.3} 79 | Expression { 80 | channel0 {matrix2.0 -matrix2.1 -matrix2.2 -matrix2.3} 81 | expr0 Axis1.world_matrix.8 82 | channel1 {-matrix2.0 matrix2.1 -matrix2.2 -matrix2.3} 83 | expr1 Axis1.world_matrix.9 84 | channel2 {-matrix2.0 -matrix2.1 matrix2.2 -matrix2.3} 85 | expr2 Axis1.world_matrix.10 86 | channel3 {-matrix2.0 -matrix2.1 -matrix2.2 matrix2.3} 87 | expr3 Axis1.world_matrix.11 88 | name Expression3 89 | xpos 774 90 | ypos 379 91 | } 92 | add_layer {matrix3 matrix3.0 matrix3.1 matrix3.2 matrix3.3} 93 | Expression { 94 | channel0 {matrix3.0 -matrix3.1 -matrix3.2 -matrix3.3} 95 | expr0 Axis1.world_matrix.12 96 | channel1 {-matrix3.0 matrix3.1 -matrix3.2 -matrix3.3} 97 | expr1 Axis1.world_matrix.13 98 | channel2 {-matrix3.0 -matrix3.1 matrix3.2 -matrix3.3} 99 | expr2 Axis1.world_matrix.14 100 | channel3 {-matrix3.0 -matrix3.1 -matrix3.2 matrix3.3} 101 | expr3 Axis1.world_matrix.15 102 | name Expression4 103 | xpos 774 104 | ypos 403 105 | } 106 | Dot { 107 | name Dot3 108 | xpos 808 109 | ypos 574 110 | } 111 | set N1e5759e0 [stack 0] 112 | push $N1e536770 113 | push $N1e5759e0 114 | Group { 115 | inputs 2 116 | name Product_Matrix4_ 117 | help "Multiply two pixel based Matrix4 (Defined as layers matrix0, matrix1, matrix2 and matrix3)" 118 | xpos 451 119 | ypos 571 120 | addUserKnob {20 Matrix4Product l "Product Matrix4"} 121 | addUserKnob {26 Description l "" +STARTLINE T "Multiply two matrix4: matrixA*matrixB"} 122 | addUserKnob {26 divider_copyright l "" +STARTLINE} 123 | addUserKnob {26 copyright l "" +STARTLINE T "v1.0 - Mathieu Goulet-Aubin & Erwan Leroy - Github"} 124 | } 125 | Input { 126 | inputs 0 127 | name matrixA 128 | xpos 344 129 | ypos 139 130 | } 131 | Dot { 132 | name Dot3 133 | xpos 378 134 | ypos 252 135 | } 136 | set N1ef44020 [stack 0] 137 | push $N1ef44020 138 | push $N1ef44020 139 | push $N1ef44020 140 | Input { 141 | inputs 0 142 | name matrixB 143 | xpos 21 144 | ypos 142 145 | number 1 146 | } 147 | MergeExpression { 148 | inputs 2 149 | channel0 {matrix0.0 -matrix0.1 -matrix0.2 -matrix0.3} 150 | expr0 (Bmatrix0.0*Amatrix0.0)+(Bmatrix0.1*Amatrix1.0)+(Bmatrix0.2*Amatrix2.0)+(Bmatrix0.3*Amatrix3.0) 151 | channel1 {-matrix0.0 matrix0.1 -matrix0.2 -matrix0.3} 152 | expr1 (Bmatrix0.0*Amatrix0.1)+(Bmatrix0.1*Amatrix1.1)+(Bmatrix0.2*Amatrix2.1)+(Bmatrix0.3*Amatrix3.1) 153 | channel2 {-matrix0.0 -matrix0.1 matrix0.2 -matrix0.3} 154 | expr2 (Bmatrix0.0*Amatrix0.2)+(Bmatrix0.1*Amatrix1.2)+(Bmatrix0.2*Amatrix2.2)+(Bmatrix0.3*Amatrix3.2) 155 | channel3 {-matrix0.0 -matrix0.1 -matrix0.2 matrix0.3} 156 | expr3 (Bmatrix0.0*Amatrix0.3)+(Bmatrix0.1*Amatrix1.3)+(Bmatrix0.2*Amatrix2.3)+(Bmatrix0.3*Amatrix3.3) 157 | name MergeExpression1 158 | xpos 21 159 | ypos 249 160 | } 161 | MergeExpression { 162 | inputs 2 163 | channel0 {matrix1.0 -matrix1.1 -matrix1.2 -matrix1.3} 164 | expr0 (Bmatrix1.0*Amatrix0.0)+(Bmatrix1.1*Amatrix1.0)+(Bmatrix1.2*Amatrix2.0)+(Bmatrix1.3*Amatrix3.0) 165 | channel1 {-matrix1.0 matrix1.1 -matrix1.2 -matrix1.3} 166 | expr1 (Bmatrix1.0*Amatrix0.1)+(Bmatrix1.1*Amatrix1.1)+(Bmatrix1.2*Amatrix2.1)+(Bmatrix1.3*Amatrix3.1) 167 | channel2 {-matrix1.0 -matrix1.1 matrix1.2 -matrix1.3} 168 | expr2 (Bmatrix1.0*Amatrix0.2)+(Bmatrix1.1*Amatrix1.2)+(Bmatrix1.2*Amatrix2.2)+(Bmatrix1.3*Amatrix3.2) 169 | channel3 {-matrix1.0 -matrix1.1 -matrix1.2 matrix1.3} 170 | expr3 (Bmatrix1.0*Amatrix0.3)+(Bmatrix1.1*Amatrix1.3)+(Bmatrix1.2*Amatrix2.3)+(Bmatrix1.3*Amatrix3.3) 171 | name MergeExpression2 172 | xpos 21 173 | ypos 273 174 | } 175 | MergeExpression { 176 | inputs 2 177 | channel0 {matrix2.0 -matrix2.1 -matrix2.2 -matrix2.3} 178 | expr0 (Bmatrix2.0*Amatrix0.0)+(Bmatrix2.1*Amatrix1.0)+(Bmatrix2.2*Amatrix2.0)+(Bmatrix2.3*Amatrix3.0) 179 | channel1 {-matrix2.0 matrix2.1 -matrix2.2 -matrix2.3} 180 | expr1 (Bmatrix2.0*Amatrix0.1)+(Bmatrix2.1*Amatrix1.1)+(Bmatrix2.2*Amatrix2.1)+(Bmatrix2.3*Amatrix3.1) 181 | channel2 {-matrix2.0 -matrix2.1 matrix2.2 -matrix2.3} 182 | expr2 (Bmatrix2.0*Amatrix0.2)+(Bmatrix2.1*Amatrix1.2)+(Bmatrix2.2*Amatrix2.2)+(Bmatrix2.3*Amatrix3.2) 183 | channel3 {-matrix2.0 -matrix2.1 -matrix2.2 matrix2.3} 184 | expr3 (Bmatrix2.0*Amatrix0.3)+(Bmatrix2.1*Amatrix1.3)+(Bmatrix2.2*Amatrix2.3)+(Bmatrix2.3*Amatrix3.3) 185 | name MergeExpression3 186 | xpos 21 187 | ypos 297 188 | } 189 | MergeExpression { 190 | inputs 2 191 | channel0 {matrix3.0 -matrix3.1 -matrix3.2 -matrix3.3} 192 | expr0 (Bmatrix3.0*Amatrix0.0)+(Bmatrix3.1*Amatrix1.0)+(Bmatrix3.2*Amatrix2.0)+(Bmatrix3.3*Amatrix3.0) 193 | channel1 {-matrix3.0 matrix3.1 -matrix3.2 -matrix3.3} 194 | expr1 (Bmatrix3.0*Amatrix0.1)+(Bmatrix3.1*Amatrix1.1)+(Bmatrix3.2*Amatrix2.1)+(Bmatrix3.3*Amatrix3.1) 195 | channel2 {-matrix3.0 -matrix3.1 matrix3.2 -matrix3.3} 196 | expr2 (Bmatrix3.0*Amatrix0.2)+(Bmatrix3.1*Amatrix1.2)+(Bmatrix3.2*Amatrix2.2)+(Bmatrix3.3*Amatrix3.2) 197 | channel3 {-matrix3.0 -matrix3.1 -matrix3.2 matrix3.3} 198 | expr3 (Bmatrix3.0*Amatrix0.3)+(Bmatrix3.1*Amatrix1.3)+(Bmatrix3.2*Amatrix2.3)+(Bmatrix3.3*Amatrix3.3) 199 | name MergeExpression4 200 | selected true 201 | xpos 21 202 | ypos 321 203 | } 204 | Output { 205 | name Output1 206 | xpos 21 207 | ypos 421 208 | } 209 | end_group 210 | Switch { 211 | inputs 2 212 | which {{"\[exists parent.input]"}} 213 | name HasInput 214 | xpos 451 215 | ypos 788 216 | } 217 | Output { 218 | name Output1 219 | xpos 451 220 | ypos 852 221 | } 222 | Input { 223 | inputs 0 224 | name axis 225 | xpos 1041 226 | ypos 158 227 | number 1 228 | } 229 | Dot { 230 | name Dot4 231 | tile_color 0xcccccc00 232 | xpos 1075 233 | ypos 370 234 | } 235 | Axis2 { 236 | name Axis1 237 | xpos 912 238 | ypos 346 239 | addUserKnob {20 wpp} 240 | addUserKnob {18 pointPosition l "Point Position"} 241 | pointPosition {0 0 0} 242 | addUserKnob {6 pointPosition_panelDropped l "panel dropped state" -STARTLINE +HIDDEN} 243 | addUserKnob {6 pointPosition_panelDropped_1 l "panel dropped state" -STARTLINE +HIDDEN} 244 | } 245 | end_group 246 | -------------------------------------------------------------------------------- /nuke/Math/Matrix4/TranslateMatrix4.nk: -------------------------------------------------------------------------------- 1 | Group { 2 | name TranslateMatrix4_ 3 | help "Translate a matrix4 using a control channel (rgb from vector input) for which each channel is considered as a scalar for x, y and z" 4 | xpos -2223 5 | ypos 1055 6 | addUserKnob {20 Matrix4x4_Translate} 7 | addUserKnob {26 Description l "" +STARTLINE T "Translate a matrix4 using a control channel (rgb) for which each channel is considered as a scalar for x, y and z"} 8 | addUserKnob {26 divider_copyright l "" +STARTLINE} 9 | addUserKnob {26 copyright l "" +STARTLINE T "v1.0 - Mathieu Goulet-Aubin & Erwan Leroy - Github"} 10 | } 11 | Input { 12 | inputs 0 13 | name vector 14 | xpos 491 15 | ypos 155 16 | number 1 17 | } 18 | Dot { 19 | name Dot1 20 | xpos 525 21 | ypos 252 22 | } 23 | Input { 24 | inputs 0 25 | name matrix 26 | xpos 344 27 | ypos 161 28 | } 29 | add_layer {matrix0 matrix0.0 matrix0.1 matrix0.2 matrix0.3} 30 | add_layer {matrix1 matrix1.0 matrix1.1 matrix1.2 matrix1.3} 31 | add_layer {matrix2 matrix2.0 matrix2.1 matrix2.2 matrix2.3} 32 | MergeExpression { 33 | inputs 2 34 | channel0 {-matrix0.0 -matrix0.1 -matrix0.2 matrix0.3} 35 | expr0 matrix0.3+Ar 36 | channel1 {-matrix1.0 -matrix1.1 -matrix1.2 matrix1.3} 37 | expr1 matrix1.3+Ag 38 | channel2 {-matrix2.0 -matrix2.1 -matrix2.2 matrix2.3} 39 | expr2 matrix2.3+Ab 40 | channel3 none 41 | name MergeExpression1 42 | xpos 344 43 | ypos 249 44 | } 45 | Output { 46 | name Output1 47 | xpos 344 48 | ypos 349 49 | } 50 | end_group 51 | -------------------------------------------------------------------------------- /nuke/Math/Matrix4/TransposeMatrix4.nk: -------------------------------------------------------------------------------- 1 | Group { 2 | name TransposeMatrix4_ 3 | help "Transpose a pixel based Matrix4 (Defined as layers matrix0, matrix1, matrix2 and matrix3)" 4 | addUserKnob {20 Matrix4 l TransposeMatrix4} 5 | addUserKnob {26 Description l "" +STARTLINE T "Transpose matrix channels"} 6 | addUserKnob {26 divider_copyright l "" +STARTLINE} 7 | addUserKnob {26 copyright l "" +STARTLINE T "v1.0 - Mathieu Goulet-Aubin & Erwan Leroy - Github"} 8 | } 9 | Input { 10 | inputs 0 11 | name Inputmatrix 12 | xpos 361 13 | ypos 272 14 | } 15 | Dot { 16 | name Dot31 17 | tile_color 0xcccccc00 18 | xpos 395 19 | ypos 355 20 | } 21 | set N2070ca60 [stack 0] 22 | Dot { 23 | name Dot32 24 | tile_color 0xcccccc00 25 | xpos 497 26 | ypos 355 27 | } 28 | set N15d21900 [stack 0] 29 | Dot { 30 | name Dot33 31 | tile_color 0xcccccc00 32 | xpos 619 33 | ypos 355 34 | } 35 | set N202b2f20 [stack 0] 36 | Dot { 37 | name Dot34 38 | tile_color 0xcccccc00 39 | xpos 736 40 | ypos 355 41 | } 42 | add_layer {matrix3 matrix3.0 matrix3.1 matrix3.2 matrix3.3} 43 | Expression { 44 | channel0 {matrix3.0 -matrix3.1 -matrix3.2 -matrix3.3} 45 | expr0 matrix0.3 46 | channel1 {-matrix3.0 matrix3.1 -matrix3.2 -matrix3.3} 47 | expr1 matrix1.3 48 | channel2 {-matrix3.0 -matrix3.1 matrix3.2 -matrix3.3} 49 | expr2 matrix2.3 50 | channel3 {-matrix3.0 -matrix3.1 -matrix3.2 matrix3.3} 51 | name Expression56 52 | xpos 702 53 | ypos 402 54 | } 55 | Dot { 56 | name Dot2 57 | tile_color 0xcccccc00 58 | xpos 736 59 | ypos 638 60 | } 61 | push $N202b2f20 62 | add_layer {matrix2 matrix2.0 matrix2.1 matrix2.2 matrix2.3} 63 | Expression { 64 | channel0 {matrix2.0 -matrix2.1 -matrix2.2 -matrix2.3} 65 | expr0 matrix0.2 66 | channel1 {-matrix2.0 matrix2.1 -matrix2.2 -matrix2.3} 67 | expr1 matrix1.2 68 | channel2 {-matrix2.0 -matrix2.1 matrix2.2 -matrix2.3} 69 | channel3 {-matrix2.0 -matrix2.1 -matrix2.2 matrix2.3} 70 | expr3 matrix3.2 71 | name Expression55 72 | xpos 585 73 | ypos 399 74 | } 75 | Dot { 76 | name Dot1 77 | tile_color 0xcccccc00 78 | xpos 619 79 | ypos 548 80 | } 81 | push $N15d21900 82 | add_layer {matrix1 matrix1.0 matrix1.1 matrix1.2 matrix1.3} 83 | Expression { 84 | channel0 {matrix1.0 -matrix1.1 -matrix1.2 -matrix1.3} 85 | expr0 matrix0.1 86 | channel1 {-matrix1.0 matrix1.1 -matrix1.2 -matrix1.3} 87 | channel2 {-matrix1.0 -matrix1.1 matrix1.2 -matrix1.3} 88 | expr2 matrix2.1 89 | channel3 {-matrix1.0 -matrix1.1 -matrix1.2 matrix1.3} 90 | expr3 matrix3.1 91 | name Expression54 92 | xpos 463 93 | ypos 398 94 | } 95 | Dot { 96 | name Dot37 97 | tile_color 0xcccccc00 98 | xpos 497 99 | ypos 464 100 | } 101 | push $N2070ca60 102 | add_layer {matrix0 matrix0.0 matrix0.1 matrix0.2 matrix0.3} 103 | Expression { 104 | channel0 {matrix0.0 -matrix0.1 -matrix0.2 -matrix0.3} 105 | channel1 {-matrix0.0 matrix0.1 -matrix0.2 -matrix0.3} 106 | expr1 matrix1.0 107 | channel2 {-matrix0.0 -matrix0.1 matrix0.2 -matrix0.3} 108 | expr2 matrix2.0 109 | channel3 {-matrix0.0 -matrix0.1 -matrix0.2 matrix0.3} 110 | expr3 matrix3.0 111 | name Expression53 112 | xpos 361 113 | ypos 395 114 | } 115 | Copy { 116 | inputs 2 117 | from0 matrix1.0 118 | to0 matrix1.0 119 | from1 matrix1.2 120 | to1 matrix1.2 121 | from2 matrix1.3 122 | to2 matrix1.3 123 | bbox B 124 | name Copy1 125 | xpos 361 126 | ypos 442 127 | } 128 | Copy { 129 | inputs 2 130 | from0 matrix2.0 131 | to0 matrix2.0 132 | from1 matrix2.1 133 | to1 matrix2.1 134 | from2 matrix2.3 135 | to2 matrix2.3 136 | bbox B 137 | name Copy2 138 | xpos 361 139 | ypos 526 140 | } 141 | Copy { 142 | inputs 2 143 | from0 matrix3.0 144 | to0 matrix3.0 145 | from1 matrix3.1 146 | to1 matrix3.1 147 | from2 matrix3.2 148 | to2 matrix3.2 149 | bbox B 150 | name Copy3 151 | xpos 361 152 | ypos 616 153 | } 154 | Output { 155 | name Output1 156 | xpos 361 157 | ypos 733 158 | } 159 | end_group 160 | -------------------------------------------------------------------------------- /nuke/Math/Vector2/CrossProductVector2.nk: -------------------------------------------------------------------------------- 1 | Group { 2 | name CrossProductVector2_ 3 | help "Calculates the cross product of 2 Vector2 inputs." 4 | addUserKnob {20 main_tab l "Cross Product Vector2"} 5 | addUserKnob {41 in l "Vector B Layer" t "Layer containing the vector information for input B" T vector_layer.in} 6 | addUserKnob {41 in_1 l "Vector A Layer" t "Layer containing the vector information for input A" T vector_layer1.in} 7 | addUserKnob {26 ""} 8 | addUserKnob {26 copyright l "" +STARTLINE T "v1.0 - Mathieu Goulet-Aubin & Erwan Leroy - Github"} 9 | } 10 | Input { 11 | inputs 0 12 | name vectorA 13 | xpos 457 14 | ypos -6 15 | number 1 16 | } 17 | Shuffle { 18 | name vector_layer1 19 | xpos 457 20 | ypos 103 21 | } 22 | Remove { 23 | operation keep 24 | channels rgba 25 | name Remove2 26 | xpos 457 27 | ypos 129 28 | } 29 | Dot { 30 | name Dot3 31 | tile_color 0x9e3c6300 32 | xpos 491 33 | ypos 210 34 | } 35 | Input { 36 | inputs 0 37 | name vectorB 38 | xpos 0 39 | } 40 | Dot { 41 | name Dot1 42 | tile_color 0xcccccc00 43 | xpos 34 44 | ypos 108 45 | } 46 | set N71872f0 [stack 0] 47 | Shuffle { 48 | name vector_layer 49 | xpos 140 50 | ypos 104 51 | } 52 | Remove { 53 | operation keep 54 | channels rgba 55 | name Remove1 56 | xpos 140 57 | ypos 130 58 | } 59 | MergeExpression { 60 | inputs 2 61 | channel0 rgb 62 | expr0 "Br*Ag - Bg*Ar" 63 | name MergeExpression2 64 | xpos 140 65 | ypos 206 66 | } 67 | Dot { 68 | name Dot2 69 | tile_color 0x4b5ec600 70 | xpos 174 71 | ypos 364 72 | } 73 | push $N71872f0 74 | ShuffleCopy { 75 | inputs 2 76 | in2 none 77 | red red 78 | green green 79 | blue blue 80 | out {{{parent.vector_layer.in}}} 81 | name ShuffleCopy1 82 | xpos 0 83 | ypos 360 84 | } 85 | Output { 86 | name Output1 87 | xpos 0 88 | ypos 506 89 | } 90 | end_group 91 | -------------------------------------------------------------------------------- /nuke/Math/Vector2/DotProductVector2.nk: -------------------------------------------------------------------------------- 1 | Group { 2 | name DotProductVector2_ 3 | help "Calculates the dot product of 2 Vector2 inputs." 4 | addUserKnob {20 main_tab l "Dot Product Vector2"} 5 | addUserKnob {41 in l "Vector B Layer" t "Layer containing the vector information for input B" T vector_layer.in} 6 | addUserKnob {41 in_1 l "Vector A Layer" t "Layer containing the vector information for input A" T vector_layer1.in} 7 | addUserKnob {26 ""} 8 | addUserKnob {26 copyright l "" +STARTLINE T "v1.0 - Mathieu Goulet-Aubin & Erwan Leroy - Github"} 9 | } 10 | Input { 11 | inputs 0 12 | name vectorA 13 | xpos 457 14 | ypos -6 15 | number 1 16 | } 17 | Shuffle { 18 | name vector_layer1 19 | xpos 457 20 | ypos 103 21 | } 22 | Remove { 23 | operation keep 24 | channels rgba 25 | name Remove2 26 | xpos 457 27 | ypos 129 28 | } 29 | Dot { 30 | name Dot3 31 | tile_color 0x9e3c6300 32 | xpos 491 33 | ypos 210 34 | } 35 | Input { 36 | inputs 0 37 | name vectorB 38 | xpos 0 39 | } 40 | Dot { 41 | name Dot1 42 | tile_color 0xcccccc00 43 | xpos 34 44 | ypos 108 45 | } 46 | set N78454e0 [stack 0] 47 | Shuffle { 48 | name vector_layer 49 | xpos 140 50 | ypos 104 51 | } 52 | Remove { 53 | operation keep 54 | channels rgba 55 | name Remove1 56 | xpos 140 57 | ypos 130 58 | } 59 | MergeExpression { 60 | inputs 2 61 | channel0 rgb 62 | expr0 Br*Ar+Bg*Ag 63 | channel1 none 64 | channel2 none 65 | channel3 none 66 | name MergeExpression1 67 | xpos 140 68 | ypos 206 69 | } 70 | Dot { 71 | name Dot2 72 | tile_color 0x4b5ec600 73 | xpos 174 74 | ypos 364 75 | } 76 | push $N78454e0 77 | ShuffleCopy { 78 | inputs 2 79 | in2 none 80 | red red 81 | green green 82 | blue blue 83 | out {{{parent.vector_layer.in}}} 84 | name ShuffleCopy1 85 | xpos 0 86 | ypos 360 87 | } 88 | Output { 89 | name Output1 90 | xpos 0 91 | ypos 506 92 | } 93 | end_group 94 | -------------------------------------------------------------------------------- /nuke/Math/Vector2/MagnitudeVector2.nk: -------------------------------------------------------------------------------- 1 | Group { 2 | name MagnitudeVector2_ 3 | help "Calculate the magnitude (scalar) of an input Vector2." 4 | addUserKnob {20 main_tab l "Magnitude Vector2"} 5 | addUserKnob {41 in l "Vector B Layer" t "Layer containing the vector information for input B" T vector_layer.in} 6 | addUserKnob {26 ""} 7 | addUserKnob {26 copyright l "" +STARTLINE T "v1.0 - Mathieu Goulet-Aubin & Erwan Leroy - Github"} 8 | } 9 | Input { 10 | inputs 0 11 | name vectorB 12 | xpos 0 13 | } 14 | Dot { 15 | name Dot1 16 | tile_color 0xcccccc00 17 | xpos 34 18 | ypos 108 19 | } 20 | set N75db0d0 [stack 0] 21 | Shuffle { 22 | name vector_layer 23 | xpos 140 24 | ypos 104 25 | } 26 | Remove { 27 | operation keep 28 | channels rgba 29 | name Remove1 30 | xpos 140 31 | ypos 130 32 | } 33 | Expression { 34 | channel0 rgba 35 | expr0 sqrt((r*r)+(g*g)) 36 | channel2 {-rgba.red -rgba.green -rgba.blue none} 37 | channel3 {none none none -rgba.alpha} 38 | name Mag2 39 | xpos 140 40 | ypos 218 41 | } 42 | Dot { 43 | name Dot2 44 | tile_color 0xcccccc00 45 | xpos 174 46 | ypos 364 47 | } 48 | push $N75db0d0 49 | ShuffleCopy { 50 | inputs 2 51 | in2 none 52 | red red 53 | green green 54 | blue blue 55 | out {{{parent.vector_layer.in}}} 56 | name ShuffleCopy1 57 | xpos 0 58 | ypos 360 59 | } 60 | Output { 61 | name Output1 62 | xpos 0 63 | ypos 506 64 | } 65 | end_group 66 | -------------------------------------------------------------------------------- /nuke/Math/Vector2/NormalizeVector2.nk: -------------------------------------------------------------------------------- 1 | Group { 2 | name NormalizeVector2_ 3 | help "Normalize the magnitude of a Vector2 (to be of magnitude 1)" 4 | addUserKnob {20 main_tab l "Normalize Vector2"} 5 | addUserKnob {41 in l "Vector B Layer" t "Layer containing the vector information for input B" T vector_layer.in} 6 | addUserKnob {26 ""} 7 | addUserKnob {26 copyright l "" +STARTLINE T "v1.0 - Mathieu Goulet-Aubin & Erwan Leroy - Github"} 8 | } 9 | Input { 10 | inputs 0 11 | name vectorB 12 | xpos 0 13 | } 14 | Dot { 15 | name Dot1 16 | tile_color 0xcccccc00 17 | xpos 34 18 | ypos 108 19 | } 20 | set N78cf630 [stack 0] 21 | Shuffle { 22 | name vector_layer 23 | xpos 140 24 | ypos 104 25 | } 26 | Remove { 27 | operation keep 28 | channels rgba 29 | name Remove1 30 | xpos 140 31 | ypos 130 32 | } 33 | set N78e2f00 [stack 0] 34 | push $N78e2f00 35 | Expression { 36 | channel0 {rgba.red rgba.green -rgba.blue -rgba.alpha} 37 | expr0 sqrt((r*r)+(g*g)) 38 | channel1 {-rgba.red -rgba.green rgba.blue rgba.alpha} 39 | expr1 1 40 | channel2 {-rgba.red -rgba.green -rgba.blue none} 41 | channel3 {none none none -rgba.alpha} 42 | name Mag2 43 | xpos 289 44 | ypos 216 45 | } 46 | Merge2 { 47 | inputs 2 48 | operation divide 49 | bbox B 50 | name Merge1 51 | xpos 140 52 | ypos 267 53 | } 54 | Dot { 55 | name Dot2 56 | tile_color 0x4b5ec600 57 | xpos 174 58 | ypos 364 59 | } 60 | push $N78cf630 61 | ShuffleCopy { 62 | inputs 2 63 | in2 none 64 | red red 65 | green green 66 | blue blue 67 | out {{{parent.vector_layer.in}}} 68 | name ShuffleCopy1 69 | xpos 0 70 | ypos 360 71 | } 72 | Output { 73 | name Output1 74 | xpos 0 75 | ypos 506 76 | } 77 | end_group 78 | -------------------------------------------------------------------------------- /nuke/Math/Vector2/RotateVector2.nk: -------------------------------------------------------------------------------- 1 | Group { 2 | name RotateVector2_ 3 | help "Rotate a 2D vector on the same 2D plane." 4 | knobChanged "\nnode = nuke.thisNode()\nknob = nuke.thisKnob()\nif knob.name() == \"mode\":\n if knob.value() == \"Knob (Degrees 0-360)\":\n node\['angle'].setEnabled(True)\n else:\n node\['angle'].setEnabled(False)\n" 5 | addUserKnob {20 main_tab l "Rotate Vector2"} 6 | addUserKnob {41 in l "Vector B Layer" t "Layer containing the vector information for input B" T vector_layer.in} 7 | addUserKnob {4 mode l "Rotate by" t "Pick whether to rotate the input vector by:\nKnob (Degrees 0-360)\nAngle Map (Degrees 0-360)\nAngle Map (Degrees 0-1)\nAngle Map (Radians)\n\nAn Angle map is a single channel image (expected in red channel) that represents an angle value at each pixel." M {"Knob (Degrees 0-360)" "Angle Map (Degrees 0-360)" "Angle Map (Degrees 0-1)" "Angle Map (Radians)" "" "" ""}} 8 | addUserKnob {26 "" +STARTLINE} 9 | addUserKnob {7 angle l Angle R -180 180} 10 | addUserKnob {26 ""} 11 | addUserKnob {26 copyright l "" +STARTLINE T "v1.0 - Mathieu Goulet-Aubin & Erwan Leroy - Github"} 12 | } 13 | Input { 14 | inputs 0 15 | name angleMap 16 | xpos 479 17 | ypos 5 18 | number 1 19 | } 20 | Multiply { 21 | channels rgb 22 | value 360 23 | name Multiply_360 24 | xpos 479 25 | ypos 90 26 | disable {{parent.mode!=2}} 27 | } 28 | Expression { 29 | expr0 radians(r) 30 | name Degrees_to_Radians 31 | xpos 479 32 | ypos 132 33 | disable {{parent.mode==3}} 34 | } 35 | Dot { 36 | name Dot5 37 | tile_color 0xcccccc00 38 | xpos 513 39 | ypos 249 40 | } 41 | Input { 42 | inputs 0 43 | name vectorB 44 | xpos 0 45 | } 46 | Dot { 47 | name Dot1 48 | tile_color 0xcccccc00 49 | xpos 34 50 | ypos 108 51 | } 52 | set N8a49d10 [stack 0] 53 | Shuffle { 54 | name vector_layer 55 | xpos 140 56 | ypos 104 57 | } 58 | Remove { 59 | operation keep 60 | channels rgba 61 | name Remove1 62 | xpos 140 63 | ypos 130 64 | } 65 | Dot { 66 | name Dot3 67 | tile_color 0x9e3c6300 68 | xpos 174 69 | ypos 181 70 | } 71 | set N31f4270 [stack 0] 72 | Dot { 73 | name Dot4 74 | tile_color 0x9e3c6300 75 | xpos 372 76 | ypos 181 77 | } 78 | MergeExpression { 79 | inputs 2 80 | expr0 "Br * cos(Ar) - Bg * sin(Ar)" 81 | expr1 "Br * sin(Ar) + Bg * cos(Ar)" 82 | name MergeExpression1 83 | xpos 338 84 | ypos 245 85 | } 86 | Dot { 87 | name Dot6 88 | tile_color 0x4b5ec600 89 | xpos 372 90 | ypos 311 91 | } 92 | push $N31f4270 93 | Expression { 94 | temp_name0 angleRad 95 | temp_expr0 radians(parent.angle) 96 | expr0 "r * cos(angleRad) - g * sin(angleRad)" 97 | expr1 "r * sin(angleRad) + g * cos(angleRad)" 98 | name Rotation 99 | xpos 140 100 | ypos 240 101 | } 102 | Switch { 103 | inputs 2 104 | which {{parent.mode!=0}} 105 | name Switch1 106 | xpos 140 107 | ypos 307 108 | } 109 | Dot { 110 | name Dot2 111 | tile_color 0xcccccc00 112 | xpos 174 113 | ypos 364 114 | } 115 | push $N8a49d10 116 | ShuffleCopy { 117 | inputs 2 118 | in2 none 119 | red red 120 | green green 121 | blue blue 122 | out {{{parent.vector_layer.in}}} 123 | name ShuffleCopy1 124 | xpos 0 125 | ypos 360 126 | } 127 | Output { 128 | name Output1 129 | xpos 0 130 | ypos 506 131 | } 132 | end_group 133 | -------------------------------------------------------------------------------- /nuke/Math/Vector2/TransformVector2.nk: -------------------------------------------------------------------------------- 1 | Group { 2 | name TransformVector2_ 3 | help "Transforms an image assuming it is a motion vector in RGBA.\nCompared to a regular transform, this will edit the pixel colors to compensate for vector direction and magnitude.\n\nWarning: This node breaks concatenation." 4 | tile_color 0xc692ccff 5 | addUserKnob {20 transform l "Transform Vector2"} 6 | addUserKnob {41 matrix T Transform1.matrix} 7 | addUserKnob {41 translate T Transform1.translate} 8 | addUserKnob {41 rotate T Transform1.rotate} 9 | addUserKnob {41 scale T Transform1.scale} 10 | addUserKnob {41 skewX l "skew X" T Transform1.skewX} 11 | addUserKnob {41 skewY l "skew Y" T Transform1.skewY} 12 | addUserKnob {41 skew_order l "skew order" T Transform1.skew_order} 13 | addUserKnob {41 center T Transform1.center} 14 | addUserKnob {41 invert_matrix l invert T Transform1.invert_matrix} 15 | addUserKnob {41 filter T Transform1.filter} 16 | addUserKnob {41 clamp -STARTLINE T Transform1.clamp} 17 | addUserKnob {41 black_outside l "black outside" -STARTLINE T Transform1.black_outside} 18 | addUserKnob {41 motionblur T Transform1.motionblur} 19 | addUserKnob {41 shutter T Transform1.shutter} 20 | addUserKnob {41 shutteroffset l "shutter offset" T Transform1.shutteroffset} 21 | addUserKnob {41 shuttercustomoffset l "" -STARTLINE T Transform1.shuttercustomoffset} 22 | addUserKnob {26 ""} 23 | addUserKnob {26 copyright l "" +STARTLINE T "v1.0 - Mathieu Goulet-Aubin & Erwan Leroy - Github"} 24 | } 25 | Input { 26 | inputs 0 27 | name vectorB 28 | xpos -482 29 | ypos -5 30 | } 31 | set N9f70fb0 [stack 0] 32 | Transform { 33 | center {1024 778} 34 | shutteroffset centred 35 | name Transform1 36 | xpos -482 37 | ypos 92 38 | } 39 | set N9f756d0 [stack 0] 40 | ColorMatrix { 41 | matrix { 42 | {{"\[python nuke.toNode('Transform1')\\\['matrix'\\].value()\\\[0\\]]"} {"\[python nuke.toNode('Transform1')\\\['matrix'\\].value()\\\[4\\]]"} 0} 43 | {{"\[python nuke.toNode('Transform1')\\\['matrix'\\].value()\\\[1\\]]"} {"\[python nuke.toNode('Transform1')\\\['matrix'\\].value()\\\[5\\]]"} 0} 44 | {0 0 0} 45 | } 46 | name ColorMatrix1 47 | xpos -482 48 | ypos 172 49 | } 50 | Output { 51 | name Output1 52 | xpos -482 53 | ypos 232 54 | } 55 | push $N9f756d0 56 | push $N9f70fb0 57 | end_group 58 | -------------------------------------------------------------------------------- /nuke/Math/Vector3/CrossProductVector3.nk: -------------------------------------------------------------------------------- 1 | Group { 2 | name CrossProductVector3_ 3 | help "Calculates the cross product of 2 Vector3 inputs." 4 | addUserKnob {20 main_tab l "Cross Product Vector3"} 5 | addUserKnob {41 in l "Vector B Layer" t "Layer containing the vector information for input B" T vector_layer.in} 6 | addUserKnob {41 in_1 l "Vector A Layer" t "Layer containing the vector information for input A" T vector_layer1.in} 7 | addUserKnob {26 ""} 8 | addUserKnob {26 copyright l "" +STARTLINE T "v1.0 - Mathieu Goulet-Aubin & Erwan Leroy - Github"} 9 | } 10 | Input { 11 | inputs 0 12 | name vectorA 13 | xpos 457 14 | ypos -6 15 | number 1 16 | } 17 | Shuffle { 18 | name vector_layer1 19 | xpos 457 20 | ypos 103 21 | } 22 | Remove { 23 | operation keep 24 | channels rgba 25 | name Remove2 26 | xpos 457 27 | ypos 129 28 | } 29 | Dot { 30 | name Dot3 31 | tile_color 0x9e3c6300 32 | xpos 491 33 | ypos 210 34 | } 35 | Input { 36 | inputs 0 37 | name vectorB 38 | xpos 0 39 | } 40 | Dot { 41 | name Dot1 42 | tile_color 0xcccccc00 43 | xpos 34 44 | ypos 108 45 | } 46 | set N762f800 [stack 0] 47 | Shuffle { 48 | name vector_layer 49 | xpos 140 50 | ypos 104 51 | } 52 | Remove { 53 | operation keep 54 | channels rgba 55 | name Remove1 56 | xpos 140 57 | ypos 130 58 | } 59 | MergeExpression { 60 | inputs 2 61 | expr0 "Ag*Bb - Ab*Bg" 62 | expr1 "Ab*Br - Ar*Bb" 63 | expr2 "Ar*Bg - Ag*Br" 64 | name MergeExpression2 65 | xpos 140 66 | ypos 206 67 | } 68 | Dot { 69 | name Dot2 70 | tile_color 0x4b5ec600 71 | xpos 174 72 | ypos 364 73 | } 74 | push $N762f800 75 | ShuffleCopy { 76 | inputs 2 77 | in2 none 78 | red red 79 | green green 80 | blue blue 81 | out {{{parent.vector_layer.in}}} 82 | name ShuffleCopy1 83 | xpos 0 84 | ypos 360 85 | } 86 | Output { 87 | name Output1 88 | xpos 0 89 | ypos 506 90 | } 91 | end_group 92 | -------------------------------------------------------------------------------- /nuke/Math/Vector3/DotProductVector3.nk: -------------------------------------------------------------------------------- 1 | Group { 2 | name DotProductVector3_ 3 | help "Calculates the dot product of 2 Vector3 inputs." 4 | addUserKnob {20 main_tab l "Dot Product Vector3"} 5 | addUserKnob {41 in l "Vector B Layer" t "Layer containing the vector information for input B" T vector_layer.in} 6 | addUserKnob {41 in_1 l "Vector A Layer" t "Layer containing the vector information for input A" T vector_layer1.in} 7 | addUserKnob {26 ""} 8 | addUserKnob {26 copyright l "" +STARTLINE T "v1.0 - Mathieu Goulet-Aubin & Erwan Leroy - Github"} 9 | } 10 | Input { 11 | inputs 0 12 | name vectorA 13 | xpos 457 14 | ypos -6 15 | number 1 16 | } 17 | Shuffle { 18 | name vector_layer1 19 | xpos 457 20 | ypos 103 21 | } 22 | Remove { 23 | operation keep 24 | channels rgba 25 | name Remove2 26 | xpos 457 27 | ypos 129 28 | } 29 | Dot { 30 | name Dot3 31 | tile_color 0x9e3c6300 32 | xpos 491 33 | ypos 210 34 | } 35 | Input { 36 | inputs 0 37 | name vectorB 38 | xpos 0 39 | } 40 | Dot { 41 | name Dot1 42 | tile_color 0xcccccc00 43 | xpos 34 44 | ypos 108 45 | } 46 | set N79e48f0 [stack 0] 47 | Shuffle { 48 | name vector_layer 49 | xpos 140 50 | ypos 104 51 | } 52 | Remove { 53 | operation keep 54 | channels rgba 55 | name Remove1 56 | xpos 140 57 | ypos 130 58 | } 59 | MergeExpression { 60 | inputs 2 61 | channel0 rgb 62 | expr0 Br*Ar+Bg*Ag+Bb*Ab 63 | channel1 none 64 | channel2 none 65 | channel3 none 66 | name MergeExpression1 67 | xpos 140 68 | ypos 206 69 | } 70 | Dot { 71 | name Dot2 72 | tile_color 0x4b5ec600 73 | xpos 174 74 | ypos 364 75 | } 76 | push $N79e48f0 77 | ShuffleCopy { 78 | inputs 2 79 | in2 none 80 | red red 81 | green green 82 | blue blue 83 | out {{{parent.vector_layer.in}}} 84 | name ShuffleCopy1 85 | xpos 0 86 | ypos 360 87 | } 88 | Output { 89 | name Output1 90 | xpos 0 91 | ypos 506 92 | } 93 | end_group 94 | -------------------------------------------------------------------------------- /nuke/Math/Vector3/MagnitudeVector3.nk: -------------------------------------------------------------------------------- 1 | Group { 2 | name Magnitude_Vector3_ 3 | help "Calculate the magnitude (scalar) of an input Vector3." 4 | addUserKnob {20 main_tab l "Magnitude Vector3"} 5 | addUserKnob {41 in l "Vector B Layer" t "Layer containing the vector information for input B" T vector_layer.in} 6 | addUserKnob {26 ""} 7 | addUserKnob {26 copyright l "" +STARTLINE T "v1.0 - Mathieu Goulet-Aubin & Erwan Leroy - Github"} 8 | } 9 | Input { 10 | inputs 0 11 | name vectorB 12 | xpos 0 13 | } 14 | Dot { 15 | name Dot1 16 | tile_color 0xcccccc00 17 | xpos 34 18 | ypos 108 19 | } 20 | set N3f91a00 [stack 0] 21 | Shuffle { 22 | name vector_layer 23 | xpos 140 24 | ypos 104 25 | } 26 | Remove { 27 | operation keep 28 | channels rgba 29 | name Remove1 30 | xpos 140 31 | ypos 130 32 | } 33 | Expression { 34 | channel0 rgba 35 | expr0 sqrt((r*r)+(g*g)+(b*b)) 36 | channel2 {-rgba.red -rgba.green -rgba.blue none} 37 | channel3 {none none none -rgba.alpha} 38 | name Mag3 39 | xpos 140 40 | ypos 227 41 | } 42 | Dot { 43 | name Dot2 44 | tile_color 0xcccccc00 45 | xpos 174 46 | ypos 364 47 | } 48 | push $N3f91a00 49 | ShuffleCopy { 50 | inputs 2 51 | in2 none 52 | red red 53 | green green 54 | blue blue 55 | out {{{parent.vector_layer.in}}} 56 | name ShuffleCopy1 57 | xpos 0 58 | ypos 360 59 | } 60 | Output { 61 | name Output1 62 | xpos 0 63 | ypos 506 64 | } 65 | end_group 66 | -------------------------------------------------------------------------------- /nuke/Math/Vector3/MultiplyVector3Matrix3.nk: -------------------------------------------------------------------------------- 1 | Group { 2 | name MultiplyVector3Matrix3_ 3 | help "Multiply (transform) a Vector3 by a Matrix3. This is the equivalent of applying Rotation/Scale/Skew from a Matrix to the vector.\nA Matrix4 can be used, but the last row/column will be ignored." 4 | addUserKnob {20 main_tab l "Mutiply Vector3 Matrix3"} 5 | addUserKnob {26 ""} 6 | addUserKnob {26 copyright l "" +STARTLINE T "v1.0 - Mathieu Goulet-Aubin & Erwan Leroy - Github"} 7 | } 8 | Input { 9 | inputs 0 10 | name InputMatrix3 11 | xpos 402 12 | ypos 7 13 | number 1 14 | } 15 | Dot { 16 | name Dot3 17 | tile_color 0xcccccc00 18 | xpos 436 19 | ypos 62 20 | } 21 | add_layer {matrix0 matrix0.0 matrix0.1 matrix0.2 matrix0.3} 22 | Shuffle { 23 | in matrix0 24 | name Shuffle1 25 | label "in \[value in]-->out \[value out]" 26 | xpos 402 27 | ypos 109 28 | } 29 | set Ne478bfd0 [stack 0] 30 | add_layer {matrix1 matrix1.0 matrix1.1 matrix1.2 matrix1.3} 31 | Shuffle { 32 | in matrix1 33 | name Shuffle2 34 | label "in \[value in]-->out \[value out]" 35 | xpos 402 36 | ypos 147 37 | } 38 | set Nd8882950 [stack 0] 39 | add_layer {matrix2 matrix2.0 matrix2.1 matrix2.2 matrix2.3} 40 | Shuffle { 41 | in matrix2 42 | name Shuffle3 43 | label "in \[value in]-->out \[value out]" 44 | xpos 402 45 | ypos 185 46 | } 47 | set N2858d430 [stack 0] 48 | add_layer {matrix3 matrix3.0 matrix3.1 matrix3.2 matrix3.3} 49 | Shuffle { 50 | in matrix3 51 | name Shuffle4 52 | label "in \[value in]-->out \[value out]" 53 | xpos 402 54 | ypos 223 55 | } 56 | push $N2858d430 57 | Dot { 58 | name Dot7 59 | tile_color 0x9e3c6300 60 | xpos 343 61 | ypos 195 62 | } 63 | push $Nd8882950 64 | Dot { 65 | name Dot6 66 | tile_color 0x9e3c6300 67 | xpos 343 68 | ypos 157 69 | } 70 | push $Ne478bfd0 71 | Dot { 72 | name Dot5 73 | tile_color 0x9e3c6300 74 | xpos 343 75 | ypos 119 76 | } 77 | Input { 78 | inputs 0 79 | name InputVector3 80 | xpos 219 81 | ypos 8 82 | } 83 | Dot { 84 | name Dot4 85 | tile_color 0xcccccc00 86 | xpos 253 87 | ypos 115 88 | } 89 | BlinkScript { 90 | inputs 4 91 | recompileCount 12 92 | ProgramGroup 1 93 | KernelDescription "2 \"TransformVector3byMatrix3\" iterate pixelWise 156e29276da8287b847626148a2a784d9969b7d1a3ad81e28187d00a7aaafaca 5 \"src\" Read Point \"matrix0\" Read Point \"matrix1\" Read Point \"matrix2\" Read Point \"dst\" Write Point 0 0 0" 94 | kernelSource "kernel TransformVector3byMatrix3 : ImageComputationKernel\n\{\n Image src; // the input image\n Image matrix0; // the input image\n Image matrix1; // the input image\n Image matrix2; // the input image\n Image dst; // the output image\n\n void process() \{\n // Read the input image\n SampleType(src) input = src();\n SampleType(matrix0) m0 = matrix0();\n SampleType(matrix1) m1 = matrix1();\n SampleType(matrix2) m2 = matrix2();\n\n // Create the matrix object (matrix3 in this case)\n float3x3 matrix;\n matrix\[0]\[0] = m0.x;\n matrix\[0]\[1] = m0.y;\n matrix\[0]\[2] = m0.z;\n matrix\[1]\[0] = m1.x;\n matrix\[1]\[1] = m1.y;\n matrix\[1]\[2] = m1.z;\n matrix\[2]\[0] = m2.x;\n matrix\[2]\[1] = m2.y;\n matrix\[2]\[2] = m2.z;\n\n // Multiply the Matrix and the Vector\n float3 vector(input.x, input.y, input.z);\n vector = matrix*vector;\n\n // Write the result to the output image\n dst() = float4(vector.x, vector.y, vector.z, input.w);\n \}\n\};\n" 95 | rebuild "" 96 | rebuild_finalise "" 97 | name BlinkScript1 98 | xpos 219 99 | ypos 223 100 | } 101 | Output { 102 | name Output1 103 | xpos 219 104 | ypos 323 105 | } 106 | end_group 107 | -------------------------------------------------------------------------------- /nuke/Math/Vector3/NormalizeVector3.nk: -------------------------------------------------------------------------------- 1 | Group { 2 | name NormalizeVector3_ 3 | help "Normalize the magnitude of a Vector3 (to be of magnitude 1)" 4 | addUserKnob {20 main_tab l "Normalize Vector3"} 5 | addUserKnob {41 in l "Vector B Layer" t "Layer containing the vector information for input B" T vector_layer.in} 6 | addUserKnob {26 ""} 7 | addUserKnob {26 copyright l "" +STARTLINE T "v1.0 - Mathieu Goulet-Aubin & Erwan Leroy - Github"} 8 | } 9 | Input { 10 | inputs 0 11 | name vectorB 12 | xpos 0 13 | } 14 | Dot { 15 | name Dot1 16 | tile_color 0xcccccc00 17 | xpos 34 18 | ypos 108 19 | } 20 | set N792f390 [stack 0] 21 | Shuffle { 22 | name vector_layer 23 | xpos 140 24 | ypos 104 25 | } 26 | Remove { 27 | operation keep 28 | channels rgba 29 | name Remove1 30 | xpos 140 31 | ypos 130 32 | } 33 | Dot { 34 | name Dot3 35 | tile_color 0x9e3c6300 36 | xpos 174 37 | ypos 156 38 | } 39 | set Ne7eccb90 [stack 0] 40 | push $Ne7eccb90 41 | Dot { 42 | name Dot4 43 | tile_color 0x9e3c6300 44 | xpos 377 45 | ypos 156 46 | } 47 | Expression { 48 | channel0 rgba 49 | expr0 sqrt((r*r)+(g*g)+(b*b)) 50 | channel2 {-rgba.red -rgba.green -rgba.blue none} 51 | channel3 {none none none -rgba.alpha} 52 | name Mag3 53 | xpos 343 54 | ypos 209 55 | } 56 | Dot { 57 | name Dot5 58 | tile_color 0xcccccc00 59 | xpos 377 60 | ypos 271 61 | } 62 | Merge2 { 63 | inputs 2 64 | operation divide 65 | bbox B 66 | name Merge1 67 | xpos 140 68 | ypos 267 69 | } 70 | Dot { 71 | name Dot2 72 | tile_color 0x4b5ec600 73 | xpos 174 74 | ypos 364 75 | } 76 | push $N792f390 77 | ShuffleCopy { 78 | inputs 2 79 | in2 none 80 | red red 81 | green green 82 | blue blue 83 | out {{{parent.vector_layer.in}}} 84 | name ShuffleCopy1 85 | xpos 0 86 | ypos 360 87 | } 88 | Output { 89 | name Output1 90 | xpos 0 91 | ypos 506 92 | } 93 | end_group 94 | -------------------------------------------------------------------------------- /nuke/Math/Vector3/RotateVector3.nk: -------------------------------------------------------------------------------- 1 | Group { 2 | name RotateVector3_ 3 | help "Rotate a Vector3 in 3 dimensions." 4 | knobChanged "node = nuke.thisNode()\nknob = nuke.thisKnob()\nif knob.name() == \"mode\":\n if knob.value() == \"Knob\":\n node\['rotate'].setEnabled(True)\n node\['rot_order'].setEnabled(True)\n else:\n node\['rotate'].setEnabled(False)\n node\['rot_order'].setEnabled(False)\n" 5 | addUserKnob {20 main_tab l RotateVector3} 6 | addUserKnob {41 in l "Vector B Layer" t "Layer containing the vector information for input B" T vector_layer.in} 7 | addUserKnob {4 mode l "Rotate by" t "Either control the rotation by the knob present on this node, or via the Matrix input." M {Knob "Pixel Matrix" ""}} 8 | addUserKnob {26 ""} 9 | addUserKnob {4 rot_order l "rotation order" t "Specifies the order to apply euler angles to the rotation." M {XYZ XZY YXZ YZX ZXY ZYX "" "" ""}} 10 | rot_order ZXY 11 | addUserKnob {13 rotate} 12 | addUserKnob {26 ""} 13 | addUserKnob {26 copyright l "" +STARTLINE T "v1.0 - Mathieu Goulet-Aubin & Erwan Leroy - Github"} 14 | } 15 | Input { 16 | inputs 0 17 | name vectorB 18 | xpos 0 19 | ypos -30 20 | } 21 | Dot { 22 | name Dot1 23 | tile_color 0xcccccc00 24 | xpos 34 25 | ypos 72 26 | } 27 | set N101e6610 [stack 0] 28 | Shuffle { 29 | name vector_layer 30 | xpos 366 31 | ypos 68 32 | } 33 | Remove { 34 | operation keep 35 | channels rgba 36 | name Remove1 37 | xpos 366 38 | ypos 94 39 | } 40 | Dot { 41 | name Dot3 42 | tile_color 0x9e3c6300 43 | xpos 400 44 | ypos 156 45 | } 46 | set N102036e0 [stack 0] 47 | Dot { 48 | name Dot6 49 | tile_color 0x9e3c6300 50 | xpos 220 51 | ypos 156 52 | } 53 | Group { 54 | name Magnitude_Vector3_ 55 | help "Calculate the magnitude (scalar) of an input Vector3." 56 | xpos 186 57 | ypos 231 58 | addUserKnob {20 main_tab l "Magnitude Vector3"} 59 | addUserKnob {41 in l "Vector B Layer" t "Layer containing the vector information for input B" T vector_layer.in} 60 | addUserKnob {26 ""} 61 | addUserKnob {26 copyright l "" +STARTLINE T "v1.0 - Mathieu Goulet-Aubin & Erwan Leroy - Github"} 62 | } 63 | Input { 64 | inputs 0 65 | name vectorB 66 | xpos 0 67 | } 68 | Dot { 69 | name Dot1 70 | tile_color 0xcccccc00 71 | xpos 34 72 | ypos 108 73 | } 74 | set N10219760 [stack 0] 75 | Shuffle { 76 | name vector_layer 77 | xpos 140 78 | ypos 104 79 | } 80 | Remove { 81 | operation keep 82 | channels rgba 83 | name Remove1 84 | xpos 140 85 | ypos 130 86 | } 87 | Expression { 88 | channel0 rgba 89 | expr0 sqrt((r*r)+(g*g)+(b*b)) 90 | channel2 {-rgba.red -rgba.green -rgba.blue none} 91 | channel3 {none none none -rgba.alpha} 92 | name Mag3 93 | xpos 140 94 | ypos 227 95 | } 96 | Dot { 97 | name Dot2 98 | tile_color 0xcccccc00 99 | xpos 174 100 | ypos 364 101 | } 102 | push $N10219760 103 | ShuffleCopy { 104 | inputs 2 105 | in2 none 106 | red red 107 | green green 108 | blue blue 109 | out {{{parent.vector_layer.in}}} 110 | name ShuffleCopy1 111 | xpos 0 112 | ypos 360 113 | } 114 | Output { 115 | name Output1 116 | xpos 0 117 | ypos 506 118 | } 119 | end_group 120 | Dot { 121 | name Dot7 122 | tile_color 0xcccccc00 123 | xpos 220 124 | ypos 529 125 | } 126 | push $N102036e0 127 | Dot { 128 | name Dot4 129 | tile_color 0x9e3c6300 130 | xpos 556 131 | ypos 156 132 | } 133 | set N10261db0 [stack 0] 134 | Input { 135 | inputs 0 136 | name matrix 137 | xpos 614 138 | ypos -30 139 | number 1 140 | } 141 | CopyBBox { 142 | inputs 2 143 | name CopyBBox1 144 | xpos 614 145 | ypos 152 146 | } 147 | push $N10261db0 148 | Dot { 149 | name Dot5 150 | tile_color 0x9e3c6300 151 | xpos 556 152 | ypos 198 153 | } 154 | Group { 155 | inputs 2 156 | name MultiplyVector3Matrix3_2 157 | help "Multiply (transform) a Vector3 by a Matrix3. This is the equivalent of applying Rotation/Scale/Skew from a Matrix to the vector.\nA Matrix4 can be used, but the last row/column will be ignored." 158 | xpos 614 159 | ypos 195 160 | addUserKnob {20 main_tab l "Mutiply Vector3 Matrix3"} 161 | addUserKnob {26 ""} 162 | addUserKnob {26 copyright l "" +STARTLINE T "v1.0 - Mathieu Goulet-Aubin & Erwan Leroy - Github"} 163 | } 164 | Input { 165 | inputs 0 166 | name InputMatrix3 167 | xpos 402 168 | ypos 7 169 | number 1 170 | } 171 | Dot { 172 | name Dot3 173 | tile_color 0xcccccc00 174 | xpos 436 175 | ypos 62 176 | } 177 | add_layer {matrix0 matrix0.0 matrix0.1 matrix0.2 matrix0.3} 178 | Shuffle { 179 | in matrix0 180 | name Shuffle1 181 | label "in \[value in]-->out \[value out]" 182 | xpos 402 183 | ypos 109 184 | } 185 | set N102888a0 [stack 0] 186 | add_layer {matrix1 matrix1.0 matrix1.1 matrix1.2 matrix1.3} 187 | Shuffle { 188 | in matrix1 189 | name Shuffle2 190 | label "in \[value in]-->out \[value out]" 191 | xpos 402 192 | ypos 147 193 | } 194 | set N10298df0 [stack 0] 195 | add_layer {matrix2 matrix2.0 matrix2.1 matrix2.2 matrix2.3} 196 | Shuffle { 197 | in matrix2 198 | name Shuffle3 199 | label "in \[value in]-->out \[value out]" 200 | xpos 402 201 | ypos 185 202 | } 203 | set N102a9320 [stack 0] 204 | add_layer {matrix3 matrix3.0 matrix3.1 matrix3.2 matrix3.3} 205 | Shuffle { 206 | in matrix3 207 | name Shuffle4 208 | label "in \[value in]-->out \[value out]" 209 | xpos 402 210 | ypos 223 211 | } 212 | push $N102a9320 213 | Dot { 214 | name Dot7 215 | tile_color 0x9e3c6300 216 | xpos 343 217 | ypos 195 218 | } 219 | push $N10298df0 220 | Dot { 221 | name Dot6 222 | tile_color 0x9e3c6300 223 | xpos 343 224 | ypos 157 225 | } 226 | push $N102888a0 227 | Dot { 228 | name Dot5 229 | tile_color 0x9e3c6300 230 | xpos 343 231 | ypos 119 232 | } 233 | Input { 234 | inputs 0 235 | name InputVector3 236 | xpos 219 237 | ypos 8 238 | } 239 | Dot { 240 | name Dot4 241 | tile_color 0xcccccc00 242 | xpos 253 243 | ypos 115 244 | } 245 | BlinkScript { 246 | inputs 4 247 | recompileCount 12 248 | ProgramGroup 1 249 | KernelDescription "2 \"TransformVector3byMatrix3\" iterate pixelWise 156e29276da8287b847626148a2a784d9969b7d1a3ad81e28187d00a7aaafaca 5 \"src\" Read Point \"matrix0\" Read Point \"matrix1\" Read Point \"matrix2\" Read Point \"dst\" Write Point 0 0 0" 250 | kernelSource "kernel TransformVector3byMatrix3 : ImageComputationKernel\n\{\n Image src; // the input image\n Image matrix0; // the input image\n Image matrix1; // the input image\n Image matrix2; // the input image\n Image dst; // the output image\n\n void process() \{\n // Read the input image\n SampleType(src) input = src();\n SampleType(matrix0) m0 = matrix0();\n SampleType(matrix1) m1 = matrix1();\n SampleType(matrix2) m2 = matrix2();\n\n // Create the matrix object (matrix3 in this case)\n float3x3 matrix;\n matrix\[0]\[0] = m0.x;\n matrix\[0]\[1] = m0.y;\n matrix\[0]\[2] = m0.z;\n matrix\[1]\[0] = m1.x;\n matrix\[1]\[1] = m1.y;\n matrix\[1]\[2] = m1.z;\n matrix\[2]\[0] = m2.x;\n matrix\[2]\[1] = m2.y;\n matrix\[2]\[2] = m2.z;\n\n // Multiply the Matrix and the Vector\n float3 vector(input.x, input.y, input.z);\n vector = matrix*vector;\n\n // Write the result to the output image\n dst() = float4(vector.x, vector.y, vector.z, input.w);\n \}\n\};\n" 251 | rebuild "" 252 | rebuild_finalise "" 253 | name BlinkScript1 254 | xpos 219 255 | ypos 223 256 | } 257 | Output { 258 | name Output1 259 | xpos 219 260 | ypos 323 261 | } 262 | end_group 263 | Dot { 264 | name Dot2 265 | tile_color 0xcccccc00 266 | xpos 648 267 | ypos 364 268 | } 269 | push $N102036e0 270 | ColorMatrix { 271 | matrix { 272 | {{Axis1.world_matrix.0} {Axis1.world_matrix.1} {Axis1.world_matrix.2}} 273 | {{Axis1.world_matrix.4} {Axis1.world_matrix.5} {Axis1.world_matrix.6}} 274 | {{Axis1.world_matrix.8} {Axis1.world_matrix.9} {Axis1.world_matrix.10}} 275 | } 276 | name ColorMatrix1 277 | xpos 366 278 | ypos 269 279 | } 280 | Switch { 281 | inputs 2 282 | which {{parent.mode}} 283 | name Switch1 284 | xpos 366 285 | ypos 360 286 | } 287 | Group { 288 | name NormalizeVector3_ 289 | help "Normalize the magnitude of a Vector3 (to be of magnitude 1)" 290 | xpos 366 291 | ypos 450 292 | addUserKnob {20 main_tab l "Normalize Vector3"} 293 | addUserKnob {41 in l "Vector B Layer" t "Layer containing the vector information for input B" T vector_layer.in} 294 | addUserKnob {26 ""} 295 | addUserKnob {26 copyright l "" +STARTLINE T "v1.0 - Mathieu Goulet-Aubin & Erwan Leroy - Github"} 296 | } 297 | Input { 298 | inputs 0 299 | name vectorB 300 | xpos 0 301 | } 302 | Dot { 303 | name Dot1 304 | tile_color 0xcccccc00 305 | xpos 34 306 | ypos 108 307 | } 308 | set N1031bd80 [stack 0] 309 | Shuffle { 310 | name vector_layer 311 | xpos 140 312 | ypos 104 313 | } 314 | Remove { 315 | operation keep 316 | channels rgba 317 | name Remove1 318 | xpos 140 319 | ypos 130 320 | } 321 | Dot { 322 | name Dot3 323 | tile_color 0x9e3c6300 324 | xpos 174 325 | ypos 156 326 | } 327 | set N10338e50 [stack 0] 328 | push $N10338e50 329 | Dot { 330 | name Dot4 331 | tile_color 0x9e3c6300 332 | xpos 377 333 | ypos 156 334 | } 335 | Expression { 336 | channel0 rgba 337 | expr0 sqrt((r*r)+(g*g)+(b*b)) 338 | channel2 {-rgba.red -rgba.green -rgba.blue none} 339 | channel3 {none none none -rgba.alpha} 340 | name Mag3 341 | xpos 343 342 | ypos 209 343 | } 344 | Dot { 345 | name Dot5 346 | tile_color 0xcccccc00 347 | xpos 377 348 | ypos 271 349 | } 350 | Merge2 { 351 | inputs 2 352 | operation divide 353 | bbox B 354 | name Merge1 355 | xpos 140 356 | ypos 267 357 | } 358 | Dot { 359 | name Dot2 360 | tile_color 0x4b5ec600 361 | xpos 174 362 | ypos 364 363 | } 364 | push $N1031bd80 365 | ShuffleCopy { 366 | inputs 2 367 | in2 none 368 | red red 369 | green green 370 | blue blue 371 | out {{{parent.vector_layer.in}}} 372 | name ShuffleCopy1 373 | xpos 0 374 | ypos 360 375 | } 376 | Output { 377 | name Output1 378 | xpos 0 379 | ypos 506 380 | } 381 | end_group 382 | Merge2 { 383 | inputs 2 384 | operation multiply 385 | bbox B 386 | name Merge1 387 | xpos 366 388 | ypos 525 389 | } 390 | Dot { 391 | name Dot8 392 | tile_color 0x4b5ec600 393 | xpos 400 394 | ypos 601 395 | } 396 | push $N101e6610 397 | ShuffleCopy { 398 | inputs 2 399 | in2 none 400 | red red 401 | green green 402 | blue blue 403 | out {{{parent.vector_layer.in}}} 404 | name ShuffleCopy1 405 | xpos 0 406 | ypos 597 407 | } 408 | Output { 409 | name Output1 410 | xpos 0 411 | ypos 671 412 | } 413 | Axis2 { 414 | inputs 0 415 | rot_order {{parent.rot_order x1 2}} 416 | rotate {{parent.rotate.x} {parent.rotate.y} {parent.rotate.z}} 417 | name Axis1 418 | xpos 471 419 | ypos 252 420 | } 421 | end_group 422 | -------------------------------------------------------------------------------- /nuke/Math/Vector3/TransformVector3.nk: -------------------------------------------------------------------------------- 1 | Group { 2 | name TransformVector3_ 3 | help "Transform a Vector3 in 3 dimensions." 4 | addUserKnob {20 main_tab l "Normalize Vector3"} 5 | addUserKnob {4 matrix_source l "Use matrix from" t "The vectors can be transformed either by the an Axis connected to the Axis input, or a pixel matrix connected to the matrix input.\nOnly one can be used at once." M {Axis "Pixel Matrix"}} 6 | addUserKnob {6 is_vec4 l "Use alpha as vector W" t "4x4 Matrices can only transform vectors of dimention 4. The common method to transform a vecor3 with a matrix4 is to promote the vector3 to a vector4 by setting the w dimention to 1.\nBy checking this box, the vector w will be set to the alpha value instead. Only use if you know what you are trying to achieve." +STARTLINE} 7 | addUserKnob {6 normalize l "Normalize result" t "When enabled, the resulting vector is divided by the vector.w after the transformation.\nFor some type of transformations (for example 3d to 2d projection), this step may be required." -STARTLINE} 8 | normalize true 9 | addUserKnob {6 invert l Invert t "Invert the transform Matrix" -STARTLINE} 10 | addUserKnob {41 mix T Merge1.mix} 11 | addUserKnob {26 ""} 12 | addUserKnob {26 copyright l "" +STARTLINE T "v1.0 - Mathieu Goulet-Aubin & Erwan Leroy - Github"} 13 | } 14 | Input { 15 | inputs 0 16 | name axis 17 | xpos 546 18 | ypos -298 19 | number 2 20 | } 21 | Axis2 { 22 | useMatrix true 23 | name MatrixKnob 24 | xpos 556 25 | ypos -206 26 | } 27 | Input { 28 | inputs 0 29 | name matrix 30 | xpos 358 31 | ypos -303 32 | number 1 33 | } 34 | Input { 35 | inputs 0 36 | name vector3 37 | xpos 0 38 | ypos -315 39 | } 40 | Dot { 41 | name Dot1 42 | tile_color 0xcccccc00 43 | xpos 34 44 | ypos -190 45 | } 46 | set Nf115350 [stack 0] 47 | add_layer {matrix0 matrix0.0 matrix0.1 matrix0.2 matrix0.3} 48 | Expression { 49 | channel0 {matrix0.0 -matrix0.1 -matrix0.2 -matrix0.3} 50 | expr0 MatrixKnob.world_matrix.0 51 | channel1 {-matrix0.0 matrix0.1 -matrix0.2 -matrix0.3} 52 | expr1 MatrixKnob.world_matrix.1 53 | channel2 {-matrix0.0 -matrix0.1 matrix0.2 -matrix0.3} 54 | expr2 MatrixKnob.world_matrix.2 55 | channel3 {-matrix0.0 -matrix0.1 -matrix0.2 matrix0.3} 56 | expr3 MatrixKnob.world_matrix.3 57 | name Expression1 58 | xpos 195 59 | ypos -193 60 | } 61 | add_layer {matrix1 matrix1.0 matrix1.1 matrix1.2 matrix1.3} 62 | Expression { 63 | channel0 {matrix1.0 -matrix1.1 -matrix1.2 -matrix1.3} 64 | expr0 MatrixKnob.world_matrix.4 65 | channel1 {-matrix1.0 matrix1.1 -matrix1.2 -matrix1.3} 66 | expr1 MatrixKnob.world_matrix.5 67 | channel2 {-matrix1.0 -matrix1.1 matrix1.2 -matrix1.3} 68 | expr2 MatrixKnob.world_matrix.6 69 | channel3 {-matrix1.0 -matrix1.1 -matrix1.2 matrix1.3} 70 | expr3 MatrixKnob.world_matrix.7 71 | name Expression2 72 | xpos 195 73 | ypos -169 74 | } 75 | add_layer {matrix2 matrix2.0 matrix2.1 matrix2.2 matrix2.3} 76 | Expression { 77 | channel0 {matrix2.0 -matrix2.1 -matrix2.2 -matrix2.3} 78 | expr0 MatrixKnob.world_matrix.8 79 | channel1 {-matrix2.0 matrix2.1 -matrix2.2 -matrix2.3} 80 | expr1 MatrixKnob.world_matrix.9 81 | channel2 {-matrix2.0 -matrix2.1 matrix2.2 -matrix2.3} 82 | expr2 MatrixKnob.world_matrix.10 83 | channel3 {-matrix2.0 -matrix2.1 -matrix2.2 matrix2.3} 84 | expr3 MatrixKnob.world_matrix.11 85 | name Expression3 86 | xpos 195 87 | ypos -145 88 | } 89 | add_layer {matrix3 matrix3.0 matrix3.1 matrix3.2 matrix3.3} 90 | Expression { 91 | channel0 {matrix3.0 -matrix3.1 -matrix3.2 -matrix3.3} 92 | expr0 MatrixKnob.world_matrix.12 93 | channel1 {-matrix3.0 matrix3.1 -matrix3.2 -matrix3.3} 94 | expr1 MatrixKnob.world_matrix.13 95 | channel2 {-matrix3.0 -matrix3.1 matrix3.2 -matrix3.3} 96 | expr2 MatrixKnob.world_matrix.14 97 | channel3 {-matrix3.0 -matrix3.1 -matrix3.2 matrix3.3} 98 | expr3 MatrixKnob.world_matrix.15 99 | name Expression4 100 | xpos 195 101 | ypos -121 102 | } 103 | Dot { 104 | name Dot2 105 | tile_color 0xcccccc00 106 | xpos 229 107 | ypos -36 108 | } 109 | Switch { 110 | inputs 2 111 | which {{parent.matrix_source}} 112 | name Switch1 113 | xpos 358 114 | ypos -39 115 | } 116 | Shuffle { 117 | in matrix0 118 | name Shuffle1 119 | label "in \[value in]-->out \[value out]" 120 | xpos 358 121 | ypos 107 122 | } 123 | set Ne5f8350 [stack 0] 124 | Shuffle { 125 | in matrix1 126 | name Shuffle2 127 | label "in \[value in]-->out \[value out]" 128 | xpos 358 129 | ypos 147 130 | } 131 | set Ne68eb10 [stack 0] 132 | Shuffle { 133 | in matrix2 134 | name Shuffle3 135 | label "in \[value in]-->out \[value out]" 136 | xpos 358 137 | ypos 183 138 | } 139 | set Ne36aef0 [stack 0] 140 | Shuffle { 141 | in matrix3 142 | name Shuffle4 143 | label "in \[value in]-->out \[value out]" 144 | xpos 358 145 | ypos 220 146 | } 147 | push $Ne36aef0 148 | push $Ne68eb10 149 | push $Ne5f8350 150 | push $Nf115350 151 | Dot { 152 | name Dot3 153 | tile_color 0xcccccc00 154 | xpos 30 155 | ypos 165 156 | } 157 | set N119252d0 [stack 0] 158 | BlinkScript { 159 | inputs 5 160 | recompileCount 18 161 | ProgramGroup 1 162 | KernelDescription "2 \"TransformVector4\" iterate pixelWise e9bfb03cdbf363d4b657df0f835e68dba3bb796a594c3822ebad3f28e4e0e81c 6 \"src\" Read Point \"matrix0\" Read Point \"matrix1\" Read Point \"matrix2\" Read Point \"matrix3\" Read Point \"dst\" Write Point 3 \"Input is Vector 4\" Bool 1 AA== \"Divide by W\" Bool 1 AQ== \"Invert Transform\" Bool 1 AA== 3 \"is_vector4\" 1 1 \"do_normalization\" 1 1 \"invert\" 1 1 0" 163 | kernelSource "kernel TransformVector4 : ImageComputationKernel\n\{\n Image src; // the input image\n Image matrix0; // the input image\n Image matrix1; // the input image\n Image matrix2; // the input image\n Image matrix3; // the input image\n Image dst; // the output image\n\n param:\n bool is_vector4; \n bool do_normalization; \n bool invert;\n\n // In define(), parameters can be given labels and default values.\n void define() \{\n defineParam(is_vector4, \"Input is Vector 4\", false);\n defineParam(do_normalization, \"Divide by W\", true);\n defineParam(invert, \"Invert Transform\", false);\n \}\n\n void process() \{\n // Read the input image\n SampleType(src) vector = src();\n SampleType(matrix0) m0 = matrix0();\n SampleType(matrix1) m1 = matrix1();\n SampleType(matrix2) m2 = matrix2();\n SampleType(matrix3) m3 = matrix3();\n\n // Create the matrix object (matrix3 in this case)\n float4x4 matrix;\n matrix\[0]\[0] = m0.x;\n matrix\[0]\[1] = m0.y;\n matrix\[0]\[2] = m0.z;\n matrix\[0]\[3] = m0.w;\n matrix\[1]\[0] = m1.x;\n matrix\[1]\[1] = m1.y;\n matrix\[1]\[2] = m1.z;\n matrix\[1]\[3] = m1.w;\n matrix\[2]\[0] = m2.x;\n matrix\[2]\[1] = m2.y;\n matrix\[2]\[2] = m2.z;\n matrix\[2]\[3] = m2.w;\n matrix\[3]\[0] = m3.x;\n matrix\[3]\[1] = m3.y;\n matrix\[3]\[2] = m3.z;\n matrix\[3]\[3] = m3.w;\n\n if (invert) \{\n matrix = matrix.invert();\n \}\n\n // Transform\n float a = vector.w;\n if (!is_vector4) \{\n vector.w = 1.0f;\n \}\n vector = matrix*vector;\n if (do_normalization) \{\n vector = vector/vector.w;\n \}\n if (!is_vector4) \{\n vector.w = a;\n \}\n\n // Write the result to the output image\n dst() = float4(vector.x, vector.y, vector.z, vector.w);\n \}\n\};\n" 164 | rebuild "" 165 | "TransformVector4_Input is Vector 4" {{parent.is_vec4}} 166 | "TransformVector4_Divide by W" {{parent.normalize}} 167 | "TransformVector4_Invert Transform" {{parent.invert}} 168 | rebuild_finalise "" 169 | name BlinkScript1 170 | xpos 128 171 | ypos 156 172 | } 173 | Dot { 174 | name Dot4 175 | tile_color 0xcccccc00 176 | xpos 162 177 | ypos 296 178 | } 179 | push $N119252d0 180 | Merge2 { 181 | inputs 2 182 | operation copy 183 | bbox B 184 | name Merge1 185 | xpos -4 186 | ypos 293 187 | } 188 | Output { 189 | name Output1 190 | xpos -4 191 | ypos 544 192 | } 193 | end_group 194 | -------------------------------------------------------------------------------- /transform_utils/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mapoga/nuke-vector-matrix/b55276cd253bab70a09b5ef63ef04c5718d09bab/transform_utils/__init__.py -------------------------------------------------------------------------------- /transform_utils/rotation_filters.py: -------------------------------------------------------------------------------- 1 | import nuke 2 | import nukescripts 3 | from math import pi, degrees, radians 4 | 5 | 6 | # Math Functions 7 | 8 | 9 | def split_axis_order(order='XYZ'): 10 | """ Converts a string 'XYZ' into a list of the corresponding indices: [0, 1, 2] 11 | 12 | :param str order: A string containing the letters X, Y or Z, in any order. 13 | :return: List of axis indices. 14 | """ 15 | axis_map = {'x': 0, 'y': 1, 'z': 2} 16 | return [axis_map[axis] for axis in order.lower()] 17 | 18 | 19 | def flip_euler(euler, rotation_order): 20 | axis0, axis1, axis2 = split_axis_order(rotation_order) 21 | 22 | flipped = list(euler) 23 | flipped[axis0] += pi 24 | flipped[axis1] *= -1 25 | flipped[axis1] += pi 26 | flipped[axis2] += pi 27 | return flipped 28 | 29 | 30 | def euler_filter_1d(previous, current): 31 | """ Naively rotates the current angle until it's as close as possible to the previous angle 32 | 33 | :param float previous: Previous angle in radians 34 | :param float current: Current angle in radians 35 | :return: Modified current angle towards previous angle. 36 | """ 37 | while abs(previous - current) > pi: 38 | if previous < current: 39 | current -= 2 * pi 40 | else: 41 | current += 2 * pi 42 | 43 | return current 44 | 45 | 46 | def distance_squared(vec1, vec2): 47 | """ Calculate distance between two vector3 represented as lists of len 3 48 | 49 | :param list vec1: List of 3 floats 50 | :param list vec2: List of 3 floats 51 | :return: Squared distance between the 2 vectors 52 | """ 53 | return (vec1[0] - vec2[0])**2 + (vec1[1] - vec2[1])**2 + (vec1[2] - vec2[2])**2 54 | 55 | 56 | def euler_filter_3d(previous, current, rotation_order="XYZ"): 57 | """ Attempts to minimize the amount of rotation between the current orientation and the previous one. 58 | 59 | Orientations are preserved, but amount of rotation is minimized. 60 | 61 | :param list previous: Previous XYZ rotation values as a vector 62 | :param list current: Current XYZ rotation values as a vector 63 | :param str rotation_order: String representing the rotation order (ex: "XYZ" or "ZXY") 64 | :return: Modified angles to minimize rotation 65 | :rtype: list 66 | """ 67 | # Start with a pass of Naive 1D filtering 68 | filtered = list(current) 69 | for axis in range(3): 70 | filtered[axis] = euler_filter_1d(previous[axis], filtered[axis]) 71 | 72 | # Then flip the whole thing and do another pass of Naive filtering 73 | flipped = flip_euler(filtered, rotation_order) 74 | for axis in range(3): 75 | flipped[axis] = euler_filter_1d(previous[axis], flipped[axis]) 76 | 77 | # Return the vector with the shortest distance from the target value. 78 | if distance_squared(filtered, previous) > distance_squared(flipped, previous): 79 | return flipped 80 | return filtered 81 | 82 | 83 | def match_target_rotation_1d(current, target_rotation): 84 | """ Applies 360 degree (2pi radians) rotations to a value to approach a target value, 85 | without modifying apparent orientation""" 86 | while abs(target_rotation - current) > pi: 87 | if current < target_rotation: 88 | current += 2 * pi 89 | else: 90 | current -= 2 * pi 91 | 92 | return current 93 | 94 | 95 | # Nuke functions 96 | class CurveList: 97 | def __init__(self, knob): 98 | values = [] 99 | # TODO: Test behavior on multiview scripts 100 | for channel in range(knob.arraySize()): 101 | curve = knob.animation(channel) 102 | if curve is None: 103 | knob.setAnimated(channel) 104 | curve = knob.animation(channel) 105 | values.append(curve) 106 | self.list = values 107 | 108 | def __getitem__(self, idx): 109 | return self.list[idx] 110 | 111 | def __len__(self): 112 | return len(self.list) 113 | 114 | def value_at(self, frame, convert_to_rad=False): 115 | if len(self) == 1: 116 | value = self[0].evaluate(frame) 117 | if convert_to_rad: 118 | value = radians(value) 119 | return [value] 120 | else: 121 | values = [curve.evaluate(frame) for curve in self.list] 122 | if convert_to_rad: 123 | values = [radians(val) for val in values] 124 | return values 125 | 126 | def set_values_at(self, values, frame, convert_to_deg=False): 127 | if len(values) != len(self): 128 | raise ValueError("Number of values to set doesn't match number of curves") 129 | if convert_to_deg: 130 | values = [degrees(value) for value in values] 131 | for idx, value in enumerate(values): 132 | self.list[idx].setKey(frame, value) 133 | 134 | def get_all_keyframes(self): 135 | return sorted(list(set([key.x for curve in self.list for key in curve.keys()]))) 136 | 137 | 138 | def euler_filter(knob, use_3d=False, rotation_order=None, use_degrees=True): 139 | curves = CurveList(knob) 140 | keyframes = curves.get_all_keyframes() 141 | new_keys = [] 142 | previous = None 143 | 144 | for frame in keyframes: 145 | current = curves.value_at(frame, convert_to_rad=use_degrees) 146 | if previous is not None: # This filters out the first keyframe 147 | if use_3d: 148 | current = euler_filter_3d(previous, current, rotation_order) 149 | else: 150 | current = [euler_filter_1d(previous[0], current[0])] # Value is in a list for consistency with 3d 151 | 152 | new_keys.append(current) 153 | previous = current 154 | 155 | for frame, value in zip(keyframes, new_keys): 156 | curves.set_values_at(value, frame, convert_to_deg=use_degrees) 157 | 158 | 159 | def angular_velocity_filter(knob, use_degrees=True): 160 | """ Naive angular velocity filter, calculates velocity on a per axis basis """ 161 | curves = CurveList(knob) 162 | keyframes = curves.get_all_keyframes() 163 | new_keys = [] 164 | velocities = [] 165 | previous = None 166 | previous_frame = None 167 | 168 | for frame in keyframes: 169 | current = curves.value_at(frame, convert_to_rad=use_degrees) 170 | if previous is not None: # This filters out the first keyframe 171 | if velocities: 172 | for channel in range(len(current)): 173 | current_value = match_target_rotation_1d( 174 | current=current[channel], 175 | target_rotation=previous[channel] + velocities[channel] * (frame - previous_frame)) 176 | current[channel] = current_value 177 | # Calculate new velocities 178 | velocities = [(c-p)/(frame-previous_frame) for p, c in zip(previous, current)] 179 | 180 | new_keys.append(current) 181 | previous = current 182 | previous_frame = frame 183 | 184 | for frame, value in zip(keyframes, new_keys): 185 | curves.set_values_at(value, frame, convert_to_deg=use_degrees) 186 | 187 | 188 | def setup_filter_rotations(knob=None): 189 | print("AAAAAAA") 190 | 191 | valid_rotation_orders = ['XYZ', 'XZY', 'YXZ', 'YZX', 'ZXY', 'ZYX'] 192 | strategies = ["Minimum Rotation (Euler Filter)", "Preserve Angular Velocity"] 193 | #strategies_3d = ["Minimum Rotation (Euler Filter)"] # 3d Angular Velocity needs to be figured out (but could try Naive Angular, on a per curve basis) 194 | 195 | if knob is None: 196 | knob = nuke.thisKnob() 197 | 198 | rotation_order = None 199 | 200 | if knob.Class() == 'XYZ_Knob': 201 | use_3d_filter = True 202 | elif knob.Class() == 'Double_Knob': 203 | use_3d_filter = False 204 | else: 205 | raise ValueError("Don't know how to apply a rotation filter on knobs of type %s" % knob.Class()) 206 | 207 | node = knob.node() 208 | # Figure out if the node has a built-in rotation order 209 | if rotation_order is None and node.knob('rot_order'): 210 | value = node.knob('rot_order').value() 211 | if value in valid_rotation_orders: 212 | rotation_order = value 213 | 214 | # Build panel 215 | panel = RotationFilterPanel( 216 | strategies, 217 | rotation_orders=valid_rotation_orders if use_3d_filter and rotation_order is None else None) 218 | 219 | if panel.showModalDialog(): 220 | strategy = strategies.index(panel.strategy.value()) 221 | use_degrees = panel.unit.value() == 'Degrees' 222 | if strategy == 0: 223 | if use_3d_filter and rotation_order is None: 224 | rotation_order = panel.rotation_order.value() 225 | euler_filter(knob, use_3d_filter, rotation_order, use_degrees) 226 | elif strategy == 1: 227 | angular_velocity_filter(knob, use_degrees) 228 | 229 | 230 | # Panel Classes 231 | class RotationFilterPanel(nukescripts.PythonPanel): 232 | """ Panel presenting options for merging transforms """ 233 | def __init__(self, strategies, rotation_orders=None): 234 | nukescripts.PythonPanel.__init__(self, 'Rotation Filter') 235 | 236 | # CREATE KNOBS 237 | self.strategy = nuke.Enumeration_Knob('strategy', 'Filter Strategy', strategies) 238 | self.strategy.setTooltip('Pick a strategy for rotation filtering. Results might differ based on picked strategy') 239 | self.addKnob(self.strategy) 240 | 241 | if rotation_orders: 242 | self.rotation_order = nuke.Enumeration_Knob('rot_order', 'Rotation Order', rotation_orders) 243 | self.addKnob(self.rotation_order) 244 | 245 | self.unit = nuke.Enumeration_Knob('unit', 'Angle Units', ['Degrees', 'Radians']) 246 | self.addKnob(self.unit) 247 | -------------------------------------------------------------------------------- /transform_utils/tracker4_api.py: -------------------------------------------------------------------------------- 1 | """ 2 | Shim to give the Tracker4 node a slightly more convenient API, closer to interacting with regular Nuke knobs. 3 | While it can do a lot of things conveniently, it's not as fast as some direct manipulation as it may parse 4 | values multiple times while doing some operations. 5 | 6 | Examples: 7 | 8 | tracker = Tracker(nuke.toNode('Tracker1')) 9 | point = tracker.add_point('My Tracker') 10 | point['T'].setValue(True) 11 | for point in tracker: 12 | point['R'].setValue(False) 13 | 14 | # Point can be obtained by name or index 15 | first_point = tracker[0] 16 | mine = tracker['My Tracker'] 17 | 18 | """ 19 | import nuke 20 | 21 | 22 | class Tracker(object): 23 | _columns = None 24 | 25 | def __init__(self, node): 26 | if not node.Class() == 'Tracker4': 27 | raise ValueError("Tracker4 node required, got {}".format(node.Class())) 28 | self.node = node 29 | self.knob = node['tracks'] 30 | self._parser = TCLListParser() 31 | 32 | def __getitem__(self, item): 33 | if not isinstance(item, int): 34 | item = self.point_names.index(item) 35 | n_points = len(self) 36 | if item >= n_points: 37 | return None 38 | if item < 0: # Support negative indices 39 | item = n_points+item 40 | if item < 0: 41 | return None 42 | return TrackerPoint(self, item) 43 | 44 | def __contains__(self, item): 45 | if not isinstance(item, int): 46 | try: 47 | item = self.point_names.index(item) 48 | except ValueError: 49 | return False 50 | if item >= len(self): 51 | return False 52 | if item < 0: 53 | return False 54 | return True 55 | 56 | def __len__(self): 57 | return len(self.get_internals()[2]) 58 | 59 | def __iter__(self): 60 | for i in range(len(self)): 61 | yield self[i] 62 | 63 | @staticmethod 64 | def _get_point_names(internals): 65 | return [p[1] for p in internals[2]] 66 | 67 | def get_internals(self): 68 | tcl_list = self.knob.toScript() 69 | py = self._parser.parse(tcl_list) 70 | return py 71 | 72 | @property 73 | def point_names(self): 74 | return self._get_point_names(self.get_internals()) 75 | 76 | @property 77 | def columns(self): 78 | if self._columns: 79 | return self._columns 80 | columns = [k[3] for k in self.get_internals()[1]] 81 | self.__class__._columns = columns 82 | TrackerPoint.col_count = len(columns) 83 | return columns 84 | 85 | def add_point(self, name='track', ref_frame=None, translate=False, rotate=False, scale=False): 86 | parsed = self.get_internals() 87 | 88 | n = 1 89 | name_candidate = name 90 | existing_names = self._get_point_names(parsed) 91 | while name_candidate in existing_names: 92 | name_candidate = '{} {}'.format(name, n) 93 | n += 1 94 | 95 | # TODO: Nuke actually calculates the default track size and search size based on the image res. Do the same. 96 | track = 22 97 | search = 32 98 | 99 | # Gross, but we have to inject the point in TCL otherwise it may not work if the control panel is closed 100 | f = 'x{}'.format(int(nuke.frame()) if ref_frame is None else int(ref_frame)) 101 | blank_row = [['curve', 'K', f, '1']] 102 | blank_row += [name_candidate] 103 | blank_row += [['curve', f, '0']] * 2 104 | blank_row += [['curve', 'K', f, '0']] * 2 105 | blank_row += [int(translate), int(rotate), int(scale), ['curve', f, '0']] 106 | blank_row += ['1', '0', -search, -search, search, search, -track, -track, track, track] 107 | blank_row += [[]] * 11 108 | 109 | parsed[0][2] = int(parsed[0][2])+1 110 | parsed[2].append(blank_row) 111 | if self.knob.fromScript(self._parser.encode(parsed)): 112 | return self[-1] 113 | else: 114 | return None 115 | 116 | def delete_point(self, item): 117 | if item not in self: 118 | return False 119 | idx = self[item].index 120 | parsed = self.get_internals() 121 | parsed[2].pop(idx) 122 | parsed[0][2] = int(parsed[0][2]) - 1 123 | 124 | return self.knob.fromScript(self._parser.encode(parsed)) 125 | 126 | def rename_point(self, item, name): 127 | if item not in self: 128 | return False 129 | idx = self[item].index 130 | parsed = self.get_internals() 131 | parsed[2][idx][1] = name 132 | return self.knob.fromScript(self._parser.encode(parsed)) 133 | 134 | 135 | class TrackerPoint(object): 136 | col_count = 31 137 | 138 | def __init__(self, parent, index): 139 | self.parent = parent 140 | self.index = index 141 | 142 | def __getitem__(self, item): 143 | if not isinstance(item, int): 144 | item = self.parent.columns.index(item) 145 | return TrackerPointKnob(self, item) 146 | 147 | 148 | class TrackerPointKnob(object): 149 | def __init__(self, parent, index): 150 | self.parent = parent 151 | self.index = index 152 | self.real_index = self.parent.index * self.parent.col_count + self.index 153 | 154 | def clearAnimated(self): 155 | return self.parent.parent.knob.clearAnimated(self.real_index) 156 | 157 | def getValue(self): 158 | return self.value() 159 | 160 | def getValueAt(self, t): 161 | # Special case for name 162 | if self.index == 1: 163 | return self.parent.parent.get_internals()[2][self.parent.index][self.index] 164 | else: 165 | return self.parent.parent.knob.getValueAt(t, self.real_index) 166 | 167 | def hasExpression(self): 168 | # Seems to always return False? Even if explicitly using setExpression 169 | return self.parent.parent.knob.hasExpression(self.real_index) 170 | 171 | def isAnimated(self): 172 | return self.parent.parent.knob.isAnimated(self.real_index) 173 | 174 | def removeKey(self): 175 | return self.parent.parent.knob.removeKey(self.real_index) 176 | 177 | def removeKeyAt(self, t): 178 | return self.parent.parent.knob.removeKeyAt(t, self.real_index) 179 | 180 | def setAnimated(self): 181 | return self.parent.parent.knob.setAnimated(self.real_index) 182 | 183 | def setExpression(self, expression): 184 | return self.parent.parent.knob.setExpression(expression, self.real_index) 185 | 186 | def setValue(self, value): 187 | # Special case for name 188 | if self.index == 1: 189 | return self.parent.parent.rename_point(self.parent.index, value) 190 | else: 191 | return self.parent.parent.knob.setValue(value, self.real_index) 192 | 193 | def setValueAt(self, value, t): 194 | return self.parent.parent.knob.setValueAt(value, t, self.real_index) 195 | 196 | def value(self): 197 | # Special case for name 198 | if self.index == 1: 199 | return self.parent.parent.get_internals()[2][self.parent.index][self.index] 200 | else: 201 | return self.parent.parent.knob.value(self.real_index) 202 | 203 | 204 | class TCLListParser(object): 205 | 206 | NO_ESCAPE = 0 207 | SINGLE_ESCAPE = 1 208 | STRING_ESCAPE = 2 209 | WHITESPACE = [" ", "\t", "\r", "\n"] 210 | 211 | def __init__(self): 212 | self._out = None 213 | self._buffer = None 214 | self._stack = None 215 | 216 | def _flush(self): 217 | if self._buffer is not None: 218 | self._stack[-1].append(self._buffer) 219 | self._buffer = None 220 | 221 | def _add_char(self, char): 222 | if self._buffer is None: 223 | self._buffer = char 224 | else: 225 | self._buffer += char 226 | 227 | def parse(self, tcl_list): 228 | self._out = [] 229 | self._stack = [self._out] 230 | self._buffer = None 231 | 232 | escape = self.NO_ESCAPE 233 | 234 | for char in tcl_list: 235 | # Single escapes 236 | if escape & self.SINGLE_ESCAPE: 237 | self._add_char(char) 238 | escape &= ~self.SINGLE_ESCAPE 239 | elif char == '\\': 240 | escape |= self.SINGLE_ESCAPE 241 | # Strings with spaces, like "hello world" 242 | elif char == '"': 243 | escape ^= self.STRING_ESCAPE 244 | else: 245 | if escape & self.STRING_ESCAPE: 246 | self._add_char(char) 247 | elif char in self.WHITESPACE: 248 | self._flush() 249 | elif char == "{": 250 | _ = [] 251 | self._stack[-1].append(_) 252 | self._stack.append(_) 253 | elif char == "}": 254 | self._flush() 255 | self._stack.pop() 256 | else: 257 | self._add_char(char) 258 | return self._out 259 | 260 | def encode(self, python_list): 261 | """ Brute force dumb re-encoding from the output of parse """ 262 | def _encode(item): 263 | str_buf = '' 264 | if isinstance(item, list): 265 | str_buf += '{' 266 | str_buf += ' '.join([_encode(sub_item) for sub_item in item]) 267 | str_buf += '}' 268 | else: 269 | sub_item = str(item) 270 | if any((c in sub_item for c in self.WHITESPACE)): 271 | str_buf += '"' + sub_item.replace('"', '\\"') + '"' 272 | else: 273 | str_buf += sub_item.replace('{', '\\{').replace('"', '\\"').replace('\\', '\\\\') 274 | 275 | pass 276 | return str_buf[:] 277 | 278 | encoded = _encode(python_list)[1:-1] 279 | return encoded 280 | --------------------------------------------------------------------------------