Files
gtav-src/tools_ng/dcc/debug/max2011/scripts/rockstar/helpers/environmentmap.ms
T
2025-09-29 00:52:08 +02:00

440 lines
13 KiB
Plaintext
Executable File

--
-- File:: rockstar/helpers/environmentmap.ms
-- Description:: Rockstar Cubic Reflection Map Generator
-- Render a cubic reflection map for the selected object. Also includes functionality for previewing a
-- render of any the of the sides of the "cube".
--
-- Author:: Luke Openshaw <luke.openshaw@rockstarnorth.com
-- Date:: 14/10/2005
--
-----------------------------------------------------------------------------
-----------------------------------------------------------------------------
-- Uses
-----------------------------------------------------------------------------
filein "pipeline/util/file.ms"
-----------------------------------------------------------------------------
-- Rollout
-----------------------------------------------------------------------------
rollout RsReflMapRoll "Cubic Reflection Map"
(
--////////////////////////////////////////////////////////////
-- interface
--////////////////////////////////////////////////////////////
hyperlink lnkHelp "Help?" address:"https://devstar.rockstargames.com/wiki/index.php/Environment_Map_Generator" align:#right color:(color 0 0 255) hoverColor:(color 0 0 255) visitedColor:(color 0 0 255)
spinner spnFOV "Field of View" pos:[190,30] width:80 range:[0,180,90]
spinner spnMult "Z Position" pos:[190,60] width:80 range:[0,1,0]
dropdownlist lstResol "Resolution:" pos:[40,10] items:#("256", "128") width:80
groupBox grp5 "Preview" pos:[10,90] width:290 height:91
dropdownlist lstAxis "Axis:" pos:[45,110] items:#("X-Pos", "X-Neg", "Y-Pos", "Y-Neg", "Z-Pos", "Z-Neg") width:100
button btnPreview "Preview Axis" pos:[160,125] width:110 height:30
groupBox grp6 "Generate" pos:[10,190] width:290 height:91
edittext edtOutPath "Output Directory:" pos:[15,210] text:"x:\\"
button btnRender "Generate Cubic Map" pos:[90,240] width:110 height:30
--////////////////////////////////////////////////////////////
-- methods
--////////////////////////////////////////////////////////////
--------------------------------------------------------------
-- Create the script to be passed to dxops.exe
--------------------------------------------------------------
fn WriteCubeScript inPath mapRes = (
ddsFileName = inPath + "cubeScript.txt"
ddsFile = openfile ddsFileName mode:"w+"
format ("load '" + inPath + "*.bmp';\n") to:ddsFile
format ("newtexcube dst:newEnvironmentMap format:DXT5 size:" + mapRes as string + " Mips:1 srcXP:XPositive srcXM:XNegative srcYP:YPositive srcYM:YNegative srcZP:ZPositive srcZM:ZNegative;\n") to:ddsFile
format ("save src:newEnvironmentMap filename:'" + inPath + "cubemap.dds';\n") to:ddsFile
close ddsFile
return true
)
--------------------------------------------------------------
-- Calculate the geometric aveage of the selected object
--------------------------------------------------------------
fn CalcGeoAvg obj = (
numFace = getNumFaces obj.mesh
geoAvg = [0,0,0]
curVec = [0,0,0]
-- Find the geometric average of all vertices in the selected object
for i = 1 to numFace do (
curFace = getface obj.mesh i
for j = 1 to 3 do (
curVec = obj.mesh.verts[curFace[j]].pos * obj.transform
geoAvg += curVec
)
)
geoAvg = geoAvg / (numFace * 3)
return geoAvg
)
fn CalcZPos obj multiplier = (
numFace = getNumFaces obj.mesh
zMin = 1000000
zMax = -1000000
-- Find the geometric average of all vertices in the selected object
for i = 1 to numFace do (
curFace = getface obj.mesh i
for j = 1 to 3 do (
curVec = obj.mesh.verts[curFace[j]].pos * obj.transform
if curVec.z < zMin then zMin = curVec.z
if curVec.z > zMax then zMax = curVec.z
)
)
print zMin
print zMax
print multiplier
return (zMin + ((zMax - zMin) * multiplier))
)
--------------------------------------------------------------
-- Create the render camera
--------------------------------------------------------------
fn CreateCamera geoAvg = (
tempObj = box length:1 width:1 height:1
hide tempObj
fovVal = spnFOV.value as float
newCam = targetCamera pos:[0,0,0] target:tempObj fov:fovVal
newcam.name = "renderCam"
newCam.pos = geoAvg
return true
)
--------------------------------------------------------------
-- Delete the render camera
--------------------------------------------------------------
fn DeleteCamera = (
delete $renderCam
return true
)
--------------------------------------------------------------
-- Render an image from the render camera
--------------------------------------------------------------
fn RenderOutput geoAvg dirVec mapRes vfbVal preCamRot postCamRot= (
$renderCam.target.pos = geoAvg + dirVec
rotate $renderCam preCamRot
renderObj = render camera:$renderCam outputwidth:mapRes outputheight:mapRes mapping:true shadows:false vfb:vfbVal
rotate $renderCam postCamRot
return renderObj
)
--------------------------------------------------------------
-- Ensure one and only one object has been selected.
--------------------------------------------------------------
fn ValidateSelection = (
sel = selection as array
if sel.count == 0 then (
messagebox "No object has been selected"
return false
)
if sel.count > 1 then (
messagebox "More than one object is selected"
return false
)
if outPath == "" then (
messagebox "Please provide an output path"
return false
)
return true
)
--------------------------------------------------------------
-- Render the preview for the selected axis
--------------------------------------------------------------
fn RenderPreview = (
sel = selection as array
obj = sel[1]
axis = lstAxis.selected
mapRes = lstResol.selected as integer
preCamRot = eulerangles 0 0 0
postCamRot = eulerangles 0 0 0
multiplier = spnMult.value as float
geoAvg = CalcGeoAvg obj
zPos = CalcZPos obj multiplier
geoAvg.z = zPos
hide obj
if CreateCamera geoAvg == false then return false
if axis == "X-Pos" then (
RenderOutput geoAvg [10,0,0] mapRes true preCamRot postCamRot
)
else if axis == "X-Neg" then (
RenderOutput geoAvg [-10,0,0] mapRes true preCamRot postCamRot
)
else if axis == "Y-Pos" then (
RenderOutput geoAvg [0,10,0] mapRes true preCamRot postCamRot
)
else if axis == "Y-Neg" then (
RenderOutput geoAvg [0,-10,0] mapRes true preCamRot postCamRot
)
else if axis == "Z-Pos" then (
RenderOutput geoAvg [0,0,10] mapRes true preCamRot postCamRot
)
else if axis == "Z-Neg" then (
RenderOutput geoAvg [0,0,-10] mapRes true preCamRot postCamRot
)
unhide obj
if DeleteCamera() == false then return false
return true
)
--------------------------------------------------------------
-- Function for reversing the contents of an array
--------------------------------------------------------------
fn ReverseArray bitmapArr res = (
arrRev = #()
for i = 1 to res do (
arrRev[i] = bitmapArr[res-(i-1)]
)
return arrRev
)
--------------------------------------------------------------
-- Flip the bitmap provided horizontally
--------------------------------------------------------------
fn FlipBitmapHoriz bitmapPath res = (
bitmapObj = openBitmap bitmapPath
bitmapObjW = bitmap 256 256
for i = 1 to 256 do (
bitmapArr = #()
bitmapArr = getPixels bitmapObj [0,i-1] res
--if i==256 then print bitmapArr
bitmapRev = ReverseArray bitmapArr res
--print bitmapRev[1]
setPixels bitmapObjW [0,i-1] bitmapRev
)
bitmapObjW.filename = bitmapPath
save bitmapObjW
close bitmapObjW
return true
)
--------------------------------------------------------------
-- Flip the bitmap provided vertically
--------------------------------------------------------------
fn FlipBitmapVert bitmapPath res = (
bitmapObj = openBitmap bitmapPath
bitmapObjW = bitmap 256 256
for i = 1 to 256 do (
bitmapArr = #()
bitmapArr = getPixels bitmapObj [0,i-1] res
setPixels bitmapObjW [0,res-(i-1)] bitmapArr
)
bitmapObjW.filename = bitmapPath
save bitmapObjW
close bitmapObjW
return true
)
--------------------------------------------------------------
-- Render the six views that make up the cubemap.
--------------------------------------------------------------
fn RenderViews = (
outPath = edtOutpath.text
fovVal = spnFOV.value as float
outPath = outPath + "\\"
RsMakeSurePathExists outPath
sel = selection as array
obj = sel[1]
numFace = getNumFaces obj.mesh
mapRes = lstResol.selected as integer
geoAvg = CalcGeoAvg obj
CreateCamera geoAvg
hide obj
-- Positive X-axis render
preCamRot = eulerangles -90 0 0
postCamRot = eulerangles 90 0 0
renderObj = RenderOutput geoAvg [10,0,0] mapRes false preCamRot postCamRot
renderObj.filename = outPath + "XPositive.bmp"
save renderObj
if FlipBitmapVert renderObj.filename mapRes == false then return false
-- Negative X-axis render
preCamRot = eulerangles -90 0 0
postCamRot = eulerangles 90 0 0
renderObj = RenderOutput geoAvg [-10,0,0] mapRes false preCamRot postCamRot
renderObj.filename = outPath + "XNegative.bmp"
save renderObj
if FlipBitmapVert renderObj.filename mapRes == false then return false
-- Positive Y-axis render
preCamRot = eulerangles 0 180 0
postCamRot = eulerangles 0 -180 0
renderObj = RenderOutput geoAvg [0,10,0] mapRes false preCamRot postCamRot
renderObj.filename = outPath + "YPositive.bmp"
save renderObj
if FlipBitmapHoriz renderObj.filename mapRes == false then return false
-- Negative Y-axis render
preCamRot = eulerangles 0 0 0
postCamRot = eulerangles 0 0 0
renderObj = RenderOutput geoAvg [0,-10,0] mapRes false preCamRot postCamRot
renderObj.filename = outPath + "YNegative.bmp"
save renderObj
if FlipBitmapHoriz renderObj.filename mapRes == false then return false
-- Positive Z-axis render
preCamRot = eulerangles 0 0 180
postCamRot = eulerangles 0 0 -180
renderObj = RenderOutput geoAvg [0,0,10] mapRes false preCamRot postCamRot
renderObj.filename = outPath + "ZPositive.bmp"
save renderObj
if FlipBitmapHoriz renderObj.filename mapRes == false then return false
-- Negative Z-axis render
preCamRot = eulerangles 0 0 0
postCamRot = eulerangles 0 0 0
renderObj = RenderOutput geoAvg [0,0,-10] mapRes false preCamRot postCamRot
renderObj.filename = outPath + "ZNegative.bmp"
save renderObj
if FlipBitmapHoriz renderObj.filename mapRes == false then return false
-- This also deletes the tempObj object used
-- for providing the camera an initial target object
DeleteCamera()
unhide obj
if WriteCubeScript outPath mapRes == false then return false
dosString = "-f \"" + outPath + "cubeScript.txt\""
--ShellLaunch "C:\\Program Files\\Microsoft DirectX 9.0 SDK (October 2005)\\Utilities\\Bin\\x86\\dxops.exe" dosString
dosString = "dxops.exe " + dosString
DOSCommand dosString
--DOSCommand ("C:\\Program Files\\Microsoft DirectX 9.0 SDK (October 2005)\\Utilities\\Bin\\x86\\dxops.exe " + dosString)
dosString = "del " + outPath + "*p"
DOSCommand dosString
dosString = "del " + outPath + "*t"
DOSCommand dosString
return true
)
--////////////////////////////////////////////////////////////
-- events
--////////////////////////////////////////////////////////////
--------------------------------------------------------------
-- Render Cubemap button pressed.
--------------------------------------------------------------
on btnRender pressed do (
if edtOutpath.text == "" then (
messagebox "Please enter a directory for output"
return false
)
if ValidateSelection() == false then return false
if RenderViews() == false then return false
return true
)
--------------------------------------------------------------
-- Render Preview.
--------------------------------------------------------------
on btnPreview pressed do (
--if ValidateSelection() == false then return false
if RenderPreview() == false then return false
return true
)
)
--------------------------------------------------------------
-- beginning of execution
--------------------------------------------------------------
try CloseRolloutFloater RsReflMap catch()
RsReflMap = newRolloutFloater "Environment Map Generator" 320 320 100 206
addRollout RsReflMapRoll RsReflMap