├── .gitignore ├── part1 ├── example_com.hip ├── example_mom_of_inert.hip └── example_rotate_in_a_proper_way.hip ├── otls ├── visualizearrows.hda └── create_representation.hda ├── houdini.project ├── README.md └── houdini_launcher.py /.gitignore: -------------------------------------------------------------------------------- 1 | **/backup 2 | -------------------------------------------------------------------------------- /part1/example_com.hip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/permahorse/RBDtutorial/HEAD/part1/example_com.hip -------------------------------------------------------------------------------- /otls/visualizearrows.hda: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/permahorse/RBDtutorial/HEAD/otls/visualizearrows.hda -------------------------------------------------------------------------------- /otls/create_representation.hda: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/permahorse/RBDtutorial/HEAD/otls/create_representation.hda -------------------------------------------------------------------------------- /part1/example_mom_of_inert.hip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/permahorse/RBDtutorial/HEAD/part1/example_mom_of_inert.hip -------------------------------------------------------------------------------- /part1/example_rotate_in_a_proper_way.hip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/permahorse/RBDtutorial/HEAD/part1/example_rotate_in_a_proper_way.hip -------------------------------------------------------------------------------- /houdini.project: -------------------------------------------------------------------------------- 1 | { 2 | "formatVersion": [ 3 | 1, 4 | 0 5 | ], 6 | "configs": [ 7 | { 8 | "binary": "houdinifx", 9 | "formatVersion": [ 10 | 1, 11 | 0 12 | ], 13 | "version": [ 14 | 16, 15 | 0, 16 | 600 17 | ], 18 | "name": "workBitch", 19 | "env": [ 20 | [ 21 | "JOB", 22 | "[PWD]" 23 | ], 24 | [ 25 | "HOUDINI_VEX_PATH", 26 | "[PWD]/vex;&" 27 | ], 28 | [ 29 | "HOUDINI_OTLSCAN_PATH", 30 | "[PWD]/otls;&" 31 | ] 32 | ] 33 | } 34 | ] 35 | } -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | This is supplementary material for the RBD try-to-be-tutorial for Houdini that can be found here: 2 | #### Part 1: https://vimeo.com/243886050 3 | 4 | ## Part 1 5 | 6 | * ### example_com 7 | This example shows you how center of mass is calculated 8 | You can see how any object is divided into tetrahedrons, orange arrows will be pointint to those tetrahedrons' centers of masses. 9 | Red arrow is pointint to the whole object's center of mass 10 | 11 | Use the display node to change the visualisation scale of tetrahedrons to understand better how they fill up the mesh 12 | 13 | You can plug your custom object into *"PUT_OBJECT_HERE"* red null. 14 | Just remember, that for calculations to be correct the object has to be closed, with little-to-none self intersections 15 | 16 | * ### example_mom_of_inert 17 | This example shows how moment of inertia is calculated 18 | You may see the object and it's calculated rest(I0) and current(I) moment of inertia matrices 19 | 20 | Use the display node to change object's rotation and see how I changes with it 21 | 22 | You can plug your custom object into *PUT_ANY_RAW_OBJECT_HERE* red null. 23 | as in com example, remember to keep the object closed and without self intersections (we are working with physically correct objects here after all) 24 | 25 | * ### example_rotate_in_a_proper_way 26 | This example shows different ways RBD integrator can work, and compares it with Houdini's standard Bullet's integrator. 27 | 28 | Use the display node to change solver type 29 | 0. Trivial integrator, one that keeps angular velocity(w) constant, witch is the most fast and simple way to implement integrator, but which leads to non physically correct behaviour, including possible energy additions and subtractions 30 | 1. Simplest physically correct integrator, uses Euler first order integration method - not accurate, requires high substeps to converge 31 | 2. Same simplest physically correct integrator, but using second order Euler-trapezoid predictor-corrector method - notice how much more accurate it becomes with significantly less substeps 32 | 3. Bullet integrator. Notice that bullet does integration pretty neat, though at high velocities does not converge properly, and tend to reduce energy during calculations - probably it helps keeping big simulations more stable. 33 | 34 | ## How to launch 35 | * use the python launcher script provided, it's supposed to cover both windows and linux/mac cases 36 | * use [cgLauncher](https://github.com/pedohorse/cglauncher) to launch - there is a preconfigured project supplied 37 | * or just manually set following env variables if you are using your ways of starting houdini 38 | * HOUDINI_OTLSCAN_PATH = "/otls:&" 39 | * HOUDINI_VEX_PATH = "/vex:&" 40 | -------------------------------------------------------------------------------- /houdini_launcher.py: -------------------------------------------------------------------------------- 1 | import os 2 | import subprocess 3 | import re 4 | import time 5 | 6 | import platform 7 | 8 | def locateHoudini(ver=()): 9 | if(len(ver)==0):ver=(9999,0,9999) 10 | elif(len(ver)==1):ver=(ver[0],0,9999) 11 | elif(len(ver)==2): 12 | if(ver[1]<10):ver=(ver[0],ver[1],9999) 13 | else:ver=(ver[0],0,ver[1]) 14 | elif(len(ver)>3):raise ValueError("version must have max 3 components") 15 | #now ver has format (XX.X.XXX) 16 | 17 | system=platform.system() 18 | 19 | if(system=='Windows'): 20 | commonpaths = [r"C:\Program Files\Side Effects Software"] 21 | elif(system=='Linux'): 22 | commonpaths = [r"/opt"] 23 | elif(system=='Darwin'): 24 | commonpaths = ["r/Applications/Houdini"] 25 | else: 26 | raise RuntimeError("looks like someone purposefully deleted you OS from jedi archives...") 27 | 28 | houdinies={} 29 | for path in commonpaths: 30 | dirs=[] 31 | try: 32 | dirs=os.listdir(path) 33 | except: 34 | continue 35 | 36 | for dir in dirs: 37 | if (system == 'Windows'): 38 | matchexpr=r"[Hh]oudini ?(\d+)(\.(\d))?(\.(\d{3,}))?" 39 | elif(system == 'Linux'): 40 | matchexpr = r"hfs(\d+)(\.(\d))(\.(\d{3,}))" #we want full versions, not links or shortcuts 41 | elif(system == 'Darwin'): 42 | matchexpr = r"[Hh]oudini ?(\d+)(\.(\d))(\.(\d{3,}))" 43 | match = re.match(matchexpr, dir) 44 | if(not match):continue 45 | cver=(int(match.group(1)),0 if match.group(3)=="" else int(match.group(3)), 9999 if match.group(5)=="" else int(match.group(5))) 46 | if(system=='Windows' or system=='Linux'): 47 | houdinies[cver] = os.path.join(path, dir) 48 | elif(system=='Darwin'): 49 | houdinies[cver] = os.path.join(path, dir,'Frameworks','Houdini.framework','Version',"%s.%s.%s"%cver,'Resources') 50 | 51 | vers=houdinies.keys() 52 | if(len(vers)==0):raise RuntimeError("houdini not found!!") 53 | #elif(len(vers)==1):return houdinies[vers[0]] 54 | 55 | sortvers=[((abs(x[0]-ver[0]),abs(x[1]-ver[1]),abs(x[2]-ver[2])),x) for x in vers] 56 | 57 | sortvers.sort(key=lambda el:el[0][0]) 58 | sortvers=[x for x in sortvers if x[0][0]==sortvers[0][0][0]] 59 | sortvers.sort(key=lambda el:el[0][1]) 60 | sortvers=[x for x in sortvers if x[0][1]==sortvers[0][0][1]] 61 | sortvers.sort(key=lambda el:el[0][2]) 62 | sortvers=[x for x in sortvers if x[0][2]==sortvers[0][0][2]] 63 | 64 | return os.path.join(houdinies[sortvers[0][1]],"bin","houdinifx") 65 | 66 | 67 | def launchHoudini(ver,vars): 68 | 69 | for var in vars: 70 | os.environ[var]=vars[var] 71 | print("%s set to %s"%(str(var),str(vars[var]))) 72 | houbin=locateHoudini(ver) 73 | print("Calling closest found version: %s"%(houbin,)) 74 | subprocess.Popen(houbin,stdin=None,stdout=None,stderr=None) 75 | print("Done!") 76 | 77 | 78 | print("Welcome to houdini hsite launcher ver. %s !!"%("0.0.0.003 preAlphaTechDemo")) 79 | print("----------") 80 | jobpath=os.path.join(os.path.split(os.getcwd())[0],"fxproject") 81 | launchHoudini((16,0,600),{'HOUDINI_VEX_PATH':os.getcwd()+'/vex'+os.pathsep+'&','HOUDINI_OTLSCAN_PATH':os.getcwd()+'/otls'+os.pathsep+'&'}) 82 | print("----------") 83 | print("you can now close this window, it will close automatically in 5 sec") 84 | time.sleep(5) --------------------------------------------------------------------------------