├── .gitignore ├── .project ├── .vscode ├── launch.json ├── settings.json └── tasks.json ├── Assets └── animation.gif ├── AttachWeights ├── AttachWeights.cpp ├── AttachWeights.vcproj ├── AttachWeights.vcxproj ├── AttachWeights.vcxproj.filters ├── Makefile ├── ReadMe.txt ├── stdafx.cpp └── stdafx.h ├── Makefile ├── Pinocchio.sln ├── Pinocchio.slnenv ├── Pinocchio ├── COPYING ├── Makefile ├── Pinocchio.cpp ├── Pinocchio.h ├── Pinocchio.vcproj ├── Pinocchio.vcxproj ├── Pinocchio.vcxproj.filters ├── attachment.cpp ├── attachment.h ├── debugging.h ├── deriv.h ├── discretization.cpp ├── dtree.h ├── embedding.cpp ├── graphutils.cpp ├── graphutils.h ├── hashutils.h ├── indexer.cpp ├── indexer.h ├── intersector.cpp ├── intersector.h ├── lsqSolver.cpp ├── lsqSolver.h ├── mathutils.h ├── matrix.cpp ├── matrix.h ├── mesh.cpp ├── mesh.h ├── mesh │ └── fbx.h ├── multilinear.h ├── pinocchioApi.cpp ├── pinocchioApi.h ├── pointprojector.h ├── quaddisttree.h ├── rect.h ├── refinement.cpp ├── skeleton.cpp ├── skeleton.h ├── transform.h ├── utils.h ├── vector.h └── vecutils.h ├── PinocchioStatic ├── PinocchioStatic.vcproj ├── PinocchioStatic.vcxproj └── PinocchioStatic.vcxproj.filters ├── Project ├── CMakeLists.txt ├── Makefile ├── Project.vcproj ├── Project.vcxproj ├── Project.vcxproj.filters ├── Shaders │ └── skeleton │ │ ├── skeleton_fs.glsl │ │ └── skeleton_vs.glsl ├── data │ ├── human.obj │ ├── joints.out │ └── skeleton.out ├── defmesh.cpp ├── defmesh.h ├── device.h ├── main.cpp ├── motion.cpp ├── motion.h ├── program.h ├── renderer.h ├── tools.h ├── window.cpp └── window.h └── README.md /.gitignore: -------------------------------------------------------------------------------- 1 | *~ 2 | ._* 3 | *.ali 4 | *.o 5 | *.db 6 | *.out 7 | *.log.* 8 | *log.200* 9 | *.orig 10 | *.patch 11 | **b~* 12 | bin/ 13 | obj/ 14 | Debug/ 15 | debug/ 16 | Release/ 17 | release/ 18 | *.obj 19 | \#* 20 | .\#* 21 | *.log 22 | *.pdb 23 | *.ncb 24 | *.user 25 | *.idb 26 | *.dep 27 | *.suo 28 | !**/data/* 29 | **/misc 30 | **/.vs/ 31 | **/out/ 32 | **/Libs/ 33 | **/output/ 34 | BuildLog.htm 35 | /debug/ 36 | /fltk-1.1.9/ 37 | Pinocchio/libpinocchio.a 38 | /cmake-build-debug 39 | .idea 40 | AttachWeights/attachWeights 41 | AttachWeights/AttachWeights 42 | AttachWeights/AttachWeights.exe 43 | AttachWeights/AttachWeightsMac 44 | AttachWeights/AttachWeightsLinux 45 | -------------------------------------------------------------------------------- /.project: -------------------------------------------------------------------------------- 1 | 2 | 3 | Pinocchio 4 | 5 | 6 | 7 | 8 | 9 | org.eclipse.cdt.managedbuilder.core.genmakebuilder 10 | clean,full,incremental, 11 | 12 | 13 | ?name? 14 | 15 | 16 | 17 | org.eclipse.cdt.make.core.append_environment 18 | true 19 | 20 | 21 | org.eclipse.cdt.make.core.autoBuildTarget 22 | all 23 | 24 | 25 | org.eclipse.cdt.make.core.buildArguments 26 | 27 | 28 | 29 | org.eclipse.cdt.make.core.buildCommand 30 | make 31 | 32 | 33 | org.eclipse.cdt.make.core.buildLocation 34 | ${workspace_loc:/Pinocchio/Debug} 35 | 36 | 37 | org.eclipse.cdt.make.core.cleanBuildTarget 38 | clean 39 | 40 | 41 | org.eclipse.cdt.make.core.contents 42 | org.eclipse.cdt.make.core.activeConfigSettings 43 | 44 | 45 | org.eclipse.cdt.make.core.enableAutoBuild 46 | false 47 | 48 | 49 | org.eclipse.cdt.make.core.enableCleanBuild 50 | true 51 | 52 | 53 | org.eclipse.cdt.make.core.enableFullBuild 54 | true 55 | 56 | 57 | org.eclipse.cdt.make.core.fullBuildTarget 58 | all 59 | 60 | 61 | org.eclipse.cdt.make.core.stopOnError 62 | true 63 | 64 | 65 | org.eclipse.cdt.make.core.useDefaultBuildCmd 66 | true 67 | 68 | 69 | 70 | 71 | org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder 72 | 73 | 74 | 75 | 76 | 77 | org.eclipse.cdt.core.ccnature 78 | org.eclipse.cdt.managedbuilder.core.ScannerConfigNature 79 | org.eclipse.cdt.managedbuilder.core.managedBuildNature 80 | org.eclipse.cdt.core.cnature 81 | 82 | 83 | -------------------------------------------------------------------------------- /.vscode/launch.json: -------------------------------------------------------------------------------- 1 | { 2 | // Use IntelliSense to learn about possible attributes. 3 | // Hover to view descriptions of existing attributes. 4 | // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 5 | "version": "0.2.0", 6 | "configurations": [ 7 | { 8 | "name": "g++ build and debug active file", 9 | "type": "cppdbg", 10 | "request": "launch", 11 | "program": "${workspaceFolder}/Project/Project", 12 | "args": [ "/home/mansoor/Downloads/human_mesh.obj" ,"-motion", "${workspaceFolder}/Project/data/walk.txt"], 13 | "stopAtEntry": false, 14 | "cwd": "${workspaceFolder}", 15 | "environment": [], 16 | "externalConsole": false, 17 | "MIMode": "gdb", 18 | "setupCommands": [ 19 | { 20 | "description": "Enable pretty-printing for gdb", 21 | "text": "-enable-pretty-printing", 22 | "ignoreFailures": true 23 | } 24 | ], 25 | "preLaunchTask": "build", 26 | "miDebuggerPath": "/usr/bin/gdb" 27 | } 28 | ] 29 | } -------------------------------------------------------------------------------- /.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "files.associations": { 3 | "new": "cpp", 4 | "iosfwd": "cpp", 5 | "iostream": "cpp", 6 | "ostream": "cpp", 7 | "array": "cpp", 8 | "string": "cpp", 9 | "string_view": "cpp", 10 | "memory": "cpp", 11 | "istream": "cpp", 12 | "functional": "cpp", 13 | "hash_map": "cpp", 14 | "hash_set": "cpp", 15 | "initializer_list": "cpp", 16 | "utility": "cpp", 17 | "map": "cpp", 18 | "dense": "cpp", 19 | "geometry": "cpp", 20 | "complex": "cpp", 21 | "atomic": "cpp", 22 | "*.tcc": "cpp", 23 | "deque": "cpp", 24 | "unordered_map": "cpp", 25 | "vector": "cpp", 26 | "iterator": "cpp", 27 | "memory_resource": "cpp", 28 | "optional": "cpp", 29 | "fstream": "cpp", 30 | "sstream": "cpp", 31 | "streambuf": "cpp", 32 | "system_error": "cpp", 33 | "tuple": "cpp", 34 | "typeinfo": "cpp", 35 | "algorithm": "cpp", 36 | "cctype": "cpp", 37 | "clocale": "cpp", 38 | "cmath": "cpp", 39 | "cstdarg": "cpp", 40 | "cstddef": "cpp", 41 | "cstdint": "cpp", 42 | "cstdio": "cpp", 43 | "cstdlib": "cpp", 44 | "cstring": "cpp", 45 | "cwchar": "cpp", 46 | "cwctype": "cpp", 47 | "exception": "cpp", 48 | "numeric": "cpp", 49 | "set": "cpp", 50 | "type_traits": "cpp", 51 | "limits": "cpp", 52 | "stdexcept": "cpp", 53 | "cinttypes": "cpp" 54 | } 55 | } -------------------------------------------------------------------------------- /.vscode/tasks.json: -------------------------------------------------------------------------------- 1 | { 2 | // See https://go.microsoft.com/fwlink/?LinkId=733558 3 | // for the documentation about the tasks.json format 4 | "version": "2.0.0", 5 | "tasks": [ 6 | { 7 | "label": "build", 8 | "type": "shell", 9 | "command": "cd Project && make && make cleanobj" 10 | }, 11 | 12 | ] 13 | } 14 | -------------------------------------------------------------------------------- /Assets/animation.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DomainFlag/automatic-rigging-animation/81db10d35da885efe2613c64347d50d4b34bd7c9/Assets/animation.gif -------------------------------------------------------------------------------- /AttachWeights/AttachWeights.cpp: -------------------------------------------------------------------------------- 1 | // AttachWeights.cpp : Defines the entry point for the console application. 2 | // 3 | 4 | #include "stdafx.h" 5 | 6 | #include 7 | 8 | #include "../Pinocchio/skeleton.h" 9 | #include "../Pinocchio/utils.h" 10 | #include "../Pinocchio/debugging.h" 11 | #include "../Pinocchio/attachment.h" 12 | #include "../Pinocchio/pinocchioApi.h" 13 | 14 | struct ArgData 15 | { 16 | ArgData() : 17 | stopAtMesh(false), stopAfterCircles(false), skelScale(1.), noFit(true), 18 | skeleton(HumanSkeleton()), stiffness(1.), 19 | skelOutName("skeleton.out"), weightOutName("attachment.out") 20 | { 21 | } 22 | 23 | bool stopAtMesh; 24 | bool stopAfterCircles; 25 | string filename; 26 | Quaternion<> meshTransform; 27 | double skelScale; 28 | bool noFit; 29 | Skeleton skeleton; 30 | string skeletonname; 31 | double stiffness; 32 | string skelOutName; 33 | string weightOutName; 34 | }; 35 | 36 | 37 | void printUsageAndExit() 38 | { 39 | cout << "Usage: attachWeights filename.{obj | ply | off | gts | stl}" << endl; 40 | cout << " [-skel skelname] [-rot x y z deg]* [-scale s]" << endl; 41 | cout << " [-meshonly | -mo] [-circlesonly | -co]" << endl; 42 | cout << " [-fit] [-stiffness s]" << endl; 43 | cout << " [-skelOut skelOutFile] [-weightOut weightOutFile]" << endl; 44 | 45 | exit(0); 46 | } 47 | 48 | ArgData processArgs(const vector &args) 49 | { 50 | ArgData out; 51 | int cur = 2; 52 | int num = args.size(); 53 | if(num < 2) 54 | printUsageAndExit(); 55 | 56 | out.filename = args[1]; 57 | 58 | while(cur < num) { 59 | string curStr = args[cur++]; 60 | if(curStr == string("-skel")) { 61 | if(cur == num) { 62 | cout << "No skeleton specified; ignoring." << endl; 63 | continue; 64 | } 65 | curStr = args[cur++]; 66 | if(curStr == string("human")) 67 | out.skeleton = HumanSkeleton(); 68 | else if(curStr == string("horse")) 69 | out.skeleton = HorseSkeleton(); 70 | else if(curStr == string("kinect")) 71 | out.skeleton = HorseSkeleton(); 72 | else if(curStr == string("quad")) 73 | out.skeleton = QuadSkeleton(); 74 | else if(curStr == string("centaur")) 75 | out.skeleton = CentaurSkeleton(); 76 | else 77 | out.skeleton = FileSkeleton(curStr); 78 | out.skeletonname = curStr; 79 | continue; 80 | } 81 | if(curStr == string("-rot")) { 82 | if(cur + 3 >= num) { 83 | cout << "Too few rotation arguments; exiting." << endl; 84 | printUsageAndExit(); 85 | } 86 | double x, y, z, deg; 87 | sscanf(args[cur++].c_str(), "%lf", &x); 88 | sscanf(args[cur++].c_str(), "%lf", &y); 89 | sscanf(args[cur++].c_str(), "%lf", &z); 90 | sscanf(args[cur++].c_str(), "%lf", °); 91 | 92 | out.meshTransform = Quaternion<>(Pinocchio::Vector3(x, y, z), deg * M_PI / 180.) * out.meshTransform; 93 | continue; 94 | } 95 | if(curStr == string("-scale")) { 96 | if(cur >= num) { 97 | cout << "No scale provided; exiting." << endl; 98 | printUsageAndExit(); 99 | } 100 | sscanf(args[cur++].c_str(), "%lf", &out.skelScale); 101 | continue; 102 | } 103 | if(curStr == string("-meshonly") || curStr == string("-mo")) { 104 | out.stopAtMesh = true; 105 | continue; 106 | } 107 | if(curStr == string("-circlesonly") || curStr == string("-co")) { 108 | out.stopAfterCircles = true; 109 | continue; 110 | } 111 | if(curStr == string("-fit")) { 112 | out.noFit = false; 113 | continue; 114 | } 115 | if(curStr == string("-stiffness")) { 116 | if(cur >= num) { 117 | cout << "No stiffness provided; exiting." << endl; 118 | printUsageAndExit(); 119 | } 120 | sscanf(args[cur++].c_str(), "%lf", &out.stiffness); 121 | continue; 122 | } 123 | if(curStr == string("-skelOut")) { 124 | if(cur == num) { 125 | cout << "No skeleton output specified; ignoring." << endl; 126 | continue; 127 | } 128 | curStr = args[cur++]; 129 | out.skelOutName = curStr; 130 | continue; 131 | } 132 | if(curStr == string("-weightOut")) { 133 | if(cur == num) { 134 | cout << "No weight output specified; ignoring." << endl; 135 | continue; 136 | } 137 | curStr = args[cur++]; 138 | out.weightOutName = curStr; 139 | continue; 140 | } 141 | cout << "Unrecognized option: " << curStr << endl; 142 | printUsageAndExit(); 143 | } 144 | 145 | return out; 146 | } 147 | 148 | void process(const vector &args) 149 | { 150 | int i; 151 | ArgData a = processArgs(args); 152 | 153 | Debugging::setOutStream(cout); 154 | 155 | Mesh m(a.filename); 156 | if(m.vertices.size() == 0) { 157 | cout << "Error reading file. Aborting." << endl; 158 | exit(0); 159 | return; 160 | } 161 | 162 | for(i = 0; i < (int)m.vertices.size(); ++i) 163 | m.vertices[i].pos = a.meshTransform * m.vertices[i].pos; 164 | m.normalizeBoundingBox(); 165 | m.computeVertexNormals(); 166 | 167 | Skeleton given = a.skeleton; 168 | given.scale(a.skelScale * 0.7); 169 | 170 | if(a.stopAtMesh) { //if early bailout 171 | return; 172 | } 173 | 174 | PinocchioOutput o; 175 | if(!a.noFit) { //do everything 176 | o = autorig(given, m); 177 | } 178 | else { //skip the fitting step--assume the skeleton is already correct for the mesh 179 | TreeType *distanceField = constructDistanceField(m); 180 | VisTester *tester = new VisTester(distanceField); 181 | 182 | o.embedding = a.skeleton.fGraph().verts; 183 | for(i = 0; i < (int)o.embedding.size(); ++i) 184 | o.embedding[i] = m.toAdd + o.embedding[i] * m.scale; 185 | 186 | o.attachment = new Attachment(m, a.skeleton, o.embedding, tester, a.stiffness); 187 | 188 | delete tester; 189 | delete distanceField; 190 | } 191 | 192 | if(o.embedding.size() == 0) { 193 | cout << "Error embedding" << endl; 194 | exit(0); 195 | } 196 | 197 | //output skeleton embedding 198 | for(i = 0; i < (int)o.embedding.size(); ++i) 199 | o.embedding[i] = (o.embedding[i] - m.toAdd) / m.scale; 200 | ofstream os(a.skelOutName.c_str()); 201 | for(i = 0; i < (int)o.embedding.size(); ++i) { 202 | os << i << " " << o.embedding[i][0] << " " << o.embedding[i][1] << 203 | " " << o.embedding[i][2] << " " << a.skeleton.fPrev()[i] << endl; 204 | } 205 | 206 | //output attachment 207 | std::ofstream astrm(a.weightOutName.c_str()); 208 | for(i = 0; i < (int)m.vertices.size(); ++i) { 209 | Vector v = o.attachment->getWeights(i); 210 | for(int j = 0; j < v.size(); ++j) { 211 | double d = floor(0.5 + v[j] * 10000.) / 10000.; 212 | astrm << d << " "; 213 | } 214 | astrm << endl; 215 | } 216 | 217 | delete o.attachment; 218 | } 219 | 220 | 221 | int main(int argc, char **argv) 222 | { 223 | 224 | vector args; 225 | for(int i = 0; i < argc; ++i) 226 | args.push_back(argv[i]); 227 | process(args); 228 | 229 | return 0; 230 | } 231 | -------------------------------------------------------------------------------- /AttachWeights/AttachWeights.vcproj: -------------------------------------------------------------------------------- 1 | 2 | 10 | 11 | 14 | 15 | 16 | 17 | 18 | 25 | 28 | 31 | 34 | 37 | 40 | 52 | 55 | 58 | 61 | 68 | 71 | 74 | 77 | 80 | 83 | 86 | 89 | 92 | 93 | 101 | 104 | 107 | 110 | 113 | 116 | 129 | 132 | 135 | 138 | 148 | 151 | 154 | 157 | 160 | 163 | 166 | 169 | 172 | 173 | 174 | 175 | 176 | 177 | 182 | 185 | 186 | 189 | 190 | 191 | 196 | 199 | 200 | 201 | 206 | 207 | 210 | 211 | 212 | 213 | 214 | 215 | -------------------------------------------------------------------------------- /AttachWeights/AttachWeights.vcxproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Debug 6 | Win32 7 | 8 | 9 | Release 10 | Win32 11 | 12 | 13 | 14 | {09E0B2DD-ABD8-4202-A4E7-047CC86BA355} 15 | AttachWeights 16 | Win32Proj 17 | 18 | 19 | 20 | Application 21 | v142 22 | Unicode 23 | true 24 | 25 | 26 | Application 27 | v142 28 | Unicode 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | <_ProjectFileVersion>16.0.29511.113 42 | 43 | 44 | $(SolutionDir)$(Configuration)\ 45 | $(Configuration)\ 46 | true 47 | MinimumRecommendedRules.ruleset 48 | 49 | 50 | 51 | 52 | $(SolutionDir)$(Configuration)\ 53 | $(Configuration)\ 54 | false 55 | MinimumRecommendedRules.ruleset 56 | 57 | 58 | 59 | 60 | 61 | Disabled 62 | WIN32;_DEBUG;_CONSOLE;PINOCCHIO_STATIC;%(PreprocessorDefinitions) 63 | true 64 | EnableFastChecks 65 | MultiThreadedDebug 66 | 67 | Level3 68 | EditAndContinue 69 | 70 | 71 | true 72 | Console 73 | MachineX86 74 | $(FBX_DIR)/lib/vs2015/x86/debug 75 | libfbxsdk-mt.lib;%(AdditionalDependencies) 76 | 77 | 78 | 79 | 80 | Full 81 | AnySuitable 82 | true 83 | Speed 84 | WIN32;NDEBUG;_CONSOLE;PINOCCHIO_STATIC;%(PreprocessorDefinitions) 85 | MultiThreaded 86 | 87 | Level3 88 | ProgramDatabase 89 | 90 | 91 | $(OutDir)$(ProjectName)Win.exe 92 | true 93 | Console 94 | true 95 | true 96 | MachineX86 97 | $(FBX_DIR)/lib/vs2015/x86/release 98 | libfbxsdk-mt.lib;%(AdditionalDependencies) 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | {f66ad322-abb4-4992-8fef-bb9cb6bdd9d7} 114 | false 115 | 116 | 117 | 118 | 119 | 120 | -------------------------------------------------------------------------------- /AttachWeights/AttachWeights.vcxproj.filters: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF} 6 | cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx 7 | 8 | 9 | {93995380-89BD-4b04-88EB-625FBE52EBFB} 10 | h;hpp;hxx;hm;inl;inc;xsd 11 | 12 | 13 | {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} 14 | rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav 15 | 16 | 17 | 18 | 19 | Source Files 20 | 21 | 22 | Source Files 23 | 24 | 25 | 26 | 27 | Header Files 28 | 29 | 30 | 31 | 32 | 33 | -------------------------------------------------------------------------------- /AttachWeights/Makefile: -------------------------------------------------------------------------------- 1 | # OS-Specfic Stuff 2 | ifeq ($(OSTYPE),darwin) 3 | OS_COMPILE_FLAGS = -DOSX 4 | TARGET_EXT = Mac 5 | else 6 | # LINUX stuff 7 | OS_COMPILE_FLAGS = -DLINUX 8 | TARGET_EXT = Linux 9 | endif 10 | 11 | LIBS = -lm -pthread -I./../fbx/include -lfbxsdk -I/usr/include/libxml2/libxml -lxml2 -ldl -lrt -luuid -lz 12 | 13 | CC = g++ 14 | # CCFLAGS = -c -O3 -Wall -fPIC $(OS_COMPILE_FLAGS) 15 | # Uncomment this to use a debug version 16 | CCFLAGS = -c -g3 -O0 -Wall $(LIBS) -fPIC $(OS_COMPILE_FLAGS) 17 | 18 | TARGETBASE = AttachWeights 19 | TARGET = $(TARGETBASE)$(TARGET_EXT) 20 | 21 | $(TARGET) : stdfx.o $(TARGETBASE).o 22 | gcc -O3 -Wall -fPIC -o $(TARGET) stdafx.o $(TARGETBASE).o ../Pinocchio/libpinocchio.a -lstdc++ -lm $(LIBS) 23 | 24 | stdfx.o : stdafx.cpp stdafx.h 25 | $(CC) $(CCFLAGS) stdafx.cpp 26 | 27 | $(TARGET).o : stdafx.h 28 | $(CC) $(CCFLAGS) $(TARGET).cpp 29 | 30 | clean : 31 | rm -f *.o 32 | rm -f $(TARGET) 33 | -------------------------------------------------------------------------------- /AttachWeights/ReadMe.txt: -------------------------------------------------------------------------------- 1 | ======================================================================== 2 | CONSOLE APPLICATION : AttachWeights Project Overview 3 | ======================================================================== 4 | 5 | AppWizard has created this AttachWeights application for you. 6 | 7 | This file contains a summary of what you will find in each of the files that 8 | make up your AttachWeights application. 9 | 10 | 11 | AttachWeights.vcproj 12 | This is the main project file for VC++ projects generated using an Application Wizard. 13 | It contains information about the version of Visual C++ that generated the file, and 14 | information about the platforms, configurations, and project features selected with the 15 | Application Wizard. 16 | 17 | AttachWeights.cpp 18 | This is the main application source file. 19 | 20 | ///////////////////////////////////////////////////////////////////////////// 21 | Other standard files: 22 | 23 | StdAfx.h, StdAfx.cpp 24 | These files are used to build a precompiled header (PCH) file 25 | named AttachWeights.pch and a precompiled types file named StdAfx.obj. 26 | 27 | ///////////////////////////////////////////////////////////////////////////// 28 | Other notes: 29 | 30 | AppWizard uses "TODO:" comments to indicate parts of the source code you 31 | should add to or customize. 32 | 33 | ///////////////////////////////////////////////////////////////////////////// 34 | -------------------------------------------------------------------------------- /AttachWeights/stdafx.cpp: -------------------------------------------------------------------------------- 1 | // stdafx.cpp : source file that includes just the standard includes 2 | // AttachWeights.pch will be the pre-compiled header 3 | // stdafx.obj will contain the pre-compiled type information 4 | 5 | #include "stdafx.h" 6 | 7 | // TODO: reference any additional headers you need in STDAFX.H 8 | // and not in this file 9 | -------------------------------------------------------------------------------- /AttachWeights/stdafx.h: -------------------------------------------------------------------------------- 1 | // stdafx.h : include file for standard system include files, 2 | // or project specific include files that are used frequently, but 3 | // are changed infrequently 4 | // 5 | 6 | #pragma once 7 | 8 | 9 | #include 10 | #ifdef WIN32 // Windows defs 11 | #define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers 12 | #include 13 | 14 | #else // linux / OSX defs 15 | #include 16 | #include 17 | #include 18 | #include 19 | #include 20 | #include 21 | #include 22 | 23 | #include 24 | #include 25 | #include 26 | #include 27 | #include 28 | #include 29 | #include 30 | 31 | #ifdef LINUX 32 | #include 33 | #endif 34 | 35 | #include 36 | #include 37 | 38 | // these are needed for Win32/Linux string comparisons 39 | #define stricmp strcasecmp 40 | #define strnicmp strncasecmp 41 | 42 | typedef int BOOL; 43 | typedef long int LONG; 44 | typedef short int SHORT; 45 | typedef char CHAR; 46 | 47 | typedef unsigned long int DWORD; 48 | typedef unsigned short WORD; 49 | typedef unsigned char BYTE; 50 | typedef unsigned int UINT; 51 | 52 | typedef long long INT64; 53 | typedef unsigned long long UINT64; 54 | 55 | typedef int PT_FILEHANDLE; 56 | typedef void * DLL_HANDLE; 57 | 58 | typedef unsigned long DWORD; 59 | typedef unsigned long* LPDWORD; 60 | typedef void* LPOVERLAPPED; 61 | typedef void* OVERLAPPED; 62 | typedef void* LPVOID; 63 | typedef void* PVOID; 64 | typedef void VOID; 65 | typedef int HANDLE; // note that handle here is assumed to be 66 | // a pointer to a file decriptor 67 | typedef int* PHANDLE; 68 | typedef int BOOL; 69 | 70 | typedef unsigned long UINT32; 71 | typedef unsigned long ULONG; 72 | typedef unsigned short USHORT; 73 | typedef unsigned char UCHAR; 74 | typedef long long INT64; 75 | typedef long long LARGE_INTEGER; 76 | typedef unsigned char BYTE; 77 | 78 | /* These are defined so we can use TCHAR compatible string calls */ 79 | #define _T(arg) arg 80 | #define TCHAR char 81 | #define tstrcpy strcpy 82 | #define tstrncpy strncpy 83 | #define _tcscat strcat 84 | #define _tcscpy(str1, str2) strcpy(str1, str2) 85 | #define _tcslen(str1) strlen(str1) 86 | #define _tfopen(filename, access) fopen(filename, access) 87 | #define _gettc getc 88 | #define _puttc putc 89 | #define _stscanf sscanf 90 | #define _stprintf sprintf 91 | #define _tprintf printf 92 | 93 | 94 | 95 | /* common constants */ 96 | #define SUCCESS 0 97 | #define FAILURE -1 98 | 99 | #define IOCTL_FAIL(status) (status < 0) 100 | 101 | /** unusual return codes */ 102 | #define UNIMPLEMENTED -1001 103 | 104 | // create some equivalent constants in linux that windows have 105 | #define STATIC static 106 | 107 | #ifndef TRUE 108 | #define TRUE 1 109 | #endif 110 | 111 | #ifndef FALSE 112 | #define FALSE 0 113 | #endif 114 | 115 | #ifndef INVALID_HANDLE_VALUE 116 | #define INVALID_HANDLE_VALUE -1 117 | #endif 118 | 119 | /** sleep for x milliseconds */ 120 | inline void nap(unsigned long msec) { usleep(msec*1000); } 121 | 122 | #define Sleep sleep 123 | 124 | typedef double VWTIME; 125 | /** returns the amount of time in seconds since some arbitrary moment. */ 126 | inline VWTIME VWGetTime() { return 0.0; } 127 | 128 | #endif // end linux defs 129 | 130 | // TODO: reference additional headers your program requires here 131 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | # Makefile for Pinocchio 2 | 3 | dirs = Pinocchio AttachWeights 4 | # DemoUI is a windows prog, and on windows, VisualC++ is used, 5 | # so we can ignore it here 6 | # dirs = Pinocchio AttachWeights DemoUI 7 | 8 | # Define a standard makePerDir command, which goes into 9 | # each dir, and runs make $(makerule) 10 | define makePerDir 11 | for dir in $(dirs); \ 12 | do \ 13 | cd $$dir && { $(MAKE) $(makerule); cd ..; }; \ 14 | done 15 | endef 16 | 17 | nullstring := 18 | 19 | all: makerule = $(nullstring) 20 | depend: makerule = depend 21 | clean: makerule = clean 22 | 23 | all depend clean: 24 | $(makePerDir) 25 | 26 | 27 | #all: 28 | # cd Pinocchio && $(MAKE) 29 | # cd DemoUI && $(MAKE) 30 | # 31 | #depend: 32 | # cd Pinocchio && $(MAKE) depend 33 | # cd DemoUI && $(MAKE) depend 34 | # 35 | #clean: 36 | # cd Pinocchio && $(MAKE) clean 37 | # cd DemoUI && $(MAKE) clean 38 | 39 | 40 | # DO NOT DELETE 41 | -------------------------------------------------------------------------------- /Pinocchio.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio Version 16 4 | VisualStudioVersion = 16.0.29613.14 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Project", "Project\Project.vcxproj", "{D512EF05-3826-4CE9-A527-EF75DF68FE26}" 7 | EndProject 8 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Pinocchio", "Pinocchio\Pinocchio.vcxproj", "{835E35C4-9AB1-4CB3-A8A9-A0B89171280D}" 9 | EndProject 10 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "AttachWeights", "AttachWeights\AttachWeights.vcxproj", "{09E0B2DD-ABD8-4202-A4E7-047CC86BA355}" 11 | EndProject 12 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "PinocchioStatic", "PinocchioStatic\PinocchioStatic.vcxproj", "{F66AD322-ABB4-4992-8FEF-BB9CB6BDD9D7}" 13 | EndProject 14 | Global 15 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 16 | Debug|Win32 = Debug|Win32 17 | Release|Win32 = Release|Win32 18 | EndGlobalSection 19 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 20 | {D512EF05-3826-4CE9-A527-EF75DF68FE26}.Debug|Win32.ActiveCfg = Debug|Win32 21 | {D512EF05-3826-4CE9-A527-EF75DF68FE26}.Debug|Win32.Build.0 = Debug|Win32 22 | {D512EF05-3826-4CE9-A527-EF75DF68FE26}.Release|Win32.ActiveCfg = Release|Win32 23 | {D512EF05-3826-4CE9-A527-EF75DF68FE26}.Release|Win32.Build.0 = Release|Win32 24 | {835E35C4-9AB1-4CB3-A8A9-A0B89171280D}.Debug|Win32.ActiveCfg = Debug|Win32 25 | {835E35C4-9AB1-4CB3-A8A9-A0B89171280D}.Debug|Win32.Build.0 = Debug|Win32 26 | {835E35C4-9AB1-4CB3-A8A9-A0B89171280D}.Release|Win32.ActiveCfg = Release|Win32 27 | {835E35C4-9AB1-4CB3-A8A9-A0B89171280D}.Release|Win32.Build.0 = Release|Win32 28 | {09E0B2DD-ABD8-4202-A4E7-047CC86BA355}.Debug|Win32.ActiveCfg = Debug|Win32 29 | {09E0B2DD-ABD8-4202-A4E7-047CC86BA355}.Debug|Win32.Build.0 = Debug|Win32 30 | {09E0B2DD-ABD8-4202-A4E7-047CC86BA355}.Release|Win32.ActiveCfg = Release|Win32 31 | {09E0B2DD-ABD8-4202-A4E7-047CC86BA355}.Release|Win32.Build.0 = Release|Win32 32 | {F66AD322-ABB4-4992-8FEF-BB9CB6BDD9D7}.Debug|Win32.ActiveCfg = Debug|Win32 33 | {F66AD322-ABB4-4992-8FEF-BB9CB6BDD9D7}.Debug|Win32.Build.0 = Debug|Win32 34 | {F66AD322-ABB4-4992-8FEF-BB9CB6BDD9D7}.Release|Win32.ActiveCfg = Release|Win32 35 | {F66AD322-ABB4-4992-8FEF-BB9CB6BDD9D7}.Release|Win32.Build.0 = Release|Win32 36 | EndGlobalSection 37 | GlobalSection(SolutionProperties) = preSolution 38 | HideSolutionNode = FALSE 39 | EndGlobalSection 40 | GlobalSection(ExtensibilityGlobals) = postSolution 41 | SolutionGuid = {BEEC3BB2-CE3D-4AC0-AEF5-B1A15849DF2F} 42 | EndGlobalSection 43 | EndGlobal 44 | -------------------------------------------------------------------------------- /Pinocchio.slnenv: -------------------------------------------------------------------------------- 1 | FLTKDIR=$(SolutionDir)\fltk-1.1.9 -------------------------------------------------------------------------------- /Pinocchio/Makefile: -------------------------------------------------------------------------------- 1 | # Makefile for Pinocchio 2 | CC = g++ 3 | # CCFLAGS = -c -O3 -Wall -fPIC -lm -DDEBUG -g 4 | CCFLAGS = -c -g3 -O0 -Wall -fPIC 5 | LIBS = -lm -pthread -I./../fbx/include -I/usr/include/libxml2/libxml -lxml2 -ldl -lrt -luuid -lz 6 | 7 | OBJECTS := attachment.o discretization.o indexer.o lsqSolver.o mesh.o \ 8 | graphutils.o intersector.o matrix.o skeleton.o embedding.o \ 9 | pinocchioApi.o refinement.o 10 | 11 | BUILD_DIR = ./`uname -s`-`uname -m` 12 | 13 | TARGET = libpinocchio.a 14 | 15 | $(TARGET): $(OBJECTS) 16 | ar rcs $@ $^ 17 | 18 | .cpp.o: 19 | $(CC) $(CCFLAGS) $(LIBS) $< 20 | 21 | 22 | #do a makedepend and remove all the external dependencies from the makefile 23 | #works on my system, no one else should need to do it. 24 | depend: 25 | makedepend *.cpp > /dev/null >& 1 26 | perl -pi -e 's/\.c\.o/\.o/' Makefile 27 | perl -pi -e 's/\/u[Ss]r[a-zA-Z0-9\+\-\/\.\_]*//' Makefile 28 | perl -pi -e 's/\/u[Ss]r[a-zA-Z0-9\+\-\/\.\_]*//' Makefile 29 | perl -pi -e 's/\/u[Ss]r[a-zA-Z0-9\+\-\/\.\_]*//' Makefile 30 | perl -pi -e 's/\/u[Ss]r[a-zA-Z0-9\+\-\/\.\_]*//' Makefile 31 | perl -pi -e 's/\/u[Ss]r[a-zA-Z0-9\+\-\/\.\_]*//' Makefile 32 | perl -pi -e 's/\/u[Ss]r[a-zA-Z0-9\+\-\/\.\_]*//' Makefile 33 | perl -pi -e 's/\/u[Ss]r[a-zA-Z0-9\+\-\/\.\_]*//' Makefile 34 | perl -pi -e 's/\/u[Ss]r[a-zA-Z0-9\+\-\/\.\_]*//' Makefile 35 | perl -pi -e 's/^[a-zA-Z].*\.o\:\s*$$//' Makefile 36 | 37 | clean: 38 | rm -f $(OBJECTS) libpinocchio.a *~ core gmon.out *.bak 39 | 40 | 41 | # DO NOT DELETE 42 | 43 | Pinocchio.o: Pinocchio.h 44 | attachment.o: attachment.h mesh.h vector.h hashutils.h mathutils.h 45 | attachment.o: Pinocchio.h rect.h skeleton.h 46 | attachment.o: graphutils.h transform.h vecutils.h lsqSolver.h 47 | discretization.o: pinocchioApi.h mesh.h vector.h hashutils.h mathutils.h 48 | discretization.o: Pinocchio.h rect.h 49 | discretization.o: quaddisttree.h dtree.h indexer.h multilinear.h 50 | discretization.o: intersector.h vecutils.h pointprojector.h debugging.h 51 | discretization.o: attachment.h skeleton.h graphutils.h transform.h deriv.h 52 | embedding.o: pinocchioApi.h mesh.h vector.h hashutils.h mathutils.h 53 | embedding.o: Pinocchio.h rect.h quaddisttree.h 54 | embedding.o: dtree.h indexer.h multilinear.h intersector.h vecutils.h 55 | embedding.o: pointprojector.h debugging.h attachment.h skeleton.h 56 | embedding.o: graphutils.h transform.h 57 | graphutils.o: graphutils.h vector.h hashutils.h mathutils.h 58 | graphutils.o: Pinocchio.h debugging.h 59 | indexer.o: indexer.h hashutils.h mathutils.h 60 | indexer.o: Pinocchio.h vector.h 61 | intersector.o: intersector.h mesh.h vector.h hashutils.h mathutils.h 62 | intersector.o: Pinocchio.h rect.h vecutils.h 63 | lsqSolver.o: lsqSolver.h 64 | lsqSolver.o: mathutils.h 65 | lsqSolver.o: Pinocchio.h hashutils.h debugging.h 66 | matrix.o: matrix.h mathutils.h 67 | matrix.o: Pinocchio.h debugging.h 68 | mesh.o: mesh.h mesh/fbx.h vector.h hashutils.h mathutils.h 69 | mesh.o: Pinocchio.h 70 | mesh.o: rect.h utils.h debugging.h 71 | fbx.o: mesh/fbx.h mesh.h 72 | pinocchioApi.o: pinocchioApi.h mesh.h vector.h hashutils.h mathutils.h 73 | pinocchioApi.o: Pinocchio.h rect.h 74 | pinocchioApi.o: quaddisttree.h dtree.h indexer.h multilinear.h intersector.h 75 | pinocchioApi.o: vecutils.h pointprojector.h debugging.h attachment.h 76 | pinocchioApi.o: skeleton.h graphutils.h transform.h 77 | refinement.o: pinocchioApi.h mesh.h vector.h hashutils.h mathutils.h 78 | refinement.o: Pinocchio.h rect.h quaddisttree.h 79 | refinement.o: dtree.h indexer.h multilinear.h intersector.h vecutils.h 80 | refinement.o: pointprojector.h debugging.h attachment.h skeleton.h 81 | refinement.o: graphutils.h transform.h deriv.h 82 | skeleton.o: skeleton.h graphutils.h vector.h hashutils.h mathutils.h 83 | skeleton.o: Pinocchio.h utils.h debugging.h 84 | -------------------------------------------------------------------------------- /Pinocchio/Pinocchio.cpp: -------------------------------------------------------------------------------- 1 | /* This file is part of the Pinocchio automatic rigging library. 2 | Copyright (C) 2007 Ilya Baran (ibaran@mit.edu) 3 | 4 | This library is free software; you can redistribute it and/or 5 | modify it under the terms of the GNU Lesser General Public 6 | License as published by the Free Software Foundation; either 7 | version 2.1 of the License, or (at your option) any later version. 8 | 9 | This library is distributed in the hope that it will be useful, 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | Lesser General Public License for more details. 13 | 14 | You should have received a copy of the GNU Lesser General Public 15 | License along with this library; if not, write to the Free Software 16 | Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 17 | */ 18 | 19 | // Pinocchio.cpp : Defines the entry point for the DLL application. 20 | #include "windows.h" 21 | #include "Pinocchio.h" 22 | 23 | #ifdef _MANAGED 24 | #pragma managed(push, off) 25 | #endif 26 | 27 | BOOL APIENTRY DllMain( HMODULE hModule, 28 | DWORD ul_reason_for_call, 29 | LPVOID lpReserved 30 | ) 31 | { 32 | switch (ul_reason_for_call) 33 | { 34 | case DLL_PROCESS_ATTACH: 35 | case DLL_THREAD_ATTACH: 36 | case DLL_THREAD_DETACH: 37 | case DLL_PROCESS_DETACH: 38 | break; 39 | } 40 | return TRUE; 41 | } 42 | 43 | #ifdef _MANAGED 44 | #pragma managed(pop) 45 | #endif 46 | 47 | -------------------------------------------------------------------------------- /Pinocchio/Pinocchio.h: -------------------------------------------------------------------------------- 1 | /* This file is part of the Pinocchio automatic rigging library. 2 | Copyright (C) 2007 Ilya Baran (ibaran@mit.edu) 3 | 4 | This library is free software; you can redistribute it and/or 5 | modify it under the terms of the GNU Lesser General Public 6 | License as published by the Free Software Foundation; either 7 | version 2.1 of the License, or (at your option) any later version. 8 | 9 | This library is distributed in the hope that it will be useful, 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | Lesser General Public License for more details. 13 | 14 | You should have received a copy of the GNU Lesser General Public 15 | License along with this library; if not, write to the Free Software 16 | Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 17 | */ 18 | 19 | // The following ifdef block is the standard way of creating macros which make exporting 20 | // from a DLL simpler. All files within this DLL are compiled with the PINOCCHIO_EXPORTS 21 | // symbol defined on the command line. this symbol should not be defined on any project 22 | // that uses this DLL. This way any other project whose source files include this file see 23 | // PINOCCHIO_API functions as being imported from a DLL, whereas this DLL sees symbols 24 | // defined with this macro as being exported. 25 | #ifdef _WIN32 26 | #ifdef PINOCCHIO_EXPORTS 27 | #define PINOCCHIO_API __declspec(dllexport) 28 | #else //PINOCCHIO_EXPORTS 29 | #ifdef PINOCCHIO_STATIC 30 | #define PINOCCHIO_API 31 | #else //PINOCCHIO_STATIC 32 | #define PINOCCHIO_API __declspec(dllimport) 33 | #endif //PINOCCHIO_STATIC 34 | #endif //PINOCCHIO_EXPORTS 35 | #else //_WIN32 36 | #define PINOCCHIO_API 37 | #endif //_WIN32 38 | -------------------------------------------------------------------------------- /Pinocchio/Pinocchio.vcproj: -------------------------------------------------------------------------------- 1 | 2 | 10 | 11 | 14 | 15 | 16 | 17 | 18 | 25 | 28 | 31 | 34 | 37 | 40 | 52 | 55 | 58 | 61 | 65 | 68 | 71 | 74 | 77 | 80 | 83 | 86 | 89 | 90 | 98 | 101 | 104 | 107 | 110 | 113 | 126 | 129 | 132 | 135 | 138 | 141 | 144 | 147 | 150 | 153 | 156 | 159 | 162 | 163 | 164 | 165 | 166 | 167 | 172 | 175 | 176 | 179 | 180 | 183 | 184 | 187 | 188 | 191 | 192 | 195 | 196 | 199 | 200 | 203 | 204 | 207 | 208 | 211 | 212 | 215 | 216 | 219 | 220 | 223 | 224 | 225 | 230 | 233 | 234 | 237 | 238 | 241 | 242 | 245 | 246 | 249 | 250 | 253 | 254 | 257 | 258 | 261 | 262 | 265 | 266 | 269 | 270 | 273 | 274 | 277 | 278 | 281 | 282 | 285 | 286 | 289 | 290 | 293 | 294 | 297 | 298 | 301 | 302 | 305 | 306 | 309 | 310 | 313 | 314 | 317 | 318 | 321 | 322 | 323 | 324 | 325 | 326 | 327 | -------------------------------------------------------------------------------- /Pinocchio/Pinocchio.vcxproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Debug 6 | Win32 7 | 8 | 9 | Release 10 | Win32 11 | 12 | 13 | 14 | {835E35C4-9AB1-4CB3-A8A9-A0B89171280D} 15 | Pinocchio 16 | Win32Proj 17 | 18 | 19 | 20 | DynamicLibrary 21 | v142 22 | Unicode 23 | true 24 | 25 | 26 | DynamicLibrary 27 | v142 28 | Unicode 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | <_ProjectFileVersion>16.0.29511.113 42 | 43 | 44 | $(SolutionDir)$(Configuration)\ 45 | $(Configuration)\ 46 | MinimumRecommendedRules.ruleset 47 | 48 | 49 | $(VC_IncludePath);$(WindowsSDK_IncludePath);$(FBX_DIR)\include 50 | $(VC_LibraryPath_x86);$(WindowsSDK_LibraryPath_x86);$(NETFXKitsDir)Lib\um\x86;$(FBX_DIR)\lib 51 | 52 | 53 | $(SolutionDir)$(Configuration)\ 54 | $(Configuration)\ 55 | MinimumRecommendedRules.ruleset 56 | 57 | 58 | $(VC_IncludePath);$(WindowsSDK_IncludePath);$(FBX_DIR)\include 59 | $(FBX_DIR)\lib;$(LibraryPath) 60 | 61 | 62 | 63 | Disabled 64 | WIN32;_DEBUG;_WINDOWS;_USRDLL;PINOCCHIO_EXPORTS;%(PreprocessorDefinitions) 65 | true 66 | EnableFastChecks 67 | MultiThreadedDebugDLL 68 | 69 | Level3 70 | EditAndContinue 71 | stdcpp14 72 | $(FBX_DIR)/include 73 | true 74 | 75 | 76 | true 77 | $(FBX_DIR)/lib/vs2015/x86/debug 78 | kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;wininet.lib;libfbxsdk-md.lib;%(AdditionalDependencies) 79 | 80 | 81 | 82 | 83 | Full 84 | AnySuitable 85 | true 86 | Speed 87 | WIN32;NDEBUG;_WINDOWS;_USRDLL;PINOCCHIO_EXPORTS;%(PreprocessorDefinitions) 88 | MultiThreadedDLL 89 | 90 | Level3 91 | ProgramDatabase 92 | $(FBX_DIR)/include 93 | 94 | 95 | $(FBX_DIR)/lib/vs2015/x86/release 96 | wininet.lib;libfbxsdk-md.lib;%(AdditionalDependencies) 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | -------------------------------------------------------------------------------- /Pinocchio/Pinocchio.vcxproj.filters: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF} 6 | cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx 7 | 8 | 9 | {93995380-89BD-4b04-88EB-625FBE52EBFB} 10 | h;hpp;hxx;hm;inl;inc;xsd 11 | 12 | 13 | 14 | 15 | Source Files 16 | 17 | 18 | Source Files 19 | 20 | 21 | Source Files 22 | 23 | 24 | Source Files 25 | 26 | 27 | Source Files 28 | 29 | 30 | Source Files 31 | 32 | 33 | Source Files 34 | 35 | 36 | Source Files 37 | 38 | 39 | Source Files 40 | 41 | 42 | Source Files 43 | 44 | 45 | Source Files 46 | 47 | 48 | Source Files 49 | 50 | 51 | Source Files 52 | 53 | 54 | 55 | 56 | Header Files 57 | 58 | 59 | Header Files 60 | 61 | 62 | Header Files 63 | 64 | 65 | Header Files 66 | 67 | 68 | Header Files 69 | 70 | 71 | Header Files 72 | 73 | 74 | Header Files 75 | 76 | 77 | Header Files 78 | 79 | 80 | Header Files 81 | 82 | 83 | Header Files 84 | 85 | 86 | Header Files 87 | 88 | 89 | Header Files 90 | 91 | 92 | Header Files 93 | 94 | 95 | Header Files 96 | 97 | 98 | Header Files 99 | 100 | 101 | Header Files 102 | 103 | 104 | Header Files 105 | 106 | 107 | Header Files 108 | 109 | 110 | Header Files 111 | 112 | 113 | Header Files 114 | 115 | 116 | Header Files 117 | 118 | 119 | Header Files 120 | 121 | 122 | Header Files 123 | 124 | 125 | -------------------------------------------------------------------------------- /Pinocchio/attachment.h: -------------------------------------------------------------------------------- 1 | /* This file is part of the Pinocchio automatic rigging library. 2 | Copyright (C) 2007 Ilya Baran (ibaran@mit.edu) 3 | 4 | This library is free software; you can redistribute it and/or 5 | modify it under the terms of the GNU Lesser General Public 6 | License as published by the Free Software Foundation; either 7 | version 2.1 of the License, or (at your option) any later version. 8 | 9 | This library is distributed in the hope that it will be useful, 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | Lesser General Public License for more details. 13 | 14 | You should have received a copy of the GNU Lesser General Public 15 | License along with this library; if not, write to the Free Software 16 | Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 17 | */ 18 | 19 | #ifndef ATTACHMENT_H 20 | #define ATTACHMENT_H 21 | 22 | #include "mesh.h" 23 | #include "skeleton.h" 24 | #include "transform.h" 25 | 26 | class VisibilityTester 27 | { 28 | public: 29 | virtual ~VisibilityTester() {} 30 | virtual bool canSee(const Pinocchio::Vector3 &v1, const Pinocchio::Vector3 &v2) const = 0; 31 | }; 32 | 33 | template class VisTester : public VisibilityTester 34 | { 35 | public: 36 | VisTester(const T *t) : tree(t) {} 37 | 38 | virtual bool canSee(const Pinocchio::Vector3 &v1, const Pinocchio::Vector3 &v2) const //faster when v2 is farther inside than v1 39 | { 40 | const double maxVal = 0.002; 41 | double atV2 = tree->locate(v2)->evaluate(v2); 42 | double left = (v2 - v1).length(); 43 | double leftInc = left / 100.; 44 | Pinocchio::Vector3 diff = (v2 - v1) / 100.; 45 | Pinocchio::Vector3 cur = v1 + diff; 46 | while(left >= 0.) { 47 | double curDist = tree->locate(cur)->evaluate(cur); 48 | if(curDist > maxVal) 49 | return false; 50 | //if curDist and atV2 are so negative that distance won't reach above maxVal, return true 51 | if(curDist + atV2 + left <= maxVal) 52 | return true; 53 | cur += diff; 54 | left -= leftInc; 55 | } 56 | return true; 57 | } 58 | 59 | private: 60 | const T *tree; 61 | }; 62 | template VisibilityTester *makeVisibilityTester(const T *tree) { return new VisTester(tree); } //be sure to delete afterwards 63 | 64 | class AttachmentPrivate; 65 | 66 | class PINOCCHIO_API Attachment 67 | { 68 | public: 69 | Attachment() : a(NULL) {} 70 | Attachment(const Attachment &); 71 | Attachment(const Mesh &mesh, const Skeleton &skeleton, const vector &match, const VisibilityTester *tester, double initialHeatWeight=1.); 72 | virtual ~Attachment(); 73 | 74 | Mesh deform(const Mesh &mesh, const vector > &transforms) const; 75 | Vector getWeights(int i) const; 76 | private: 77 | AttachmentPrivate * a = nullptr; 78 | }; 79 | 80 | #endif 81 | -------------------------------------------------------------------------------- /Pinocchio/debugging.h: -------------------------------------------------------------------------------- 1 | /* This file is part of the Pinocchio automatic rigging library. 2 | Copyright (C) 2007 Ilya Baran (ibaran@mit.edu) 3 | 4 | This library is free software; you can redistribute it and/or 5 | modify it under the terms of the GNU Lesser General Public 6 | License as published by the Free Software Foundation; either 7 | version 2.1 of the License, or (at your option) any later version. 8 | 9 | This library is distributed in the hope that it will be useful, 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | Lesser General Public License for more details. 13 | 14 | You should have received a copy of the GNU Lesser General Public 15 | License along with this library; if not, write to the Free Software 16 | Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 17 | */ 18 | 19 | #ifndef DEBUGGING_H 20 | #define DEBUGGING_H 21 | 22 | #include "mathutils.h" 23 | 24 | class Debugging 25 | { 26 | public: 27 | static ostream &out() { return *outStream; } 28 | static void PINOCCHIO_API setOutStream(ostream &os) { outStream = &os; } 29 | 30 | private: 31 | static ostream *outStream; 32 | }; 33 | 34 | #endif //DEBUGGING_H 35 | -------------------------------------------------------------------------------- /Pinocchio/deriv.h: -------------------------------------------------------------------------------- 1 | /* This file is part of the Pinocchio automatic rigging library. 2 | Copyright (C) 2007 Ilya Baran (ibaran@mit.edu) 3 | 4 | This library is free software; you can redistribute it and/or 5 | modify it under the terms of the GNU Lesser General Public 6 | License as published by the Free Software Foundation; either 7 | version 2.1 of the License, or (at your option) any later version. 8 | 9 | This library is distributed in the hope that it will be useful, 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | Lesser General Public License for more details. 13 | 14 | You should have received a copy of the GNU Lesser General Public 15 | License along with this library; if not, write to the Free Software 16 | Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 17 | */ 18 | 19 | #ifndef DERIV_H_INCLUDED 20 | #define DERIV_H_INCLUDED 21 | 22 | #include "vector.h" 23 | 24 | template 25 | class Deriv 26 | { 27 | public: 28 | typedef Deriv Self; 29 | 30 | Deriv() : x(Real()) {} 31 | Deriv(const Real &inX) : x(inX) {} 32 | Deriv(const Real &inX, int varNum) : x(inX) { d[varNum] = Real(1.); } 33 | Deriv(const Self &inD) : x(inD.x), d(inD.d) {} 34 | Deriv(const Real &inX, const Vector &inD) : x(inX), d(inD) {} 35 | 36 | Real getReal() const { return x; } 37 | Real getDeriv(int num = 0) const { return d[num]; } 38 | 39 | Self operator*(const Self &other) const { return Self(x * other.x, x * other.d + other.x * d); } 40 | Self operator+(const Self &other) const { return Self(x + other.x, d + other.d); } 41 | Self operator-(const Self &other) const { return Self(x - other.x, d - other.d); } 42 | Self operator/(const Self &other) const { return Self(x / other.x, (other.x * d - x * other.d) / SQR(other.x)); } 43 | Self operator-() const { return Self(-x, -d); } 44 | Self &operator+=(const Self &other) { x += other.x; d += other.d; return *this; } 45 | Self &operator-=(const Self &other) { x -= other.x; d -= other.d; return *this; } 46 | Self &operator*=(const Self &other) { (*this) = (*this) * other; return *this; } 47 | Self &operator/=(const Self &other) { (*this) = (*this) / other; return *this; } 48 | 49 | bool operator<(const Self &other) const { return x < other.x; } 50 | bool operator<=(const Self &other) const { return x <= other.x; } 51 | bool operator>(const Self &other) const { return x > other.x; } 52 | bool operator>=(const Self &other) const { return x >= other.x; } 53 | bool operator==(const Self &other) const { return x == other.x; } 54 | bool operator!=(const Self &other) const { return x != other.x; } 55 | 56 | operator Real() const { return x; } 57 | 58 | //for internal use 59 | const Real &_x() const { return x; } 60 | const Vector &_d() const { return d; } 61 | 62 | private: 63 | 64 | Real x; 65 | Vector d; 66 | }; 67 | 68 | #define DerivRV Deriv 69 | #define ONEVAR(func, deriv) template \ 70 | DerivRV func(const DerivRV &x) { return DerivRV(func(x._x()), x._d() * (deriv)); } 71 | 72 | ONEVAR(sqrt, Real(0.5) / sqrt(x._x())) 73 | ONEVAR(log, Real(1.) / x._x()) 74 | ONEVAR(log10, Real(0.43429448190325182765) / x._x()) //the number is 1 / log(10) 75 | ONEVAR(exp, exp(x._x())) 76 | ONEVAR(sin, cos(x._x())) 77 | ONEVAR(cos, -sin(x._x())) 78 | ONEVAR(tan, Real(1.) / SQR(cos(x._x()))) 79 | ONEVAR(acos, Real(-1.) / sqrt(Real(1. - SQR(x._x())))) 80 | ONEVAR(asin, Real(1.) / sqrt(Real(1. - SQR(x._x())))) 81 | ONEVAR(atan, Real(1.) / (Real(1.) + SQR(x._x()))) 82 | ONEVAR(fabs, x._x() < Real(0.) ? Real(-1.) : Real(1.)) 83 | 84 | #undef ONEVAR 85 | #define TWOVAR(func, derivx, derivy) template \ 86 | DerivRV func(const DerivRV &x, const DerivRV &y) { return DerivRV(func(x._x(), y._x()), x._d() * (derivx) + y._d() * (derivy)); } 87 | 88 | TWOVAR(pow, y._x() * pow(x._x(), y._x() - Real(1.)), log(x._x()) * pow(x._x(), y._x())) 89 | TWOVAR(atan2, y._x() / (SQR(x._x()) + SQR(y._x())), -x._x() / (SQR(x._x()) + SQR(y._x()))) 90 | 91 | #undef TWOVAR 92 | #undef DerivRV 93 | 94 | template 95 | basic_ostream& operator<<(basic_ostream& os, const Deriv &d) 96 | { 97 | os << "Deriv(" << d._x() << ", " << d._d() << ")"; 98 | return os; 99 | } 100 | 101 | #endif //DERIV_H_INCLUDED 102 | -------------------------------------------------------------------------------- /Pinocchio/dtree.h: -------------------------------------------------------------------------------- 1 | /* This file is part of the Pinocchio automatic rigging library. 2 | Copyright (C) 2007 Ilya Baran (ibaran@mit.edu) 3 | 4 | This library is free software; you can redistribute it and/or 5 | modify it under the terms of the GNU Lesser General Public 6 | License as published by the Free Software Foundation; either 7 | version 2.1 of the License, or (at your option) any later version. 8 | 9 | This library is distributed in the hope that it will be useful, 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | Lesser General Public License for more details. 13 | 14 | You should have received a copy of the GNU Lesser General Public 15 | License along with this library; if not, write to the Free Software 16 | Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 17 | */ 18 | 19 | #ifndef DTREE_H 20 | #define DTREE_H 21 | 22 | #include "rect.h" 23 | #include "indexer.h" 24 | 25 | template 26 | class DNode : public Data 27 | { 28 | public: 29 | typedef DNode Self; 30 | typedef Vector Vec; 31 | typedef Rect MyRect; 32 | 33 | int countNodes() const 34 | { 35 | int nodes = 1; 36 | if(children[0] != NULL) 37 | for(int i = 0; i < numChildren; ++i) 38 | nodes += children[i]->countNodes(); 39 | return nodes; 40 | } 41 | 42 | int maxLevel() const 43 | { 44 | if(children[0] == NULL) 45 | return 0; 46 | int ml = 0; 47 | for(int i = 0; i < numChildren; ++i) 48 | ml = max(ml, children[i]->maxLevel()); 49 | return 1 + ml; 50 | } 51 | 52 | Self *getParent() const { return parent; } 53 | Self *getChild(int idx) const { return children[idx]; } 54 | const MyRect &getRect() const { return rect; } 55 | int getChildIndex() const { return childIndex; } 56 | 57 | static const int numChildren = 1 << Dim; 58 | 59 | private: 60 | DNode(MyRect r) : Data(this), parent(NULL), rect(r) 61 | { 62 | zeroChildren(); 63 | Data::init(); 64 | } 65 | 66 | DNode(Self *inParent, int inChildIndex) : Data(this), parent(inParent), childIndex(inChildIndex) 67 | { 68 | zeroChildren(); 69 | rect = MyRect(inParent->rect.getCorner(childIndex)) | MyRect(inParent->rect.getCenter()); 70 | Data::init(); 71 | } 72 | 73 | ~DNode() 74 | { 75 | for(int i = 0; i < numChildren; ++i) 76 | if(children[i]) 77 | delete children[i]; 78 | } 79 | 80 | void split() 81 | { 82 | for(int i = 0; i < numChildren; ++i) 83 | children[i] = new Self(this, i); 84 | } 85 | 86 | template class IDX> friend class DRootNode; 87 | 88 | void zeroChildren() { for(int i = 0; i < numChildren; ++i) children[i] = NULL; } 89 | 90 | //data 91 | Self *parent; 92 | Self *children[numChildren]; 93 | int childIndex; 94 | 95 | MyRect rect; 96 | }; 97 | 98 | template class Indexer = DumbIndexer> 99 | class DRootNode : public DNode, public Indexer, Dim> 100 | { 101 | public: 102 | typedef DNode Node; 103 | typedef DRootNode Self; 104 | typedef Indexer MyIndexer; 105 | typedef Vector Vec; 106 | typedef Rect MyRect; 107 | 108 | DRootNode(MyRect r = MyRect(Vec(), Vec().apply(bind2nd(plus(), 1.)))) : Node(r) 109 | { 110 | MyIndexer::setRoot(this); 111 | } 112 | 113 | void split(Node *node) 114 | { 115 | node->split(); 116 | } 117 | }; 118 | 119 | #endif 120 | -------------------------------------------------------------------------------- /Pinocchio/graphutils.cpp: -------------------------------------------------------------------------------- 1 | /* This file is part of the Pinocchio automatic rigging library. 2 | Copyright (C) 2007 Ilya Baran (ibaran@mit.edu) 3 | 4 | This library is free software; you can redistribute it and/or 5 | modify it under the terms of the GNU Lesser General Public 6 | License as published by the Free Software Foundation; either 7 | version 2.1 of the License, or (at your option) any later version. 8 | 9 | This library is distributed in the hope that it will be useful, 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | Lesser General Public License for more details. 13 | 14 | You should have received a copy of the GNU Lesser General Public 15 | License along with this library; if not, write to the Free Software 16 | Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 17 | */ 18 | 19 | #include "graphutils.h" 20 | #include "debugging.h" 21 | 22 | #define CHECK(pred) { if(!(pred)) { Debugging::out() << "Graph integrity error: " #pred << " in line " << __LINE__ << endl; return false; } } 23 | 24 | bool PtGraph::integrityCheck() const 25 | { 26 | CHECK(verts.size() == edges.size()); 27 | 28 | int i, j, k; 29 | for(i = 0; i < (int)edges.size(); ++i) { 30 | for(j = 0; j < (int)edges[i].size(); ++j) { 31 | int cur = edges[i][j]; 32 | CHECK(cur >= 0); 33 | CHECK(cur < (int)edges.size()); 34 | CHECK(cur != i); //no self edges 35 | 36 | vector::const_iterator it = find(edges[cur].begin(), edges[cur].end(), i); 37 | CHECK(it != edges[cur].end()); 38 | 39 | for(k = 0; k < j; ++k) //duplicates 40 | CHECK(cur != edges[i][k]); 41 | } 42 | } 43 | 44 | return true; 45 | } 46 | 47 | ShortestPather::ShortestPather(const PtGraph &g, int root) 48 | { 49 | int sz = g.verts.size(); 50 | priority_queue todo; 51 | vector done(sz, false); 52 | prev.resize(sz, -1); 53 | dist.resize(sz, -1); 54 | 55 | todo.push(Inf(0., root, -1)); 56 | while(!todo.empty()) 57 | { 58 | Inf cur = todo.top(); 59 | todo.pop(); 60 | if(done[cur.node]) 61 | continue; 62 | done[cur.node] = true; 63 | prev[cur.node] = cur.prev; 64 | dist[cur.node] = cur.dist; 65 | 66 | const vector &e = g.edges[cur.node]; 67 | for(int i = 0; i < (int)e.size(); ++i) { 68 | if(!done[e[i]]) { 69 | double dist = cur.dist + (g.verts[cur.node] - g.verts[e[i]]).length(); 70 | todo.push(Inf(dist, e[i], cur.node)); 71 | } 72 | } 73 | } 74 | } 75 | -------------------------------------------------------------------------------- /Pinocchio/graphutils.h: -------------------------------------------------------------------------------- 1 | /* This file is part of the Pinocchio automatic rigging library. 2 | Copyright (C) 2007 Ilya Baran (ibaran@mit.edu) 3 | 4 | This library is free software; you can redistribute it and/or 5 | modify it under the terms of the GNU Lesser General Public 6 | License as published by the Free Software Foundation; either 7 | version 2.1 of the License, or (at your option) any later version. 8 | 9 | This library is distributed in the hope that it will be useful, 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | Lesser General Public License for more details. 13 | 14 | You should have received a copy of the GNU Lesser General Public 15 | License along with this library; if not, write to the Free Software 16 | Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 17 | */ 18 | 19 | #ifndef GRAPHUTILS_H 20 | #define GRAPHUTILS_H 21 | 22 | #include 23 | #include "vector.h" 24 | 25 | struct PtGraph 26 | { 27 | vector verts; 28 | vector > edges; 29 | 30 | bool integrityCheck() const; 31 | }; 32 | 33 | class ShortestPather 34 | { 35 | public: 36 | ShortestPather(const PtGraph &g, int root); 37 | 38 | vector pathFrom(int vtx) const 39 | { 40 | vector out(1, vtx); 41 | while(prev[vtx] >= 0) 42 | out.push_back(vtx = prev[vtx]); 43 | return out; 44 | } 45 | double distFrom(int vtx) const { return dist[vtx]; } 46 | 47 | private: 48 | struct Inf 49 | { 50 | Inf(double inDist, int inNode, int inPrev) : dist(inDist), node(inNode), prev(inPrev) {} 51 | bool operator<(const Inf &inf) const { return dist > inf.dist; } 52 | double dist; 53 | int node, prev; 54 | }; 55 | 56 | vector prev; 57 | vector dist; 58 | }; 59 | 60 | class AllShortestPather 61 | { 62 | public: 63 | AllShortestPather() {} 64 | 65 | AllShortestPather(const PtGraph &g) 66 | { 67 | for(int i = 0; i < (int)g.verts.size(); ++i) 68 | paths.push_back(ShortestPather(g, i)); 69 | } 70 | 71 | vector path(int from, int to) const { return paths[to].pathFrom(from); } 72 | double dist(int from, int to) const { return paths[to].distFrom(from); } 73 | 74 | private: 75 | vector paths; 76 | }; 77 | 78 | 79 | #endif 80 | -------------------------------------------------------------------------------- /Pinocchio/hashutils.h: -------------------------------------------------------------------------------- 1 | /* This file is part of the Pinocchio automatic rigging library. 2 | Copyright (C) 2007 Ilya Baran (ibaran@mit.edu) 3 | 4 | This library is free software; you can redistribute it and/or 5 | modify it under the terms of the GNU Lesser General Public 6 | License as published by the Free Software Foundation; either 7 | version 2.1 of the License, or (at your option) any later version. 8 | 9 | This library is distributed in the hope that it will be useful, 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | Lesser General Public License for more details. 13 | 14 | You should have received a copy of the GNU Lesser General Public 15 | License along with this library; if not, write to the Free Software 16 | Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 17 | */ 18 | 19 | #ifndef HASHUTILS_H 20 | #define HASHUTILS_H 21 | 22 | #include "mathutils.h" 23 | 24 | #ifndef _WIN32 25 | #include 26 | #include 27 | 28 | #define _HASH_NAMESPACE __gnu_cxx 29 | 30 | using namespace _HASH_NAMESPACE; 31 | 32 | namespace _HASH_NAMESPACE { 33 | template struct hash > 34 | { 35 | size_t operator()(const pair &p) const { return hash()(p.first) + 37 * hash()(p.second); } 36 | }; 37 | 38 | template struct hash 39 | { 40 | size_t operator()(T *p) const { return (size_t)p; } 41 | }; 42 | } 43 | 44 | #define MAKE_HASH(type, code) \ 45 | namespace _HASH_NAMESPACE { \ 46 | template<> struct hash \ 47 | { \ 48 | size_t operator()(const type &p) const { code } \ 49 | }; \ 50 | } 51 | #else //MICROSOFT VC 2005 52 | #include 53 | #include 54 | #include 55 | #include 56 | 57 | #define _HASH_NAMESPACE stdext 58 | 59 | using namespace _HASH_NAMESPACE; 60 | 61 | namespace _HASH_NAMESPACE { 62 | template struct hash 63 | { 64 | size_t operator()(const T &p) { return hash_compare()(p); } 65 | }; 66 | 67 | template struct hash_compare > 68 | { 69 | static const size_t bucket_size = 4; 70 | static const size_t min_buckets = 8; 71 | size_t operator()(const std::pair &p) const { return hash_compare()(p.first) + 37 * hash_compare()(p.second); } 72 | bool operator()(const std::pair &p1, const std::pair &p2) const { return p1 < p2; } 73 | }; 74 | 75 | template struct hash_compare 76 | { 77 | static const size_t bucket_size = 4; 78 | static const size_t min_buckets = 8; 79 | size_t operator()(T *p) const { return (size_t)p; } 80 | bool operator()(T *p1, T *p2) const { return p1 < p2; } 81 | }; 82 | } 83 | 84 | #define MAKE_HASH(type, code) \ 85 | namespace _HASH_NAMESPACE { \ 86 | template<> struct hash_compare \ 87 | { \ 88 | static const size_t bucket_size = 4; \ 89 | static const size_t min_buckets = 8; \ 90 | size_t operator()(const type &p) const { code } \ 91 | bool operator()(const type &p1, const type &p2) const { return p1 < p2; } \ 92 | }; \ 93 | } 94 | #endif 95 | 96 | #endif //HASHUTILS_H 97 | -------------------------------------------------------------------------------- /Pinocchio/indexer.cpp: -------------------------------------------------------------------------------- 1 | /* This file is part of the Pinocchio automatic rigging library. 2 | Copyright (C) 2007 Ilya Baran (ibaran@mit.edu) 3 | 4 | This library is free software; you can redistribute it and/or 5 | modify it under the terms of the GNU Lesser General Public 6 | License as published by the Free Software Foundation; either 7 | version 2.1 of the License, or (at your option) any later version. 8 | 9 | This library is distributed in the hope that it will be useful, 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | Lesser General Public License for more details. 13 | 14 | You should have received a copy of the GNU Lesser General Public 15 | License along with this library; if not, write to the Free Software 16 | Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 17 | */ 18 | 19 | #include "indexer.h" 20 | 21 | unsigned int interLeaveLookupTable[32768]; 22 | 23 | class LookupTable 24 | { 25 | public: 26 | LookupTable() 27 | { 28 | for(int i = 0; i < 32768; ++i) { 29 | interLeaveLookupTable[i] = 0; 30 | for(int k = 0; k < 15; ++k) 31 | if(i & (1 << k)) 32 | interLeaveLookupTable[i] += (1 << (28 - 2 * k)); 33 | } 34 | } 35 | }; 36 | 37 | static LookupTable lt; 38 | 39 | unsigned int interLeave3LookupTable[1024]; 40 | 41 | class LookupTable3 42 | { 43 | public: 44 | LookupTable3() 45 | { 46 | for(int i = 0; i < 1024; ++i) { 47 | interLeave3LookupTable[i] = 0; 48 | for(int k = 0; k < 10; ++k) 49 | if(i & (1 << k)) 50 | interLeave3LookupTable[i] += (1 << (27 - 3 * k)); 51 | } 52 | } 53 | }; 54 | 55 | static LookupTable3 lt3; 56 | -------------------------------------------------------------------------------- /Pinocchio/indexer.h: -------------------------------------------------------------------------------- 1 | /* This file is part of the Pinocchio automatic rigging library. 2 | Copyright (C) 2007 Ilya Baran (ibaran@mit.edu) 3 | 4 | This library is free software; you can redistribute it and/or 5 | modify it under the terms of the GNU Lesser General Public 6 | License as published by the Free Software Foundation; either 7 | version 2.1 of the License, or (at your option) any later version. 8 | 9 | This library is distributed in the hope that it will be useful, 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | Lesser General Public License for more details. 13 | 14 | You should have received a copy of the GNU Lesser General Public 15 | License along with this library; if not, write to the Free Software 16 | Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 17 | */ 18 | 19 | #ifndef INDEXER_H 20 | #define INDEXER_H 21 | 22 | #include "hashutils.h" 23 | #include "vector.h" 24 | 25 | template 26 | class DumbIndexer 27 | { 28 | public: 29 | typedef typename Node::Vec Vec; 30 | 31 | DumbIndexer() : root(NULL) {} 32 | 33 | void setRoot(Node *n) 34 | { 35 | root = n; 36 | } 37 | 38 | void preprocessIndex() {} 39 | 40 | Node *locate(const Vec &v) const 41 | { 42 | Node *out = root; 43 | while(out->getChild(0)) { 44 | Vec center = out->getChild(0)->getRect().getHi(); 45 | out = out->getChild(BitComparator::less(center, v)); 46 | } 47 | return out; 48 | } 49 | 50 | private: 51 | Node *root; 52 | }; 53 | 54 | extern PINOCCHIO_API unsigned int interLeaveLookupTable[32768]; 55 | extern PINOCCHIO_API unsigned int interLeave3LookupTable[1024]; 56 | 57 | inline unsigned int _lookup(const Pinocchio::Vector2 &vec) 58 | { 59 | return interLeaveLookupTable[int(vec[0] * 32767.999)] + (interLeaveLookupTable[int(vec[1] * 32767.999)] << 1); 60 | } 61 | 62 | inline unsigned int _lookup(const Pinocchio::Vector3 &vec) 63 | { 64 | return interLeave3LookupTable[int(vec[0] * 1023.999)] + 65 | (interLeave3LookupTable[int(vec[1] * 1023.999)] << 1) + 66 | (interLeave3LookupTable[int(vec[2] * 1023.999)] << 2); 67 | } 68 | 69 | template 70 | class Indexer 71 | { 72 | public: 73 | typedef typename Node::Vec Vec; 74 | 75 | Indexer() : root(NULL) {} 76 | 77 | void setRoot(Node *n) 78 | { 79 | root = n; 80 | } 81 | 82 | void preprocessIndex() {} 83 | 84 | Node *locate(const Vec &v) const 85 | { 86 | Node *out = root; 87 | unsigned int idx = _lookup(v); 88 | static const int mask = (1 << Dim) - 1; 89 | while(out->getChild(idx & mask)) { 90 | out = out->getChild(idx & mask); 91 | idx = idx >> Dim; 92 | } 93 | return out; 94 | } 95 | private: 96 | Node *root; 97 | }; 98 | 99 | template 100 | class ArrayIndexer 101 | { 102 | public: 103 | typedef typename Node::Vec Vec; 104 | 105 | ArrayIndexer() : root(NULL) {} 106 | 107 | void setRoot(Node *n) 108 | { 109 | root = n; 110 | } 111 | 112 | static const int bits = 16 - (16 % Dim); 113 | 114 | void preprocessIndex() 115 | { 116 | for(int i = 0; i < (1 << bits); ++i) { 117 | table[i] = root; 118 | int cur = i; 119 | int cnt = 0; 120 | static const int mask = (1 << Dim) - 1; 121 | while(table[i]->getChild(0) && cnt < (bits / Dim)) { 122 | ++cnt; 123 | table[i] = table[i]->getChild(cur & mask); 124 | cur = cur >> Dim; 125 | } 126 | } 127 | } 128 | 129 | Node *locate(const Vec &v) const 130 | { 131 | unsigned int idx = _lookup(v); 132 | Node *out = table[idx & ((1 << bits) - 1)]; 133 | if(!out->getChild(0)) 134 | return out; 135 | idx = idx >> bits; 136 | static const int mask = (1 << Dim) - 1; 137 | do { 138 | out = out->getChild(idx & mask); 139 | idx = idx >> Dim; 140 | } while(out->getChild(idx & mask)); 141 | return out; 142 | } 143 | private: 144 | Node *root; 145 | Node *table[(1 << bits)]; 146 | }; 147 | 148 | template class HashIndex 149 | { 150 | public: 151 | HashIndex() { for(int i = 0; i < num; ++i) nodeMap[i] = make_pair(-1, (Node *)NULL); } 152 | 153 | void add(Node *node, unsigned int idx) 154 | { 155 | int idxx = (idx >> (Level - bits)); 156 | //int idxx = idx % num; 157 | if(nodeMap[idxx].first == -1) 158 | nodeMap[idxx] = make_pair(idx, node); 159 | } 160 | 161 | Node *lookup(unsigned int idx) const 162 | { 163 | const pair &p = nodeMap[(idx >> (Level - bits))]; 164 | //const pair &p = nodeMap[idx % num]; 165 | return p.first == idx ? p.second : NULL; 166 | } 167 | 168 | static const int bits = 16; 169 | static const int num = (1 << bits); 170 | //static const int num = 75437; 171 | 172 | private: 173 | pair nodeMap[num]; 174 | }; 175 | 176 | template 177 | class HashIndexer 178 | { 179 | public: 180 | typedef typename Node::Vec Vec; 181 | 182 | HashIndexer() : root(NULL) {} 183 | 184 | void setRoot(Node *n) 185 | { 186 | root = n; 187 | } 188 | 189 | static const int bits = 16; 190 | static const int hlev = 22; 191 | 192 | void preprocessIndex() 193 | { 194 | for(int i = 0; i < (1 << bits); ++i) { 195 | table[i] = root; 196 | int cur = i; 197 | int cnt = 0; 198 | while(table[i]->getChild(0) && cnt < (bits / 2)) { 199 | ++cnt; 200 | table[i] = table[i]->getChild(cur & 3); 201 | cur = cur >> 2; 202 | } 203 | } 204 | add(root, 0, 0); 205 | } 206 | 207 | Node *locate(const Vec &v) const 208 | { 209 | unsigned int idx = _lookup(v); 210 | Node *out = table[idx & ((1 << bits) - 1)]; 211 | if(!out->getChild(0)) 212 | return out; 213 | Node *n = hNodes.lookup(idx & ((1 << hlev) - 1)); 214 | if(!n) 215 | idx = idx >> bits; 216 | else { 217 | out = n; 218 | if(!out->getChild(0)) 219 | return out; 220 | idx = idx >> hlev; 221 | } 222 | do { 223 | out = out->getChild(idx & 3); 224 | idx = idx >> 2; 225 | } while(out->getChild(idx & 3)); 226 | return out; 227 | } 228 | private: 229 | unsigned int getIndex(Node *n) const 230 | { 231 | if(n == root) 232 | return 0; 233 | int level = getLevel(n); 234 | return (n->getChildIndex() << (2 * level - 2)) + getIndex(n->getParent()); 235 | } 236 | int getLevel(Node *n) const 237 | { 238 | if(n == root) 239 | return 0; 240 | return 1 + getLevel(n->getParent()); 241 | } 242 | 243 | void add(Node *cur, int level, unsigned int idx) 244 | { 245 | if(level == hlev) { 246 | hNodes.add(cur, idx); 247 | return; 248 | } 249 | if(cur->getChild(0) == NULL) 250 | return; 251 | for(int i = 0; i < 4; ++i) 252 | add(cur->getChild(i), level + 2, idx + (i << level)); 253 | } 254 | 255 | Node *root; 256 | Node *table[(1 << bits)]; 257 | HashIndex hNodes; 258 | }; 259 | #endif 260 | -------------------------------------------------------------------------------- /Pinocchio/intersector.cpp: -------------------------------------------------------------------------------- 1 | /* This file is part of the Pinocchio automatic rigging library. 2 | Copyright (C) 2007 Ilya Baran (ibaran@mit.edu) 3 | 4 | This library is free software; you can redistribute it and/or 5 | modify it under the terms of the GNU Lesser General Public 6 | License as published by the Free Software Foundation; either 7 | version 2.1 of the License, or (at your option) any later version. 8 | 9 | This library is distributed in the hope that it will be useful, 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | Lesser General Public License for more details. 13 | 14 | You should have received a copy of the GNU Lesser General Public 15 | License along with this library; if not, write to the Free Software 16 | Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 17 | */ 18 | 19 | #include "intersector.h" 20 | 21 | #include 22 | #include 23 | 24 | //------------------Intersector----------------- 25 | 26 | static const int cells = 200; 27 | 28 | void Intersector::getIndex(const Pinocchio::Vector2 &pt, int &x, int &y) const 29 | { 30 | Pinocchio::Vector2 c = (pt - bounds.getLo()).apply(divides(), bounds.getSize()); 31 | x = int(c[0] * double(cells)); 32 | y = int(c[0] * double(cells)); 33 | x = max(0, min(cells - 1, x)); 34 | y = max(0, min(cells - 1, y)); 35 | } 36 | 37 | void Intersector::init() 38 | { 39 | int i, j, k; 40 | const vector &vtc = mesh->vertices; 41 | const vector &edg = mesh->edges; 42 | 43 | dir = dir.normalize(); 44 | getBasis(dir, v1, v2); 45 | 46 | points.resize(vtc.size()); 47 | sNormals.resize(edg.size() / 3); 48 | for(i = 0; i < (int)vtc.size(); ++i) { 49 | points[i] = Pinocchio::Vector2(vtc[i].pos * v1, vtc[i].pos * v2); 50 | } 51 | 52 | bounds = Rect2(points.begin(), points.end()); 53 | 54 | triangles.resize(cells * cells); 55 | for(i = 0; i < (int)edg.size(); i += 3) { 56 | Rect2 triRect; 57 | for(j = 0; j < 3; ++j) 58 | triRect |= Rect2(points[edg[i + j].vertex]); 59 | 60 | int fromx, fromy, tox, toy; 61 | getIndex(triRect.getLo(), fromx, fromy); 62 | getIndex(triRect.getHi(), tox, toy); 63 | 64 | for(j = fromy; j <= toy; ++j) for(k = fromx; k <= tox; ++k) { 65 | triangles[j * cells + k].push_back(i); 66 | } 67 | 68 | Pinocchio::Vector3 cross = (vtc[edg[i + 1].vertex].pos - vtc[edg[i].vertex].pos) % (vtc[edg[i + 2].vertex].pos - vtc[edg[i].vertex].pos); 69 | j = i / 3; 70 | sNormals[j] = cross.normalize(); 71 | if(fabs(sNormals[j] * dir) <= 1e-8) 72 | sNormals[j] = Pinocchio::Vector3(); //zero if coplanar 73 | else 74 | sNormals[j] = sNormals[j] / (sNormals[j] * dir); //prescaled for intersection 75 | } 76 | } 77 | 78 | vector Intersector::intersect(const Pinocchio::Vector3 &pt, vector *outIndices) const 79 | { 80 | int i; 81 | const vector &vtc = mesh->vertices; 82 | const vector &edg = mesh->edges; 83 | 84 | vector out; 85 | 86 | Pinocchio::Vector2 pt2(pt * v1, pt * v2); 87 | if(!bounds.contains(pt2)) 88 | return out; //no intersections 89 | 90 | int x, y; 91 | getIndex(pt2, x, y); 92 | const vector &tris = triangles[y * cells + x]; 93 | for(i = 0; i < (int)tris.size(); ++i) { 94 | int j; 95 | //check if triangle intersects line 96 | int sign[3]; 97 | int idx[3]; 98 | for(j = 0; j < 3; ++j) { 99 | idx[j] = edg[tris[i] + j].vertex; 100 | } 101 | for(j = 0; j < 3; ++j) { 102 | Pinocchio::Vector2 d1 = points[idx[(j + 1) % 3]] - points[idx[j]]; 103 | Pinocchio::Vector2 d2 = pt2 - points[idx[j]]; 104 | sign[j] = SIGN(d1[0] * d2[1] - d1[1] * d2[0]); 105 | } 106 | if(sign[0] != sign[1] || sign[1] != sign[2]) 107 | continue; //no intersection 108 | 109 | if(outIndices) 110 | outIndices->push_back(tris[i]); 111 | 112 | //now compute the plane intersection 113 | const Pinocchio::Vector3 &n = sNormals[tris[i] / 3]; 114 | if(n.lengthsq() == 0) { //triangle and line coplanar --just project the triangle center to the line and hope for the best 115 | Pinocchio::Vector3 ctr = (vtc[idx[0]].pos + vtc[idx[1]].pos + vtc[idx[2]].pos) * (1. / 3.); 116 | out.push_back(projToLine(ctr, pt, dir)); 117 | continue; 118 | } 119 | 120 | out.push_back(pt + dir * (n * (vtc[idx[0]].pos - pt))); //intersection 121 | } 122 | 123 | return out; 124 | } 125 | -------------------------------------------------------------------------------- /Pinocchio/intersector.h: -------------------------------------------------------------------------------- 1 | /* This file is part of the Pinocchio automatic rigging library. 2 | Copyright (C) 2007 Ilya Baran (ibaran@mit.edu) 3 | 4 | This library is free software; you can redistribute it and/or 5 | modify it under the terms of the GNU Lesser General Public 6 | License as published by the Free Software Foundation; either 7 | version 2.1 of the License, or (at your option) any later version. 8 | 9 | This library is distributed in the hope that it will be useful, 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | Lesser General Public License for more details. 13 | 14 | You should have received a copy of the GNU Lesser General Public 15 | License along with this library; if not, write to the Free Software 16 | Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 17 | */ 18 | 19 | #ifndef INTERSECTOR_H 20 | #define INTERSECTOR_H 21 | 22 | #include "mesh.h" 23 | #include "vecutils.h" 24 | 25 | class PINOCCHIO_API Intersector { 26 | public: 27 | Intersector() : mesh(NULL) {} 28 | Intersector(const Mesh &m, const Pinocchio::Vector3 &inDir) : mesh(&m), dir(inDir) { init(); } 29 | 30 | vector intersect(const Pinocchio::Vector3 &pt, vector *outIndices = NULL) const; 31 | const Pinocchio::Vector3 &getDir() const { return dir; } 32 | private: 33 | void init(); 34 | void getIndex(const Pinocchio::Vector2 &pt, int &x, int &y) const; 35 | 36 | const Mesh *mesh; 37 | Pinocchio::Vector3 dir; 38 | Pinocchio::Vector3 v1, v2; //basis 39 | Rect2 bounds; //within the basis 40 | 41 | vector points; 42 | vector sNormals; //they are scaled for intersection 43 | vector > triangles; 44 | }; 45 | 46 | #endif //INTERSECTOR_H 47 | -------------------------------------------------------------------------------- /Pinocchio/mathutils.h: -------------------------------------------------------------------------------- 1 | /* This file is part of the Pinocchio automatic rigging library. 2 | Copyright (C) 2007 Ilya Baran (ibaran@mit.edu) 3 | 4 | This library is free software; you can redistribute it and/or 5 | modify it under the terms of the GNU Lesser General Public 6 | License as published by the Free Software Foundation; either 7 | version 2.1 of the License, or (at your option) any later version. 8 | 9 | This library is distributed in the hope that it will be useful, 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | Lesser General Public License for more details. 13 | 14 | You should have received a copy of the GNU Lesser General Public 15 | License along with this library; if not, write to the Free Software 16 | Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 17 | */ 18 | 19 | #ifndef MATHUTILS_H_INCLUDED 20 | #define MATHUTILS_H_INCLUDED 21 | 22 | #include 23 | #include 24 | #include 25 | 26 | #define min(x,y) ((x)>(y)?(y):(x)) 27 | #define max(x,y) ((x)>(y)?(x):(y)) 28 | 29 | #include "Pinocchio.h" 30 | 31 | #ifdef _WIN32 32 | #pragma warning(disable:4355) 33 | #pragma warning(disable:4996) 34 | #pragma warning(disable:4251) 35 | #endif //_WIN32 36 | 37 | using namespace std; 38 | 39 | #ifndef M_PI 40 | #define M_PI 3.14159265358979323846 41 | #endif 42 | 43 | inline int ROUND(double x) { return (int)(x + 0.5); } 44 | inline int SIGN(double x) { return (x > 0.) ? 1 : -1; } 45 | template T SQR(const T & x) { return x * x; } 46 | template T CUBE(const T & x) { return x * x * x; } 47 | template T QUAD(const T & x) { return SQR(SQR(x)); } 48 | 49 | template class maximum : public binary_function 50 | { 51 | public: 52 | T operator()(const T &a1, const T &a2) const { return max(a1, a2); } 53 | }; 54 | 55 | template class minimum : public binary_function 56 | { 57 | public: 58 | T operator()(const T &a1, const T &a2) const { return min(a1, a2); } 59 | }; 60 | 61 | template class myMult : public binary_function 62 | { 63 | public: 64 | R operator()(const A1 &a1, const A2 &a2) const { return a1 * a2; } 65 | }; 66 | 67 | template class myDiv : public binary_function 68 | { 69 | public: 70 | R operator()(const A1 &a1, const A2 &a2) const { return a1 / a2; } 71 | }; 72 | 73 | template class ident : public unary_function 74 | { 75 | public: 76 | T operator()(const T &v) const { return v; } 77 | }; 78 | 79 | template class construct 80 | { 81 | public: 82 | typedef T result_type; 83 | template T operator()(const From &x) const { return T(x); } 84 | }; 85 | 86 | #ifdef _WIN32 87 | inline bool operator==(const string &s1, const string &s2) { return s1.compare(s2) == 0; } 88 | inline bool operator<(const string &s1, const string &s2) { return s1.compare(s2) < 0; } 89 | #endif 90 | 91 | #endif //MATHUTILS_H_INCLUDED 92 | -------------------------------------------------------------------------------- /Pinocchio/matrix.cpp: -------------------------------------------------------------------------------- 1 | /* This file is part of the Pinocchio automatic rigging library. 2 | Copyright (C) 2007 Ilya Baran (ibaran@mit.edu) 3 | 4 | This library is free software; you can redistribute it and/or 5 | modify it under the terms of the GNU Lesser General Public 6 | License as published by the Free Software Foundation; either 7 | version 2.1 of the License, or (at your option) any later version. 8 | 9 | This library is distributed in the hope that it will be useful, 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | Lesser General Public License for more details. 13 | 14 | You should have received a copy of the GNU Lesser General Public 15 | License along with this library; if not, write to the Free Software 16 | Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 17 | */ 18 | 19 | #include "matrix.h" 20 | #include "debugging.h" 21 | 22 | namespace EigPrivate 23 | { 24 | pair findMaxAbs(const Vectorn &vec, int maxElem) 25 | { 26 | pair out = make_pair(0, fabs(vec[0])); 27 | for(int i = 1; i < maxElem; ++i) 28 | if(vec[i] > out.second) 29 | out = make_pair(i, fabs(vec[i])); 30 | return out; 31 | } 32 | 33 | void jacobi(int row, int col, Matrixn &m, Matrixn *vectors) 34 | { 35 | double num = m[row][row] - m[col][col]; 36 | double dem = 2. * m[row][col]; 37 | 38 | double theta = num / dem; 39 | double t; 40 | if(fabs(theta) > 1e20) { 41 | t = m[row][col] / num; 42 | } 43 | else { 44 | t = (theta > 0 ? 1. : -1.) / (fabs(theta) + sqrt(theta * theta + 1.)); 45 | } 46 | 47 | double c = 1. / sqrt(t * t + 1.); 48 | double s = t * c; 49 | 50 | double tau = s / (1. + c); 51 | 52 | //rotation 53 | m[col][col] -= t * m[row][col]; 54 | m[row][row] += t * m[row][col]; 55 | 56 | int i; 57 | for(i = 0; i < col; ++i) { 58 | double oldCI = m[col][i]; 59 | m[col][i] -= s * (m[row][i] + tau * m[col][i]); 60 | m[row][i] += s * (oldCI - tau * m[row][i]); 61 | } 62 | for(i = col + 1; i < row; ++i) { 63 | double oldIC = m[i][col]; 64 | m[i][col] -= s * (m[row][i] + tau * m[i][col]); 65 | m[row][i] += s * (oldIC - tau * m[row][i]); 66 | } 67 | for(i = row + 1; i < m.getRows(); ++i) { 68 | double oldIC = m[i][col]; 69 | m[i][col] -= s * (m[i][row] + tau * m[i][col]); 70 | m[i][row] += s * (oldIC - tau * m[i][row]); 71 | } 72 | 73 | if(vectors) { 74 | for(i = 0; i < m.getRows(); ++i) { 75 | double oldIC = (*vectors)[i][col]; 76 | (*vectors)[i][col] -= s * ((*vectors)[i][row] + tau * (*vectors)[i][col]); 77 | (*vectors)[i][row] += s * (oldIC - tau * (*vectors)[i][row]); 78 | } 79 | } 80 | 81 | m[row][col] = 0; 82 | } 83 | } 84 | 85 | using namespace EigPrivate; 86 | 87 | Vectorn getEigensystem(Matrixn m, Matrixn *vectors) 88 | { 89 | int i; 90 | assert(m.getRows() == m.getCols()); 91 | int sz = m.getRows(); 92 | assert(sz > 1); 93 | if(vectors) 94 | *vectors = Matrixn::identity(sz); 95 | 96 | const double tol = 1e-12; 97 | int iter = 0; 98 | while(++iter < 50) { 99 | int j; 100 | double biggestSoFar = -1; 101 | for(i = 0; i < sz; ++i) for(j = 0; j < i; ++j) { 102 | biggestSoFar = max(biggestSoFar, fabs(m[i][j])); 103 | jacobi(i, j, m, vectors); 104 | } 105 | if(biggestSoFar < tol) 106 | break; 107 | } 108 | Debugging::out() << iter << endl; 109 | 110 | Vectorn out(sz); 111 | for(i = 0; i < sz; ++i) 112 | out[i] = m[i][i]; 113 | 114 | //now sort by decreasing eigenvalue 115 | vector > perm; 116 | for(i = 0; i < sz; ++i) { 117 | perm.push_back(make_pair(fabs(out[i]), i)); 118 | } 119 | sort(perm.begin(), perm.end()); 120 | reverse(perm.begin(), perm.end()); 121 | Vectorn oldOut = out; 122 | 123 | if(!vectors) { 124 | for(i = 0; i < sz; ++i) 125 | out[i] = oldOut[perm[i].second]; 126 | } 127 | else { 128 | Matrixn oldVectors = ~(*vectors); 129 | 130 | for(i = 0; i < sz; ++i) { 131 | out[i] = oldOut[perm[i].second]; 132 | (*vectors)[i] = oldVectors[perm[i].second]; 133 | } 134 | 135 | *vectors = ~(*vectors); 136 | } 137 | 138 | return out; 139 | } 140 | 141 | -------------------------------------------------------------------------------- /Pinocchio/mesh.h: -------------------------------------------------------------------------------- 1 | /* This file is part of the Pinocchio automatic rigging library. 2 | Copyright (C) 2007 Ilya Baran (ibaran@mit.edu) 3 | 4 | This library is free software; you can redistribute it and/or 5 | modify it under the terms of the GNU Lesser General Public 6 | License as published by the Free Software Foundation; either 7 | version 2.1 of the License, or (at your option) any later version. 8 | 9 | This library is distributed in the hope that it will be useful, 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | Lesser General Public License for more details. 13 | 14 | You should have received a copy of the GNU Lesser General Public 15 | License along with this library; if not, write to the Free Software 16 | Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 17 | */ 18 | 19 | #ifndef MESH_H 20 | #define MESH_H 21 | 22 | #include 23 | #include 24 | #include 25 | 26 | #include "vector.h" 27 | #include "rect.h" 28 | 29 | using namespace std; 30 | 31 | struct MeshVertex { 32 | MeshVertex() : edge(-1) { 33 | this->texture = Pinocchio::Vector3(0, 0, -1); 34 | } 35 | 36 | Pinocchio::Vector3 pos; 37 | Pinocchio::Vector3 normal; 38 | Pinocchio::Vector3 texture; 39 | unordered_map weights; 40 | int edge; //an edge such that edge->prev->vertex is this 41 | }; 42 | 43 | struct MeshEdge 44 | { 45 | MeshEdge() : vertex(-1), prev(-1), twin(-1) {} 46 | 47 | int vertex; //the vertex the edge points to--the start vertex is prev->vertex 48 | int prev; //ccw, next is prev->prev 49 | int twin; 50 | }; 51 | 52 | struct Material { 53 | Material(string path, int index): path(path), index(index) {}; 54 | 55 | string path; 56 | int index; 57 | }; 58 | 59 | class PINOCCHIO_API Mesh { 60 | public: 61 | Mesh() : scale(1.) {} 62 | Mesh(const string &file); 63 | 64 | bool integrityCheck() const; 65 | bool isConnected() const; //returns true if the mesh consists of a single connected component 66 | void computeVertexNormals(); 67 | void computeVertexTextures(); 68 | void normalizeBoundingBox(); 69 | void computeTopology(); 70 | void writeObj(const string &filename) const; 71 | 72 | private: 73 | void readObj(istream &strm); 74 | void readOff(istream &strm); 75 | void readPly(istream &strm); 76 | void readGts(istream &strm); 77 | void readStl(istream &strm); 78 | void readFbx(const string &file, const string &hint = ""); 79 | void fixDupFaces(); 80 | void sortEdges(); //sort edges so that triplets forming faces are adjacent 81 | 82 | public: //data 83 | vector vertices; 84 | vector edges; 85 | vector textures; 86 | unordered_map joints; 87 | unordered_map materials; 88 | Pinocchio::Vector3 toAdd; 89 | double scale; 90 | }; 91 | 92 | #endif 93 | -------------------------------------------------------------------------------- /Pinocchio/multilinear.h: -------------------------------------------------------------------------------- 1 | /* This file is part of the Pinocchio automatic rigging library. 2 | Copyright (C) 2007 Ilya Baran (ibaran@mit.edu) 3 | 4 | This library is free software; you can redistribute it and/or 5 | modify it under the terms of the GNU Lesser General Public 6 | License as published by the Free Software Foundation; either 7 | version 2.1 of the License, or (at your option) any later version. 8 | 9 | This library is distributed in the hope that it will be useful, 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | Lesser General Public License for more details. 13 | 14 | You should have received a copy of the GNU Lesser General Public 15 | License along with this library; if not, write to the Free Software 16 | Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 17 | */ 18 | 19 | #ifndef MULTILINEAR_H_INCLUDED 20 | #define MULTILINEAR_H_INCLUDED 21 | 22 | #include "rect.h" 23 | 24 | //multilinear function over unit hypercube 25 | template 26 | class Multilinear 27 | { 28 | public: 29 | Multilinear() 30 | { 31 | for(int i = 0; i < num; ++i) 32 | values[i] = Value(); 33 | } 34 | 35 | void setValue(int idx, const Value &value) { values[idx] = value; } 36 | const Value &getValue(int idx) const { return values[idx]; } 37 | 38 | template 39 | Real evaluate(const Vector &v) const 40 | { 41 | Real out(0); 42 | for(int i = 0; i < num; ++i) { 43 | Vector corner; 44 | BitComparator::assignCorner(i, v, Vector(1.) - v, corner); 45 | Real factor = corner.accumulate(ident(), multiplies()); 46 | out += (factor * Real(values[i])); 47 | } 48 | return out; 49 | } 50 | 51 | template 52 | Real integrate(const Rect &r) const 53 | { 54 | return r.isEmpty() ? Real() : evaluate(r.getCenter()) * r.getContent(); 55 | } 56 | 57 | private: 58 | Multilinear(const Multilinear &); //noncopyable 59 | 60 | template 61 | static Real pos(const Real &r1, const Real &r2) 62 | { 63 | if(r1 <= Real(0) && r2 <= Real(0)) 64 | return Real(0); 65 | if(r1 >= Real(0) && r2 >= Real(0)) 66 | return Real(1); 67 | if(r2 >= r1) 68 | return r2 / (r2 - r1); 69 | return r1 / (r1 - r2); 70 | } 71 | 72 | 73 | static const int num = (1 << Dim); 74 | Value values[num]; 75 | }; 76 | 77 | #endif //MULTILINEAR_H_INCLUDED 78 | -------------------------------------------------------------------------------- /Pinocchio/pinocchioApi.cpp: -------------------------------------------------------------------------------- 1 | /* This file is part of the Pinocchio automatic rigging library. 2 | Copyright (C) 2007 Ilya Baran (ibaran@mit.edu) 3 | 4 | This library is free software; you can redistribute it and/or 5 | modify it under the terms of the GNU Lesser General Public 6 | License as published by the Free Software Foundation; either 7 | version 2.1 of the License, or (at your option) any later version. 8 | 9 | This library is distributed in the hope that it will be useful, 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | Lesser General Public License for more details. 13 | 14 | You should have received a copy of the GNU Lesser General Public 15 | License along with this library; if not, write to the Free Software 16 | Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 17 | */ 18 | 19 | #include "pinocchioApi.h" 20 | #include "debugging.h" 21 | #include 22 | 23 | ostream *Debugging::outStream = new ofstream(); 24 | 25 | PinocchioOutput autorig(const Skeleton &given, const Mesh &m) 26 | { 27 | int i; 28 | PinocchioOutput out; 29 | 30 | Mesh newMesh = prepareMesh(m); 31 | 32 | if(newMesh.vertices.size() == 0) 33 | return out; 34 | 35 | TreeType *distanceField = constructDistanceField(newMesh); 36 | 37 | //discretization 38 | vector medialSurface = sampleMedialSurface(distanceField); 39 | 40 | vector spheres = packSpheres(medialSurface); 41 | 42 | PtGraph graph = connectSamples(distanceField, spheres); 43 | 44 | //discrete embedding 45 | vector > possibilities = computePossibilities(graph, spheres, given); 46 | 47 | //constraints can be set by respecifying possibilities for skeleton joints: 48 | //to constrain joint i to sphere j, use: possiblities[i] = vector(1, j); 49 | 50 | vector embeddingIndices = discreteEmbed(graph, spheres, given, possibilities); 51 | 52 | if(embeddingIndices.size() == 0) { //failure 53 | delete distanceField; 54 | return out; 55 | } 56 | 57 | vector discreteEmbedding = splitPaths(embeddingIndices, graph, given); 58 | 59 | //continuous refinement 60 | vector medialCenters(medialSurface.size()); 61 | for(i = 0; i < (int)medialSurface.size(); ++i) 62 | medialCenters[i] = medialSurface[i].center; 63 | 64 | out.embedding = refineEmbedding(distanceField, medialCenters, discreteEmbedding, given); 65 | 66 | //attachment 67 | VisTester *tester = new VisTester(distanceField); 68 | out.attachment = new Attachment(newMesh, given, out.embedding, tester); 69 | 70 | //cleanup 71 | delete tester; 72 | delete distanceField; 73 | 74 | return out; 75 | } 76 | 77 | -------------------------------------------------------------------------------- /Pinocchio/pinocchioApi.h: -------------------------------------------------------------------------------- 1 | /* This file is part of the Pinocchio automatic rigging library. 2 | Copyright (C) 2007 Ilya Baran (ibaran@mit.edu) 3 | 4 | This library is free software; you can redistribute it and/or 5 | modify it under the terms of the GNU Lesser General Public 6 | License as published by the Free Software Foundation; either 7 | version 2.1 of the License, or (at your option) any later version. 8 | 9 | This library is distributed in the hope that it will be useful, 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | Lesser General Public License for more details. 13 | 14 | You should have received a copy of the GNU Lesser General Public 15 | License along with this library; if not, write to the Free Software 16 | Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 17 | */ 18 | 19 | #ifndef PINOCCHIOAPI_H 20 | #define PINOCCHIOAPI_H 21 | 22 | #include "mesh.h" 23 | #include "quaddisttree.h" 24 | #include "attachment.h" 25 | 26 | struct PinocchioOutput 27 | { 28 | PinocchioOutput() : attachment(NULL) {} 29 | 30 | vector embedding; 31 | Attachment *attachment; //user responsible for deletion 32 | }; 33 | 34 | //calls the other functions and does the whole rigging process 35 | //see the implementation of this function to find out how to use the individual functions 36 | PinocchioOutput PINOCCHIO_API autorig(const Skeleton &given, const Mesh &m); 37 | 38 | //============================================individual steps===================================== 39 | 40 | //fits mesh inside unit cube, makes sure there's exactly one connected component 41 | Mesh PINOCCHIO_API prepareMesh(const Mesh &m); 42 | 43 | 44 | typedef DRootNode, 3, ArrayIndexer> TreeType; //our distance field octree type 45 | static const double defaultTreeTol = 0.003; 46 | 47 | //constructs a distance field on an octree--user responsible for deleting output 48 | TreeType PINOCCHIO_API *constructDistanceField(const Mesh &m, double tol = defaultTreeTol); 49 | 50 | struct Sphere { 51 | Sphere() : radius(0.) {} 52 | Sphere(const Pinocchio::Vector3 &inC, double inR) : center(inC), radius(inR) {} 53 | 54 | Pinocchio::Vector3 center; 55 | double radius; 56 | }; 57 | 58 | //samples the distance field to find spheres on the medial surface 59 | //output is sorted by radius in decreasing order 60 | vector PINOCCHIO_API sampleMedialSurface(TreeType *distanceField, double tol = defaultTreeTol); 61 | 62 | //takes sorted medial surface samples and sparsifies the vector 63 | vector PINOCCHIO_API packSpheres(const vector &samples, int maxSpheres = 1000); 64 | 65 | //constructs graph on packed sphere centers 66 | PtGraph PINOCCHIO_API connectSamples(TreeType *distanceField, const vector &spheres); 67 | 68 | //finds which joints can be embedded into which sphere centers 69 | vector > PINOCCHIO_API computePossibilities(const PtGraph &graph, const vector &spheres, 70 | const Skeleton &skeleton); 71 | 72 | //finds discrete embedding 73 | vector PINOCCHIO_API discreteEmbed(const PtGraph &graph, const vector &spheres, 74 | const Skeleton &skeleton, const vector > &possibilities); 75 | 76 | //reinserts joints for unreduced skeleton 77 | vector PINOCCHIO_API splitPaths(const vector &discreteEmbedding, const PtGraph &graph, 78 | const Skeleton &skeleton); 79 | 80 | //refines embedding 81 | vector PINOCCHIO_API refineEmbedding(TreeType *distanceField, const vector &medialSurface, 82 | const vector &initialEmbedding, const Skeleton &skeleton); 83 | 84 | //to compute the attachment, create a new Attachment object 85 | 86 | #endif //PINOCCHIOAPI_H 87 | -------------------------------------------------------------------------------- /Pinocchio/pointprojector.h: -------------------------------------------------------------------------------- 1 | /* This file is part of the Pinocchio automatic rigging library. 2 | Copyright (C) 2007 Ilya Baran (ibaran@mit.edu) 3 | 4 | This library is free software; you can redistribute it and/or 5 | modify it under the terms of the GNU Lesser General Public 6 | License as published by the Free Software Foundation; either 7 | version 2.1 of the License, or (at your option) any later version. 8 | 9 | This library is distributed in the hope that it will be useful, 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | Lesser General Public License for more details. 13 | 14 | You should have received a copy of the GNU Lesser General Public 15 | License along with this library; if not, write to the Free Software 16 | Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 17 | */ 18 | 19 | #ifndef POINTPROJECTOR_H 20 | #define POINTPROJECTOR_H 21 | 22 | #include 23 | 24 | #include "vector.h" 25 | #include "rect.h" 26 | #include "vecutils.h" 27 | #include "debugging.h" 28 | 29 | struct Vec3Object 30 | { 31 | Vec3Object(const Pinocchio::Vector3 &inV) : v(inV) {} 32 | 33 | Rect3 boundingRect() const { return Rect3(v); } 34 | double operator[](int i) const { return v[i]; } 35 | Pinocchio::Vector3 project(const Pinocchio::Vector3 &) const { return v; } 36 | 37 | Pinocchio::Vector3 v; 38 | }; 39 | 40 | struct Tri3Object 41 | { 42 | Tri3Object(const Pinocchio::Vector3 &inV1, const Pinocchio::Vector3 &inV2, const Pinocchio::Vector3 &inV3) : v1(inV1), v2(inV2), v3(inV3) {} 43 | 44 | Rect3 boundingRect() const { return Rect3(v1) | Rect3(v2) | Rect3(v3); } 45 | double operator[](int i) const { return v1[i] + v2[i] + v3[i]; } //for comparison only, no need to divide by 3 46 | Pinocchio::Vector3 project(const Pinocchio::Vector3 &v) const { return projToTri(v, v1, v2, v3); } 47 | 48 | Pinocchio::Vector3 v1, v2, v3; 49 | }; 50 | 51 | template 52 | class ObjectProjector 53 | { 54 | public: 55 | typedef Vector Vec; 56 | typedef Rect Rec; 57 | 58 | ObjectProjector() {} 59 | ObjectProjector(const vector &inObjs) : objs(inObjs) 60 | { 61 | int i, d; 62 | vector orders[Dim]; 63 | 64 | for(d = 0; d < Dim; ++d) { 65 | orders[d].reserve(objs.size()); 66 | for(i = 0; i < (int)objs.size(); ++i) 67 | orders[d].push_back(i); 68 | sort(orders[d].begin(), orders[d].end(), DLess(d, objs)); 69 | } 70 | 71 | rnodes.reserve((int)objs.size() * 2 - 1); 72 | initHelper(orders); 73 | } 74 | 75 | Vec project(const Vec &from) const 76 | { 77 | double minDistSq = 1e37; 78 | Vec closestSoFar; 79 | 80 | int sz = 1; 81 | static pair todo[10000]; 82 | todo[0] = make_pair(rnodes[0].rect.distSqTo(from), 0); 83 | 84 | while(sz > 0) { 85 | if(todo[--sz].first > minDistSq) { 86 | continue; 87 | } 88 | int cur = todo[sz].second; //the top element that was just popped 89 | 90 | int c1 = rnodes[cur].child1; 91 | int c2 = rnodes[cur].child2; 92 | 93 | if(c1 >= 0) { //not a leaf 94 | double l1 = rnodes[c1].rect.distSqTo(from); 95 | if(l1 < minDistSq) 96 | todo[sz++] = make_pair(l1, c1); 97 | 98 | double l2 = rnodes[c2].rect.distSqTo(from); 99 | if(l2 < minDistSq) 100 | todo[sz++] = make_pair(l2, c2); 101 | 102 | if(sz >= 2 && todo[sz - 1].first > todo[sz - 2].first) { 103 | swap(todo[sz - 1], todo[sz - 2]); 104 | } 105 | if(sz > 9995) {//getting close to our array limit 106 | Debugging::out() << "Large todo list, likely to fail" << endl; 107 | } 108 | continue; 109 | } 110 | 111 | //leaf -- consider the object 112 | Vec curPt = objs[c2].project(from); 113 | double distSq = (from - curPt).lengthsq(); 114 | if(distSq <= minDistSq) { 115 | minDistSq = distSq; 116 | closestSoFar = curPt; 117 | } 118 | } 119 | 120 | return closestSoFar; 121 | }; 122 | 123 | struct RNode 124 | { 125 | Rec rect; 126 | int child1, child2; //if child1 is -1, child2 is the object index 127 | }; 128 | 129 | const vector &getRNodes() const { return rnodes; } 130 | 131 | private: 132 | 133 | struct DL { bool operator()(const pair &p1, 134 | const pair &p2) const { return p1.first > p2.first; } }; 135 | 136 | int initHelper(vector orders[Dim], int curDim = 0) 137 | { 138 | int out = rnodes.size(); 139 | rnodes.resize(out + 1); 140 | 141 | int num = orders[0].size(); 142 | if(num == 1) { 143 | rnodes[out].rect = objs[orders[0][0]].boundingRect(); 144 | rnodes[out].child1 = -1; 145 | rnodes[out].child2 = orders[0][0]; 146 | } 147 | else { 148 | int i, d; 149 | vector orders1[Dim], orders2[Dim]; 150 | set left; 151 | for(i = 0; i < num / 2; ++i) 152 | left.insert(orders[curDim][i]); 153 | 154 | for(d = 0; d < Dim; ++d) { 155 | orders1[d].reserve((num + 1) / 2); 156 | orders2[d].reserve((num + 1) / 2); 157 | for(i = 0; i < num; ++i) { 158 | if(left.count(orders[d][i])) 159 | orders1[d].push_back(orders[d][i]); 160 | else 161 | orders2[d].push_back(orders[d][i]); 162 | } 163 | } 164 | 165 | rnodes[out].child1 = initHelper(orders1, (curDim + 1) % Dim); 166 | rnodes[out].child2 = initHelper(orders2, (curDim + 1) % Dim); 167 | rnodes[out].rect = rnodes[rnodes[out].child1].rect | rnodes[rnodes[out].child2].rect; 168 | } 169 | return out; 170 | } 171 | 172 | class DLess 173 | { 174 | public: 175 | DLess(int inDim, const vector &inObjs) : dim(inDim), objs(inObjs) {} 176 | bool operator()(int i1, int i2) { return objs[i1][dim] < objs[i2][dim]; } 177 | private: 178 | int dim; 179 | const vector &objs; 180 | }; 181 | 182 | vector rnodes; 183 | vector objs; 184 | }; 185 | #endif 186 | -------------------------------------------------------------------------------- /Pinocchio/rect.h: -------------------------------------------------------------------------------- 1 | /* This file is part of the Pinocchio automatic rigging library. 2 | Copyright (C) 2007 Ilya Baran (ibaran@mit.edu) 3 | 4 | This library is free software; you can redistribute it and/or 5 | modify it under the terms of the GNU Lesser General Public 6 | License as published by the Free Software Foundation; either 7 | version 2.1 of the License, or (at your option) any later version. 8 | 9 | This library is distributed in the hope that it will be useful, 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | Lesser General Public License for more details. 13 | 14 | You should have received a copy of the GNU Lesser General Public 15 | License along with this library; if not, write to the Free Software 16 | Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 17 | */ 18 | 19 | #ifndef RECT_H_INCLUDED 20 | #define RECT_H_INCLUDED 21 | 22 | #include "vector.h" 23 | 24 | namespace _RectPrivate { 25 | template class RectOp; 26 | } 27 | 28 | template 29 | class Rect { 30 | public: 31 | typedef Vector Vec; 32 | typedef Rect Self; 33 | typedef _RectPrivate::RectOp RO; 34 | 35 | Rect() : empty(true) {} 36 | Rect(const Vec &vec) : empty(false), lo(vec), hi(vec) {} 37 | Rect(const Vec &inLo, const Vec &inHi) : lo(inLo), hi(inHi) { markEmpty(); } 38 | Rect(const Rect &inRect) : empty(inRect.empty), lo(inRect.lo), hi(inRect.hi) {} 39 | template Rect(const Rect &inRect) : empty(inRect.empty), lo(inRect.lo), hi(inRect.hi) {} 40 | 41 | //constructs a Rect given an iterator over points--could be optimized with a min-max 42 | template Rect(Iter start, const Iter &finish) : empty(false) 43 | { 44 | if(start == finish) { 45 | empty = true; 46 | return; 47 | } 48 | lo = hi = *start; 49 | while(++start != finish) { 50 | lo = lo.apply(minimum(), *start); 51 | hi = hi.apply(maximum(), *start); 52 | } 53 | } 54 | 55 | bool isEmpty() const { return empty; } 56 | 57 | Self operator&(const Self &other) const 58 | { 59 | if(!empty && !other.empty) 60 | return Self(lo.apply(maximum(), other.lo), hi.apply(minimum(), other.hi)); 61 | return Self(); 62 | } 63 | 64 | Self operator|(const Self &other) const 65 | { 66 | if(empty) 67 | return other; 68 | if(other.empty) 69 | return (*this); 70 | return Self(false, lo.apply(minimum(), other.lo), hi.apply(maximum(), other.hi)); 71 | } 72 | 73 | bool operator==(const Self &other) const 74 | { 75 | if(empty && other.empty) 76 | return true; 77 | return (empty == other.empty) && (lo == other.lo) && (hi == other.hi); 78 | } 79 | 80 | #define OPAS(op, typ) Self &operator op##=(const typ &x) { (*this) = (*this) op x; return *this; } 81 | OPAS(&, Self) 82 | OPAS(|, Self) 83 | #undef OPAS 84 | 85 | bool contains(const Self &other) const 86 | { 87 | return other.empty || !(empty || other.lo.accumulate(less(), logical_or(), lo) || 88 | hi.accumulate(less(), logical_or(), other.hi)); 89 | } 90 | 91 | bool contains(const Vec &other) const 92 | { 93 | return !(empty || other.accumulate(less(), logical_or(), lo) || 94 | hi.accumulate(less(), logical_or(), other)); 95 | } 96 | 97 | const Vec &getLo() const { return lo; } 98 | const Vec &getHi() const { return hi; } 99 | Vec getSize() const { return empty ? Vec() : hi - lo; } 100 | 101 | Real getContent() const { return empty ? Real() : (hi - lo).accumulate(ident(), multiplies()); } 102 | Real getDiagLength() const { return empty ? Real() : (hi - lo).length(); } 103 | Vec getCenter() const { return (lo + hi) / Real(2); } 104 | 105 | Real distSqTo(const Vec &other) const { return RO::distSq(*this, other); } 106 | Real distSqTo(const Self &other) const { return RO::distSq(*this, other); } 107 | 108 | Vec getCorner(int idx) const 109 | { 110 | Vec out; 111 | BitComparator::assignCorner(idx, hi, lo, out); 112 | return out; 113 | } 114 | 115 | private: 116 | template friend class Rect; 117 | 118 | Rect(bool inEmpty, const Vec &inLo, const Vec &inHi) : empty(inEmpty), lo(inLo), hi(inHi) { } 119 | void markEmpty() { empty = hi.accumulate(less(), logical_or(), lo); } 120 | 121 | bool empty; 122 | Vec lo, hi; 123 | }; 124 | 125 | typedef Rect Rect2; 126 | typedef Rect Rect3; 127 | 128 | template 129 | basic_ostream& operator<<(basic_ostream& os, const Rect &r) 130 | { 131 | if(r.isEmpty()) 132 | os << "Rect()"; 133 | else 134 | os << "Rect(" << r.getLo() << ", " << r.getHi() << ")"; 135 | return os; 136 | } 137 | 138 | namespace _RectPrivate { 139 | #define VRD Vector 140 | #define RRD Rect 141 | template 142 | class RectOp 143 | { 144 | private: 145 | static const int last = Dim - 1; 146 | typedef RectOp Next; 147 | template friend class RectOp; 148 | template friend class Rect; 149 | 150 | template 151 | static R distSq(const RRD &r, const VRD &v) 152 | { 153 | R out = Next::distSq(r, v); 154 | if(r.getLo()[last] > v[last]) 155 | return out + SQR(r.getLo()[last] - v[last]); 156 | if(r.getHi()[last] < v[last]) 157 | return out + SQR(v[last] - r.getHi()[last]); 158 | return out; 159 | } 160 | 161 | template 162 | static R distSq(const RRD &r, const RRD &r2) 163 | { 164 | R out = Next::distSq(r, r2); 165 | if(r.getLo()[last] > r2.getHi()[last]) 166 | return out + SQR(r.getLo()[last] - r2.getHi()[last]); 167 | if(r.getHi()[last] < r2.getLo()[last]) 168 | return out + SQR(r2.getLo()[last] - r.getHi()[last]); 169 | return out; 170 | } 171 | 172 | }; 173 | 174 | template <> 175 | class RectOp<1> 176 | { 177 | private: 178 | template friend class RectOp; 179 | 180 | template 181 | static R distSq(const RRD &r, const VRD &v) 182 | { 183 | if(r.getLo()[0] > v[0]) 184 | return SQR(r.getLo()[0] - v[0]); 185 | if(r.getHi()[0] < v[0]) 186 | return SQR(v[0] - r.getHi()[0]); 187 | return R(); 188 | } 189 | 190 | template 191 | static R distSq(const RRD &r, const RRD &r2) 192 | { 193 | if(r.getLo()[0] > r2.getHi()[0]) 194 | return SQR(r.getLo()[0] - r2.getHi()[0]); 195 | if(r.getHi()[0] < r2.getLo()[0]) 196 | return SQR(r2.getLo()[0] - r.getHi()[0]); 197 | return R(); 198 | } 199 | 200 | }; 201 | } //namespace _RectPrivate 202 | 203 | #endif //RECT_H_INCLUDED 204 | -------------------------------------------------------------------------------- /Pinocchio/skeleton.h: -------------------------------------------------------------------------------- 1 | /* This file is part of the Pinocchio automatic rigging library. 2 | Copyright (C) 2007 Ilya Baran (ibaran@mit.edu) 3 | 4 | This library is free software; you can redistribute it and/or 5 | modify it under the terms of the GNU Lesser General Public 6 | License as published by the Free Software Foundation; either 7 | version 2.1 of the License, or (at your option) any later version. 8 | 9 | This library is distributed in the hope that it will be useful, 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | Lesser General Public License for more details. 13 | 14 | You should have received a copy of the GNU Lesser General Public 15 | License along with this library; if not, write to the Free Software 16 | Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 17 | */ 18 | 19 | #ifndef SKELETON_H 20 | #define SKELETON_H 21 | 22 | #include 23 | #include "graphutils.h" 24 | 25 | class PINOCCHIO_API Skeleton { 26 | public: 27 | Skeleton() {} 28 | 29 | const PtGraph &fGraph() const { return fGraphV; } 30 | const vector &fPrev() const { return fPrevV; } 31 | const vector &fSym() const { return fSymV; } 32 | 33 | const PtGraph &cGraph() const { return cGraphV; } 34 | const vector &cPrev() const { return cPrevV; } 35 | const vector &cSym() const { return cSymV; } 36 | const vector &cFeet() const { return cFeetV; } 37 | const vector &cFat() const { return cFatV; } 38 | 39 | const vector &cfMap() const { return cfMapV; } 40 | const vector &fcMap() const { return fcMapV; } 41 | const vector &fcFraction() const { return fcFractionV; } 42 | const vector &cLength() const { return cLengthV; } 43 | 44 | int getJointForName(const std::string &name) const { if(jointNames.count(name)) return jointNames.find(name)->second; return -1; } 45 | 46 | void scale(double factor); 47 | 48 | vector joints; 49 | unordered_map joints_names; 50 | protected: 51 | void initCompressed(); 52 | 53 | //help for creation 54 | map jointNames; 55 | void makeJoint(const string &name, const Pinocchio::Vector3 &pos, const string &previous = string()); 56 | void makeSymmetric(const string &name1, const string &name2); 57 | void setFoot(const string &name); 58 | void setFat(const string &name); 59 | 60 | private: 61 | //full 62 | PtGraph fGraphV; 63 | vector fPrevV; //previous vertices 64 | vector fSymV; //symmetry 65 | 66 | //compressed (no degree 2 vertices) 67 | PtGraph cGraphV; 68 | vector cPrevV; //previous vertices 69 | vector cSymV; //symmetry 70 | vector cFeetV; //whether the vertex should be near the ground 71 | vector cFatV; //whether the vertex should be in a large region 72 | 73 | vector cfMapV; //compressed to full map 74 | vector fcMapV; //full to compressed map, -1 when vertex is not in compressed 75 | vector fcFractionV; //maps full vertex number to ratio of its prev edge length to total length of 76 | //containing edge in the compressed graph 77 | vector cLengthV; //lengths of the compressed bones 78 | }; 79 | 80 | class PINOCCHIO_API HumanSkeleton : public Skeleton 81 | { 82 | public: 83 | HumanSkeleton(); 84 | }; 85 | 86 | // class PINOCCHIO_API KinectSkeleton : public Skeleton 87 | // { 88 | // public: 89 | // KinectSkeleton(); 90 | // }; 91 | 92 | class PINOCCHIO_API QuadSkeleton : public Skeleton 93 | { 94 | public: 95 | QuadSkeleton(); 96 | }; 97 | 98 | class PINOCCHIO_API HorseSkeleton : public Skeleton 99 | { 100 | public: 101 | HorseSkeleton(); 102 | }; 103 | 104 | class PINOCCHIO_API CentaurSkeleton : public Skeleton 105 | { 106 | public: 107 | CentaurSkeleton(); 108 | }; 109 | 110 | class PINOCCHIO_API FileSkeleton : public Skeleton 111 | { 112 | public: 113 | FileSkeleton(const std::string &filename); 114 | }; 115 | 116 | #endif 117 | -------------------------------------------------------------------------------- /Pinocchio/utils.h: -------------------------------------------------------------------------------- 1 | /* This file is part of the Pinocchio automatic rigging library. 2 | Copyright (C) 2007 Ilya Baran (ibaran@mit.edu) 3 | 4 | This library is free software; you can redistribute it and/or 5 | modify it under the terms of the GNU Lesser General Public 6 | License as published by the Free Software Foundation; either 7 | version 2.1 of the License, or (at your option) any later version. 8 | 9 | This library is distributed in the hope that it will be useful, 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | Lesser General Public License for more details. 13 | 14 | You should have received a copy of the GNU Lesser General Public 15 | License along with this library; if not, write to the Free Software 16 | Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 17 | */ 18 | 19 | #ifndef UTILS_H_INCLUDED 20 | #define UTILS_H_INCLUDED 21 | 22 | #include 23 | #include 24 | 25 | template 26 | inline string toString(const T& obj) { 27 | ostringstream stream; 28 | stream << obj; 29 | return stream.str(); 30 | } 31 | 32 | inline vector readWords(istream &stream) 33 | { 34 | string whitespace = " \n\t\r"; 35 | stream >> noskipws; 36 | 37 | char tmp[10000]; 38 | stream.getline(tmp, 9990); 39 | string line(tmp); 40 | 41 | if(line.size() == 0) 42 | return vector(); 43 | 44 | while(line[line.size() - 1] == '\\') { 45 | line[line.size() - 1] = ' '; 46 | stream.getline(tmp, 9990); 47 | line = line + string(tmp); 48 | } 49 | 50 | //split the line into words 51 | vector words; 52 | string::size_type pos = 0; 53 | while(pos != string::npos) { 54 | pos = line.find_first_not_of(whitespace, pos); 55 | if(pos == string::npos) 56 | break; 57 | string::size_type eow = line.find_first_of(whitespace, pos); 58 | words.push_back(string(line, pos, eow - pos)); 59 | pos = eow; 60 | } 61 | 62 | return words; 63 | } 64 | 65 | 66 | #endif //UTILS_H_INCLUDED 67 | -------------------------------------------------------------------------------- /Pinocchio/vecutils.h: -------------------------------------------------------------------------------- 1 | /* This file is part of the Pinocchio automatic rigging library. 2 | Copyright (C) 2007 Ilya Baran (ibaran@mit.edu) 3 | 4 | This library is free software; you can redistribute it and/or 5 | modify it under the terms of the GNU Lesser General Public 6 | License as published by the Free Software Foundation; either 7 | version 2.1 of the License, or (at your option) any later version. 8 | 9 | This library is distributed in the hope that it will be useful, 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | Lesser General Public License for more details. 13 | 14 | You should have received a copy of the GNU Lesser General Public 15 | License along with this library; if not, write to the Free Software 16 | Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 17 | */ 18 | 19 | #ifndef VECUTILS_H_INCLUDED 20 | #define VECUTILS_H_INCLUDED 21 | 22 | #include "vector.h" 23 | 24 | template 25 | void getBasis(const Vector &n, Vector &v1, Vector &v2) 26 | { 27 | if(n.lengthsq() < Real(1e-16)) { 28 | v1 = Vector(1., 0., 0.); 29 | v2 = Vector(0., 1., 0.); 30 | return; 31 | } 32 | if(fabs(n[0]) <= fabs(n[1]) && fabs(n[0]) <= fabs(n[2])) 33 | v2 = Vector(1., 0., 0.); 34 | else if(fabs(n[1]) <= fabs(n[2])) 35 | v2 = Vector(0., 1., 0.); 36 | else 37 | v2 = Vector(0., 0., 1.); 38 | 39 | v1 = (n % v2).normalize(); //first basis vector 40 | v2 = (n % v1).normalize(); //second basis vector 41 | } 42 | 43 | template 44 | Real distsqToLine(const Vector &v, const Vector &l, const Vector &dir) 45 | { 46 | return max(Real(), (v - l).lengthsq() - SQR((v - l) * dir) / dir.lengthsq()); 47 | } 48 | 49 | template 50 | Vector projToLine(const Vector &v, const Vector &l, const Vector &dir) 51 | { 52 | return l + (((v - l) * dir) / dir.lengthsq()) * dir; 53 | } 54 | 55 | template 56 | Real distsqToSeg(const Vector &v, const Vector &p1, const Vector &p2) 57 | { 58 | typedef Vector Vec; 59 | 60 | Vec dir = p2 - p1; 61 | Vec difp2 = p2 - v; 62 | 63 | if(difp2 * dir < Real()) 64 | return difp2.lengthsq(); 65 | 66 | Vec difp1 = v - p1; 67 | Real dot = difp1 * dir; 68 | 69 | if(dot <= Real()) 70 | return difp1.lengthsq(); 71 | 72 | return max(Real(), difp1.lengthsq() - SQR(dot) / dir.lengthsq()); 73 | } 74 | 75 | template 76 | Vector projToSeg(const Vector &v, const Vector &p1, const Vector &p2) 77 | { 78 | typedef Vector Vec; 79 | 80 | Vec dir = p2 - p1; 81 | 82 | if((p2 - v) * dir < Real()) 83 | return p2; 84 | 85 | Real dot = (v - p1) * dir; 86 | 87 | if(dot <= Real()) 88 | return p1; 89 | 90 | return p1 + (dot / dir.lengthsq()) * dir; 91 | } 92 | 93 | //d is distance between centers, r1 and r2 are radii 94 | template 95 | Real getCircleIntersectionArea(const Real &d, const Real &r1, const Real &r2) 96 | { 97 | Real tol(1e-8); 98 | 99 | if(r1 + r2 <= d + tol) 100 | return Real(); 101 | if(r1 + d <= r2 + tol) 102 | return Real(M_PI) * SQR(r1); 103 | if(r2 + d <= r1 + tol) 104 | return Real(M_PI) * SQR(r2); 105 | 106 | Real sqrdif = SQR(r1) - SQR(r2); 107 | Real dsqrdif = SQR(d) - sqrdif; //d^2 - r1^2 + r2^2 108 | Real a1 = SQR(r1) * acos((SQR(d) + sqrdif) / (Real(2.) * r1 * d)); 109 | Real a2 = SQR(r2) * acos(dsqrdif / (Real(2.) * r2 * d)); 110 | return a1 + a2 - Real(0.5) * sqrt(SQR(Real(2.) * d * r2) - SQR(dsqrdif)); 111 | } 112 | 113 | template 114 | Vector projToTri(const Vector &from, const Vector &p1, const Vector &p2, const Vector &p3) 115 | { 116 | typedef Vector Vec; 117 | Real tolsq(1e-16); 118 | 119 | Vec p2p1 = (p2 - p1); 120 | Vec p3p1 = (p3 - p1); 121 | Vec normal = p2p1 % p3p1; 122 | 123 | if((p2p1 % (from - p1)) * normal >= Real()) { //inside s1 124 | bool s2 = ((p3 - p2) % (from - p2)) * normal >= Real(); 125 | bool s3 = (p3p1 % (from - p3)) * normal <= Real(); 126 | 127 | if(s2 && s3) { 128 | if(normal.lengthsq() < tolsq) 129 | return p1; //incorrect, but whatever... 130 | 131 | double dot = (from - p3) * normal; 132 | return from - (dot / normal.lengthsq()) * normal; 133 | } 134 | if(!s3 && (s2 || (from - p3) * p3p1 >= Real())) 135 | return projToSeg(from, p3, p1); 136 | return projToSeg(from, p2, p3); 137 | } 138 | //outside s1 139 | if((from - p1) * p2p1 < Real()) 140 | return projToSeg(from, p3, p1); 141 | if((from - p2) * p2p1 > Real()) 142 | return projToSeg(from, p2, p3); 143 | return projToLine(from, p1, p2p1); 144 | } 145 | 146 | #endif //VECUTILS_H_INCLUDED 147 | -------------------------------------------------------------------------------- /PinocchioStatic/PinocchioStatic.vcproj: -------------------------------------------------------------------------------- 1 | 2 | 10 | 11 | 14 | 15 | 16 | 17 | 18 | 26 | 29 | 32 | 35 | 38 | 41 | 53 | 56 | 59 | 62 | 65 | 68 | 71 | 74 | 77 | 80 | 81 | 89 | 92 | 95 | 98 | 101 | 104 | 113 | 116 | 119 | 122 | 125 | 128 | 131 | 134 | 137 | 140 | 141 | 142 | 143 | 144 | 145 | 150 | 153 | 154 | 157 | 158 | 161 | 162 | 165 | 166 | 169 | 170 | 173 | 174 | 177 | 178 | 181 | 182 | 185 | 186 | 189 | 190 | 193 | 194 | 197 | 198 | 199 | 204 | 207 | 208 | 211 | 212 | 215 | 216 | 219 | 220 | 223 | 224 | 227 | 228 | 231 | 232 | 235 | 236 | 239 | 240 | 243 | 244 | 247 | 248 | 251 | 252 | 255 | 256 | 259 | 260 | 263 | 264 | 267 | 268 | 271 | 272 | 275 | 276 | 279 | 280 | 283 | 284 | 287 | 288 | 291 | 292 | 295 | 296 | 297 | 298 | 299 | 300 | 301 | -------------------------------------------------------------------------------- /PinocchioStatic/PinocchioStatic.vcxproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Debug 6 | Win32 7 | 8 | 9 | Release 10 | Win32 11 | 12 | 13 | 14 | {F66AD322-ABB4-4992-8FEF-BB9CB6BDD9D7} 15 | PinocchioStatic 16 | Win32Proj 17 | 18 | 19 | 20 | StaticLibrary 21 | v142 22 | Unicode 23 | true 24 | Static 25 | 26 | 27 | StaticLibrary 28 | v142 29 | Static 30 | Unicode 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | <_ProjectFileVersion>16.0.29511.113 44 | 45 | 46 | $(SolutionDir)$(Configuration)\ 47 | $(Configuration)\ 48 | MinimumRecommendedRules.ruleset 49 | 50 | 51 | $(VC_IncludePath);$(WindowsSDK_IncludePath);$(FBX_DIR)\include 52 | $(VC_LibraryPath_x86);$(WindowsSDK_LibraryPath_x86);$(NETFXKitsDir)Lib\um\x86;$(FBX_DIR)\lib\vs2015\x86\debug 53 | 54 | 55 | $(SolutionDir)$(Configuration)\ 56 | $(Configuration)\ 57 | MinimumRecommendedRules.ruleset 58 | 59 | 60 | $(VC_IncludePath);$(WindowsSDK_IncludePath);$(FBX_DIR)\include 61 | $(VC_LibraryPath_x86);$(WindowsSDK_LibraryPath_x86);$(NETFXKitsDir)Lib\um\x86;$(FBX_DIR)\lib\vs2015\x86\release 62 | 63 | 64 | 65 | Disabled 66 | WIN32;_DEBUG;_LIB;PINOCCHIO_STATIC;%(PreprocessorDefinitions) 67 | true 68 | EnableFastChecks 69 | MultiThreadedDebug 70 | 71 | Level3 72 | EditAndContinue 73 | 74 | 75 | $(FBX_DIR)/lib/vs2015/x86/debug 76 | 77 | 78 | 79 | 80 | WIN32;NDEBUG;_LIB;PINOCCHIO_STATIC;%(PreprocessorDefinitions) 81 | MultiThreaded 82 | 83 | Level3 84 | ProgramDatabase 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | -------------------------------------------------------------------------------- /PinocchioStatic/PinocchioStatic.vcxproj.filters: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF} 6 | cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx 7 | 8 | 9 | {93995380-89BD-4b04-88EB-625FBE52EBFB} 10 | h;hpp;hxx;hm;inl;inc;xsd 11 | 12 | 13 | 14 | 15 | Source Files 16 | 17 | 18 | Source Files 19 | 20 | 21 | Source Files 22 | 23 | 24 | Source Files 25 | 26 | 27 | Source Files 28 | 29 | 30 | Source Files 31 | 32 | 33 | Source Files 34 | 35 | 36 | Source Files 37 | 38 | 39 | Source Files 40 | 41 | 42 | Source Files 43 | 44 | 45 | Source Files 46 | 47 | 48 | Source Files 49 | 50 | 51 | 52 | 53 | Header Files 54 | 55 | 56 | Header Files 57 | 58 | 59 | Header Files 60 | 61 | 62 | Header Files 63 | 64 | 65 | Header Files 66 | 67 | 68 | Header Files 69 | 70 | 71 | Header Files 72 | 73 | 74 | Header Files 75 | 76 | 77 | Header Files 78 | 79 | 80 | Header Files 81 | 82 | 83 | Header Files 84 | 85 | 86 | Header Files 87 | 88 | 89 | Header Files 90 | 91 | 92 | Header Files 93 | 94 | 95 | Header Files 96 | 97 | 98 | Header Files 99 | 100 | 101 | Header Files 102 | 103 | 104 | Header Files 105 | 106 | 107 | Header Files 108 | 109 | 110 | Header Files 111 | 112 | 113 | Header Files 114 | 115 | 116 | Header Files 117 | 118 | 119 | Header Files 120 | 121 | 122 | -------------------------------------------------------------------------------- /Project/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.14.5) 2 | project(Skeleton) 3 | 4 | set(CMAKE_CXX_STANDARD 17) 5 | set(LIBS_DIR ${CMAKE_CURRENT_SOURCE_DIR}/libs) 6 | set(GLFW_DIR ${LIBS_DIR}/glfw) 7 | set(GLAD_DIR ${LIBS_DIR}/glad) 8 | set(KHR_DIR ${LIBS_DIR}/KHR) 9 | set(Eigen_DIR ${LIBS_DIR}/Eigen) 10 | set(SOURCE_FILES ${GLAD_DIR}/src/glad.c) 11 | set(THREADS_PREFER_PTHREAD_FLAG ON) 12 | 13 | file(GLOB SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/src/*.h) 14 | 15 | find_package(Threads REQUIRED) 16 | 17 | add_subdirectory(${GLFW_DIR}) 18 | 19 | include_directories($ENV{KINECTSDK10_DIR}/inc ${GLAD_DIR}/inc ${KHR_DIR}) 20 | link_directories($ENV{KINECTSDK10_DIR}/lib/amd64) 21 | 22 | add_executable(Skeleton main.cpp ${HEADER_FILES} ${SOURCE_FILES} ${SOURCES}) 23 | target_link_libraries(Skeleton Kinect10 glfw Threads::Threads) 24 | target_include_directories(Skeleton PUBLIC $ENV{KINECTSDK10_DIR}/inc ${GLAD_DIR}/inc ${KHR_DIR} ${Eigen_DIR}) -------------------------------------------------------------------------------- /Project/Makefile: -------------------------------------------------------------------------------- 1 | # Makefile for UI 2 | CC = g++ 3 | CCFLAGS = -c -O3 -Wall -I../Pinocchio/ -I../fbx/include -I/usr/include/libxml2/libxml -I/usr/include/eigen3 -I./../stb -DDEBUG -g 4 | LIBS = -lm -pthread -L../Pinocchio/ -lpinocchio -lfbxsdk -lxml2 -ldl -lrt -luuid -lz -lfltk -lfltk_gl -lGL 5 | 6 | OBJECTS = main.o MyWindow.o defmesh.o motion.o 7 | 8 | Project: $(OBJECTS) 9 | $(CC) $(OBJECTS) $(LIBS) -o Project 10 | 11 | .cpp.o: 12 | $(CC) $(CCFLAGS) $< 13 | 14 | 15 | #do a makedepend and remove all the external dependencies from the makefile 16 | #works on my system, no one else should need to do it. 17 | depend: 18 | makedepend *.cpp > /dev/null >& 1 19 | perl -pi -e 's/\.c\.o/\.o/' Makefile 20 | perl -pi -e 's/\/u[Ss]r[a-zA-Z0-9\+\-\/\.\_]*//' Makefile 21 | perl -pi -e 's/\/u[Ss]r[a-zA-Z0-9\+\-\/\.\_]*//' Makefile 22 | perl -pi -e 's/\/u[Ss]r[a-zA-Z0-9\+\-\/\.\_]*//' Makefile 23 | perl -pi -e 's/\/u[Ss]r[a-zA-Z0-9\+\-\/\.\_]*//' Makefile 24 | perl -pi -e 's/\/u[Ss]r[a-zA-Z0-9\+\-\/\.\_]*//' Makefile 25 | perl -pi -e 's/\/u[Ss]r[a-zA-Z0-9\+\-\/\.\_]*//' Makefile 26 | perl -pi -e 's/\/u[Ss]r[a-zA-Z0-9\+\-\/\.\_]*//' Makefile 27 | perl -pi -e 's/\/u[Ss]r[a-zA-Z0-9\+\-\/\.\_]*//' Makefile 28 | perl -pi -e 's/^[a-zA-Z].*\.o\:\s*$$//' Makefile 29 | 30 | clean: 31 | rm -f $(OBJECTS) Project *~ core *.out *.bak 32 | 33 | cleanobj: 34 | rm -f $(OBJECTS) 35 | 36 | 37 | # DO NOT DELETE 38 | 39 | MyWindow.o: MyWindow.h 40 | MyWindow.o: ../Pinocchio/mesh.h ../Pinocchio/vector.h 41 | MyWindow.o: ../Pinocchio/hashutils.h ../Pinocchio/mathutils.h 42 | MyWindow.o: ../Pinocchio/Pinocchio.h ../Pinocchio/rect.h 43 | MyWindow.o: ../Pinocchio/transform.h ../Pinocchio/skeleton.h 44 | MyWindow.o: ../Pinocchio/graphutils.h 45 | defmesh.o: defmesh.h ../Pinocchio/attachment.h ../Pinocchio/mesh.h 46 | defmesh.o: ../Pinocchio/vector.h ../Pinocchio/hashutils.h 47 | defmesh.o: ../Pinocchio/mathutils.h 48 | defmesh.o: ../Pinocchio/Pinocchio.h ../Pinocchio/rect.h 49 | defmesh.o: ../Pinocchio/skeleton.h ../Pinocchio/graphutils.h 50 | defmesh.o: ../Pinocchio/transform.h ../Pinocchio/matrix.h 51 | defmesh.o: ../Pinocchio/vector.h ../Pinocchio/transform.h 52 | defmesh.o: ../Pinocchio/mesh.h motion.h ../Pinocchio/intersector.h 53 | defmesh.o: ../Pinocchio/vecutils.h 54 | UI.o: MyWindow.h 55 | UI.o: ../Pinocchio/mesh.h ../Pinocchio/vector.h ../Pinocchio/hashutils.h 56 | UI.o: ../Pinocchio/mathutils.h 57 | UI.o: ../Pinocchio/Pinocchio.h ../Pinocchio/rect.h 58 | motion.o: motion.h ../Pinocchio/transform.h ../Pinocchio/vector.h 59 | motion.o: ../Pinocchio/hashutils.h ../Pinocchio/mathutils.h 60 | motion.o: ../Pinocchio/Pinocchio.h 61 | motion.o: ../Pinocchio/skeleton.h ../Pinocchio/graphutils.h 62 | motion.o: ../Pinocchio/utils.h 63 | main.o: MyWindow.h 64 | main.o: ../Pinocchio/mesh.h ../Pinocchio/vector.h 65 | main.o: ../Pinocchio/hashutils.h ../Pinocchio/mathutils.h 66 | main.o: ../Pinocchio/Pinocchio.h 67 | main.o: ../Pinocchio/rect.h ../Pinocchio/transform.h 68 | main.o: ../Pinocchio/skeleton.h ../Pinocchio/graphutils.h 69 | main.o: ../Pinocchio/utils.h ../Pinocchio/debugging.h 70 | main.o: ../Pinocchio/attachment.h ../Pinocchio/mesh.h 71 | main.o: ../Pinocchio/skeleton.h ../Pinocchio/transform.h 72 | main.o: ../Pinocchio/pinocchioApi.h ../Pinocchio/quaddisttree.h 73 | main.o: ../Pinocchio/dtree.h ../Pinocchio/indexer.h 74 | main.o: ../Pinocchio/multilinear.h ../Pinocchio/intersector.h 75 | main.o: ../Pinocchio/vecutils.h ../Pinocchio/pointprojector.h 76 | main.o: ../Pinocchio/debugging.h ../Pinocchio/attachment.h defmesh.h 77 | main.o: ../Pinocchio/matrix.h ../Pinocchio/vector.h motion.h 78 | -------------------------------------------------------------------------------- /Project/Project.vcproj: -------------------------------------------------------------------------------- 1 | 2 | 10 | 11 | 14 | 15 | 16 | 17 | 18 | 25 | 28 | 31 | 34 | 37 | 40 | 53 | 56 | 59 | 62 | 72 | 75 | 78 | 81 | 84 | 87 | 90 | 93 | 96 | 97 | 105 | 108 | 111 | 114 | 117 | 120 | 134 | 137 | 140 | 143 | 155 | 158 | 161 | 164 | 167 | 170 | 173 | 176 | 179 | 180 | 181 | 182 | 183 | 184 | 189 | 192 | 193 | 196 | 197 | 200 | 201 | 204 | 205 | 210 | 213 | 214 | 217 | 218 | 221 | 222 | 225 | 226 | 227 | 228 | 229 | 230 | 231 | 232 | -------------------------------------------------------------------------------- /Project/Project.vcxproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Debug 6 | Win32 7 | 8 | 9 | Release 10 | Win32 11 | 12 | 13 | 14 | {D512EF05-3826-4CE9-A527-EF75DF68FE26} 15 | Project 16 | Win32Proj 17 | 18 | 19 | 20 | Application 21 | v142 22 | Unicode 23 | true 24 | 25 | 26 | Application 27 | v142 28 | Unicode 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | <_ProjectFileVersion>16.0.29511.113 42 | 43 | 44 | $(SolutionDir)$(Configuration)\ 45 | $(Configuration)\ 46 | true 47 | MinimumRecommendedRules.ruleset 48 | 49 | 50 | $(KINECTSDK10_DIR)/inc;$(VC_IncludePath);$(WindowsSDK_IncludePath); 51 | $(KINECTSDK10_DIR)/lib/x86;$(VC_LibraryPath_x86);$(WindowsSDK_LibraryPath_x86);$(NETFXKitsDir)Lib\um\x86 52 | 53 | 54 | $(SolutionDir)$(Configuration)\ 55 | $(Configuration)\ 56 | false 57 | MinimumRecommendedRules.ruleset 58 | 59 | 60 | $(KINECTSDK10_DIR)/inc;$(IncludePath) 61 | $(KINECTSDK10_DIR)/lib/x86;$(LibraryPath) 62 | 63 | 64 | 65 | Disabled 66 | $(FLTK_DIR);$(EIGEN_DIR);$(STB_DIR)%(AdditionalIncludeDirectories) 67 | WIN32;_DEBUG;_WINDOWS;_CONSOLE;%(PreprocessorDefinitions) 68 | true 69 | EnableFastChecks 70 | MultiThreadedDebugDLL 71 | 72 | Level3 73 | EditAndContinue 74 | 75 | 76 | $(FLTK_DIR)/lib/fltk.lib;$(FLTK_DIR)/lib/fltkgl.lib;Kinect10.lib;opengl32.lib;wsock32.lib;comctl32.lib;%(AdditionalDependencies) 77 | false 78 | true 79 | Console 80 | MachineX86 81 | $(KINECTSDK10_DIR)/lib/x86 82 | 83 | 84 | 85 | 86 | Full 87 | AnySuitable 88 | true 89 | Speed 90 | $(FLTK_DIR);$(EIGEN_DIR);$(STB_DIR)%(AdditionalIncludeDirectories) 91 | WIN32;NDEBUG;_WINDOWS;_CONSOLE;%(PreprocessorDefinitions) 92 | MultiThreadedDLL 93 | 94 | Level3 95 | ProgramDatabase 96 | 97 | 98 | $(FLTK_DIR)/lib/fltk.lib;$(FLTK_DIR)/lib/fltkgl.lib;Kinect10.lib;opengl32.lib;wsock32.lib;comctl32.lib;%(AdditionalDependencies) 99 | false 100 | true 101 | Console 102 | true 103 | true 104 | MachineX86 105 | $(KINECTSDK10_DIR)/lib/x86 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | {835e35c4-9ab1-4cb3-a8a9-a0b89171280d} 123 | false 124 | 125 | 126 | 127 | 128 | 129 | -------------------------------------------------------------------------------- /Project/Project.vcxproj.filters: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF} 6 | cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx 7 | 8 | 9 | {93995380-89BD-4b04-88EB-625FBE52EBFB} 10 | h;hpp;hxx;hm;inl;inc;xsd 11 | 12 | 13 | 14 | 15 | Source Files 16 | 17 | 18 | Source Files 19 | 20 | 21 | Source Files 22 | 23 | 24 | Source Files 25 | 26 | 27 | 28 | 29 | Source Files\Header Files 30 | 31 | 32 | Source Files\Header Files 33 | 34 | 35 | Source Files\Header Files 36 | 37 | 38 | Source Files\Header Files 39 | 40 | 41 | -------------------------------------------------------------------------------- /Project/Shaders/skeleton/skeleton_fs.glsl: -------------------------------------------------------------------------------- 1 | #version 150 2 | 3 | out vec4 outColor; 4 | 5 | void main() { 6 | outColor = vec4(1.0, 0, 0, 1.0); 7 | } -------------------------------------------------------------------------------- /Project/Shaders/skeleton/skeleton_vs.glsl: -------------------------------------------------------------------------------- 1 | #version 430 2 | 3 | layout (location = 0) in vec3 a_position; 4 | 5 | uniform mat4 u_camera; 6 | 7 | void main() { 8 | gl_PointSize = 12.0; 9 | gl_Position = u_camera * vec4(a_position.xyz, 1.0); 10 | } -------------------------------------------------------------------------------- /Project/data/joints.out: -------------------------------------------------------------------------------- 1 | hips 0. 0. 0. -1 2 | spine 0. 0.1 0. hips 3 | shoulders 0. 0.625 0. spine 4 | head 0. 0.7 0. shoulders 5 | 6 | lshoulder -0.3 0.5 0. shoulders 7 | lelbow -0.4 0.25 0.075 lshoulder 8 | lwrist -0.55 0.075 0.15 lelbow 9 | lhand -0.6 -0.0025 0.15 lwrist 10 | 11 | rshoulder 0.3 0.5 0. shoulders 12 | relbow 0.4 0.25 0.075 rshoulder 13 | rwrist 0.55 0.075 0.15 relbow 14 | rhand 0.6 -0.0025 0.15 rwrist 15 | 16 | lhip -0.1 0. 0. hips 17 | lknee -0.15 -0.35 0. lhip 18 | lankle -0.15 -0.8 0. lknee 19 | lfoot -0.14 -0.8 0.15 lankle 20 | 21 | rhip 0.1 0. 0. hips 22 | rknee 0.15 -0.35 0. rhip 23 | rankle 0.15 -0.8 0. rknee 24 | rfoot 0.14 -0.8 0.15 rankle 25 | -------------------------------------------------------------------------------- /Project/defmesh.cpp: -------------------------------------------------------------------------------- 1 | #include "defmesh.h" 2 | #include "../Pinocchio/intersector.h" 3 | 4 | 5 | Eigen::Vector3f transformToEigen(const Pinocchio::Vector3 & vec) { 6 | return Eigen::Vector3f(vec[0], vec[1], vec[2]); 7 | } 8 | 9 | Pinocchio::Vector3 transformToVec(const Eigen::Vector3f & vec) { 10 | return Pinocchio::Vector3(vec.x(), vec.y(), vec.z()); 11 | } 12 | 13 | Eigen::Vector3f getDirection(const Rotation & rot) { 14 | Eigen::Quaternionf quart(-rot.rotation[3], rot.rotation[0], rot.rotation[1], -rot.rotation[2]); 15 | 16 | return quart * Eigen::Vector3f(0, 1, 0); 17 | } 18 | 19 | Eigen::Quaternionf getRootRotation(const vector & pose, const Rotation & rot) { 20 | Eigen::Vector3f directionRoot = getDirection(rot); 21 | Eigen::Quaternionf rootRotation = Eigen::Quaternionf::FromTwoVectors(Eigen::Vector3f(0, 1, 0), directionRoot); 22 | 23 | Eigen::Vector3f parent = transformToEigen(pose[rot.joint1]); 24 | Eigen::Vector3f child = transformToEigen(pose[rot.joint2]); 25 | 26 | Eigen::Vector3f directionPose = child - parent; 27 | Eigen::Vector3f directionAvatar = getDirection(rot); 28 | 29 | return Eigen::Quaternionf::FromTwoVectors(directionPose, directionAvatar); 30 | } 31 | 32 | map> DeformableMesh::computeTransforms() const { 33 | map> transforms; 34 | 35 | const vector rotations = motion->getRelative(); 36 | 37 | vector pose = match; 38 | Eigen::Quaternionf rootRotation = getRootRotation(match, rotations[0]); 39 | Eigen::Vector3f root = transformToEigen(pose[0]); 40 | 41 | for(int g = 1; g < rotations.size(); g++) { 42 | const Rotation & rot = rotations[g]; 43 | 44 | Eigen::Vector3f parent = transformToEigen(pose[rot.joint1]); 45 | Eigen::Vector3f child = transformToEigen(pose[rot.joint2]); 46 | 47 | auto stack = transforms.find(rot.joint1); 48 | if (stack != transforms.end()) { 49 | parent = stack->second * parent; 50 | child = stack->second * child; 51 | } 52 | 53 | Eigen::Vector3f directionPose = child - parent; 54 | 55 | Eigen::Translation translForward(parent); 56 | Eigen::Translation translBack = translForward.inverse(); 57 | 58 | Eigen::Vector3f directionAvatar = getDirection(rot); 59 | 60 | auto rotation = Eigen::Quaternionf::FromTwoVectors(directionPose, directionAvatar); 61 | Eigen::Transform transform = translForward * rotation * translBack; 62 | if (transforms.find(rot.joint1) != transforms.end()) { 63 | transform = transform * transforms.find(rot.joint1)->second; 64 | } else { 65 | transform = transform * rootRotation; 66 | } 67 | 68 | transforms.insert({rot.joint2, transform}); 69 | } 70 | 71 | return transforms; 72 | } 73 | 74 | void DeformableMesh::computeBasePose() {} 75 | 76 | void DeformableMesh::updateMesh() const { 77 | map> transforms = computeTransforms(); 78 | const vector & positions = motion->getSkeletonBones(); 79 | 80 | Eigen::Translation rootTranslation(transformToEigen(positions[0]).array() * Eigen::Vector3f(1.0, 1.0, -3.0).array()); 81 | auto rotAxis = Eigen::AngleAxisf(M_PI, Eigen::Vector3f::UnitY()); 82 | 83 | Eigen::Vector3f root = transformToEigen(match[0]); 84 | 85 | curMesh = origMesh; 86 | for(int i = 0; i < origMesh.vertices.size(); i++) { 87 | Eigen::Vector3f updatedPos(0, 0, 0); 88 | 89 | if (!rigged) { 90 | Vector weights = attachment.getWeights(i); 91 | for (int j = 0; j < weights.size(); j++) { 92 | updatedPos += weights[j] * (transforms.find(j + 1)->second * transformToEigen(origMesh.vertices[i].pos)); 93 | } 94 | } else { 95 | unordered_map weights = origMesh.vertices[i].weights; 96 | for (auto weight: weights) { 97 | int index = origSkel.joints_names.find(weight.first)->second; 98 | 99 | updatedPos += weight.second * (transforms.find(index)->second * transformToEigen(origMesh.vertices[i].pos)); 100 | } 101 | } 102 | 103 | curMesh.vertices[i].pos = transformToVec(rootTranslation * updatedPos); 104 | } 105 | curMesh.computeVertexNormals(); 106 | 107 | avatar = match; 108 | for (int g = 1; g < avatar.size(); g++) { 109 | avatar[g] = transformToVec(rootTranslation * transforms.find(g)->second * transformToEigen(avatar[g])); 110 | } 111 | avatar[0] = transformToVec(rootTranslation * transformToEigen(avatar[0])); 112 | } 113 | 114 | vector DeformableMesh::getSkeletonTracked() { 115 | return motion->positions[motion->frameIdx]; 116 | } 117 | 118 | vector DeformableMesh::getSkeletonAvatar() const { 119 | return avatar; 120 | } 121 | 122 | -------------------------------------------------------------------------------- /Project/defmesh.h: -------------------------------------------------------------------------------- 1 | #ifndef DEFMESH_H_INCLUDED 2 | #define DEFMESH_H_INCLUDED 3 | 4 | #include "../Pinocchio/attachment.h" 5 | #include "motion.h" 6 | #include 7 | #include 8 | 9 | struct JointTransformation { 10 | Eigen::Quaternion rot; 11 | Eigen::Vector3d parent; 12 | Eigen::Vector3d childOld; 13 | Eigen::Vector3d childNew; 14 | }; 15 | 16 | class DeformableMesh 17 | { 18 | public: 19 | DeformableMesh() {}; 20 | DeformableMesh(const Mesh inMesh, const Skeleton& inOrigSkel, const vector& inMatch, 21 | const Attachment& inAttachment, Motion* inMotion = NULL) 22 | : origSkel(inOrigSkel), match(inMatch), attachment(inAttachment), origMesh(inMesh), motion(inMotion) {}; 23 | 24 | DeformableMesh(const Mesh inMesh, const Skeleton &inOrigSkel, Motion *inMotion = NULL): origSkel(inOrigSkel), origMesh(inMesh), motion(inMotion) { 25 | for (int g = 0; g < inOrigSkel.joints.size(); g++) { 26 | string name = inOrigSkel.joints[g]; 27 | auto iter = origMesh.joints.find(name); 28 | if (iter != origMesh.joints.end()) { 29 | match.push_back(iter->second); 30 | avatar.push_back(iter->second); 31 | } else { 32 | cout << name << " not existent" << endl; 33 | } 34 | } 35 | } 36 | 37 | const int size() const { 38 | return motion->positions.size(); 39 | }; 40 | 41 | void computeBasePose(); 42 | 43 | vector getSkeletonAvatar() const; 44 | vector getSkeletonTracked(); 45 | vector getBasePose() const { return pose; }; 46 | const Skeleton &getOrigSkel() const { return origSkel; } 47 | const Attachment &getAttachment() const { return attachment; } 48 | const Mesh & getMesh() { 49 | updateMesh(); 50 | 51 | return curMesh; 52 | } 53 | mutable vector match; 54 | mutable vector avatar; 55 | vector pose; 56 | mutable Mesh origMesh; 57 | bool rigged = false; 58 | Motion* motion; 59 | private: 60 | map> computeTransforms() const; 61 | void updateMesh() const; 62 | 63 | Skeleton origSkel; 64 | Attachment attachment; 65 | mutable Mesh curMesh; 66 | }; 67 | 68 | #endif //DEFMESH_H_INCLUDED 69 | -------------------------------------------------------------------------------- /Project/device.h: -------------------------------------------------------------------------------- 1 | #ifndef DEVICE_H 2 | #define DEVICE_H 3 | 4 | #include "Windows.h" 5 | 6 | #include 7 | #include 8 | 9 | #include 10 | #include 11 | #include 12 | 13 | #include 14 | #include 15 | #include 16 | #include 17 | #include 18 | #include 19 | #include 20 | 21 | using namespace std; 22 | 23 | class Device { 24 | public: 25 | 26 | // The kinect sensor 27 | INuiSensor* sensor = nullptr; 28 | 29 | // Initialize Skeleton Data 30 | Vector4 skeletonPositions[NUI_SKELETON_POSITION_COUNT]; 31 | NUI_SKELETON_BONE_ORIENTATION orientations[NUI_SKELETON_POSITION_COUNT]; 32 | 33 | int index = 0; 34 | bool consumed = true; 35 | bool cache = false; 36 | 37 | thread th; 38 | mutex mtx; 39 | condition_variable cv; 40 | 41 | vector joints = { 42 | "HIP_CENTER", 43 | "SPINE", 44 | "SHOULDER_CENTER", 45 | "HEAD", 46 | "SHOULDER_LEFT", 47 | "ELBOW_LEFT", 48 | "WRIST_LEFT", 49 | "HAND_LEFT", 50 | "SHOULDER_RIGHT", 51 | "ELBOW_RIGHT", 52 | "WRIST_RIGHT", 53 | "HAND_RIGHT", 54 | "HIP_LEFT", 55 | "KNEE_LEFT", 56 | "ANKLE_LEFT", 57 | "FOOT_LEFT", 58 | "HIP_RIGHT", 59 | "KNEE_RIGHT", 60 | "ANKLE_RIGHT", 61 | "FOOT_RIGHT" 62 | }; 63 | 64 | vector mapping = { 65 | 2, 1, 0, 3, 12, 13, 14, 15, 16, 17, 18, 19, 4, 5, 6, 8, 9, 10 66 | }; 67 | 68 | unordered_map mappingOrientations; 69 | 70 | int frames, delay; 71 | 72 | Device(int frames = 400, int delay = 200) : frames(frames), delay(delay) { 73 | for (int g = 0; g < mapping.size(); g++) { 74 | mappingOrientations.insert({ mapping[g], g }); 75 | } 76 | }; 77 | 78 | ~Device() { 79 | if (th.joinable()) { 80 | th.join(); 81 | } 82 | } 83 | 84 | bool initKinect() { 85 | // Get a working kinect sensor 86 | int numSensors; 87 | if (NuiGetSensorCount(&numSensors) < 0 || numSensors < 1) return false; 88 | if (NuiCreateSensorByIndex(0, &sensor) < 0) return false; 89 | 90 | // Initialize sensor 91 | sensor->NuiInitialize( 92 | NUI_INITIALIZE_FLAG_USES_DEPTH_AND_PLAYER_INDEX 93 | | NUI_INITIALIZE_FLAG_USES_COLOR 94 | | NUI_INITIALIZE_FLAG_USES_SKELETON); 95 | 96 | // NUI_SKELETON_TRACKING_FLAG_ENABLE_SEATED_SUPPORT for only upper body 97 | sensor->NuiSkeletonTrackingEnable(nullptr, NUI_SKELETON_TRACKING_FLAG_ENABLE_IN_NEAR_RANGE); 98 | 99 | return sensor; 100 | } 101 | 102 | unsigned int getSize() { 103 | return NUI_SKELETON_POSITION_COUNT; 104 | } 105 | 106 | bool getSkeletalData() { 107 | if (index != -1 && index >= frames) 108 | return false; 109 | 110 | while (true) { 111 | NUI_SKELETON_FRAME skeletonFrame = { 0 }; 112 | int frame = sensor->NuiSkeletonGetNextFrame(delay, &skeletonFrame); 113 | if (frame >= 0) { 114 | sensor->NuiTransformSmooth(&skeletonFrame, nullptr); 115 | 116 | // Loop over all sensed skeletons, stop at a valid person to be tracked 117 | for (const NUI_SKELETON_DATA& skeleton : skeletonFrame.SkeletonData) { 118 | // Check the state of the skeleton 119 | if (skeleton.eTrackingState == NUI_SKELETON_TRACKED) { 120 | unique_lock lck(mtx); 121 | 122 | // Extract bone orientations 123 | NuiSkeletonCalculateBoneOrientations(&skeleton, orientations); 124 | 125 | // For the first tracked skeleton 126 | // Copy the joint positions into our array 127 | for (int i = 0; i < NUI_SKELETON_POSITION_COUNT; i++) { 128 | skeletonPositions[i] = skeleton.SkeletonPositions[i]; 129 | 130 | if (skeleton.eSkeletonPositionTrackingState[i] == NUI_SKELETON_POSITION_NOT_TRACKED) { 131 | skeletonPositions[i].w = 0; 132 | } 133 | } 134 | 135 | if (this->cache) { 136 | consumed = false; 137 | index++; 138 | 139 | cv.notify_one(); 140 | } 141 | 142 | // Only take the data for one skeleton 143 | return true; 144 | } 145 | } 146 | } 147 | } 148 | } 149 | 150 | void printJoints(int i, string joint_name1, string joint_name2, string joint_name3) { 151 | cout << "----------" << endl; 152 | string joint1 = joints[orientations[i].startJoint]; 153 | string joint2 = joints[orientations[i].endJoint]; 154 | if ((joint1 == joint_name1 && joint2 == joint_name2) || 155 | (joint2 == joint_name1 && joint1 == joint_name2)) { 156 | printVec(orientations[i].absoluteRotation.rotationQuaternion); 157 | } 158 | 159 | string joint = joints[i]; 160 | if (joint == joint_name1 || joint == joint_name2 || joint == joint_name3) { 161 | cout << joint << endl; 162 | 163 | printVec(skeletonPositions[i]); 164 | } 165 | } 166 | 167 | void copy(float* buffer) { 168 | for (unsigned int g = 0; g < getSize(); g++) { 169 | const Vector4& joint = skeletonPositions[g]; 170 | 171 | Device::copyVectorToBuffer(joint, buffer, g * 3); 172 | } 173 | } 174 | 175 | static void copyVectorToBuffer(const Vector4& source, float* destination, unsigned int offset) { 176 | // Invalidate hidden joints 177 | if (source.w > 0) { 178 | destination[offset] = source.x; 179 | destination[offset + 1] = source.y; 180 | 181 | // The positive z axis is the visible area 182 | destination[offset + 2] = -source.z; 183 | } 184 | else { 185 | // Cull hidden & invalid joints 186 | destination[offset + 2] = 1.0; 187 | } 188 | } 189 | 190 | static void printVec(const Vector4& source) { 191 | printf("vec: %f, %f, %f, %f\n", source.x, source.y, source.z, source.w); 192 | } 193 | 194 | void initCache(const string& path) { 195 | assert(frames > 0); 196 | 197 | this->cache = true; 198 | this->th = move(thread(&Device::writeToFile, this, path)); 199 | } 200 | 201 | void clear() { 202 | sensor->Release(); 203 | } 204 | 205 | private: 206 | 207 | void writeToFile(const string& path) { 208 | string relativePath = "../output/" + path; 209 | 210 | fstream file(relativePath, fstream::out); 211 | if (file.is_open()) { 212 | printf("Writing to file: %d frames with %dms delay\n", frames, delay); 213 | 214 | while (true) { 215 | unique_lock lck(mtx); 216 | 217 | if (index >= frames) 218 | break; 219 | 220 | while (consumed) { 221 | cv.wait(lck); 222 | } 223 | 224 | for (const Vector4& joint : skeletonPositions) { 225 | file << joint.x << " " << joint.y << " " << joint.z << " "; 226 | } 227 | 228 | file << "\n"; 229 | 230 | for (const _NUI_SKELETON_BONE_ORIENTATION& orientation : orientations) { 231 | file << orientation.startJoint << " " << orientation.endJoint << " "; 232 | 233 | const Vector4& quart = orientation.absoluteRotation.rotationQuaternion; 234 | file << quart.x << " " << quart.y << " " << quart.z << " " << quart.w << "\n"; 235 | } 236 | 237 | consumed = true; 238 | } 239 | 240 | file.flush(); 241 | file.close(); 242 | 243 | printf("Finished writing to file\n"); 244 | } 245 | else { 246 | printf("Couldn't open %s\n", relativePath.c_str()); 247 | exit(-1); 248 | } 249 | } 250 | }; 251 | 252 | #endif -------------------------------------------------------------------------------- /Project/main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include "window.h" 3 | #include "motion.h" 4 | #include "defmesh.h" 5 | #include "device.h" 6 | #include "../Pinocchio/skeleton.h" 7 | #include "../Pinocchio/pinocchioApi.h" 8 | 9 | #define SKELETON_RENDER 1 10 | #define SKELETON_CACHE 0 11 | 12 | extern const string FILE_CACHE = "skeleton.out"; 13 | 14 | int main(int argc, char** argv) { 15 | if (argc != 6) { 16 | cout << "Missing either {meshPath} {skeletonPath} {motionPath} {rigged} {animation}" << endl; 17 | exit(-1); 18 | } 19 | 20 | const string meshPath = argv[1]; 21 | const string skeletonPath = argv[2]; 22 | const string motionPath = argv[3]; 23 | const string rigged = argv[4]; 24 | const string animation = argv[5]; 25 | 26 | bool SKELETON_RIGGED = false; 27 | if (rigged == "rigged") { 28 | SKELETON_RIGGED = true; 29 | } else { 30 | SKELETON_RIGGED = false; 31 | } 32 | 33 | bool SKELETON_ANIMATION = false; 34 | if (animation == "live") { 35 | SKELETON_ANIMATION = true; 36 | } else { 37 | SKELETON_ANIMATION = false; 38 | } 39 | 40 | Debugging::setOutStream(cout); 41 | 42 | MyWindow * window = new MyWindow(); 43 | Mesh mesh(meshPath); 44 | 45 | Skeleton skelton = FileSkeleton(skeletonPath); 46 | if (!SKELETON_RIGGED) { 47 | skelton.scale(0.7); 48 | 49 | mesh.normalizeBoundingBox(); 50 | } 51 | 52 | Device * device = nullptr; 53 | if (SKELETON_ANIMATION) { 54 | device = new Device(); 55 | } 56 | 57 | DeformableMesh * defmesh; 58 | Motion * motion = new Motion(device, motionPath); 59 | if (SKELETON_RIGGED) { 60 | defmesh = new DeformableMesh(mesh, skelton, motion); 61 | } else { 62 | // compute joint skin association and weights to bones attachment 63 | PinocchioOutput riggedOut = autorig(skelton, mesh); 64 | defmesh = new DeformableMesh(mesh, skelton, riggedOut.embedding, *(riggedOut.attachment), motion); 65 | } 66 | 67 | defmesh->rigged = SKELETON_RIGGED; 68 | 69 | window->addMesh(defmesh); 70 | window->show(); 71 | 72 | return Fl::run(); 73 | } -------------------------------------------------------------------------------- /Project/motion.cpp: -------------------------------------------------------------------------------- 1 | #include "motion.h" 2 | #include "defmesh.h" 3 | #include "../Pinocchio/skeleton.h" 4 | #include "../Pinocchio/utils.h" 5 | 6 | #include 7 | #include 8 | 9 | using namespace std; 10 | 11 | Motion::Motion(Device * device, const string &file) : device(device), fixedFrame(-1) { 12 | if (device) { 13 | if (!device->initKinect()) { 14 | printf("Couldn't connect to the Kinect device...\n"); 15 | exit(-1); 16 | } else { 17 | printf("Successfully connected to the Kinect device...\n"); 18 | this->fixedFrame = 0; 19 | } 20 | } else { 21 | ifstream strm(file.c_str()); 22 | 23 | if (!strm.is_open()) { 24 | cout << "Error opening file " << file << endl; 25 | return; 26 | } 27 | 28 | cout << "Reading " << file << endl; 29 | 30 | readRawFile(strm); 31 | } 32 | } 33 | 34 | void Motion::getDeviceData() { 35 | // Get skeleton data while available joints are generated 36 | bool flag = false; 37 | while (!flag) { 38 | flag = this->device->getSkeletalData(); 39 | } 40 | 41 | const int size = 20; 42 | vector positions; 43 | vector rotations; 44 | 45 | for (unsigned int g = 0; g < size; g++) { 46 | const Vector4& joint = device->skeletonPositions[g]; 47 | 48 | positions.push_back(Pinocchio::Vector3(joint.x, joint.y, joint.z)); 49 | } 50 | 51 | for (unsigned int g = 0; g < size; g++) { 52 | const _NUI_SKELETON_BONE_ORIENTATION& orientation = device->orientations[g]; 53 | 54 | Rotation rotation; 55 | 56 | rotation.joint1 = orientation.startJoint; 57 | rotation.joint2 = orientation.endJoint; 58 | 59 | const Vector4& quart = orientation.absoluteRotation.rotationQuaternion; 60 | rotation.rotation = Pinocchio::Vector4(quart.x, quart.y, quart.z, quart.w); 61 | 62 | rotations.push_back(rotation); 63 | } 64 | 65 | this->positions = vector> { positions }; 66 | this->rotations = vector> { rotations }; 67 | } 68 | 69 | void Motion::readRawFile(istream & stream) { 70 | const int size = 20; 71 | while(!stream.eof()) { 72 | vector positions(size); 73 | vector rotations(size); 74 | unordered_map hierarchicalRotations; 75 | 76 | for(int g = 0; g < size * 3; g++) { 77 | stream >> positions[g / 3][g % 3]; 78 | } 79 | 80 | for(int g = 0; g < size; g++) { 81 | Rotation & rotation = rotations[g]; 82 | stream >> rotation.joint1 >> rotation.joint2; 83 | 84 | for(int h = 0; h < 4; h++) { 85 | stream >> rotation.rotation[h]; 86 | } 87 | 88 | hierarchicalRotations.insert({rotation.joint2, rotation}); 89 | } 90 | 91 | this->positions.push_back(positions); 92 | this->rotations.push_back(rotations); 93 | this->hierarchicalRotations.push_back(hierarchicalRotations); 94 | } 95 | 96 | // translate and scale relative to avatar skeleton 97 | Pinocchio::Vector3 translation = Pinocchio::Vector3(0.492356, 0.762127, 0.476605) - positions[0][0]; 98 | double scale = 0.235319 / (positions[0][2] - positions[0][0]).length(); 99 | Transform<> trans(scale, translation); 100 | 101 | for(int g = 0; g < this->positions.size(); g++) { 102 | for(int h = 0; h < size; h++) { 103 | this->positions[g][h] = trans * this->positions[g][h]; 104 | } 105 | } 106 | } 107 | 108 | #ifdef _WIN32 109 | #include "windows.h" 110 | 111 | long getT() 112 | { 113 | SYSTEMTIME systime; 114 | GetSystemTime(&systime); 115 | 116 | return systime.wMilliseconds + 1000 * (systime.wSecond + 60 * (systime.wMinute + 60 * (systime.wHour + 24 * systime.wDay))); 117 | } 118 | #else 119 | #include 120 | 121 | long getT() 122 | { 123 | struct timeval tv; 124 | gettimeofday (&tv, NULL); 125 | 126 | return tv.tv_sec * 1000 + tv.tv_usec / 1000; 127 | } 128 | #endif 129 | 130 | int getMsecs() 131 | { 132 | static unsigned long startTime = getT(); 133 | return getT() - startTime; 134 | } 135 | 136 | void Motion::setFrameIdx() { 137 | if (fixedFrame >= 0) { 138 | this->getDeviceData(); 139 | this->frameIdx = fixedFrame; 140 | } 141 | 142 | this->frameIdx = (getMsecs() / (1000 / 15)) % positions.size(); 143 | } 144 | 145 | vector> Motion::get() const 146 | { 147 | return data[this->frameIdx]; 148 | } 149 | 150 | vector Motion::getRelative() 151 | { 152 | return rotations[this->frameIdx]; 153 | } 154 | 155 | vector Motion::getSkeletonBones() 156 | { 157 | return positions[this->frameIdx]; 158 | } 159 | 160 | unordered_map Motion::getHierarchicalRelative() { 161 | return hierarchicalRotations[this->frameIdx]; 162 | } 163 | 164 | vector Motion::getPose() const 165 | { 166 | return poses[this->frameIdx]; 167 | } 168 | 169 | -------------------------------------------------------------------------------- /Project/motion.h: -------------------------------------------------------------------------------- 1 | #ifndef MOTION_H 2 | #define MOTION_H 3 | 4 | #include "Device.h" 5 | #include "../Pinocchio/transform.h" 6 | #include 7 | 8 | struct Rotation { 9 | Pinocchio::Vector4 rotation; 10 | 11 | int joint1; 12 | int joint2; 13 | }; 14 | 15 | class Motion 16 | { 17 | public: 18 | Motion(Device * device, const string & filename); 19 | 20 | vector> positions; 21 | vector> rotations; 22 | vector> hierarchicalRotations; 23 | 24 | bool empty() const { return data.empty(); } 25 | vector > get() const; 26 | vector getPose() const; 27 | vector getRefPose() const { return refPose; } 28 | vector getSkeletonBones(); 29 | double getLegLength() const { return legLength; } 30 | double getLegWidth() const { return legWidth; } 31 | vector getRelative(); 32 | unordered_map getHierarchicalRelative(); 33 | 34 | const vector > > &getData() const { return data; } 35 | void setFixedFrame(int inFrame) { fixedFrame = inFrame < 0 ? -1 : (int)(inFrame % data.size()); } 36 | void setFrameIdx(); 37 | void getDeviceData(); 38 | 39 | int frameIdx = -1; 40 | private: 41 | void readRawFile(istream & strm); 42 | vector>> data; 43 | vector> poses; 44 | vector refPose; 45 | Device* device = nullptr; 46 | 47 | double legLength; 48 | double legWidth; 49 | int fixedFrame; 50 | }; 51 | 52 | #endif 53 | -------------------------------------------------------------------------------- /Project/renderer.h: -------------------------------------------------------------------------------- 1 | #ifndef RENDERER_H 2 | #define RENDERER_H 3 | 4 | #include "Device.h" 5 | #include "Program.h" 6 | #include "Tools.h" 7 | 8 | class Renderer: public Program { 9 | public: 10 | Device & device; 11 | 12 | GLint size; 13 | GLfloat * buffer; 14 | 15 | Renderer(Device & device): device(device) { 16 | initRenderer("../shaders/skeleton"); 17 | setClearColor(0, 0, 0, 1.0); 18 | 19 | glEnable(GL_PROGRAM_POINT_SIZE); 20 | 21 | size = device.getSize(); 22 | buffer = new GLfloat[size * 3]; 23 | 24 | initUniform(perspective(M_PI / 3, WIN_SIZE_W / WIN_SIZE_H, 0.5f, 100.0f).data(), "u_camera"); 25 | initBuffer(buffer, "a_position", size, 3); 26 | } 27 | 28 | void update() override { 29 | if(device.getSkeletalData()) { 30 | device.copy(buffer); 31 | 32 | updateBuffer(buffer, "a_position"); 33 | } else { 34 | clear(); 35 | } 36 | } 37 | 38 | void render() override { 39 | glDrawArrays(GL_POINTS, 0, size); 40 | } 41 | 42 | void clear() override { 43 | Program::clear(); 44 | 45 | delete [] buffer; 46 | } 47 | }; 48 | 49 | #endif -------------------------------------------------------------------------------- /Project/tools.h: -------------------------------------------------------------------------------- 1 | #ifndef SKELETON_TOOLS_H 2 | #define SKELETON_TOOLS_H 3 | 4 | #define _USE_MATH_DEFINES 5 | 6 | #include 7 | #include 8 | 9 | Eigen::Matrix4f perspective(float fieldOfView, float aspect, float v_near, float v_far) { 10 | float f = tan(M_PI * 0.5 - 0.5 * fieldOfView); 11 | float rangeInv = (float) 1.0 / (v_near - v_far); 12 | 13 | Eigen::Matrix4f perspective; 14 | perspective << f / aspect, 0, 0, 0, 15 | 0, f, 0, 0, 16 | 0, 0, rangeInv * (v_near + v_far), -1, 17 | 0, 0, rangeInv * v_near * v_far * 2, 0; 18 | 19 | return perspective; 20 | } 21 | 22 | #endif 23 | -------------------------------------------------------------------------------- /Project/window.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2007 Ilya Baran 3 | 4 | Permission is hereby granted, free of charge, to any person obtaining a copy 5 | of this software and associated documentation files (the "Software"), to deal 6 | in the Software without restriction, including without limitation the rights 7 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | copies of the Software, and to permit persons to whom the Software is 9 | furnished to do so, subject to the following conditions: 10 | 11 | The above copyright notice and this permission notice shall be included in 12 | all copies or substantial portions of the Software. 13 | 14 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 20 | THE SOFTWARE. 21 | */ 22 | 23 | #ifndef MYWINDOW_H 24 | #define MYWINDOW_H 25 | 26 | #include 27 | #include "../Pinocchio/mesh.h" 28 | #include "../Pinocchio/transform.h" 29 | #include "defmesh.h" 30 | #include 31 | 32 | struct LineSegment 33 | { 34 | LineSegment() : thickness(1.) {} 35 | LineSegment(const Pinocchio::Vector3 &inP1, const Pinocchio::Vector3 &inP2, 36 | const Pinocchio::Vector3 &inColor = Pinocchio::Vector3(1, 1, 1), double inThickness = 1.) 37 | : p1(inP1), p2(inP2), color(inColor), thickness(inThickness) {} 38 | 39 | Pinocchio::Vector3 p1, p2, color; 40 | double thickness; 41 | }; 42 | 43 | class MyWindow : public Fl_Gl_Window 44 | { 45 | public: 46 | MyWindow(); 47 | 48 | virtual ~MyWindow() {} 49 | virtual void draw(); 50 | virtual int handle(int); 51 | 52 | void addMesh(DeformableMesh * mesh); 53 | void addLine(const LineSegment &l) { lines.push_back(l); } 54 | void clearLines() { lines.clear(); } 55 | 56 | private: 57 | bool flatShading, floor, skeleton, toggle = true; 58 | Transform<> transform; 59 | vector meshes; 60 | vector lines; 61 | unordered_map textures; 62 | 63 | void resetTransform(); 64 | void initGL(); 65 | void drawMesh(const Mesh &m, bool flatShading, Pinocchio::Vector3 trans = Pinocchio::Vector3()); 66 | void drawFloor(); 67 | void loadFileTexture(string filename, int material); 68 | }; 69 | 70 | #endif //MYWINDOW_H 71 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 |

