513 lines
14 KiB
Plaintext
Executable File
513 lines
14 KiB
Plaintext
Executable File
|
|
-- contains project directory information.
|
|
include "rockstar\\export\\settings.ms"
|
|
|
|
|
|
-- Used by certain Spatial data types that don't want the rollout to disappear.
|
|
global g_FREEZE_ROLLOUT = false
|
|
global g_LOCKOUT_cb_CoverLineSelectionChanged = false
|
|
|
|
global g_COVER_BOX_LENGTH = 0.25
|
|
global g_COVER_BOX_WIDTH = 0.25
|
|
|
|
-- Purpose: Called By the Main Spatial Data Rollout to confirm that all the coverLines in the scene are properly initiated.
|
|
-- Params: None.
|
|
-- Returns: Will Select an uninitialized coverspline.
|
|
function CheckCoverLines=
|
|
(
|
|
|
|
)
|
|
|
|
function HasCustomAttribute obj attributeName=
|
|
(
|
|
if obj == undefined then
|
|
(
|
|
return false
|
|
)
|
|
|
|
attributeCount = custAttributes.count obj
|
|
|
|
for i = 1 to attributeCount do
|
|
(
|
|
if (custAttributes.get obj i).name == attributeName then
|
|
(
|
|
return true
|
|
)
|
|
)
|
|
return false
|
|
)
|
|
|
|
function IsCoverMesh obj=
|
|
(
|
|
if obj == undefined then
|
|
return false
|
|
|
|
if( obj.layer.name == "CoverHeightMesh" ) then
|
|
(
|
|
return true
|
|
)
|
|
|
|
return false
|
|
)
|
|
|
|
function IsStairMesh obj=
|
|
(
|
|
if obj == undefined then
|
|
return false
|
|
|
|
if( obj.layer.name == "StairSurfaces" ) then
|
|
(
|
|
return true
|
|
)
|
|
|
|
return false
|
|
)
|
|
|
|
function IsSoftCoverMesh obj=
|
|
(
|
|
if obj == undefined then
|
|
return false
|
|
|
|
if( obj.layer.name == "SoftCoverMeshes" ) then
|
|
(
|
|
return true
|
|
)
|
|
|
|
return false
|
|
)
|
|
|
|
function IsHardCoverMesh obj=
|
|
(
|
|
if obj == undefined then
|
|
return false
|
|
|
|
if( obj.layer.name == "HardCoverMeshes" ) then
|
|
(
|
|
return true
|
|
)
|
|
|
|
return false
|
|
)
|
|
|
|
function IsCoverLine obj=
|
|
(
|
|
if obj == undefined then
|
|
return false
|
|
|
|
if( obj.layer.name == "CoverLine" ) or ( (classOf (obj)) == Cover_Line ) then
|
|
(
|
|
return true
|
|
)
|
|
|
|
return false
|
|
)
|
|
|
|
function Reset_SoftCoverColor=
|
|
(
|
|
local layer = undefined
|
|
layer = layermanager.getLayerFromName "SoftCoverMeshes"
|
|
|
|
if( layer != undefined ) then
|
|
(
|
|
local layerNodes
|
|
layer.nodes &layerNodes
|
|
|
|
for obj in layerNodes do
|
|
(
|
|
if( obj != undefined ) then
|
|
(
|
|
obj.wirecolor = orange
|
|
)
|
|
)
|
|
)
|
|
)
|
|
|
|
function Reset_HardCoverColor=
|
|
(
|
|
local layer = undefined
|
|
layer = layermanager.getLayerFromName "HardCoverMeshes"
|
|
|
|
if( layer != undefined ) then
|
|
(
|
|
local layerNodes
|
|
layer.nodes &layerNodes
|
|
|
|
for obj in layerNodes do
|
|
(
|
|
if( obj != undefined ) then
|
|
(
|
|
obj.wirecolor = red
|
|
)
|
|
)
|
|
)
|
|
)
|
|
|
|
function Lockout_CoverLineSelectionChanged lockIt=
|
|
(
|
|
g_LOCKOUT_cb_CoverLineSelectionChanged = lockIt
|
|
)
|
|
|
|
-- Purpose: Callback Function for selection set changes, when the scene is frozen, we only want the tool to remain
|
|
-- Locked while the Cover_Line Edge is selected, or a spatial mesh object is selected.
|
|
-- Params: None
|
|
-- Returns: None
|
|
function cb_CoverLineSelectionChanged=
|
|
(
|
|
if g_LOCKOUT_cb_CoverLineSelectionChanged then
|
|
(
|
|
return false
|
|
)
|
|
--print "Calling cb_CoverLineSelectionChanged()"
|
|
--print selection
|
|
|
|
Reset_SoftCoverColor()
|
|
Reset_HardCoverColor()
|
|
|
|
for obj in selection do
|
|
(
|
|
objectClass = classOf obj
|
|
--print objectClass
|
|
|
|
-- If the object is a Cover_Line different than the active one.
|
|
-- Enable Rollout Changing again.
|
|
if objectClass == Cover_Line then
|
|
(
|
|
--print "Cover_Line Detected"
|
|
if g_CURRENT_COVER_LINE != undefined then
|
|
(
|
|
--print "g_CURRENT_NORMAL is Valid"
|
|
if g_CURRENT_COVER_LINE.name != obj.name then
|
|
(
|
|
print "Non-Active Cover_Line Selected"
|
|
freezeRollout false
|
|
select obj
|
|
)
|
|
)
|
|
)
|
|
else if obj.layer.name == "CoverHeightMesh" then
|
|
(
|
|
if (g_COVER_HEIGHT_SPINNER_A != undefined) and (g_COVER_HEIGHT_SPINNER_B != undefined) then
|
|
(
|
|
g_COVER_HEIGHT_SPINNER_A.value = Cover_Line.GetEdgeHeight g_CURRENT_COVER_LINE obj.MeshIndex 1
|
|
g_COVER_HEIGHT_SPINNER_B.value = Cover_Line.GetEdgeHeight g_CURRENT_COVER_LINE obj.MeshIndex 2
|
|
)
|
|
)
|
|
else if (IsSoftCoverMesh (obj)) then
|
|
(
|
|
-- Populate Rollout Values
|
|
if g_SOFT_COVER_RADIUS_SPINNER != undefined then
|
|
(
|
|
g_SOFT_COVER_RADIUS_SPINNER.value = obj.SoftCoverRadius
|
|
obj.wirecolor = blue
|
|
)
|
|
)
|
|
else if (IsHardCoverMesh (obj)) then
|
|
(
|
|
-- Populate Rollout Values
|
|
if g_HARD_COVER_RADIUS_SPINNER != undefined then
|
|
(
|
|
g_HARD_COVER_RADIUS_SPINNER.value = obj.HardCoverRadius
|
|
obj.wirecolor = blue
|
|
)
|
|
)
|
|
-- If the object is a CoverMesh
|
|
else
|
|
(
|
|
--print "Non Cover-Height Mesh selected"
|
|
--freezeRollout false
|
|
--select obj
|
|
|
|
)
|
|
)
|
|
)
|
|
|
|
-- Global Var used to track how many times someone will freeze a scene, it will only activate the callback if the the counter = 0
|
|
-- The reason being is that if we are editing soft and hardcover at the same time. We don't want the tool to reactivate the selection
|
|
-- call back. Essentially when the freezeRollout Stack is empty, or when no one is freezing the scene we can enable the the callback again.
|
|
global g_FreezeCount = 0
|
|
|
|
-- Purpose: Certain types, like cover, need to keep their rollout active regardless if another type is selected.
|
|
-- Params: Bool, True if you want to freeze the rollout, False if not. The Cover System appends it's own callback when the regular system
|
|
-- is frozen.
|
|
-- Returns: n/a
|
|
function freezeRollout freezeIt=
|
|
(
|
|
|
|
if ( freezeIt )then
|
|
(
|
|
-- If we want to freeze the scene just set the flag to freeze the scene immediately.
|
|
--print ("Debug: Freezing Rollout - Enabling Cover Selection Callback - "+ (g_FreezeCount as string))
|
|
if g_FreezeCount == 0 then
|
|
(
|
|
callbacks.addScript #selectionSetChanged "cb_CoverLineSelectionChanged()" id:#COVER_LINE_SELECTION
|
|
--print ("Debug: Actually Adding Callback")
|
|
)
|
|
|
|
g_FreezeCount = g_FreezeCount + 1
|
|
g_FREEZE_ROLLOUT = freezeIt
|
|
)
|
|
else
|
|
(
|
|
-- Only unfreeze the scene when all objects who have frozen it have allowed it to be unfrozen.
|
|
--print ("Debug: UnFreezing Rollout - Removing Cover Selection Callback - "+ (g_FreezeCount as string))
|
|
if g_FreezeCount == 1 then
|
|
(
|
|
callbacks.removeScripts id:#COVER_LINE_SELECTION
|
|
g_FREEZE_ROLLOUT = freezeIt
|
|
--print ("Debug: Actually Removing Callback")
|
|
)
|
|
|
|
g_FreezeCount = g_FreezeCount - 1
|
|
)
|
|
|
|
)
|
|
|
|
function ResetUIFreezeState=
|
|
(
|
|
g_FreezeCount = 0
|
|
)
|
|
|
|
-- Purpose: Draws a normal with fins.
|
|
-- Params: PointA - The Origin of the Arrow
|
|
-- PointB - The Tip of the Arrow
|
|
-- Returns: Nothing, but rasterizes an arrow in the scene.
|
|
function DrawArrow PointA PointB=
|
|
(
|
|
SLOPE_BACK = 0.25
|
|
FIN_WIDTH = 0.125
|
|
|
|
gw.enlargeUpdateRect #whole
|
|
|
|
lim = gw.getRndLimits()
|
|
-- Add another limit
|
|
append lim #zBuffer
|
|
-- Set the new rendering limits
|
|
gw.setRndLimits lim
|
|
|
|
--redrawViews()
|
|
completeRedraw()
|
|
|
|
|
|
-- Draw the shaft of the arrow.
|
|
gw.polyline #(PointA, PointB) false
|
|
|
|
-- Draw the fins.
|
|
lineVector = PointB - PointA
|
|
lineVector = normalize lineVector
|
|
|
|
-- fin slope back is the distance backwards on the arrow the
|
|
-- fins will be.
|
|
finSlopeback = PointB - (lineVector * SLOPE_BACK)
|
|
|
|
leftVector = cross lineVector [0,0,1]
|
|
leftVector = normalize leftVector
|
|
|
|
upVector = cross lineVector leftVector
|
|
upVector = normalize upVector
|
|
|
|
TopFinPoint = finSlopeback + ( upVector * FIN_WIDTH )
|
|
gw.polyline #(PointB, TopFinPoint) false
|
|
|
|
BottomFinPoint = finSlopeback - ( upVector * FIN_WIDTH )
|
|
gw.polyline #(PointB, BottomFinPoint) false
|
|
|
|
LeftFinPoint = finSlopeback + ( leftVector * FIN_WIDTH )
|
|
gw.polyline #(PointB, LeftFinPoint) false
|
|
|
|
RightFinPoint = finSlopeback - ( leftVector * FIN_WIDTH )
|
|
gw.polyline #(PointB, RightFinPoint) false
|
|
|
|
gw.updateScreen()
|
|
--redrawViews()
|
|
|
|
)
|
|
|
|
-- Purpose: Encapsulation for the Normal Drawing for Cover Lines.
|
|
function DrawCoverLineNormals coverLine normalDrawLength=
|
|
(
|
|
if coverLine == undefined then
|
|
return true
|
|
|
|
gw.setTransform (coverLine.transform)
|
|
|
|
splineEdgeCount = Cover_Line.GetEdgeCount g_CURRENT_COVER_LINE
|
|
|
|
for i = 1 to splineEdgeCount do
|
|
(
|
|
currentNormal = Cover_line.GetEdgeNormal g_CURRENT_COVER_LINE i
|
|
-- if the current vector is zero... Who gives a darn.
|
|
if( ( length ( currentNormal )) == 0 ) then
|
|
continue
|
|
|
|
if (i == splineEdgeCount) and (Cover_Line.IsClosed g_CURRENT_COVER_LINE) then
|
|
(
|
|
PointA = Cover_line.GetKnot g_CURRENT_COVER_LINE i
|
|
PointB = Cover_line.GetKnot g_CURRENT_COVER_LINE 1
|
|
)
|
|
else
|
|
(
|
|
PointA = Cover_line.GetKnot g_CURRENT_COVER_LINE i
|
|
PointB = Cover_line.GetKnot g_CURRENT_COVER_LINE (i + 1)
|
|
)
|
|
|
|
-- Take the Vector from i to i-1, half it and then add it to i-1
|
|
splineMidPoint = ((PointB - PointA)/2)+ PointA
|
|
|
|
gw.setColor #line green
|
|
DrawArrow splineMidPoint (splineMidPoint + (currentNormal * normalDrawLength ))
|
|
)
|
|
)
|
|
|
|
-- Purpose: Will create a cover box, from a given line and a normal, and mesh height.
|
|
function CreateCoverBoxFromLine lineOrigin lineVector lineNormal boxHeight=
|
|
(
|
|
print "==============================================="
|
|
-- Defaults for Calculation
|
|
local yAxis = [0.0, 1.0, 0.0]
|
|
local zAxis = [0.0, 0.0, 1.0]
|
|
local xAxis = [1.0, 0.0, 0.0]
|
|
boxRotation = 0.0
|
|
|
|
lineVector = normalize lineVector
|
|
lineNormal = normalize lineNormal
|
|
|
|
print "lineVector"
|
|
print lineVector
|
|
|
|
print "lineNormal"
|
|
print lineNormal
|
|
|
|
-- Get the box center point, which is dictated by the moving half the box width up the line, and
|
|
-- then half the length along the line normal.
|
|
BoxCenterPoint = lineOrigin + (lineVector * (g_COVER_BOX_WIDTH/2))
|
|
BoxCenterPoint = BoxCenterPoint + (lineNormal * (g_COVER_BOX_LENGTH/2))
|
|
|
|
NewCoverBox = Cover_Box Length_Segments:1 Width_Segments:1 Height_Segments:1 length:g_COVER_BOX_LENGTH width:g_COVER_BOX_WIDTH height:boxHeight pos:BoxCenterPoint
|
|
|
|
-- The arc cos of the dot product will give the angle between the box forward, and the line normal.
|
|
dotProd = dot(lineNormal) (yAxis)
|
|
print "dotProd"
|
|
print dotProd
|
|
|
|
boxRotation = acos( dotProd )
|
|
print "boxRotation"
|
|
print boxRotation
|
|
|
|
RotateRight = dot (xAxis) (lineNormal)
|
|
|
|
-- Since the angle will never be greater than 180, we need to test what side it is on, based on the dot result.
|
|
-- If it's negative then we need to add the rotation, negative if not.
|
|
if RotateRight > 0 then
|
|
(
|
|
NewCoverBox.rotation.z_rotation = NewCoverBox.rotation.z_rotation - boxRotation
|
|
)
|
|
else
|
|
(
|
|
NewCoverBox.rotation.z_rotation = NewCoverBox.rotation.z_rotation + boxRotation
|
|
)
|
|
|
|
-- If we cross product the zaxis(up) and the line normal we'll know which direction the a left wall would travel.
|
|
coverRightVector = cross zAxis lineNormal
|
|
coverRightVector = normalize coverRightVector
|
|
|
|
-- By dotting the right vector with the line vector we can tell what side the cover is on.
|
|
dotResult = dot coverRightVector lineVector
|
|
|
|
if dotResult < 0 then
|
|
(
|
|
Cover_Box.SetAsLeftCover NewCoverBox false
|
|
)
|
|
|
|
NewCoverBox.name = uniquename "CoverBox"
|
|
|
|
local layer = undefined
|
|
layer = layermanager.getLayerFromName "CoverBoxes"
|
|
if( layer == undefined ) then
|
|
(
|
|
layermanager.newLayerFromName "CoverBoxes"
|
|
layer = layermanager.getLayerFromName "CoverBoxes"
|
|
)
|
|
|
|
layer.addnode NewCoverBox
|
|
|
|
return NewCoverBox
|
|
)
|
|
|
|
-- Purpose: Generate Cover Boxes from a CoverLine Object.
|
|
-- Params: A Coverline to create the objects from.
|
|
-- Returns: Will Create two Cover Boxes aligned on the end of the line, or it will do nothing.
|
|
function GenerateCoverBoxesFromCoverLine coverLine=
|
|
(
|
|
-- If the Cover_Line isn't defined just break out of the function.
|
|
if (coverLine == undefined) or ( (classOf coverLine) != Cover_Line ) then
|
|
(
|
|
print "GenerateCoverBoxesFromCoverLine() - CoverLine is incorrect type, or undefined!"
|
|
return false
|
|
)
|
|
|
|
if (Cover_Line.IsClosed coverLine) or not (Cover_Line.CoverDataIsInitialized coverLine) then
|
|
(
|
|
Messagebox "GenerateCoverBoxesFromCoverLine() - Cannot Generate Cover Boxes from a closed Cover_Line!"
|
|
return false
|
|
)
|
|
|
|
-- Get the absolute position of the first knot.
|
|
StartPoint = Cover_Line.GetKnot coverLine 1
|
|
StartPoint = StartPoint * coverLine.transform
|
|
|
|
-- Get the absolute position of the second knot
|
|
SecondPoint = Cover_Line.GetKnot coverLine 2
|
|
SecondPoint = SecondPoint * coverLine.transform
|
|
|
|
-- Get the Vector going from that knot to the second knot.
|
|
lineVector = SecondPoint - StartPoint
|
|
lineVector = normalize lineVector
|
|
|
|
-- Get the normal of the associated Edge.
|
|
lineNormal = Cover_Line.GetEdgeNormal coverLine 1
|
|
lineNormal = lineNormal * coverLine.rotation
|
|
lineNormal = normalize lineNormal
|
|
|
|
-- Get the height associated to the first knot and first edge.
|
|
boxHeight = Cover_Line.GetEdgeHeight coverLine 1 1
|
|
|
|
tempBox1 = CreateCoverBoxFromLine StartPoint lineVector lineNormal boxHeight
|
|
|
|
temp = coverLine
|
|
select tempBox1
|
|
select coverLine
|
|
|
|
----------------------------------------------------------------------------------------------
|
|
|
|
-- Get the index of the last knot.
|
|
lastKnotIndex = Cover_Line.GetKnotCount coverLine
|
|
|
|
-- Get the absolute position of the last knot.
|
|
EndPoint = Cover_Line.GetKnot coverLine lastKnotIndex
|
|
EndPoint = EndPoint * coverLine.transform
|
|
|
|
-- Get the absolute position of the second to last knot.
|
|
SecondToLastPoint = Cover_Line.GetKnot coverLine (lastKnotIndex - 1)
|
|
SecondToLastPoint = SecondToLastPoint * coverLine.transform
|
|
|
|
-- Get the vector from the last knot to the second to last knot.
|
|
lineVector2 = SecondToLastPoint - EndPoint
|
|
lineVector2 = normalize lineVector2
|
|
|
|
-- Get the normal of the last edge
|
|
lineNormal2 = Cover_Line.GetEdgeNormal coverLine (Cover_Line.GetEdgeCount coverLine)
|
|
lineNormal2 = lineNormal2 * coverLine.rotation
|
|
lineNormal2 = normalize lineNormal2
|
|
|
|
-- Get the height of the last Knot
|
|
boxHeight2 = Cover_Line.GetEdgeHeight coverLine (Cover_Line.GetEdgeCount coverLine) 2
|
|
|
|
tempBox2 = CreateCoverBoxFromLine EndPoint lineVector2 lineNormal2 boxHeight2
|
|
|
|
temp = coverLine
|
|
select tempBox2
|
|
select coverLine
|
|
|
|
return true
|
|
)
|