evans_lindner_FMX08.ppt
- Количество слайдов: 57
Christopher Evans Technical Art Lead, Crytek § Responsibilities: § § Artist in R&D Pipeline tools Character technology Digital Janitor
Mathias Lindner Technical Animator, Crytek § Responsibilities § § § 3 rd Person Human Animations Animation Tools Motion Capture
What is this stuff? § A look at some scripted tools development at Crytek. § Beginner Maxscript Tutorial § § Using example code from tools at Crytek We started our maxscript journey from scratch Crysis Scripted Tool Examples A close look at the Animation tools/pipeline
Intended Audience § Beginner to Advanced § § Code examples in slides for beginners Tool videos/source online for advanced Technical Artists/Animators Anyone who wants to work faster and better in 3 ds. Max
Session Overview § § Cry. Tools Background Beginner Tutorial § Easy Street § § § § Basics Loops Animation Transformations User Feedback Hacking with DOS Production Examples
Session Overview § Animation Tools § § § Structure Function definitions Motion Capture Cleanup
Cry. Tools: Background § In the beginning: 2006 § § Current: 2008 § § 14 k+ of lines of code used by artists/animators across 3 studios 2 main contributors Scripts load from latest build on local machine § § No scripted tools No previous Maxscript experience (MEL) Pipeline/Architecture built from scratch Can also sync via Perforce/LAN/Http Modular design based on users § Rigging, Animation, Art
Cry. Tools: Background § Tools are freely available as part of the Cry. Engine 2 Mod. SDK § SDK: http: //www. crymod. com/filebase. php? fileid=1074&lim=0
Easy Street: The Basics § Do Not Store Global Variables --my script test = "hellow world“ print test --total noob --my script ( test = “hellow world” print test ) --hardened veteran § To store things globally, make global struct
Easy Street: Not so Basic (But Important!) --creating the struct _my. Tools_ ( fn function 1 = (return "my. Function 1"), fn function 2 = (return "my. Function 2"), var 1, var 2, var 3 ) --instance your struct my. Tools = _my. Tools_() --testing your struct my. Tools. function 1() "my. Function 1" my. Tools. var 1 = "store. Me" Print my. Tools. var 1 "store. Me"
Easy Street: The Basics § Use the Listener/Macro recorder § Maxscript docs rock (go Bobo!) Read other people’s scripts § § § www. scriptspot. com Use the Debugger!
Easy Street: The Basics showproperties $bone. width : world. Units. height : world. Units. taper : percent. length : float. . showinterface layer. Manager Interface: Layer. Manager Properties: . count : integer : Read. current : Interface : Read Methods: <Interface>get. Layer <integer>which <Interface>new. Layer(). .
Easy Street: Loops for i=1 to 4 (m += 2) for item in array do (print item. x) for obj in selection do (append obj array) for obj in $C 3 D* do (obj. parent = $node) for i=1 to (poly. Op. get. Num. Verts obj) do ( append locations (poly. Op. get. Vert obj i) )
Easy Street: Loops --sometimes you want to start later ss = Spline. Shape pos: (obj. position. keys[1]. value) add. New. Spline ss for i = 2 to obj. position. keys. count do ( add. Knot ss 1 #corner #line obj. position. keys[i]. value ) --or end sooner for i=1 to (items. count-1) do ( rot. Bind items[i] root 0 0 180 false ) rot. Bind items[items. count] root 0 0 180 true
Easy Street: Simplification for obj in selection do ( if (classof obj) == Sphere then ( if obj. wirecolor == red do ( obj. pos. z += 10 ) ) )
Easy Street: Simplification for obj in selection do ( if (classof obj) == Sphere then ( if obj. wirecolor == red do ( obj. pos. z += 10 ) ) )
Easy Street: Where! for obj in selection where (classof obj) == Sphere and obj. wirecolor == red do ( obj. pos. z += 10 ) --another example, this puts all spheres into an array called ‘spheres’ spheres = for obj in selection where (classof obj) == Sphere collect obj
Easy Street: Loop Examples --if a selected object had a turbosmooth modifier change it’s prefs for obj in selection do ( if (obj. modifiers[#turbosmooth] != undefined) do ( obj. modifiers[#turbosmooth]. iterations = 1 obj. modifiers[#turbosmooth]. use. Render. Iterations = true obj. modifiers[#turbosmooth]. render. Iterations = 2 ) )
Easy Street: Nested Loops --this removes bones in an array from a skin modifier for u=1 to rem. Bones. count do ( for i=1 to (skin. Ops. get. Number. Bones obj. skin) do ( if (skin. Ops. Get. Bone. Name obj. skin i 0) == rem. Bones[u]. name then ( skin. Ops. remove. Bone obj. skin i print ("removing " + rem. Bones[u]. name) ) --how can we simplify? my. Bones = for i=1 to skin. Ops. Get. Number. Bones obj. skin collect --cont next line (skin. Ops. Get. Bone. Name obj. skin i 0) for i=1 to rem. Bones. count where (finditem my. Bones rem. Bones[i]) != 0 do ( skin. Ops. removebone obj. skin (finditem my. Bones rem. Bones[i]) )
Easy Street: Animation/Time --stepping through frames with animate on ( for i = animationrange. start to animationrange. end do ( slidertime = i obj. pos. x += 10 ) ) --same as above, but much faster with animate on ( for i = animationrange. start to animationrange. end do ( at time i (obj. pos. x += 10) ) )
Easy Street: Functions fn cut. String string. In cut = ( start. Cut = (find. String string. In cut) return (replace string. In start. Cut cut. count "") ) --simple usage cut. String “chicks dig technical artists” “ technical” “chicks dig artists” --more complex (getnodebyname ((cut. String obj. name "C 3 D: ") + "_bone")). pos. controller = Position_XYZ()
Easy Street: Self Referencing --returns an array containing all children fn get. Children the. Node = ( node. Array = #() for obj in the. Node. children do ( append node. Array obj join node. Array (get. Children obj) ) return node. Array )
Transformations $. transform (matrix 3 [1, 0, 0] [0, 1, 0] [0, 0, 1] [23. 1612, 0. 667526, 0]) [-----orientation-----] [-----position-----] --maxscript cannot set parts of a transform like so: $. transform[1] = [1, 0, 0] --but this will work: new = $. transform new[1] = [1, 0, 0] $. transform = new
Transformations: Dealing with Biped --let’s get the position of a biped object print $'Bip 01 Head'. position -- Unknown property: "position" in $Editable_Mesh: Bip 01 Head @ [-25. 684864, -37. 348450, 118. 445419] --fail, ok let’s check out what properties does have showproperties $'Bip 01 Head' false --again: fail… when all else fails, go the transform print $'Bip 01 Head'. transform. position [-25. 6849, -37. 3484, 118. 445]
Other tips: Variables a = 5 b = a a += 2 print b 5 a = "ftw" b = a a[3] = a[1] = "w" print b "wtf“ --this is because of how subsets are stored in memory --for data-types that are groups of items (strings, arrays, etc) use ‘copy’ instead, example: b = copy a
Other tips: --try/catch try (print $. name) catch(print “nothing selected”) --reach into rollout floaters to pass vars my. Tool. rollouts[1]. variable --create undos Undo "make point" on ( point name: "test" ) --is an object animated? obj. is. Animated --getting a position at a certain time print (at time 11 f obj. pos)
Altogether: Better User Feedback On checkbutton changed state do ( if state == true then ( if selection != undefined then ( objs = (selection as array) checkbutton. text = (objs. count as string + “ objs selected”) ) else ( messagebox “No objects selected” checkbutton. checked = false ) ) else ( checkbutton. text = “Select Objects” ) ) --sample ui in course materials
Altogether: Better User Feedback On checkbutton changed state do ( if state == true then ( if selection != undefined then ( objs = (selection as array) checkbutton. text = (objs. count as string + “ objs selected”) ) else ( messagebox “No objects selected” checkbutton. checked = false ) ) else ( checkbutton. text = “Select Objects” ) ) --sample ui in course materials
Altogether: Better User Feedback try ( throw "This will be the name of your error" ) catch ( messagebox (get. Current. Exception()) ) --you could also use this to write out error logs on remote machines, have people send them to you when they get an error (or automatically send it)
Hacking Things in DOS § § DOSCommand [command <string>] Cry. Tools has a silent command line fn § § crytools. scmd [command <string>] [wait? <bool>] Many general uses § § § Moving files Perforce, Alien. Brain Glean info from ipconfig (domain, ip, MAC) Get external info Run small executables § § Hash generator Building/Executing external scripts § VBS/Python
DOS Example 1: Simple --This function will make a file writable, I use this a lot before writing to files. fn minus. R path = ( if doesfileexist path == true then ( doscommand ("attrib -r "" + path + ""“) ) else ( print (path + " does not exist") ) )
Getting info from DOS § First figure out the DOS command § § Dump generated text to a file with ‘>’ Then look at it’s output § Figure out how you want to parse it
Getting info from DOS § Then look at it’s output § Figure out how you want to parse it
DOS Example 2: Output fn local 2 unc letter = ( cmd = ("net use " + letter + ": > " + sys. Info. temp. Dir + “cmd. txt") doscommand cmd load. In = openfile (sys. Info. temp. Dir + "local_unc. txt") skip. To. String load. In "Remote" load. In. ARR = (filter. String (readline load. In) " ") close load. In doscommand ("del " + sys. Info. temp. Dir + "local_unc. txt") return load. In. ARR[2] ) local 2 unc "s" "\storageBuilds" local 2 unc "k" "\fs 1Artists"
DOS Example 2: Output file C: Documents and SettingschristopherLocal SettingsTempcmd. txt Local name S: Remote name \storageBuilds Resource type Disk Status Disconnected # Opens 0 # Connections 1 The command completed successfully. --tidbit from experience: people install DOS in different languages ; )
Callbacks! § Do things based on user input fn my. Fn = ( the. Faces = 0 for obj in selection do (the. Faces += obj. mesh. numfaces) print the. Faces ) --register callbacks. add. Script #selection. Set. Changed "my. Fn()" id: #my. Fn --unregister callbacks. remove. Scripts id: #my. Fn § Always remember to unregister!
Cry. Tools: Examples § § § Transfer Facial Morphs [ transfer_morphs. avi ] Mirror Morphs/Deformation [ mirror. Morphs. avi ] Hierarchy to Bones [ hierarch 2 bones. avi ] Hierarchy Tools [hierarchy_tools. avi] Cry. Info [ cryinfo. avi ]
In Closing § § Maxscript helped immensely on Crysis Scripting is a slippery slope § § One day you write a script to help someone, the next it’s your job : ) Screw efficiency § § § If something works, and is fast… let it be. Refactoring can be dangerous Cry. Tools has a lot of ‘beginner code’, but very few tools that take longer than an eyeblink to execute.
Animation Tools § Overview § Structure § § Function definitions § § How we used structures How we used functions Motion Capture Cleanup § Problems and solutions
Animation Tools § Structures § § § § Are declared in global scope Initialized with defined values Structure name is self-explaining Good for instancing variables in a structured way Behave a bit like classes Used about 60 different structures Example struct pivot. Sel. St ( index = 0, position = [0, 0, 0], piv. Object ) struct bip. Part. St ( object, part, name, pivot. Sel = ( pivot. Sel. St piv. Object = undefined ) )
Animation Tools § Function definitions § § Structure placeholder will be overwritten by function Global functions get removed Function name is self-explaining Example cry. Tools. cry. Anim. get. Bip. Names = function get. Bip. Names index = (. . . ) get. Bip. Names = undefined
Animation Tools cry. Tools. cry. Anim. get. Bip. Names = function get. Bip. Names index = (. . . ) get. Bip. Names = undefined § Advantages § § Easy to maintain (for development) No need to look at local scope of functions Function can be defined outside of the structure Disadvantages § Functions will be duplicated once = more time to load
Animation Tools § Motion Capture Cleanup § Problems we encountered § Slow workflow for Animators (lots of repeated clicks) § § Too technical to achieve code requirements § § Bad for health and time management Animators had trouble to get used to constant changes No feedback when something went wrong § Endless time spent with debugging
Animation Tools § Motion Capture Cleanup § Solutions: § Everything repetitive needs to be gone § § § Packed functions executed at once Designed tools to speed up the animation process Powerful User Interface § § Self-explaining functionality Compact set of tools
Animation Tools § Motion Capture Cleanup § Everything repetitive needs to be gone: § One Click Solutions § § § Simple scripts just for the purpose No user interface needed Examples: § Set planted keys for biped (video) § Copy Paste Transformations (video)
Animation Tools § Motion Capture Cleanup § Everything repetitive needs to be gone: § Batch process for animations § § § Use of different file formats Sub folder support File mask Execute scripts to solve different problems Status report (video)
Animation Tools § Motion Capture Cleanup § Powerful User Interface: Goals: § Fast production of assets § § Animator should not care about technical things § § Compact functionality in one place Solutions for complex bone behavior User Customization § Animator can change the look and functionality of dialogs
Animation Tools § Motion Capture Cleanup § Powerful User Interface - Solutions: § Fast production of assets § Fast loading and saving of assets § § § Load files directly out of the production folder Export files into the game Using snapshots for foot alignment § § (video) Speed up hand foot cleanup How it works (video)
Animation Tools § Motion Capture Cleanup § Powerful User Interface - Solutions: § Animators should not care about technical things § Locomotion Locator animation § § § Used for linking the animation to the character in-game In some cases complex behaviour Weapon / Item adjustment § § (video) Specific bones to carry weapons / items in the game Rotation and position can change for each item
Animation Tools § Motion Capture Cleanup § Powerful User Interface - Solutions: § User Customization § No hardcoded values / states § Dialog should represent the needs of Animators § Easy to add new elements
Animation Tools § Motion Capture Cleanup § Powerful User Interface - Solutions: Normal Multi Row (video)
Thank you for your attention
Questions?
Full Source of Examples at: www. Chris. Evans 3 D. com/files/fmx 08. rar Crytools/Source at: www. Chris. Evans 3 D. com/files/crytools. rar Should be up by 12/05/08
Questions or comments via email? Christopher Evans Chris. Evans@Gmail. com Mathias Lindner Mathias_Lin@Hotmail. com
evans_lindner_FMX08.ppt