-- Ped Renderer -- A script to merge in a camera and light setup and prepare the scene for rendering -- -- Stewart Wright -- 24/05/10 - v1 -- 25/05/10 - added anim loading based on model gender. also added a load of prints so i can track crashes a bit easier. -- 26/08/10 - added make alpha function -- 13/01/11 - v2 changed setup from mentalray to scanline renderer -- 09/03/11 - added decl settings -- 13/04/11 - Fixed scope of prop align function. added extra filein propsettingsfile -- 08/03/12 - moved to new wildwest -- **************************************************************************************** -- **************************************************************************************** -- Common script headers, setup paths and load common functions --start fileins filein (RsConfigGetWildWestDir() + "script/3dsMax/_config_files/Wildwest_header.ms") RsCollectToolUsageData (getThisScriptFilename()) -- Load project specific prop settings filein (pathToConfigFiles + "characters\max_prop_settings.dat") -- Load project specific shader settings filein (pathToConfigFiles + "characters\max_shader_settings.dat") -- Figure out the project ped folder theProjectPedFolder = theProjectRoot + "art/peds/" -- Where to get the animations from animFolder = (theProjectPedFolder + "Skeletons/Animations/") animmappingfile = (animFolder + "/SKEL_MALE_TRANSFORM_MAPPING.xmm") -- **************************************************************************************** -- Setup some variables rootbone = $'SKEL_ROOT' rsdState = undefined saveRenderPath = null renderAs = theProjectPedFolder + "/Rendering/textures/tempRender.jpg" renderThese = #() RenderRigParts = #() animFile = animFolder +"Render_Pose_Male.xaf" allGeo = #() whereItWas = "" -- **************************************************************************************** -- create some functions -- try to figure out the gender based on the models name fn defineGender = ( tempModelName = uppercase maxfilename currentModelGender = tempModelName if currentModelGender[3] == "M" then ( print "Male Skeleton" animFile = animfolder +"Render_Pose_Male.xaf" ) else if currentModelGender[3] == "F" then ( print "Female Skeleton" animFile = animfolder +"Render_Pose_Female.xaf" ) print "File gender defined." ) -- end defineGender -- **************************************************************************************** --delete some stuff that gets in the way fn deleteShit = ( hideByCategory.none() clearselection() try ( selectbywildcard "col" delete selection )catch() try ( selectbywildcard "con" delete selection )catch() tempName = filterString maxfilename "." lodDummy = tempName[1] + "-l" actualObject = (getNodebyName lodDummy) try ( select actualObject actionMan.executeAction 0 "40194" --Selection: Select Child delete selection delete actualObject )catch() hideByCategory.all() hideByCategory.geometry = false ) -- **************************************************************************************** -- work out where to save to fn renderTo = ( if maxfilepath == "" then ( loTime = localtime filtTime = filterString loTime "/: " folTime = filtTime[1] + "_" + filtTime[2] + "_" + filtTime[3] + "-" + filtTime[4] + "_" + filtTime[5] + "_" + filtTime[6] thePath = "c:\\" BakePath = thePath + "Temp\\Renders\\" + folTime try ( makedir renderPath ) catch() saveRenderPath = renderPath ) else ( -- get filename thePath = maxfilepath as string renderPath = thePath + "Renders" -- create folder if needed try ( makedir renderPath ) catch() saveRenderPath = renderPath ) ) -- end renderTo -- **************************************************************************************** -- collects all children recursively. arguments: -- found on http://forums.cgsociety.org/showpost.php?p=4427477&postcount=2 fn collectChildren obj &allChildren includeParent:false includeHidden:false = ( -- check if object should be collected if (includeHidden or not obj.isHiddenInVpt) and includeParent and finditem allChildren obj == 0 then append allChildren obj -- collect current object's children for c in obj.children do collectChildren c &allChildren includeParent:true includeHidden:includeHidden ) -- end collectChildren -- **************************************************************************************** -- a function for setting all the render values we want (and resetting the ones we don't to default) fn renderSettings = ( print "Starting to apply custome render settings." -- store the state of the render scene dialogue because we can rsdState = renderSceneDialog.isopen() -- close the render scene dialogue so that these settings work renderSceneDialog.close() -- Enviroment and Effects -- set enviroment values -- common parameters backgroundColor = color 129 129 129 backgroundFile = theProjectRoot + "art/peds/Rendering/textures/background.tga" environmentMap = bitmapTexture filename:backgroundFile useEnvironmentMap = on -- global lighting lightTintColor = color 134 141 172 lightLevel = 1.0 ambientColor = color 90 86 82 -- exposure control SceneExposureControl.exposureControl = undefined -- atmosphere try deleteAtmospheric 1 catch () -- set effects values try deleteEffect 1 catch () --Render Setup -- Common -- assign renderer renderers.current = default_scanline_renderer() -- output size renderHeight = 1024 renderWidth = 768 setRendApertureWidth 36.0 -- options rendAtmosphere = false renderEffects = false renderDisplacements = false rendColorCheck = false rendFieldRender = false rendHidden = false rendSimplifyAreaLights = false rendForce2Side = false rendSuperBlack = false -- adcanced lighting RadiosityPreferences.useAdvancedLighting = true RadiosityPreferences.computeAdvancedLighting = false -- render output rendOutputFilename = "" -- scripts usePreRendScript = false usePostRendScript = false -- Renderer --Options renderers.current.mapping = true renderers.current.shadows = true renderers.current.enableSSE = false renderers.current.autoReflect = true renderers.current.forceWireFrame = false renderers.current.wireThickness = 1.0 --Antialiasing renderers.current.antiAliasing = true renderers.current.antiAliasFilter = Catmull_Rom() renderers.current.filterMaps = true renderers.current.antiAliasFilterSize = 4.0 --Global SuperSampling renderers.current.globalSamplerEnabled = false --Object Motion Blur renderers.current.objectMotionBlur = true renderers.current.objectBlurDuration = 0.5 renderers.current.objectBlurSamples = 10 renderers.current.objectBlurSubdivisions = 10 --Image Motion Blur renderers.current.imageMotionBlur = true renderers.current.imageBlurEnv = false renderers.current.imageBlurTrans = false renderers.current.enablePixelSampler = true renderers.current.imageBlurDuration = 0.5 --Auto Reflect/Refract Maps renderers.current.autoReflectLevels = 1 --Color Range Lighting renderers.current.colorClampType = 0 --Memory Management renderers.current.conserveMemory = false --Advanced Lighting --Select Advanced Lighting SceneRadiosity.radiosity = undefined --Render Elements local reMan=maxOps.GetCurRenderElementMgr() reMan.RemoveAllRenderElements() --Raytracer local r=RaytraceGlobalSettings() r.showProgressDlg = false r.showMessages = false --Ray Depth Control r.max_ray_depth = 9 r.adaptive_ray_depth_threshold = 0.05 r.max_levels_color_mode = 1 r.max_levels_specify_color = color 0 0 0 --Global Ray Antialiaser r.adaptive_antialiasing_enable_flag= false --Global Raytrace Engine Options r.enable_raytracing=true r.enable_atmosphere=true r.enable_self_reflect_refract=true r.enable_material_id_rendering_support=true r.enable_objects_in_raytrace_objects=true r.enable_atmosphere_in_raytrace_objects=true r.enable_refract_special_effects=true --Acceleration Controls r.vox_face_limit=10 r.vox_dim=30 r.vox_previs=4.0 r.vox_maxdepth=8 --Exclude r.excludeList=#() -- open the render scene dialogue if it was open to begin with if rsdState == true then ( renderSceneDialog.open ) print "Render settings applied." ) -- end renderSettings -- **************************************************************************************** -- merge in the render setup (lights, camera, plinth etc) fn mergeScene = ( print "Merging render scene." renderFile = theProjectPedFolder + "/Rendering/RenderRig_001.max" mergeMaxFile renderFile #deleteOldDups #useSceneMtlDups #alwaysReparent quiet:true -- clear selection clearSelection() -- switch to camera view viewport.setCamera $Render_Cam displaySafeFrames = true RenderRigParts = #() collectChildren $Render_Rig &RenderRigParts includeParent:true includeHidden:true print "Render scene merged." ) -- end mergeScene -- **************************************************************************************** -- create an array to store the rendered objects fn toRender = ( renderThese = getCurrentSelection() selectionsets["*Render Set"] = renderThese print "Render Set created." ) -- end toRender -- **************************************************************************************** -- create standard materials for the model using the highRes folder's textures fn buildStdMats = ( print "Begin building materials." textureFolder = ((rsconfigmakesafeslashes maxfilepath) + "textures/highres" + "/") -- create textures for the components create_ped_multi_component() fill_ped_multi_component textureFolder 3 -- create textures for head props create_ped_multi_prop "p_head" 6 1 fill_ped_multi_prop textureFolder "p_head" 6 1 -- create textures for eye props create_ped_multi_prop "p_eyes" 5 2 fill_ped_multi_prop textureFolder "p_eyes" 5 2 print "Finished building materials." ) -- end buildStdMats -- **************************************************************************************** --turn off some things from the decl map fn fixDecl = ( d=14 --decl sub material for m=1 to 4 do ( try( meditMaterials[m].materialList[d].bumpMapEnable = off meditMaterials[m].materialList[d].glossinessMapEnable = off meditMaterials[m].materialList[d].specularLevelMapEnable = off )catch() ) )--end fixDecl -- **************************************************************************************** -- try and assign the materials to the meshes fn assignMats = ( print "Starting to assign materials to meshes." -- empty the arrays allGeo = #() mesh000 = #() mesh001 = #() mesh002 = #() mesh003 = #() mesh004 = #() -- unhide all by categry hideByCategory.none() -- unhide all unhide (for obj in objects where obj.ishidden collect obj) -- delete those pesky particle views try (delete $particle*) catch () --hide everything that isn't geometry by category hideByCategory.shapes = true hideByCategory.lights = true hideByCategory.cameras = true hideByCategory.helpers = true hideByCategory.spacewarps = true hideByCategory.particles = true hideByCategory.bones = true -- fill the arrays -- select 000 variations clearSelection() select $*000* deselect $p_* mesh000 = getCurrentSelection() mesh000.material = meditMaterials[1] -- select 001 variations clearSelection() select $*001* deselect $p_* mesh001 = getCurrentSelection() mesh001.material = meditMaterials[2] -- select 002 variations clearSelection() select $*002* deselect $p_* mesh002 = getCurrentSelection() mesh002.material = meditMaterials[3] -- select 003 variations clearSelection() select $*003* deselect $p_* mesh003 = getCurrentSelection() mesh003.material = meditMaterials[4] -- select 004 variations clearSelection() select $*004* deselect $p_* mesh004 = getCurrentSelection() mesh004.material = meditMaterials[5] -- select everything and pass it into an array for us to use later max select all deselect $mover allGeo = getCurrentSelection() -- unhide all by categry hideByCategory.none() -- clear selection clearSelection() displayColor.shaded = #material hideByCategory.all() hideByCategory.geometry = false print "Finished assigning materials to meshes." ) -- end assignMats -- **************************************************************************************** -- Show the maps in viewport, make things pretty fn showMats geoList = ( --loop through all selected objects that have a valid material assigned: for geo in geoList where geo.material != undefined do ( if classof geo.material == MultiMaterial then ( for i = 1 to geo.material.numsubs do showTextureMap geo.material[i] on --loop through all sub-materials and enable ) else --if the material is anything but Multi/Sub ( showTextureMap geo.material on ) ) ) -- end showMats -- **************************************************************************************** -- align and link props so they work in the render pose fn sortTheProps = ( print "Sorting Props..." try ( selectbywildcard propPrefix if selection.count != 0 do ( AlignProps () unlinkProps () LinkProps () print "...Props Linked and Aligned" ) ) catch(print "...No Props in scene") -- --filein propsettingsfile -- print "Sorting Props..." -- try ( -- select $p_* -- if selection.count != 0 do -- ( -- AlignProps () -- unlinkProps () -- LinkProps () -- print "...Props Linked and Aligned" -- ) -- )catch(print "...No Props in scene") )-- end sortTheProps -- **************************************************************************************** -- Function to query user meta-data on skel_root to see if it contains a correct version no. Returns version or Undefined fn querySkelVersion = ( currentSkelversion = undefined if $SKEL_Root != undefined then ( -- Read the User Defined Properties currentUDP = getUserPropbuffer $SKEL_Root filterUDP = filterString currentUDP "\r\n" -- Look for skeleton version numbers for i = 1 to filterUDP.count do ( tagTest = filterstring filterUDP[i] "=" skeltest = substring tagtest[1] 1 18 if skelTest== "SkeletonVersionTag" do ( verInt = (tagtest[2] as float) --hacky way to strip off any leading whitespace shite! currentSkelversion = (verInt as string) ) ) currentSkelversion -- return this ) else ( messageBox "WARNING! Couldn't find SKEL_Root" ) ) -- end querySkelVersion -- **************************************************************************************** fn assumeSkinPose = ( rootbone = $'SKEL_ROOT' -- Figure out what version this skeleton is. currentSkelVersion = querySkelVersion() -- If skeleton version is up to date just 'assume skin pose'. if ((currentSkelVersion == currentSkeletonNumber) or (currentSkelVersion != undefined)) then ( print "Skeleton is versioned so assuming skinPose." -- Build a list of all the bones in the object select rootBone for p in selection do ( p.assumeSkinPose -- print ("assumedSkinPose on "+p.name) if p.children != undefined do ( selectmore p.children ) ) -- go to fram 0, just incase sliderTime = 0f selectKeys $ deletekeys $ ) --skeleton version is not the most up to date so we need to set frame to 0 before we do anything else to hackily get a skin pose else ( print "WARNING!!! Current Skeleton is not up to date. Doing hacky fig pose thingy." sliderTime = 0f ) ) -- end assumeSkinPose -- **************************************************************************************** fn loadAnim = ( rootbone = $'SKEL_ROOT' print "Starting animation loading functions." --****-- delete existing animation objArray = objects as array for fb in objArray do ( print ("deleting keys from "+fb.name) deleteKeys fb.controller ) --now set back to bind pose filein (theWildWest + "script/3dsMax/Characters/Rigging/usefulscripts/resetBindPose.ms") --****-- end delete existing animation clearSelection() try (select rootbone) catch() if $ == rootbone then ( assumeSkinPose() skelObjects = objects as array clearSelection() for pB = 1 to skelObjects.count do ( if substring skelObjects[pB].name 1 5 == "SKEL_" do ( selectMore skelObjects[pB] ) ) print ("attempting to load "+animFile) print ("Mapping file = "+animmappingfile) try ( LoadSaveAnimation.loadAnimation animFile selection useMapFile:true mapFileName:animmappingfile print ("Loaded " + animFile) print "Finished animation function." )catch (print "Failed to load animation") ) ) -- end loadAnim -- **************************************************************************************** --check if the model has heels on, move the root bone up if they do fn heelCheck renderStage = ( if renderStage == true then ( print "pre-render heel check" whereItWas = in coordsys world $skel_root.pos print ("root bone position is " + whereItWas as string) try ( select $EO_R_Foot )catch() if selection.count == 1 then ( raiseItUp = [whereItWas[1],whereItWas[2],(whereItWas[3] + 0.065)] --high heels --raiseItUp = [whereItWas[1],whereItWas[2],(whereItWas[3] + 0.114)] --stripper heels in coordsys world $skel_root.pos = raiseItUp print ("root bone position raised to " + raiseItUp as string) ) ) else if renderStage == false do ( print "post render heel reset" in coordsys world $skel_root.pos = whereItWas print ("root bone position is " + whereItWas as string) ) )--end heelCheck -- **************************************************************************************** -- lets all go and render some shit fn renderNow = ( print "Begining render process" -- sort the scene out so that only the render elements are visible -- unhide all by categry hideByCategory.none() -- unhide all unhide (for obj in objects where obj.ishidden collect obj) SetSelectFilter 1 --make sure we can select stuff max select all deselect renderThese deselect RenderRigParts hide selection -- clear selection clearSelection() -- create a timestamp loTime = localtime filtTime = filterString loTime "/: " renTime = filtTime[1] + "_" + filtTime[2] + "_" + filtTime[3] + "-" + filtTime[4] + "_" + filtTime[5] + "_" + filtTime[6] Targa.setColorDepth 32 --i need to set alpha renderAs = saveRenderPath + "\\" + renTime +".tga" render camera:$Render_Cam outputfile:renderAs hideByCategory.all() hideByCategory.geometry = false print ("Finished render. Saved to " + renderAs) ) -- end renderNow -- **************************************************************************************** -- **************************************************************************************** if ((renderScript != undefined) and (renderScript.isDisplayed)) do (destroyDialog renderScript) -- **************************************************************************************** rollout renderScript "Character Render Tools" ( hyperlink lnkHelp "Help?" address:"https://devstar.rockstargames.com/wiki/index.php/Character_Render_Tool" align:#right color:(color 20 20 255) hoverColor:(color 255 255 255) visitedColor:(color 0 0 255) button btnPrepScene "Prepare Scene" width:150 height:50 pos:[5,20] tooltip:"Cleanup scene, setup standard materials and apply them" button btnRenderGroup "Create Render Set" width:150 height:50 pos:[5,75] tooltip:"Store the currently selected geo as what you want to render" button btnRender "Render" width:150 height:90 pos:[5,130] tooltip:"Let's go render!" label renderLabel "Last Render:" pos:[160,5] imgTag imgLastRender width:150 height:200 pos:[160,20] bitmap:(openbitmap renderAs) on renderScript open do ( WWP4vSync pedRenderFiles WWP4vSync pedAnimFiles ) on btnPrepScene pressed do ( filein (pathToConfigFiles + "characters\max_prop_settings.dat") deleteShit() clear_all_materials() -- delete current scene materials because mental ray doesn't like rager shaders kill_materials() -- delete current scene materials because mental ray doesn't like rager shaders buildStdMats () fixDecl() assignMats() showMats allGeo sortTheProps() --align the props ) on btnRenderGroup pressed do ( -- Lets check that there is something selected if selection.count == 0 then ( messagebox "Nothing Selected" ) else ( renderThese = #() toRender () ) ) on btnRender pressed do ( if renderThese.count == 0 then ( messagebox "I don't know what you want to render. Have you ran the 'Create Render Set' button?" ) else ( saveRenderPath = null renderTo () defineGender () print "File Paths and Model Gender defined." mergeScene () loadAnim () renderSettings () heelCheck true --adjust the heel height if we find eo_r_Foot animationRange = interval 0f 1f --should be plenty of frames sliderTime = animationRange.end --go to the end frame where the render pose is renderNow () -- make a pretty button with the last render on it miniRender = render outputsize:[150,200] vfb:off imgLastRender.bitmap = miniRender heelCheck false --adjust the height back to what it was at the start try (select renderThese) catch() ) ) on imgLastRender lbuttonup do ( try (shellLaunch saveRenderPath "") catch (messagebox "Nothing Rendered") ) on imgLastRender rbuttonup do ( try (shellLaunch renderAs "") catch (messagebox "Nothing Rendered") ) ) -- end renderScript rollout createDialog renderScript width:315