├── .gitignore ├── LICENSE ├── README.md └── simpleConstraint ├── Options.txt ├── ReadMe.txt ├── simpleConstraint.cpp ├── simpleConstraint.h ├── simpleConstraint.sln ├── simpleConstraint.vcxproj ├── simpleConstraint.vcxproj.filters └── simpleConstraint.vcxproj.user /.gitignore: -------------------------------------------------------------------------------- 1 | # Compiled Object files 2 | *.slo 3 | *.lo 4 | *.o 5 | *.obj 6 | 7 | # Compiled Dynamic libraries 8 | *.so 9 | *.dylib 10 | *.dll 11 | 12 | # Compiled Static libraries 13 | *.lai 14 | *.la 15 | *.a 16 | *.lib 17 | 18 | # Executables 19 | *.exe 20 | *.out 21 | *.app 22 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2014 ADN-DevTech 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | Maya-CustomConstraint 2 | ===================== 3 | 4 | Maya CustomConstraint Sample 5 | 6 | May 23rd, 2014 7 | -------------------------------------------------------------------------------- /simpleConstraint/Options.txt: -------------------------------------------------------------------------------- 1 | ////////////////////////////////////////////////////////////////// 2 | // Options.txt - These are the base options that you selected 3 | ////////////////////////////////////////////////////////////////// 4 | 5 | You have selected to use Maya 2015 6 | 7 | Vendor Name is: Autodesk 8 | 9 | Verbose Comments OFF 10 | 11 | Plug-in type number (0-Empty, 1-MEL, 2-MEL w/Undo, 3-DG Node) 12 | 0 13 | 14 | Maya Type Name (Plug-in Name) 15 | simpleConstraint 16 | 17 | Included Libraries: 18 | Foundation 19 | OpenMaya 20 | OpenMayaAnim 21 | -------------------------------------------------------------------------------- /simpleConstraint/ReadMe.txt: -------------------------------------------------------------------------------- 1 | ======================================================================== 2 | MayaPlugInWizard : "simpleConstraint" Project Overview 3 | ======================================================================== 4 | 5 | MayaPlugInWizard has created this "simpleConstraint" project for you as a starting point. 6 | 7 | This file contains a summary of what you will find in each of the files that make up your project. 8 | 9 | MayaPlugInWizard.vcproj 10 | This is the main project file for projects generated using an Application Wizard. 11 | It contains information about the version of the product that generated the file, and 12 | information about the platforms, configurations, and project features selected with the 13 | Application Wizard. 14 | 15 | Options.txt 16 | This text file explains which options you selected for your new project. 17 | 18 | ///////////////////////////////////////////////////////////////////////////// 19 | Other notes: 20 | 21 | ///////////////////////////////////////////////////////////////////////////// 22 | -------------------------------------------------------------------------------- /simpleConstraint/simpleConstraint.cpp: -------------------------------------------------------------------------------- 1 | #include "SimpleConstraint.h" 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | 15 | MTypeId SimpleConstraint::id( 0x001078e2 ); 16 | 17 | // Compound attribute for the targets 18 | MObject SimpleConstraint::target; 19 | 20 | // Each target has the following child attributes: target weight and target translation value 21 | MObject SimpleConstraint::weight; 22 | MObject SimpleConstraint::targetTranslate; 23 | 24 | //Offset attribute for keeping offset when the constraint is active 25 | MObject SimpleConstraint::offset; 26 | 27 | //Input Attributes of constraint from target object 28 | MObject SimpleConstraint::targetRotatePivot; 29 | MObject SimpleConstraint::targetRotateTranslate; 30 | MObject SimpleConstraint::targetParentMatrix; 31 | 32 | // Input Attributes of constraint from constrained object 33 | MObject SimpleConstraint::constraintRotatePivot; 34 | MObject SimpleConstraint::constraintRotateTranslate; 35 | MObject SimpleConstraint::constraintParentInverseMatrix; 36 | 37 | // Simple Attributes that affect the final position of the constrained object 38 | MObject SimpleConstraint::constraintTranslate; 39 | 40 | 41 | 42 | MStatus initializePlugin( MObject obj ) 43 | { 44 | MFnPlugin plugin( obj, "Autodesk", "1.0" ); 45 | 46 | plugin.registerNode( "simpleConstraint", 47 | SimpleConstraint::id, 48 | SimpleConstraint::creator, 49 | SimpleConstraint::initialize, 50 | MPxNode::kConstraintNode ); 51 | 52 | plugin.registerConstraintCommand("simpleConstraintCmd", SimpleConstraintCommand::creator); 53 | 54 | return MStatus::kSuccess; 55 | } 56 | 57 | MStatus uninitializePlugin( MObject obj ) 58 | { 59 | MFnPlugin plugin( obj ); 60 | 61 | plugin.deregisterNode( SimpleConstraint::id ); 62 | plugin.deregisterConstraintCommand( "simpleConstraintCmd" ); 63 | 64 | return MStatus::kSuccess; 65 | } 66 | 67 | void* SimpleConstraint::creator() 68 | { 69 | return new SimpleConstraint(); 70 | } 71 | 72 | MStatus SimpleConstraint::initialize() 73 | { 74 | MFnCompoundAttribute cAttr; 75 | MFnNumericAttribute nAttr; 76 | MFnMatrixAttribute mAttr; 77 | 78 | // Parameters for each target 79 | targetTranslate = nAttr.create("targetTranslate", "tt", MFnNumericData::k3Double); 80 | 81 | targetRotatePivot = nAttr.create("targetRotatePivot","trp",MFnNumericData::k3Double); 82 | targetRotateTranslate = nAttr.create("targetRotateTranslate","trt",MFnNumericData::k3Double); 83 | targetParentMatrix = mAttr.create("targetParentMatrix", "tpm"); 84 | 85 | weight = nAttr.create( "weight", "wt", MFnNumericData::kDouble, 1.0 ); 86 | 87 | // Compound target parameter 88 | target = cAttr.create( "target", "tar" ); 89 | cAttr.setHidden( true ); 90 | cAttr.addChild( targetTranslate ); 91 | cAttr.addChild( targetRotatePivot); 92 | cAttr.addChild( targetRotateTranslate); 93 | cAttr.addChild( targetParentMatrix); 94 | cAttr.addChild( weight ); 95 | cAttr.setArray( true ); 96 | addAttribute( target ); 97 | 98 | offset = nAttr.create("offset", "os",MFnNumericData::k3Double); 99 | addAttribute(offset); 100 | 101 | constraintRotatePivot = nAttr.create("constraintRotatePivot","crp", MFnNumericData::k3Double); 102 | addAttribute(constraintRotatePivot); 103 | 104 | constraintRotateTranslate = nAttr.create("constraintRotateTranslate","crt", MFnNumericData::k3Double); 105 | addAttribute(constraintRotateTranslate); 106 | 107 | constraintParentInverseMatrix = mAttr.create("constraintParentInverseMatrix", "cpim"); 108 | addAttribute(constraintParentInverseMatrix); 109 | 110 | constraintTranslate = nAttr.create( "constraintTranslate", "ct", MFnNumericData::k3Double ); 111 | addAttribute( constraintTranslate ); 112 | 113 | // Setup the "attribute affects" 114 | attributeAffects( target, constraintTranslate ); 115 | attributeAffects( offset, constraintTranslate); 116 | 117 | attributeAffects( constraintRotatePivot, constraintTranslate); 118 | attributeAffects( constraintRotateTranslate, constraintTranslate); 119 | attributeAffects( constraintParentInverseMatrix, constraintTranslate); 120 | 121 | return MStatus::kSuccess; 122 | } 123 | 124 | void SimpleConstraint::getOutputAttributes( MObjectArray& objects ) 125 | { 126 | objects.clear(); 127 | objects.append( constraintTranslate ); 128 | } 129 | 130 | const MObject SimpleConstraint::passiveOutputAttribute() const 131 | { 132 | return constraintTranslate; 133 | } 134 | 135 | MStatus SimpleConstraint::compute( const MPlug& plug, MDataBlock& data ) 136 | { 137 | MStatus status; 138 | 139 | if( plug == constraintTranslate || plug.parent() == constraintTranslate ) 140 | { 141 | // For this simple constraint we just get the translation from the first target 142 | MArrayDataHandle targetArray = data.inputArrayValue( target ); 143 | 144 | //Calculate the weight for each target, if they are all zero, just set the constraintTranslate clean without doing anything 145 | double weightSum = 0.0; 146 | double individualweight = 0; 147 | for (int i = 0; i < targetArray.elementCount(); i++) 148 | { 149 | individualweight = targetArray.inputValue().child(weight).asDouble(); 150 | weightSum += individualweight; 151 | targetArray.next(); 152 | } 153 | if(weightSum == 0.0) 154 | { 155 | data.setClean(constraintTranslate); 156 | return MStatus::kUnknownParameter; 157 | } 158 | 159 | //Reset weightSum 160 | weightSum = 0.0; 161 | MMatrix tarparentMatrix; 162 | MMatrix objParentInverseMatrix; 163 | MPoint sumPos(0.0,0.0,0.0); 164 | 165 | //Reset the array handle so that it starts at the beginning of the array 166 | targetArray = data.inputArrayValue( target ); 167 | for (int i = 0; i < targetArray.elementCount(); i++) 168 | { 169 | MDataHandle elementHandle = targetArray.inputValue(); 170 | double3& tarTranslation = elementHandle.child( targetTranslate ).asDouble3(); 171 | double3& tarRotatePivot = elementHandle.child( targetRotatePivot ).asDouble3(); 172 | double3& tarRotateTranslate = elementHandle.child( targetRotateTranslate ).asDouble3(); 173 | double curWeight = elementHandle.child( weight ).asDouble(); 174 | 175 | MPoint tmpPoint(tarTranslation[0] + tarRotatePivot[0] + tarRotateTranslate[0], 176 | tarTranslation[1] + tarRotatePivot[1] + tarRotateTranslate[1], 177 | tarTranslation[2] + tarRotatePivot[2] + tarRotateTranslate[2]); 178 | 179 | tarparentMatrix = elementHandle.child(targetParentMatrix).asMatrix(); 180 | tmpPoint = tmpPoint * tarparentMatrix; 181 | 182 | sumPos[0] += tmpPoint[0] * curWeight; 183 | sumPos[1] += tmpPoint[1] * curWeight; 184 | sumPos[2] += tmpPoint[2] * curWeight; 185 | 186 | weightSum += curWeight; 187 | targetArray.next(); 188 | } 189 | 190 | weightSum = 1.0 / weightSum; 191 | sumPos[0] = sumPos[0] * weightSum; 192 | sumPos[1] = sumPos[1] * weightSum; 193 | sumPos[2] = sumPos[2] * weightSum; 194 | 195 | 196 | objParentInverseMatrix = data.inputValue(constraintParentInverseMatrix).asMatrix(); 197 | sumPos = sumPos * objParentInverseMatrix; 198 | 199 | 200 | double3& offsetVal = data.inputValue(offset,&status).asDouble3(); 201 | sumPos[0] += offsetVal[0]; 202 | sumPos[1] += offsetVal[1]; 203 | sumPos[2] += offsetVal[2]; 204 | 205 | 206 | //Retrieve constraint object rotatePivot and rotatePivotTranslate information 207 | double3& rpdata = data.inputValue(constraintRotatePivot).asDouble3(); 208 | double3& rtdata = data.inputValue(constraintRotateTranslate).asDouble3(); 209 | MPoint PivotPoint(rpdata[0] + rtdata[0], rpdata[1] + rtdata[1], rpdata[2] + rtdata[2]); 210 | 211 | MVector result; 212 | result.x = sumPos[0] - PivotPoint[0]; 213 | result.y = sumPos[1] - PivotPoint[1]; 214 | result.z = sumPos[2] - PivotPoint[2]; 215 | 216 | data.outputValue( constraintTranslate ).set(result.x, result.y, result.z); 217 | 218 | 219 | return MStatus::kSuccess; 220 | } 221 | 222 | return MStatus::kUnknownParameter; 223 | 224 | } 225 | 226 | //SimpleConstraintCommand implementation 227 | 228 | void* SimpleConstraintCommand::creator() 229 | { 230 | return new SimpleConstraintCommand(); 231 | } 232 | 233 | 234 | MStatus SimpleConstraintCommand::connectTarget( MDagPath& path, int index ) 235 | { 236 | MStatus status; 237 | // Connect target attributes to input attributes of constrain 238 | status = connectTargetAttribute(path, index, MPxTransform::rotatePivot,SimpleConstraint::targetRotatePivot,false); 239 | status = connectTargetAttribute(path, index, MPxTransform::rotatePivotTranslate,SimpleConstraint::targetRotateTranslate,false); 240 | status = connectTargetAttribute(path, index, MPxTransform::parentMatrix, SimpleConstraint::targetParentMatrix, false); 241 | status = connectTargetAttribute(path, index, MPxTransform::translate, SimpleConstraint::targetTranslate, false); 242 | return status; 243 | } 244 | 245 | MStatus SimpleConstraintCommand::connectObjectAndConstraint( MDGModifier& modifier ) 246 | { 247 | MStatus status; 248 | 249 | // Connect the attributes of constrained object to the constraint 250 | status = connectObjectAttribute(MPxTransform::rotatePivot, SimpleConstraint::constraintRotatePivot,true,false); 251 | status = connectObjectAttribute(MPxTransform::rotatePivotTranslate,SimpleConstraint::constraintRotateTranslate, true,false); 252 | status = connectObjectAttribute(MPxTransform::parentInverseMatrix,SimpleConstraint::constraintParentInverseMatrix, true, false); 253 | // 254 | // Connect the constraint output attribute to the constrained object 255 | // 256 | status = connectObjectAttribute( MPxTransform::translate,SimpleConstraint::constraintTranslate, false, false ); 257 | 258 | 259 | return status; 260 | } 261 | -------------------------------------------------------------------------------- /simpleConstraint/simpleConstraint.h: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | 10 | 11 | 12 | class SimpleConstraint : public MPxConstraint 13 | { 14 | public: 15 | static MTypeId id; 16 | 17 | static MObject target; 18 | static MObject weight; 19 | static MObject targetTranslate; 20 | static MObject offset; 21 | 22 | //Input Attributes of constraint from target object 23 | static MObject targetRotatePivot; 24 | static MObject targetRotateTranslate; 25 | static MObject targetParentMatrix; 26 | 27 | // The input attribute connected from the constrained object 28 | static MObject constraintRotatePivot; 29 | static MObject constraintRotateTranslate; 30 | static MObject constraintParentInverseMatrix; 31 | 32 | // The output translation attribute, connected to the constrained object 33 | static MObject constraintTranslate; 34 | 35 | static void* creator(); 36 | static MStatus initialize(); 37 | 38 | virtual const MObject targetAttribute() const { return target; } 39 | virtual const MObject weightAttribute() const { return weight; } 40 | 41 | virtual void getOutputAttributes( MObjectArray& ); 42 | virtual const MObject passiveOutputAttribute() const; 43 | 44 | virtual MStatus compute( const MPlug&, MDataBlock& ); 45 | }; 46 | 47 | class SimpleConstraintCommand : public MPxConstraintCommand 48 | { 49 | public: 50 | 51 | static void* creator(); 52 | 53 | //The following two functions needs to be implemented to support 54 | //"-maintainOffset" and "-offset" flags 55 | virtual bool supportsOffset() const { return true; } 56 | virtual const MObject& offsetAttribute() const { return SimpleConstraint::offset; } 57 | 58 | virtual MTypeId constraintTypeId() const { return SimpleConstraint::id; } 59 | 60 | virtual const MObject& objectAttribute() const { return MPxTransform::translate; } 61 | 62 | virtual const MObject& constraintOutputAttribute() const { return SimpleConstraint::constraintTranslate; } 63 | virtual const MObject& constraintTargetAttribute() const { return SimpleConstraint::target; } 64 | virtual const MObject& constraintTargetWeightAttribute() const { return SimpleConstraint::weight; } 65 | 66 | virtual MStatus connectTarget( MDagPath&, int ); 67 | virtual MStatus connectObjectAndConstraint( MDGModifier& ); 68 | }; 69 | -------------------------------------------------------------------------------- /simpleConstraint/simpleConstraint.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio 2012 4 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "simpleConstraint", "simpleConstraint.vcxproj", "{8E9A171C-757C-43C8-932E-336BA3598A62}" 5 | EndProject 6 | Global 7 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 8 | Debug|x64 = Debug|x64 9 | Release|x64 = Release|x64 10 | EndGlobalSection 11 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 12 | {8E9A171C-757C-43C8-932E-336BA3598A62}.Debug|x64.ActiveCfg = Debug|x64 13 | {8E9A171C-757C-43C8-932E-336BA3598A62}.Debug|x64.Build.0 = Debug|x64 14 | {8E9A171C-757C-43C8-932E-336BA3598A62}.Release|x64.ActiveCfg = Release|x64 15 | {8E9A171C-757C-43C8-932E-336BA3598A62}.Release|x64.Build.0 = Release|x64 16 | EndGlobalSection 17 | GlobalSection(SolutionProperties) = preSolution 18 | HideSolutionNode = FALSE 19 | EndGlobalSection 20 | EndGlobal 21 | -------------------------------------------------------------------------------- /simpleConstraint/simpleConstraint.vcxproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Debug 6 | x64 7 | 8 | 9 | Release 10 | x64 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | Win32Proj 25 | {8E9A171C-757C-43C8-932E-336BA3598A62} 26 | 27 | 28 | 29 | DynamicLibrary 30 | true 31 | v110 32 | 33 | 34 | DynamicLibrary 35 | false 36 | v110 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | true 50 | $(Configuration)\ 51 | .mll 52 | AllRules.ruleset 53 | $(Configuration)\ 54 | 55 | 56 | 57 | _DEBUG;WIN32;_WINDOWS;_USRDLL;NT_PLUGIN;_HAS_ITERATOR_DEBUGGING=0;_SECURE_SCL=0;_SECURE_SCL_THROWS=0;_SECURE_SCL_DEPRECATE=0;_CRT_SECURE_NO_DEPRECATE;TBB_USE_DEBUG=0;__TBB_LIB_NAME=tbb.lib;REQUIRE_IOSTREAM;AW_NEW_IOSTREAMS;Bits64_;%(PreprocessorDefinitions) 58 | MultiThreadedDebugDLL 59 | Level3 60 | ProgramDatabase 61 | true 62 | $(IntDir)$(ProjectName).pdb 63 | Disabled 64 | Sync 65 | EnableFastChecks 66 | true 67 | true 68 | %(AdditionalOptions) 69 | .;C:\Program Files\Autodesk\Maya2015\include;%(AdditionalIncludeDirectories) 70 | $(Configuration)\simpleConstraint.pch 71 | 72 | 73 | true 74 | Windows 75 | false 76 | /export:initializePlugin /export:uninitializePlugin %(AdditionalOptions) 77 | Foundation.lib;OpenMaya.lib;OpenMayaAnim.lib;%(AdditionalDependencies) 78 | C:\Program Files\Autodesk\Maya2015\lib;%(AdditionalLibraryDirectories) 79 | $(Configuration)\simpleConstraint.mll 80 | $(Configuration)\simpleConstraint.lib 81 | $(Configuration)\simpleConstraint.pdb 82 | 83 | 84 | 85 | false 86 | $(Configuration)\ 87 | .mll 88 | AllRules.ruleset 89 | $(Configuration)\ 90 | 91 | 92 | 93 | NDEBUG;WIN32;_WINDOWS;_USRDLL;NT_PLUGIN;_HAS_ITERATOR_DEBUGGING=0;_SECURE_SCL=0;_SECURE_SCL_THROWS=0;_SECURE_SCL_DEPRECATE=0;_CRT_SECURE_NO_DEPRECATE;TBB_USE_DEBUG=0;__TBB_LIB_NAME=tbb.lib;REQUIRE_IOSTREAM;AW_NEW_IOSTREAMS;Bits64_;%(PreprocessorDefinitions) 94 | MultiThreadedDLL 95 | Level3 96 | ProgramDatabase 97 | true 98 | $(IntDir)$(ProjectName).pdb 99 | OnlyExplicitInline 100 | true 101 | true 102 | Sync 103 | true 104 | %(AdditionalOptions) 105 | .;C:\Program Files\Autodesk\Maya2015\include;%(AdditionalIncludeDirectories) 106 | $(Configuration)\simpleConstraint.pch 107 | 108 | 109 | false 110 | Windows 111 | false 112 | /export:initializePlugin /export:uninitializePlugin %(AdditionalOptions) 113 | true 114 | true 115 | Foundation.lib;OpenMaya.lib;OpenMayaAnim.lib;%(AdditionalDependencies) 116 | C:\Program Files\Autodesk\Maya2015\lib;%(AdditionalLibraryDirectories) 117 | $(Configuration)\simpleConstraint.mll 118 | $(Configuration)\simpleConstraint.lib 119 | $(Configuration)\simpleConstraint.pdb 120 | 121 | 122 | 123 | 124 | 125 | -------------------------------------------------------------------------------- /simpleConstraint/simpleConstraint.vcxproj.filters: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | {a1a842a9-b98d-4e9c-90aa-a9902990dafa} 6 | cpp 7 | 8 | 9 | {01936e0c-a8da-40ee-9bc0-bf280231c365} 10 | h 11 | 12 | 13 | {18719b9c-8061-4088-83c2-d35ab82ca65c} 14 | txt 15 | 16 | 17 | 18 | 19 | Miscellaneous Files 20 | 21 | 22 | Miscellaneous Files 23 | 24 | 25 | 26 | 27 | Source Files 28 | 29 | 30 | 31 | 32 | Source Files 33 | 34 | 35 | -------------------------------------------------------------------------------- /simpleConstraint/simpleConstraint.vcxproj.user: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | C:\Program Files\Autodesk\Maya2015\bin\maya.exe 5 | 6 | --------------------------------------------------------------------------------