Automatic 3D model rigging and real-time Linear Mesh Blending avatar animation in C++ and Kinect.

2 | 3 |

4 | LBS animation 5 |

6 | 7 | ## Key Features 8 | 9 | * Kinect animation and caching 10 | * 3D model animation based on LBS 11 | * Automatic skeleton and bone weights generation 12 | * Support for various 3D models: .obj .fbx .off, .ply and .stl file formats. 13 | * Cross platform 14 | - Windows (only Kinect), macOS and Linux ready. 15 | 16 | ## Dependencies 17 | 18 | The project was built / run on Windows, Visual Studio 2019. The [Desktop development with C++ bundle](https://visualstudio.microsoft.com/downloads/) 19 | must include MSVC v142 - VS 2019 build tools, Windows 10 SDK, C++ MFC for MSVC v142. 20 | 21 | - [FLTK](https://www.fltk.org) - library v1.3.5 is needed for rendering. Download and unzip it and follow 22 | the [instructions](http://www.c-jump.com/bcc/common/Talk2/Cxx/FltkInstallVC/FltkInstallVC.html), set the appropriate env `FLTK_DIR`. 23 | 24 | - [STB](https://github.com/nothings/stb) - is required for image texture loading. Clone the [project](https://github.com/nothings/stb), 25 | as it is a header library, set only the appropriate env `STB_DIR`. 26 | 27 | - [Eigen](https://gitlab.com/libeigen/eigen) - is used for linear algebra related problems. Clone the [project](https://gitlab.com/libeigen/eigen), 28 | as it is a header library, set only the appropriate env `EIGEN_DIR`. 29 | 30 | - [Kinect for Windows SDK v1.8](https://www.microsoft.com/en-us/download/details.aspx?id=40278) - allows skeleton tracking to cache animations and live animate a 3D model. 31 | Download and install the distribution and set `KINECTSDK10_DIR` if it's not defined to the installation path. 32 | 33 | - [FBX SDK](https://www.autodesk.com/developer-network/platform-technologies/fbx-sdk-2019-0) - is useful to load complex 3D models that contain textures, skeleton... 34 | Download and install the distribution for Windows and set `FBX_DIR` to the installation path or follow the following [instructions](http://help.autodesk.com/view/FBX/2017/ENU/?guid=__files_GUID_6E7B1A2E_584C_49C6_999E_CD8367841B7C_htm). 35 | 36 | Older releases may work too... 37 | 38 | ## How To Use 39 | 40 | Loading a 3D model that is automatically rigged based on the joints.out and animate live based on Kinect: 41 | 42 | `data/human.obj data/joints.out data/skeleton.out non-rigged live` 43 | 44 | Loading a 3D model that is rigged and animated based on cached animation skeleton.out: 45 | 46 | `data/model.fbx data/joints.out data/skeleton.out rigged non-live` 47 | 48 | Note: Run in release mode to speed up things. To set up the command arguments in VS2019, select `Project project > Properties > Configuration Properties > Debugging > Command Arguments` 49 | 50 | ## Interaction 51 | 52 | - Press `s` to toggle skeleton, `g` for floor, `f` for flat shading rendering. 53 | - Use mouse wheel or by mouse dragging to move the camera. 54 | 55 | ## Miscellaneous 56 | 57 | The file `data/joints.out` contain the definition of the desired base skeleton (human, monkey, koala...). The loaded 3D model 58 | is embedded / scaled into [-1, 1] world space, thus each line contains an unique joint, its desired / expected 3D location, 59 | and his parent joint. Specify -1 if the corresponding joint is the root. 60 | 61 | The motion file `data/skeleton.out` is based on our custom motion format, where the skeleton 62 | is tracked each frame with first line representing [20 joints (Kinect v1)](https://de.mathworks.com/help/supportpkg/kinectforwindowsruntime/ug/use-skeleton-viewer-for-kinect-v1-skeletal-data.html) 63 | world positions and 20 new lines each representing the `index of parent joint`, `index of child joint`, `absolute quaternion rotation w.t.r Y-axis for joints world orientation` 64 | 65 | ## Credits 66 | 67 | The rigging is based on: 68 | 69 | - [Pinocchio](https://github.com/elrond79/Pinocchio) - please refer also the paper for extra information about rigging process. 70 | --------------------------------------------------------------------------------