587 lines
24 KiB
Plaintext
Executable File
587 lines
24 KiB
Plaintext
Executable File
---------------------------------------------------------------------------------------------------------------------------------------
|
|
-- RSL_CollisionOps2
|
|
-- By Paul Truss
|
|
-- Senior Technical Artist
|
|
-- Rockstar Games London
|
|
-- 12/01/2011
|
|
--
|
|
-- Modified for Rockstar North by Neil Gregory
|
|
-- 08/2011
|
|
--
|
|
-- Collision Tools
|
|
-- Create collision objects with pre-defined attributes
|
|
-- Edit collision object attributes, both standard and rexbound. Display surface types on rexbound collision meshes.
|
|
-- Select/Display collision objects based on class, attribute and surface type
|
|
---------------------------------------------------------------------------------------------------------------------------------------
|
|
|
|
-- dotNet class shortcuts script
|
|
filein (RsConfigGetWildWestDir()+"/script/max/rockstar_london/utils/RSL_dotNetClasses.ms")
|
|
-- dotNet UI functions script
|
|
filein (RsConfigGetWildWestDir()+"/script/max/rockstar_london/utils/RSL_dotNetUIOps.ms")
|
|
|
|
filein (RsConfigGetToolsDir()+"/dcc/current/max2011/scripts/pipeline/util/collision_funcs.ms")
|
|
|
|
-- Collision Ops 2 specific scripts
|
|
filein (RsConfigGetWildWestDir()+"/script/3dsMax/General_tools/RSL_CollisionOps2Attribute.ms")
|
|
filein (RsConfigGetWildWestDir()+"/script/3dsMax/General_tools/RSL_CollisionOps2Create.ms")
|
|
filein (RsConfigGetWildWestDir()+"/script/3dsMax/General_tools/RSL_CollisionOps2Edit.ms")
|
|
filein (RsConfigGetWildWestDir()+"/script/3dsMax/General_tools/RSL_CollisionOps2SelectDisplay.ms")
|
|
|
|
global RSL_CollisionOps
|
|
|
|
/*
|
|
-- Struct used to store collision types for collision meshes so that we know what it's currently set to
|
|
-- and we can change them so something else in create mode.
|
|
struct RSL_CollisionType
|
|
(
|
|
--camera = true, -- Camera attribute
|
|
--physics = true, -- Physics attribute
|
|
--hiDetail = true, -- Hi Detail attribute
|
|
--loco = false, -- Loco attribute
|
|
|
|
-- if we change any of the collision type attributes we set this to true so that when the object is switched back to a collision mesh
|
|
-- we know to update the collision type attributes for the object
|
|
modified = false,
|
|
|
|
-- collision type attribute indices
|
|
--idxCamera = getAttrIndex "Gta Collision" "Camera",
|
|
--idxPhysics = getAttrIndex "Gta Collision" "Physics",
|
|
--idxHiDetail = getAttrIndex "Gta Collision" "Hi Detail",
|
|
--idxLoco = getAttrIndex "Gta Collision" "Loco",
|
|
|
|
---------------------------------------------------------------------------------------------------------------------------------------
|
|
-- setTypesByObject() gets the attributes from the parsed object
|
|
---------------------------------------------------------------------------------------------------------------------------------------
|
|
fn setTypesByObject object =
|
|
(
|
|
camera = try (getAttr object idxCamera) catch(false)
|
|
physics = try (getAttr object idxPhysics) catch(false)
|
|
hiDetail = try (getAttr object idxHiDetail) catch(false)
|
|
loco = try (getAttr object idxLoco) catch(false)
|
|
)
|
|
)
|
|
*/
|
|
|
|
-- main struct
|
|
struct RSL_CollisionOps2
|
|
(
|
|
---------------------------------------------------------------------------------------------------------------------------------------
|
|
-- Struct variables
|
|
---------------------------------------------------------------------------------------------------------------------------------------
|
|
INIfile = (RsConfigGetWildWestDir() + "etc/config/general/collisionOps2.ini"),
|
|
helpLink = "https://devstar.rockstargames.com/wiki/index.php/Collision_Operations",
|
|
|
|
-- struct instances
|
|
createUI = RSL_CollisionOps2Create(),
|
|
editUI = RSL_CollisionOps2Edit(),
|
|
selectDisplayUI = RSL_CollisionOps2SelectDisplay(),
|
|
attribute = RSL_CollisionOps2Attribute(),
|
|
|
|
currentTool, -- variable containing the interface for the current mode
|
|
|
|
theObjects = #(), -- variable containing the currently selected objects if they are valid
|
|
|
|
currentMesh, -- variable containing the currently selected collision mesh
|
|
--currentColType = RSL_CollisionType(), -- struct instance
|
|
currentType = #primitive, -- variable containing the currently selected collision type e.g. #rexbound or #primitive
|
|
|
|
---------------------------------------------------------------------------------------------------------------------------------------
|
|
-- UI variables
|
|
---------------------------------------------------------------------------------------------------------------------------------------
|
|
CollisionForm,
|
|
mainTableLayout,
|
|
helpButton,
|
|
createCheckButton,editCheckButton,displayCheckButton,
|
|
|
|
---------------------------------------------------------------------------------------------------------------------------------------
|
|
--
|
|
-- FUNCTIONS
|
|
--
|
|
---------------------------------------------------------------------------------------------------------------------------------------
|
|
|
|
---------------------------------------------------------------------------------------------------------------------------------------
|
|
-- checkCreateSelection() checks the current selection to see if it is a vaild selection when in create mode. Returns true or false
|
|
---------------------------------------------------------------------------------------------------------------------------------------
|
|
fn checkCreateSelection =
|
|
(
|
|
-- make sure we have at least one object selected
|
|
local result = selection.count > 0
|
|
|
|
-- if we do have at least one object selected...
|
|
if result then
|
|
(
|
|
-- set theObjects struct variable to the current selection
|
|
theObjects = selection as array
|
|
|
|
-- loop through theObjects making sure we have only geometry selected and that they are not Xref objects
|
|
for object in theObjects do
|
|
(
|
|
if (getAttrClass object) != "Gta Object" or (classOf object) == XrefObject then
|
|
(
|
|
result = false
|
|
)
|
|
)
|
|
)
|
|
|
|
result
|
|
),
|
|
|
|
---------------------------------------------------------------------------------------------------------------------------------------
|
|
-- createSelectionChanged() CallBack function used in create mode that checks the selection is valid. Sets the createUI.statusLabel
|
|
-- and the enabled state of the createUI.createButton
|
|
---------------------------------------------------------------------------------------------------------------------------------------
|
|
fn createSelectionChanged =
|
|
(
|
|
if (checkCreateSelection()) then
|
|
(
|
|
-- if one valid object is selected, set the createUI.statusLabel to the name of the object
|
|
-- otherwise set it to "Multiple Objects"
|
|
if theObjects.count == 1 then
|
|
(
|
|
createUI.statusLabel.text = " Selected: " + theObjects[1].name
|
|
)
|
|
else
|
|
(
|
|
createUI.statusLabel.text = " Selected: Multiple Objects"
|
|
)
|
|
|
|
createUI.createButton.enabled = true
|
|
)
|
|
else
|
|
(
|
|
-- if no objects are selected, set createUI.statusLabel to "None" or if the selection is invalid, set it to "Invalid Selection"
|
|
if selection.count == 0 then
|
|
(
|
|
createUI.statusLabel.text = " Selected: None"
|
|
)
|
|
else
|
|
(
|
|
createUI.statusLabel.text = " Selected: Invalid Selection"
|
|
)
|
|
|
|
createUI.createButton.enabled = false
|
|
|
|
theObjects = undefined
|
|
)
|
|
),
|
|
|
|
---------------------------------------------------------------------------------------------------------------------------------------
|
|
-- checkCreateSelection() checks the current selection to see if it is a vaild selection when in edit mode. Returns true or false
|
|
---------------------------------------------------------------------------------------------------------------------------------------
|
|
fn checkEditSelection =
|
|
(
|
|
-- make sure we have at least one object selected
|
|
local result = selection.count > 0
|
|
|
|
-- if the currentMesh struct variable is not undefined then we need to switch the currentMesh back to a collision mesh
|
|
if currentMesh != undefined then
|
|
(
|
|
editUI.switchToCollision currentMesh
|
|
|
|
currentMesh = undefined
|
|
)
|
|
|
|
-- if we do have at least one object selected...
|
|
if result then
|
|
(
|
|
theObjects = selection as array
|
|
|
|
-- in edit mode we allow you to have multiple primitive objects selected or just one collision mesh.
|
|
-- if we have multiple objects selected, we check so make sure they are all "Gta Collision" and that none of then are collision meshes
|
|
if theObjects.count > 1 then
|
|
(
|
|
for object in theObjects do
|
|
(
|
|
if (getAttrClass object) != "Gta Collision" then
|
|
(
|
|
result = false
|
|
exit
|
|
)
|
|
else
|
|
(
|
|
if (classOf object) == Col_Mesh then
|
|
(
|
|
result = false
|
|
exit
|
|
)
|
|
)
|
|
)
|
|
)
|
|
else
|
|
(
|
|
-- if we have just one object selected, we check that it is a "Gta Collision" object
|
|
if (getAttrClass theObjects[1]) != "Gta Collision" then
|
|
(
|
|
result = false
|
|
)
|
|
else
|
|
(
|
|
-- if it is a collision mesh object, we set the currentMesh struct variable to the object
|
|
-- and gather it's collision type attributes into the currentColType struct instance
|
|
if (classOf theObjects[1]) == Col_Mesh then
|
|
(
|
|
currentMesh = theObjects[1]
|
|
--currentColType.setTypesByObject theObjects[1]
|
|
)
|
|
)
|
|
)
|
|
)
|
|
|
|
result
|
|
),
|
|
|
|
---------------------------------------------------------------------------------------------------------------------------------------
|
|
-- createSelectionChanged() CallBack function used in edit mode that checks the selection is valid. Sets up the attribute
|
|
-- controls depending on the selection e.g. one collision mesh is selected so we create rexbound attribute controls
|
|
---------------------------------------------------------------------------------------------------------------------------------------
|
|
fn editSelectionChanged =
|
|
(
|
|
if (checkEditSelection()) then
|
|
(
|
|
-- if the selection is valid, enable the edit controls
|
|
currentTool.enabled = true
|
|
|
|
-- if one valid object is selected and it's a collision mesh...
|
|
if theObjects.count == 1 and (classOf theObjects[1]) == Col_Mesh then
|
|
(
|
|
-- swicth the collision mesh over to an editable mesh, gather the attributes and setup the display material
|
|
editUI.switchToMesh currentMesh
|
|
|
|
-- if the currentType is not #rexbound, we need to re-create the attribute controls for rexbound specific attributes
|
|
if editUI.attributesGroup != undefined and currentType != #rexbound then
|
|
(
|
|
currentType = #rexbound
|
|
|
|
editUI.attributesGroup.controls.clear()
|
|
|
|
editUI.attributesGroup.controls.add (editUI.createAttributeControls #rexbound)
|
|
)
|
|
)
|
|
else
|
|
(
|
|
-- if one or more valid objects are selected and they're collision primitives and the currentType is not #primitive
|
|
-- we need to re-create the attribute controls for standard collision object attributes
|
|
if editUI.attributesGroup != undefined and currentType != #primitive then
|
|
(
|
|
currentType = #primitive
|
|
|
|
editUI.attributesGroup.controls.clear()
|
|
|
|
editUI.attributesGroup.controls.add (editUI.createAttributeControls #primitive)
|
|
)
|
|
)
|
|
|
|
-- the select controls only work on #rexbound collision meshes so we dissable them if the currentType is not #rexbound
|
|
editUI.selectGroup.enabled = currentType == #rexbound
|
|
)
|
|
else
|
|
(
|
|
theObjects = undefined
|
|
|
|
-- dissable the edit controls if the selection is invalid.
|
|
currentTool.enabled = false
|
|
)
|
|
),
|
|
|
|
|
|
|
|
---------------------------------------------------------------------------------------------------------------------------------------
|
|
--
|
|
-- UI FUNCTIONS
|
|
--
|
|
---------------------------------------------------------------------------------------------------------------------------------------
|
|
|
|
---------------------------------------------------------------------------------------------------------------------------------------
|
|
-- dispatchOnFormClosing() Dispatches onFormClosing() Called when the user closes collision ops
|
|
---------------------------------------------------------------------------------------------------------------------------------------
|
|
fn dispatchOnFormClosing s e =
|
|
(
|
|
RSL_CollisionOps.onFormClosing s e
|
|
),
|
|
|
|
---------------------------------------------------------------------------------------------------------------------------------------
|
|
-- onFormClosing() Called when collision ops is closed
|
|
---------------------------------------------------------------------------------------------------------------------------------------
|
|
fn onFormClosing s e =
|
|
(
|
|
-- if the currentMesh struct variable is not undefined then we need to switch the currentMesh back to a collision mesh
|
|
if currentMesh != undefined then
|
|
(
|
|
editUI.switchToCollision currentMesh
|
|
|
|
currentMesh = undefined
|
|
)
|
|
|
|
-- NEEDS MORE WORK
|
|
-- if currentTool != undefined and currentTool.name == "mainTableLayout" then
|
|
-- (
|
|
-- selectDisplayUI.exitSelectDisplay()
|
|
-- )
|
|
|
|
-- close any of the separate dialogs if they are open
|
|
try (attribute.surfaceTypeForm.close()) catch()
|
|
try (attribute.proceduralTypeForm.close()) catch()
|
|
try (attribute.pieceTypeForm.close()) catch()
|
|
|
|
-- remove the callbacks if they are running
|
|
callbacks.removeScripts id:#RSL_CollisionOps_createCallBacks
|
|
callbacks.removeScripts id:#RSL_CollisionOps_editCallBacks
|
|
),
|
|
|
|
---------------------------------------------------------------------------------------------------------------------------------------
|
|
-- disableAccelerators() Called when the user enters any control that needs keyboard input e.g. a textBox
|
|
---------------------------------------------------------------------------------------------------------------------------------------
|
|
fn disableAccelerators s e =
|
|
(
|
|
enableAccelerators = false
|
|
),
|
|
|
|
---------------------------------------------------------------------------------------------------------------------------------------
|
|
-- dispatchOnFormClosing() Dispatches helpButtonPressed() Called when the user presses the help button
|
|
---------------------------------------------------------------------------------------------------------------------------------------
|
|
fn dispatchHelpButtonPressed s e =
|
|
(
|
|
RSL_CollisionOps.helpButtonPressed s e
|
|
),
|
|
|
|
---------------------------------------------------------------------------------------------------------------------------------------
|
|
-- helpButtonPressed() Opens the help page in a browser
|
|
---------------------------------------------------------------------------------------------------------------------------------------
|
|
fn helpButtonPressed s e =
|
|
(
|
|
ShellLaunch helpLink ""
|
|
),
|
|
|
|
---------------------------------------------------------------------------------------------------------------------------------------
|
|
-- dispatchModeCheck() Dispatches modeCheck() Called when the user presses any one of the three mode buttons
|
|
---------------------------------------------------------------------------------------------------------------------------------------
|
|
fn dispatchModeCheck s e =
|
|
(
|
|
RSL_CollisionOps.modeCheck s e
|
|
),
|
|
|
|
---------------------------------------------------------------------------------------------------------------------------------------
|
|
-- helpButtonPressed() Switches the mode depending on which mode button is pressed
|
|
---------------------------------------------------------------------------------------------------------------------------------------
|
|
fn modeCheck s e =
|
|
(
|
|
-- if the mode button is checked...
|
|
if s.checked then
|
|
(
|
|
CollisionForm.MaximumSize = dotNetObject "System.Drawing.Size" 2048 2048
|
|
|
|
case s.name of
|
|
(
|
|
"createCheckButton":-- if create mode is checked
|
|
(
|
|
-- if the currentMesh struct variable is not undefined then we need to switch the currentMesh back to a collision mesh
|
|
if currentMesh != undefined then
|
|
(
|
|
editUI.switchToCollision currentMesh
|
|
|
|
currentMesh = undefined
|
|
)
|
|
|
|
-- remove the edit callbacks
|
|
callbacks.removeScripts id:#RSL_CollisionOps_editCallBacks
|
|
|
|
-- un-check the other mode check buttons
|
|
editCheckButton.checked = false
|
|
displayCheckButton.checked = false
|
|
|
|
-- dispose of the current tool and create the new UI
|
|
if currentTool != undefined then currentTool.Dispose()
|
|
currentTool = createUI.getUI()
|
|
|
|
CollisionForm.Height = 750
|
|
|
|
-- run the create callback function the first time and then enabled the callback
|
|
createSelectionChanged()
|
|
callbacks.addScript #selectionSetChanged "RSL_CollisionOps.createSelectionChanged()" id:#RSL_CollisionOps_createCallBacks
|
|
)
|
|
"editCheckButton":
|
|
(
|
|
-- remove the create callbacks
|
|
callbacks.removeScripts id:#RSL_CollisionOps_createCallBacks
|
|
|
|
-- dispose of the current tool and create the new UI
|
|
if currentTool != undefined then currentTool.Dispose()
|
|
currentTool = editUI.getUI()
|
|
|
|
-- run the edit callback function the first time
|
|
editSelectionChanged()
|
|
|
|
-- un-check the other mode check buttons
|
|
createCheckButton.checked = false
|
|
displayCheckButton.checked = false
|
|
|
|
-- set the form height if it's not big enough
|
|
if CollisionForm.Height < 768 then
|
|
(
|
|
CollisionForm.Height = 768
|
|
)
|
|
|
|
-- enabled the edit callback
|
|
callbacks.addScript #selectionSetChanged "RSL_CollisionOps.editSelectionChanged()" id:#RSL_CollisionOps_editCallBacks
|
|
)
|
|
"displayCheckButton":
|
|
(
|
|
-- if the currentMesh struct variable is not undefined then we need to switch the currentMesh back to a collision mesh
|
|
if currentMesh != undefined then
|
|
(
|
|
editUI.switchToCollision currentMesh
|
|
|
|
currentMesh = undefined
|
|
)
|
|
|
|
-- remove both the create and edit callbacks
|
|
callbacks.removeScripts id:#RSL_CollisionOps_createCallBacks
|
|
callbacks.removeScripts id:#RSL_CollisionOps_editCallBacks
|
|
|
|
-- un-check the other mode check buttons
|
|
createCheckButton.checked = false
|
|
editCheckButton.checked = false
|
|
|
|
-- dispose of the current tool and create the new UI
|
|
if currentTool != undefined then currentTool.Dispose()
|
|
currentTool = selectDisplayUI.getUI()
|
|
|
|
-- set the form height
|
|
CollisionForm.Height = 808
|
|
)
|
|
)
|
|
|
|
-- add the currentTool to the mainTableLayout control and set its column span
|
|
mainTableLayout.Controls.Add currentTool 0 2
|
|
mainTableLayout.SetColumnSpan currentTool 3
|
|
)
|
|
else
|
|
(
|
|
-- the mode button is un-checked so we remove the callbacks, dispose of the currentTool and reset the form height
|
|
callbacks.removeScripts id:#RSL_CollisionOps_createCallBacks
|
|
callbacks.removeScripts id:#RSL_CollisionOps_editCallBacks
|
|
|
|
if currentTool != undefined then
|
|
(
|
|
currentTool.dispose()
|
|
)
|
|
|
|
CollisionForm.MaximumSize = dotNetObject "System.Drawing.Size" 2048 82
|
|
CollisionForm.Height = 82
|
|
)
|
|
),
|
|
|
|
---------------------------------------------------------------------------------------------------------------------------------------
|
|
-- dispatchOnFormResize() Dispatches formResize() Called when the user resizes the form
|
|
---------------------------------------------------------------------------------------------------------------------------------------
|
|
fn dispatchOnFormResize s e =
|
|
(
|
|
RSL_CollisionOps.formResize s e
|
|
),
|
|
|
|
---------------------------------------------------------------------------------------------------------------------------------------
|
|
-- dispatchOnFormResize() Does nothing, only used for debug
|
|
---------------------------------------------------------------------------------------------------------------------------------------
|
|
fn formResize s e =
|
|
(
|
|
-- format "w:% h:%\n" s.size.width s.size.height
|
|
),
|
|
|
|
---------------------------------------------------------------------------------------------------------------------------------------
|
|
-- createForm() Creates the main form
|
|
---------------------------------------------------------------------------------------------------------------------------------------
|
|
fn createForm =
|
|
(
|
|
clearListener()
|
|
|
|
-- if all the files we need are available, we can create the main form
|
|
if (doesFileExist attribute.rsNorthAttFile) and (doesFileExist attribute.materialsDatFile) and (doesFileExist attribute.proceduralDatFile) then
|
|
(
|
|
attribute.readAttFile()
|
|
attribute.readMaterialsDatFile()
|
|
attribute.readPoceduralDatFile()
|
|
attribute.filterTemp()
|
|
attribute.generateTextures()
|
|
|
|
--In this case, we're going to use a standard form rather than the custom maxForm written for max. this is because I want to change the
|
|
-- form back colour which you can't do if you use the custom maxForm. For this to work, we need to set the parent of the form to be Max.
|
|
-- USING THIS TYPE OF FORM MEANS WE NEED TO DISSABLE ACCELERATORS WHEN WE FOCUS ON A CONTROL THAT TAKES
|
|
-- KEY PRESSES SUCH AS SPINNERS AND TEXT BOXES
|
|
|
|
--Get the max handle pointer.
|
|
local maxHandlePointer=(Windows.GetMAXHWND())
|
|
|
|
--Convert the HWND handle of Max to a dotNet system pointer
|
|
local sysPointer = DotNetObject "System.IntPtr" maxHandlePointer
|
|
|
|
--Create a dotNet wrapper containing the maxHWND
|
|
local maxHwnd = DotNetObject "MaxCustomControls.Win32HandleWrapper" sysPointer
|
|
|
|
CollisionForm = RS_dotNetUI.form "CollisionForm" text:" R* Collision Operations V2.1" size:[320, 82] max:[2048, 82] min:[250, 82] borderStyle:RS_dotNetPreset.FB_SizableToolWindow
|
|
CollisionForm.StartPosition = (dotNetClass "System.Windows.Forms.FormStartPosition").Manual
|
|
CollisionForm.Location = dotNetObject "System.Drawing.Point" 95 125
|
|
|
|
dotnet.addEventHandler CollisionForm "FormClosing" dispatchOnFormClosing
|
|
dotnet.addEventHandler CollisionForm "Enter" disableAccelerators
|
|
dotnet.addEventHandler CollisionForm "Resize" dispatchOnFormResize
|
|
|
|
helpButton = RS_dotNetUI.Button "helpButton" text:(toUpper "Help") dockStyle:RS_dotNetPreset.DS_Fill
|
|
dotnet.addEventHandler helpButton "click" dispatchHelpButtonPressed
|
|
|
|
createCheckButton = RS_dotNetUI.checkBox "createCheckButton" text:(toUpper "Create") appearance:RS_dotNetPreset.AC_Button dockStyle:RS_dotNetPreset.DS_Fill
|
|
dotnet.addEventHandler createCheckButton "click" dispatchModeCheck
|
|
|
|
editCheckButton = RS_dotNetUI.checkBox "editCheckButton" text:(toUpper "Edit") appearance:RS_dotNetPreset.AC_Button dockStyle:RS_dotNetPreset.DS_Fill
|
|
dotnet.addEventHandler editCheckButton "click" dispatchModeCheck
|
|
|
|
displayCheckButton = RS_dotNetUI.checkBox "displayCheckButton" text:(toUpper "Select/Display") appearance:RS_dotNetPreset.AC_Button dockStyle:RS_dotNetPreset.DS_Fill
|
|
dotnet.addEventHandler displayCheckButton "click" dispatchModeCheck
|
|
|
|
mainTableLayout = RS_dotNetUI.tableLayout "mainTableLayout" text:"mainTableLayout" collumns:#((dataPair type:"Percent" value:50),(dataPair type:"Percent" value:50),(dataPair type:"Percent" value:50)) \
|
|
rows:#((dataPair type:"Absolute" value:24),(dataPair type:"Absolute" value:24),(dataPair type:"Percent" value:50)) dockStyle:RS_dotNetPreset.DS_Fill
|
|
|
|
mainTableLayout.controls.add helpButton 0 0
|
|
mainTableLayout.controls.add createCheckButton 0 1
|
|
mainTableLayout.controls.add editCheckButton 1 1
|
|
mainTableLayout.controls.add displayCheckButton 2 1
|
|
|
|
mainTableLayout.SetColumnSpan helpButton 3
|
|
|
|
CollisionForm.controls.add mainTableLayout
|
|
|
|
CollisionForm.Show (maxHwnd)
|
|
)
|
|
else
|
|
(
|
|
-- check to see which file is missing and display a messageBox
|
|
if not (doesFileExist attribute.rsNorthAttFile) then
|
|
(
|
|
messageBox ("rsnorth.att file missing. Unable to continue.\n" + attribute.rsNorthAttFile) title:"Error..."
|
|
)
|
|
else
|
|
(
|
|
if not (doesFileExist attribute.materialsDatFile) then
|
|
(
|
|
messageBox ("materials.dat file missing. Unable to continue.\n" + attribute.materialsDatFile) title:"Error..."
|
|
)
|
|
else
|
|
(
|
|
messageBox ("procedural.dat file missing. Unable to continue.\n" + attribute.proceduralDatFile) title:"Error..."
|
|
)
|
|
)
|
|
)
|
|
)
|
|
)
|
|
|
|
-- if the global struct instance is not undefined the form is probably open so we close it
|
|
if RSL_CollisionOps != undefined then
|
|
(
|
|
try
|
|
(
|
|
RSL_CollisionOps.CollisionForm.close()
|
|
)
|
|
catch()
|
|
)
|
|
|
|
RSL_CollisionOps = RSL_CollisionOps2()
|
|
RSL_CollisionOps.createForm() |