Files
gtav-src/tools_ng/wildwest/script/3dsMax/Characters/Setup/Ped_Renderer.ms
T
2025-09-29 00:52:08 +02:00

729 lines
22 KiB
Plaintext
Executable File

-- 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