(
global PhysXPainterROL
try(destroyDialog PhysXPainterROL)catch()
local PhysXPainter_HELPER
local LastSubRollout = 1
local Ground
local Colliders = #()
-- local CustomGravity
local WorldGravity = true
local UseGround = true
local TheViewPoint
local MAT
local ToolType = undefined
local DropRAD = 10.0
local DropHEIGHT = 10.0
local DropMaxLEN = 0.0
local DropCount = 5
local DropPoses = #()
local RAD = 30.0
local FRC
local DisplayVECS
local CurrentCopies = #()
local SourceAssets = #()
local SourcePerc = #()
local DIST = 100.0
local Over = true
local Collide = true
local PhysX = true
local RXA= RXB= RYA= RYB= RZA= RZB= PXA= PXB= PYA= PYB= PZA= PZB = 0.0
local SXA= SXB= SYA= SYB= SZA= SZB =1.0
local LX = LY = LZ = false
local L_ALL = POS_ALL = ROT_ALL = true
local StaticCOLOR = (color 30 30 30)
local SimCOLOR = green
local LoadPath
-- local ContactDIST = 0.1
local PackCircle
local foo
local VertsCNT = 200
local tempLIST, theMOD, ITM
local LIC = false
fn MakeHULL objs VertsCount =
(
max create mode
local COPS = #()
for o in OBJS do
(
for M in o.modifiers where classof M == K_HULL do M.enabled = false
COP = copy o ; hide COP
converttomesh COP
local Num = ( getnumverts o.mesh ) as float
-- PU = Push()
-- PU.Push_Value = 0.2
-- addmodifier COP PU
-- addmodifier COP ( Cap_Holes() )
if Num > VertsCount do
(
addmodifier COP ( ProOptimizer() )
COP.modifiers[#ProOptimizer].LockMat = on
COP.modifiers[#ProOptimizer].KeepUV = on
COP.modifiers[#ProOptimizer].LockUV = off
)
append COPS COP
)
redrawviews()
for o in COPS where o.modifiers[#ProOptimizer] != undefined do
(
o.modifiers[#ProOptimizer].Calculate = on
)
redrawviews()
for o in COPS do
(
local OptimMOD = o.modifiers[#ProOptimizer]
if OptimMOD != undefined do
( -- d閒inir le pourcentage de verts pour en avoir 200
local Num = ( getnumverts o.mesh ) as float
local MaxCNT = VertsCount as float
local PERC = (MaxCNT / Num) * 100.0
if Num < MaxCNT do PERC = 100.0
o.modifiers[#ProOptimizer].VertexPercent = PERC
)
converttomesh o
)
redrawviews()
for o=1 to OBJS.count do
(
local obj = OBJS[o]
( -- Get the Modifier or create it if it's not there
if obj.modifiers.count > 0 then
(
local HULLmods = for M in obj.modifiers where classof M == K_HULL collect M
if HULLmods.count > 0 then
(
K_MOD = HULLmods[1]
)
else
(
local K_MOD = K_HULL()
addmodifier obj K_MOD
)
)
else
(
local K_MOD = K_HULL()
addmodifier obj K_MOD
)
)
( -- Set the Mod parameters
K_MOD.HULLmesh = COPS[o].mesh
K_MOD.VERTScount = VertsCount
K_MOD.Switch_BTN = on
K_MOD.enabled = true
)
)
delete COPS
)
fn PackCircle R SZ DropCount =
(
local Diam = R * 2.0
local DIVS = ( floor ( Diam / SZ as float ) ) as integer
local Rdiv = Diam / DIVS
local circlePOSES = #()
for X = 1 to DIVS do
(
for Y=1 to DIVS do
(
if mod Y 2 == 0 then -- each 2 : d閏aller d'1/2 閏art, pour placement en quinconce
(
local Xpos = Rdiv * X - R
)
else
(
local Xpos = Rdiv * X - R - Rdiv/2.0
)
local Ypos = Rdiv * Y - R - Rdiv/2.0
local POS = [Xpos, Ypos,0]
local DIST = ( distance [0,0,0] POS ) + SZ/2.0
if DIST <= R do
(
append circlePOSES POS
)
)
)
if circlePOSES.count == 0 do circlePOSES = #([0,0,0])
-- Number of Height levels
local CircleCNT = circlePOSES.count
POSES = #()
for o = 1 to DropCount do
(
local INcircleID = mod o CircleCNT
if INcircleID == 0 do INcircleID = CircleCNT
local Cpos = copy circlePOSES[INcircleID]
local Zmult = ceil ( (o as float ) / ( CircleCNT as float ) )
-- Rotate l'閠age
local RotMAT = rotateZMatrix (45.0 * (Zmult-1) )
Cpos *= RotMAT
Cpos.Z = (Zmult-1) * SZ
append POSES Cpos
)
POSES
)
fn SetMassFX=
(
gPxUseMultiThread = true
gPxUseHardwareScene = true
px_sdk_contactDistance = 0.1
if px_sdk_sub_sim_steps < 2 do
px_sdk_sub_sim_steps = 2
--display
nvpx.SetPMVisibleForRigidBodies 3
)
rollout VFBTabsRollout01 "Sources"
(
local normalfont, boldfont
local initLv, addColumns, populateList, theMOD
-- pickbutton GroundBTN "pick Surface" width:200 pos:[10,10]
button SelectPhysXHelper_BTN "Select PhysX_Painter Helper" width:248 offset:[2,0]
dotNetControl Collider_LV "system.windows.forms.listView" width:220 height:150 offset:[-5,3]
dotNetControl lv "system.windows.forms.listView" width:220 height:250 offset:[-5,10]
label sepLBL "" height:1
group "Assets Parameters"
(
spinner Percentage_SPN "% :" width:60 range:[0,10000,0] type:#integer offset:[0,-5] align:#right
spinner VertsCNT_SPN "Vertex Count:" range:[1,10000,200] width:110 type:#integer align:#left offset:[-3,2] across:2 tooltip:"number of vertices of the low res version"
button GenHULL_BTN "Generate LOW" width:100 align:#right offset:[0,0] tooltip:"Create a low res version of the selected assets"
)
button AddCOL_BTN "+" width:20 height:20 pos:[235,35] tooltip:"add selected Collider in the list." images:#("PhysXPainter_Icons_i.bmp","PhysXPainter_Icons_a.bmp",19, 10, 10 ,1,1 )
button DelCOL_BTN "-" width:20 height:20 pos:[235,55] tooltip:"remove selected Collider from the list." images:#("PhysXPainter_Icons_i.bmp","PhysXPainter_Icons_a.bmp",19, 11, 11 ,1,1 )
button SelCOL_BTN "s" width:20 height:20 pos:[235,75] tooltip:"select List -> Scene." images:#("PhysXPainter_Icons_i.bmp","PhysXPainter_Icons_a.bmp",19, 16, 16 ,1,1 )
button SelCOLFrom_BTN "s" width:20 height:20 pos:[235,95] tooltip:"select Scene -> List." images:#("PhysXPainter_Icons_i.bmp","PhysXPainter_Icons_a.bmp",19, 12, 12 ,1,1 )
button AddBTN "+" width:20 height:20 pos:[235,200] tooltip:"add selected asset in the list." images:#("PhysXPainter_Icons_i.bmp","PhysXPainter_Icons_a.bmp",19, 10, 10 ,1,1 )
button DelBTN "-" width:20 height:20 pos:[235,220] tooltip:"remove selected asset from the list." images:#("PhysXPainter_Icons_i.bmp","PhysXPainter_Icons_a.bmp",19, 11, 11 ,1,1 )
button SelBTN "s" width:20 height:20 pos:[235,240] tooltip:"select List -> Scene." images:#("PhysXPainter_Icons_i.bmp","PhysXPainter_Icons_a.bmp",19, 16, 16 ,1,1 )
button SelFrom_BTN "s" width:20 height:20 pos:[235,260] tooltip:"select Scene -> List." images:#("PhysXPainter_Icons_i.bmp","PhysXPainter_Icons_a.bmp",19, 12, 12 ,1,1 )
fn initLv theLv =
(
theLv.view = (dotNetClass "system.windows.forms.view").Details
theLv.FullRowSelect = true
theLv.GridLines = false
theLv.MultiSelect = true --multiple selections
theLv.CheckBoxes = false
theLv.hideSelection = false
theLv.IsAccessible = true
theLv.LabelEdit = false --true
-- k_formatprops (dotnetobject "system.windows.forms.listView")
theLv.BackColor = K_dotnetcolor 50 50 50
theLv.BorderStyle = theLv.BorderStyle.None
)
fn addColumns theLv COLUMNS =
(
for C in COLUMNS do
(
theLv.columns.add C[1] C[2]
)
-- theLv.columns.add "Assets" 165
-- theLv.columns.add "%" 55
)
fn populateList theLv arr arrB arrC =
(
rows=#()
CNT = arr.count
for t=1 to CNT do
(
li=dotNetObject "System.Windows.Forms.ListViewItem" ( arr[t] )
li.UseItemStyleForSubItems=true
colAdd = 70 + (if (mod t 2)==0 then 30 else 0)
li.BackColor = K_dotnetcolor (colAdd ) (colAdd) (colAdd)
li.ForeColor = K_dotnetcolor 255 255 255
li.subitems.add ( arrB[t] as string )
li.subitems.add ( arrC[t] as string )
append rows li
)
theLv.items.addRange rows
theLv.Update()
)
fn populateCOLList theLv arr =
(
rows=#()
CNT = arr.count
for t=1 to CNT do
(
li = dotNetObject "System.Windows.Forms.ListViewItem" ( arr[t] )
li.UseItemStyleForSubItems=true
colAdd = 70 + (if (mod t 2)==0 then 30 else 0)
li.BackColor = K_dotnetcolor (colAdd ) (colAdd) (colAdd)
li.ForeColor = K_dotnetcolor 255 255 255
-- li.subitems.add ( arrB[t] as string )
append rows li
)
theLv.items.addRange rows
theLv.Update()
)
fn RemoveAssets OBJ =
(
for m in OBJ.modifiers where classof m == K_HULL or classof m == MassFX_RBody do
deletemodifier OBJ m
)
on VFBTabsRollout01 open do
(
-- normalfont = dotNetObject "System.Drawing.Font" "Microsoft Sans Serif" 11 \
-- (dotNetClass "System.Drawing.FontStyle").Regular (dotNetClass "System.Drawing.GraphicsUnit").Pixel
-- boldfont = dotNetObject "System.Drawing.Font" "Microsoft Sans Serif" 11 \
-- (dotNetClass "System.Drawing.FontStyle").Bold (dotNetClass "System.Drawing.GraphicsUnit").Pixel
-- K_formatprops (dotnetobject "system.windows.forms.listView")
( -- Update the UI
if K_ISVALID PhysXPainter_HELPER and LIC do
(
( -- Get the Colliders
Collider_LV.Clear()
initLv Collider_LV
addColumns Collider_LV #( #("Colliders", 202) )
Colliders = for o in PhysXPainter_HELPER.CollidersLIST where K_ISVALID o collect o
local Assets = #()
for o=1 to Colliders.count do
(
append Assets Colliders[o].name
)
populateCOLList Collider_LV Assets
)
( -- Get the Assets
lv.Clear()
initLv lv
addColumns lv #( #("Assets", 128) , #("Verts", 45), #("%", 30) )
SourceAssets = #()
SourcePerc = #()
for o=1 to PhysXPainter_HELPER.SourceLIST.count where K_ISVALID PhysXPainter_HELPER.SourceLIST[o] do
(
append SourceAssets PhysXPainter_HELPER.SourceLIST[o]
append SourcePerc PhysXPainter_HELPER.SourcePerc[o]
)
local Assets = #()
local Perc = #()
local Verts = #()
for o=1 to SourceAssets.count do
(
local OBJ = SourceAssets[o]
append Assets OBJ.name
append Perc SourcePerc[o]
if OBJ.modifiers[#K_HULL] != undefined then
append Verts OBJ.modifiers[#K_HULL].VertsCOUNT
else
append Verts "?"
)
populateList lv Assets Verts Perc
)
VertsCNT_SPN.value = VertsCNT
)
)
PhysXPainterROL.height = 605
)
on VFBTabsRollout01 close do
(
)
on SelectPhysXHelper_BTN pressed do
(
if K_ISVALID PhysXPainter_HELPER and LIC do ( select PhysXPainter_HELPER ; max modify mode)
)
on AddCOL_BTN pressed do -- ADD colliders
(
if K_ISVALID PhysXPainter_HELPER and LIC do
(
local sel = selection as array
for o in sel where o != PhysXPainter_HELPER do
(
if finditem Colliders o == 0 do
(
append Colliders o
append PhysXPainter_HELPER.CollidersLIST o
)
)
( -- Update UI
Collider_LV.Clear()
initLv Collider_LV
addColumns Collider_LV #( #("Colliders", 220) )
local Assets = #()
for o=1 to Colliders.count where K_ISVALID Colliders[o] do
(
append Assets Colliders[o].name
)
populateCOLList Collider_LV Assets
)
)
)
on DelCOL_BTN pressed do -- DELETE colliders
(
if K_ISVALID PhysXPainter_HELPER and LIC do
(
local Sel = Collider_LV.SelectedItems
if Sel.count > 0 do
(
for i = Sel.count-1 to 0 by -1 do
(
local ID = Sel.item[i].index + 1
RemoveAssets Colliders[ID]
deleteItem PhysXPainter_HELPER.CollidersLIST ID
deleteItem Colliders ID
)
)
( -- Update UI
Collider_LV.Clear()
initLv Collider_LV
addColumns Collider_LV #( #("Colliders", 220) )
local Assets = #()
for o=1 to Colliders.count where K_ISVALID Colliders[o] do
(
append Assets Colliders[o].name
)
populateCOLList Collider_LV Assets
)
)
)
on SelCOL_BTN pressed do --SEL colliders List to Scene
(
if K_ISVALID PhysXPainter_HELPER and LIC do
(
local LISTSEL = Collider_LV.SelectedItems
local sel = #()
if LISTSEL.count > 0 do
(
for i = LISTSEL.count-1 to 0 by -1 do
(
ID = LISTSEL.item[i].index + 1
local theOBJ = PhysXPainter_HELPER.CollidersLIST[ID]
if K_ISVALID theOBJ do append sel theOBJ
)
)
if sel.count > 0 then
select Sel
else
clearSelection()
)
)
on SelCOLFrom_BTN pressed do -- Select Scene to List
(
if K_ISVALID PhysXPainter_HELPER and LIC do
(
local Sel = selection as array
local ColLIST = PhysXPainter_HELPER.CollidersLIST
Collider_LV.BeginUpdate();
for i=1 to Collider_LV.Items.count do
(
if ( finditem Sel ColLIST[i] ) != 0 then
(
Collider_LV.Items.item[i-1].Selected = true
Collider_LV.Items.item[i-1].EnsureVisible()
)
else
Collider_LV.Items.item[i-1].Selected = false
)
Collider_LV.EndUpdate();
)
)
on lv MouseUp arg do
(
local Sel = lv.SelectedItems
for i=0 to (Sel.count-1) do
(
local ID = Sel.item[i].index
local theOBJ = PhysXPainter_HELPER.SourceLIST[ID+1]
if K_ISVALID theOBJ do
(
Percentage_SPN.value = SourcePerc[ID+1]
local KHullMOD = theOBJ.modifiers[#K_HULL]
if KHullMOD != undefined do
(
VertsCNT_SPN.value = KHullMOD.VertsCOUNT
)
)
)
)
on lv MouseEnter arg do
(
lv.focus()
)
on Collider_LV MouseEnter arg do
(
Collider_LV.focus()
)
local dnKeys=dotnetclass "System.Windows.Forms.Keys"
on lv KeyDown arg do
(
if arg.Control and arg.KeyCode == dnKeys.i do -- invert list selection
(
lv.BeginUpdate();
for i=1 to lv.Items.count do
(
if lv.Items.item[i-1].Selected == true then
lv.Items.item[i-1].Selected = false
else
lv.Items.item[i-1].Selected = true
)
lv.EndUpdate();
)
if arg.Control and arg.KeyCode == dnKeys.a do -- select all
(
lv.BeginUpdate();
for i=1 to lv.Items.count do
(
lv.Items.item[i-1].Selected = true
)
lv.EndUpdate();
)
if arg.Control and arg.KeyCode == dnKeys.d do -- select none
(
lv.BeginUpdate();
for i=1 to lv.Items.count do
(
lv.Items.item[i-1].Selected = false
)
lv.EndUpdate();
)
)
on Collider_LV KeyDown arg do
(
if arg.Control and arg.KeyCode == dnKeys.i do -- invert list selection
(
Collider_LV.BeginUpdate();
for i=1 to Collider_LV.Items.count do
(
if Collider_LV.Items.item[i-1].Selected == true then
Collider_LV.Items.item[i-1].Selected = false
else
Collider_LV.Items.item[i-1].Selected = true
)
Collider_LV.EndUpdate();
)
if arg.Control and arg.KeyCode == dnKeys.a do -- select all
(
Collider_LV.BeginUpdate();
for i=1 to Collider_LV.Items.count do
(
Collider_LV.Items.item[i-1].Selected = true
)
Collider_LV.EndUpdate();
)
if arg.Control and arg.KeyCode == dnKeys.d do -- select none
(
Collider_LV.BeginUpdate();
for i=1 to Collider_LV.Items.count do
(
Collider_LV.Items.item[i-1].Selected = false
)
Collider_LV.EndUpdate();
)
)
on AddBTN pressed do --ADD assets
(
if K_ISVALID PhysXPainter_HELPER and LIC do
(
local Sel = selection as array
for o in sel where finditem Colliders o == 0 and o != PhysXPainter_HELPER do -- Add only if the asset is not already in the Colliders list.
(
if finditem SourceAssets o == 0 do
(
append SourceAssets o
append SourcePerc 20
append PhysXPainter_HELPER.SourceLIST o
append PhysXPainter_HELPER.SourcePerc 20
if o.modifiers[#K_HULL] == undefined do ( MakeHULL #(o) VertsCNT )
)
)
( -- Update the UI
lv.Clear()
initLv lv
addColumns lv #( #("Assets", 128) , #("Verts", 45), #("%", 30) )
-- addColumns lv #( #("Assets", 165) , #("%", 55) )
local Assets = #()
local Perc = #()
local Verts = #()
for o=1 to SourceAssets.count where K_ISVALID SourceAssets[o] do
(
local OBJ = SourceAssets[o]
append Assets OBJ.name
append Perc SourcePerc[o]
if OBJ.modifiers[#K_HULL] != undefined then
append Verts OBJ.modifiers[#K_HULL].VertsCOUNT
else
append Verts "?"
)
populateList lv Assets Verts Perc
if SourcePerc.count > 0 do
Percentage_SPN.value = SourcePerc[1]
)
)
)
on DelBTN pressed do --DEL assets
(
if K_ISVALID PhysXPainter_HELPER and LIC do
(
local Sel = lv.SelectedItems
if Sel.count > 0 do
(
for i = Sel.count-1 to 0 by -1 do
(
local ID = Sel.item[i].index + 1
--check if the item is still used in the modifier
(
local Sources = PhysXPainter_HELPER.SourceLIST as array
local Copies = PhysXPainter_HELPER.CopiesLIST as array
local SourceOBJ = PhysXPainter_HELPER.SourceLIST[ID]
if K_ISVALID SourceOBJ do
(
InstanceMgr.GetInstances SourceOBJ &instances
Instances --list of the instances before switch
if Instances.count > 1 then -- check instances
(
local COPS = for o in Instances where finditem Copies o !=0 collect i --les instances dans la liste des copies
if COPS.count == 0 do
(
RemoveAssets SourceAssets[ID]
deleteItem PhysXPainter_HELPER.SourceLIST ID
deleteItem PhysXPainter_HELPER.SourcePerc ID
deleteItem SourceAssets ID
deleteItem SourcePerc ID
)
)
else -- check copies
(
local COPS = #()
for o in Copies where K_ISVALID o do
(
local Appdata = (getAppData o 20100805)
if Appdata != undefined do
(
local SourceINSTANCE = getAnimByHandle (execute Appdata)
if K_ISVALID SourceINSTANCE and SourceINSTANCE == SourceOBJ do
(
append COPS o
)
)
)
if COPS.count == 0 do
(
RemoveAssets SourceAssets[ID]
deleteItem PhysXPainter_HELPER.SourceLIST ID
deleteItem PhysXPainter_HELPER.SourcePerc ID
deleteItem SourceAssets ID
deleteItem SourcePerc ID
)
)
)
)
)
)
( -- Update the UI
lv.Clear()
initLv lv
-- addColumns lv #( #("Assets", 165) , #("%", 55) )
addColumns lv #( #("Assets", 128) , #("Verts", 45), #("%", 30) )
local Assets = #()
local Perc = #()
local Verts = #()
for o=1 to SourceAssets.count where K_ISVALID SourceAssets[o] do
(
local OBJ = SourceAssets[o]
append Assets OBJ.name
append Perc SourcePerc[o]
if OBJ.modifiers[#K_HULL] != undefined then
append Verts OBJ.modifiers[#K_HULL].VertsCOUNT
else
append Verts "?"
)
populateList lv Assets Verts Perc
if SourcePerc.count > 0 do
Percentage_SPN.value = SourcePerc[1]
)
)
)
on SelBTN pressed do --SEL assets
(
if K_ISVALID PhysXPainter_HELPER and LIC do
(
local LISTSEL = lv.SelectedItems
local sel = #()
if LISTSEL.count > 0 do
(
for i = LISTSEL.count-1 to 0 by -1 do
(
local ID = LISTSEL.item[i].index + 1
local theOBJ = PhysXPainter_HELPER.SourceLIST[ID]
if K_ISVALID theOBJ do append sel theOBJ
)
)
if sel.count > 0 then
select Sel
else
clearSelection()
)
)
on SelFrom_BTN pressed do -- Select Scene to List
(
if K_ISVALID PhysXPainter_HELPER and LIC do
(
local Sel = selection as array
local SourceLIST = PhysXPainter_HELPER.SourceLIST
lv.BeginUpdate();
for i=1 to lv.Items.count do
(
if ( ID = finditem Sel SourceLIST[i] ) != 0 then
(
lv.Items.item[i-1].Selected = true
lv.Items.item[i-1].EnsureVisible()
( -- update UI values
Percentage_SPN.value = SourcePerc[i]
local KHullMOD = Sel[ID].modifiers[#K_HULL]
if KHullMOD != undefined do
(
VertsCNT_SPN.value = KHullMOD.VertsCOUNT
)
)
)
else
lv.Items.item[i-1].Selected = false
)
lv.EndUpdate();
)
)
on Percentage_SPN changed state do --%
(
if K_ISVALID PhysXPainter_HELPER and LIC do
(
local Sel = lv.SelectedItems
for i=0 to (Sel.count-1) do
(
local ID = Sel.item[i].index + 1
SourcePerc[ID] = state
PhysXPainter_HELPER.SourcePerc[ID] = state
--update in the list
Sel.item[i].SubItems.item[2].text = state as string
)
)
)
on GenHULL_BTN pressed do -- Generate K_HULL on selected source objects
(
if K_ISVALID PhysXPainter_HELPER and LIC do
(
local Sel = lv.SelectedItems
for i=0 to (Sel.count-1) do
(
local ID = Sel.item[i].index + 1
local theOBJ = PhysXPainter_HELPER.SourceLIST[ID]
if K_ISVALID theOBJ do
(
MakeHULL #( theOBJ ) VertsCNT
-- update the modifier value
theOBJ.modifiers[#K_HULL].VertsCOUNT = VertsCNT_SPN.value
--update in the list
Sel.item[i].SubItems.item[1].text = VertsCNT_SPN.value as string
)
)
)
)
on VertsCNT_SPN changed state do
(
VertsCNT = state
-- if K_ISVALID PhysXPainter_HELPER and LIC do
-- (
-- local Sel = lv.SelectedItems
--
-- for i=0 to (Sel.count-1) do
-- (
-- local ID = Sel.item[i].index + 1
--
-- SourcePerc[ID] = state
-- PhysXPainter_HELPER.SourcePerc[ID] = state
--
-- --update in the list
-- Sel.item[i].SubItems.item[2].text = state as string
-- )
--
-- )
)
)
rollout VFBTabsRollout02 "Brush"
(
local COP, COPIES
local ManualExit = false
button SelectPhysXHelper_BTN "Select PhysX_Painter Helper" width:248 offset:[2,0]
spinner DistSPN "Distance" range:[0.00,10000.00, 1.00] pos:[35,35] width:80 height:30 tooltip:"distance threshold between the previous and the new asset."
checkbox OverCHK "Paint Over" checked:true pos:[10,60] tooltip:"Paint over existing assets."
checkbox CollideCHK "Self Collide" checked:true pos:[100,60] tooltip:"Avoid collisions while painting."
checkbox PhysXCHK "PhysX" checked:true pos:[190,60] tooltip:"Run PhysX sim on mouse release."
label lineLBL03 "" height:5
group "Colors"
(
colorpicker StaticCOL "Static" align:#left color:(color 30 30 30) across:3
colorpicker SimCOL "Sim" align:#left color:green offset:[15,0]
checkbox UseCOL_CHK "use" align:#left offset:[25,3] tooltip:"display Simulation colors" checked:true
)
groupbox XGRP "X" width:61 height:230 pos:[50,150]
groupbox YGRP "Y" width:61 height:230 pos:[110,150]
groupbox ZGRP "Z" width:82 height:230 pos:[170,150]
groupbox posGRP "Pos" width:249 height:70 pos:[4, 150]
label Pmin "min" pos:[20, 170]
label Pmax "max" pos:[20, 195]
groupbox rotGRP "Rot" width:249 height:70 pos:[5, 220]
label Rmin "min" pos:[20, 240]
label Rmax "max" pos:[20, 265]
groupbox sclGRP "ScL" width:249 height:90 pos:[5, 290]
label Smin "min" pos:[20, 310]
label Smax "max" pos:[20, 335]
label LockS "lock" pos:[20, 360]
label X_LBL "X" pos:[75,150]
label Y_LBL "Y" pos:[135,150]
label Z_LBL "Z" pos:[195,150]
spinner PXmin "" range:[-10000.00,10000.00, 0.00] pos:[52,170] width:55 height:30
spinner PXmax "" range:[-10000.00,10000.00, 0.00] pos:[52,195] width:55 height:30
spinner PYmin "" range:[-10000.00,10000.00, 0.00] pos:[112,170] width:55 height:30
spinner PYmax "" range:[-10000.00,10000.00, 0.00] pos:[112,195] width:55 height:30
spinner PZmin "" range:[-10000.00,10000.00, 0.00] pos:[172,170] width:55 height:30
spinner PZmax "" range:[-10000.00,10000.00, 0.00] pos:[172,195] width:55 height:30
checkbox POS_CHK "" pos:[230, 180] width:15 tooltip:"Homothetic X, Y, Z position"
spinner RXmin "" range:[-360.00,360.00, 0.00] pos:[52,240] width:55 height:30
spinner RXmax "" range:[-360.00,360.00, 0.00] pos:[52,265] width:55 height:30
spinner RYmin "" range:[-360.00,360.00, 0.00] pos:[112,240] width:55 height:30
spinner RYmax "" range:[-360.00,360.00, 0.00] pos:[112,265] width:55 height:30
spinner RZmin "" range:[-360.00,360.00, 0.00] pos:[172,240] width:55 height:30
spinner RZmax "" range:[-360.00,360.00, 0.00] pos:[172,265] width:55 height:30
checkbox ROT_CHK "" pos:[230, 255] width:15 tooltip:"Homothetic X, Y, Z rotation"
spinner SXmin "" range:[ 0.001,10.00, 1.00] pos:[52,310] width:55 height:30
spinner SXmax "" range:[ 0.001,10.00, 1.00] pos:[52,335] width:55 height:30
spinner SYmin "" range:[ 0.001,10.00, 1.00] pos:[112,310] width:55 height:30
spinner SYmax "" range:[ 0.001,10.00, 1.00] pos:[112,335] width:55 height:30
spinner SZmin "" range:[ 0.001,10.00, 1.00] pos:[172,310] width:55 height:30
spinner SZmax "" range:[ 0.001,10.00, 1.00] pos:[172,335] width:55 height:30
checkbox X_CHK "" pos:[70, 360]
checkbox Y_CHK "" pos:[130, 360]
checkbox Z_CHK "" pos:[190, 360]
checkbox SCl_CHK "" pos:[230, 325] width:15 tooltip:"Homothetic X, Y, Z scale"
label lineLBL01 "" height:40
group "Tools"
(
button Paint_BTN "PAINT" height:30 width:30 pos:[10, 410] images:#("PhysXPainter_Icons_i.bmp","PhysXPainter_Icons_a.bmp",19, 1, 1 ,1,1 ) toolTip:"Paint Assets"
checkbutton Normal_BTN "Norm" height:30 width:30 pos:[45, 410] images:#("PhysXPainter_Icons_i.bmp","PhysXPainter_Icons_a.bmp",19, 3, 3 ,1,1 ) toolTip:"Orient to Surface Normal" highlightColor:(color 240 120 0)
checkbutton Direct_BTN "Direct" height:30 width:30 pos:[80, 410] images:#("PhysXPainter_Icons_i.bmp","PhysXPainter_Icons_a.bmp",19, 4, 4 ,1,1 ) toolTip:"Look At Brush Direction" highlightColor:(color 240 0 120)
checkbutton Gravity_BTN "Grav" height:30 width:30 pos:[145, 410] checked:true images:#("PhysXPainter_Icons_i.bmp","PhysXPainter_Icons_a.bmp",19, 5, 5 ,1,1 ) toolTip:"Gravity" highlightColor:(color 0 120 255)
checkbutton Attract_BTN "Attract" height:30 width:30 pos:[180, 410] images:#("PhysXPainter_Icons_i.bmp","PhysXPainter_Icons_a.bmp",19, 6, 6 ,1,1 ) toolTip:"Attract" highlightColor:(color 0 200 0)
checkbutton Explode_BTN "Explode" height:30 width:30 pos:[215, 410] images:#("PhysXPainter_Icons_i.bmp","PhysXPainter_Icons_a.bmp",19, 7, 7 ,1,1 ) toolTip:"Explode" highlightColor:red
spinner Force_SPN "Force" range:[-100000000.0, 100000000.0, 1.0] pos:[160, 450] width:85 align:#right tooltip:"the strength of Attraction or Explosion Forces"
button Drop_BTN "DROP" height:30 width:30 pos:[10, 445] images:#("PhysXPainter_Icons_i.bmp","PhysXPainter_Icons_a.bmp",19, 2, 2 ,1,1 ) toolTip:"Drop Assets"
checkbutton SIMALL "Sim ALL" height:30 width:30 pos:[45, 445] images:#("PhysXPainter_Icons_i.bmp","PhysXPainter_Icons_a.bmp",19, 8, 8 ,1,1 ) toolTip:"Simulate ALL" highlightColor:red
checkbutton SIMSEL "Sim SEL" height:30 width:30 pos:[80, 445] images:#("PhysXPainter_Icons_i.bmp","PhysXPainter_Icons_a.bmp",19, 9, 9 ,1,1 ) toolTip:"Simulate Selected" highlightColor:red
)
label lineLBL02 "" height:0
group "Save Load Presets"
(
button Folder_BTN "Folder" width:25 height:20 align:#left images:#("PhysXPainter_Icons_i.bmp","PhysXPainter_Icons_a.bmp",19, 13, 13 ,1,1 ) tooltip:"Choose Preset Folder"
edittext SaveName_EDT "" text:"New_Preset" width:160 align:#left offset:[25,-24] tooltip:"Preset Name"
button Save_BTN "Save Preset" width:25 height:20 align:#right offset:[-20,-24] images:#("PhysXPainter_Icons_i.bmp","PhysXPainter_Icons_a.bmp",19, 14, 14 ,1,1 ) tooltip:"Save Preset"
button Reset_BTN "R" width:20 height:20 align:#right offset:[0,-25] images:#("PhysXPainter_Icons_i.bmp","PhysXPainter_Icons_a.bmp",19, 15, 15 ,1,1 ) tooltip:"Reset to Default Settings"
dropdownlist Load_LIST "" width:232 align:#left offset:[0,0] tooltip:"Load Preset"
)
on SelectPhysXHelper_BTN pressed do
(
if K_ISVALID PhysXPainter_HELPER and LIC do ( select PhysXPainter_HELPER ; max modify mode)
)
on DistSPN changed state do ( if LIC do ( DIST = state*100.0 ; redrawviews() ) )
on OverCHK changed state do
(
if LIC do
(
Over = state
CollideCHK.enabled = state
if state == true then
PhysXCHK.enabled = CollideCHK.checked
else
PhysXCHK.enabled = state
)
)
on CollideCHK changed state do
(
if LIC do
(
Collide = state
PhysXCHK.enabled = state
)
)
on PhysXCHK changed state do (if LIC do PhysX = state)
on Attract_BTN changed state do
(
if state == true and LIC do
(
Explode_BTN.checked = false
)
)
on Explode_BTN changed state do
(
if state == true and LIC do
(
Attract_BTN.checked = false
)
)
on PXmin changed state do (PXA = state)
on PXmax changed state do (PXB = state)
on PYmin changed state do (PYA = state)
on PYmax changed state do (PYB = state)
on PZmin changed state do (PZA = state)
on PZmax changed state do (PZB = state)
on RXmin changed state do (RXA = state)
on RXmax changed state do (RXB = state)
on RYmin changed state do (RYA = state)
on RYmax changed state do (RYB = state)
on RZmin changed state do (RZA = state)
on RZmax changed state do (RZB = state)
on SXmin changed state do
(
SXA = state
( -- update the DropBrush points
local ML = DropMaxLEN * (SXA + SXB ) --/ 2.0
DropPoses = PackCircle DropRAD ML DropCount
redrawviews()
)
)
on SXmax changed state do
(
SXB = state
( -- update the DropBrush points
local ML = DropMaxLEN * (SXA + SXB ) --/ 2.0
DropPoses = PackCircle DropRAD ML DropCount
redrawviews()
)
)
on SYmin changed state do (SYA = state)
on SYmax changed state do (SYB = state)
on SZmin changed state do (SZA = state)
on SZmax changed state do (SZB = state)
on VFBTabsRollout02 open do
(
if LIC do
(
with printAllElements on -- Load saved settings from the Helper
(
local SavedSettings = ( getAppData PhysXPainter_HELPER 16573547 )
if SavedSettings != undefined and SavedSettings != "" and PhysXPainterROL != undefined then -- load the saved settings
(
execute SavedSettings
DIST = DistSPN.value * 100.0
)
else -- take the default values
(
StaticCOL.color = StaticCOLOR
SimCOL.color = SimCOLOR
PXmin.value = PXA
PXmax.value = PXB
PYmin.value = PYA
PYmax.value = PYB
PZmin.value = PZA
PZmax.value = PZB
POS_CHK.state = POS_ALL
RXmin.value = RXA
RXmax.value = RXB
RYmin.value = RYA
RYmax.value = RYB
RZmin.value = RZA
RZmax.value = RZB
ROT_CHK.state = ROT_ALL
SXmin.value = SXA
SXmax.value = SXB
SYmin.value = SYA
SYmax.value = SYB
SZmin.value = SZA
SZmax.value = SZB
X_CHK.state = LX
Y_CHK.state = LY
Z_CHK.state = LZ
SCl_CHK.state = L_ALL
DistSPN.value = DIST / 100.0
OverCHK.state = Over
CollideCHK.state = Collide
PhysXCHK.state = PhysX
)
)
if SCl_CHK.checked == true then
(
SXmin.enabled = true
if X_CHK.checked == true then
SXmax.enabled = false
else
SXmax.enabled = true
SYmin.enabled = false
SYmax.enabled = false
SZmin.enabled = false
SZmax.enabled = false
)
else
(
SXmin.enabled = true
SYmin.enabled = true
SZmin.enabled = true
if X_CHK.checked == true then
( SXmax.enabled = false )
else
( SXmax.enabled = true )
if Y_CHK.checked == true then
( SYmax.enabled = false )
else
( SYmax.enabled = true )
if Z_CHK.checked == true then
( SZmax.enabled = false )
else
( SZmax.enabled = true )
)
if POS_CHK.checked == true then
(
PXmin.enabled = true
PXmax.enabled = true
PYmin.enabled = false
PYmax.enabled = false
PZmin.enabled = false
PZmax.enabled = false
)
else
(
PXmin.enabled = true
PXmax.enabled = true
PYmin.enabled = true
PYmax.enabled = true
PZmin.enabled = true
PZmax.enabled = true
)
if ROT_CHK.checked == true then
(
RXmin.enabled = true
RXmax.enabled = true
RYmin.enabled = false
RYmax.enabled = false
RZmin.enabled = false
RZmax.enabled = false
)
else
(
RXmin.enabled = true
RXmax.enabled = true
RYmin.enabled = true
RYmax.enabled = true
RZmin.enabled = true
RZmax.enabled = true
)
PhysXPainterROL.height = 645
( -- load INI
INIfile = ( getdir #plugcfg_ln ) + "\\KinematicLAB_PhysXPainterPreset.ini"
LoadPath = ( getINISetting INIfile "PhysXPainter" "PresetFolder" )
--update preset list
if LoadPath != undefined do
(
files = getFiles (LoadPath + "\\*.phxp")
presetLIST = #()
for f in files do
(
Filename = getFilenameFile f
append presetLIST Filename
)
Load_LIST.items = presetLIST
)
)
)
)
on VFBTabsRollout02 close do
(
if LIC do
(
INIfile =( getdir #plugcfg_ln ) + "\\KinematicLAB_PhysXPainterPreset.ini"
-- setINISetting INIfile "PhysXPainter" "StaticCOLOR" (StaticCOL.color as string) forceUTF16:false --force ASCII
-- setINISetting INIfile "PhysXPainter" "SimCOLOR" (SimCOL.color as string) forceUTF16:false --force ASCII
setINISetting INIfile "PhysXPainter" "PresetFolder" LoadPath forceUTF16:false --force ASCII
-- setINISetting INIfile "PhysXPainter" "UIpos" ((GetDialogPos PhysXPainterROL ) as string) --forceUTF16:false --force ASCII
( -- Save Settings in the Helper to be loaded on each tool launch
if K_ISVALID PhysXPainter_HELPER and LIC do
(
local Settings = ""
local ROL = "PhysXPainterROL.theSubRollout.rollouts[2]."
Settings += ROL + "DistSPN.value = " + ( DistSPN.value as string ) + "\n"
Settings += ROL + "OverCHK.state = " + ( OverCHK.state as string ) + "\n"
Settings += ROL + "CollideCHK.state = " + ( CollideCHK.state as string ) + "\n"
Settings += ROL + "PhysXCHK.state = " + ( PhysXCHK.state as string ) + "\n"
local SpinnerLIST = #(PXmin, PXmax, PYmin, PYmax, PZmin, PZmax, RXmin, RXmax, RYmin, RYmax, RZmin, RZmax, SXmin, SXmax, SYmin, SYmax, SZmin, SZmax, Force_SPN)
for n in SpinnerLIST do
(
Settings += ROL + (n.name) + ".value = " + (n.value as string ) + "\n"
)
local CheckBoxLIST = #(X_CHK, Y_CHK, Z_CHK, SCl_CHK, POS_CHK, ROT_CHK, Normal_BTN, Direct_BTN, Gravity_BTN, Attract_BTN, Explode_BTN, UseCOL_CHK)
for n in CheckBoxLIST do
(
Settings += ROL + (n.name) + ".state = " + (n.state as string ) + "\n"
)
Settings += ROL + "StaticCOL.color = " + (StaticCOL.color as string ) + "\n"
Settings += ROL + "SimCOL.color = " + (SimCOL.color as string ) + "\n"
-- Settings += "SetDialogPos PhysXPainterROL " + ((GetDialogPos PhysXPainterROL ) as string)
with printAllElements on
(
setAppData PhysXPainter_HELPER 16573547 Settings
)
)
)
)
)
on StaticCOL changed col do
(
if LIC do
(
StaticCOLOR = col
)
)
on SimCOL changed col do
(
if LIC do
(
SimCOLOR = col
)
)
on X_CHK changed state do
(
if LIC do
(
LX = state
if state == true then
( SXmax.enabled = false )
else
( SXmax.enabled = true )
)
)
on Y_CHK changed state do
(
if LIC do
(
LY = state
if SCl_CHK.state == false then
(
if state == true then
( SYmax.enabled = false )
else
( SYmax.enabled = true )
)
else
(
SYmax.enabled = false
)
)
)
on Z_CHK changed state do
(
if LIC do
(
LZ = state
if SCl_CHK.state == false then
(
if state == true then
( SZmax.enabled = false )
else
( SZmax.enabled = true )
)
else
(
SZmax.enabled = false
)
)
)
on SCl_CHK changed state do
(
if LIC do
(
L_ALL = state
if state == true then
(
if X_CHK.state == false then
(
SXmin.enabled = true
SXmax.enabled = true
)
else
(
SXmin.enabled = true
SXmax.enabled = false
)
SYmin.enabled = false
SYmax.enabled = false
SZmin.enabled = false
SZmax.enabled = false
)
else
(
-- SXmin.enabled = true
-- SXmax.enabled = true
if X_CHK.state == false then
( SXmin.enabled = true
SXmax.enabled = true
)
else
(
SXmin.enabled = true
SXmax.enabled = false
)
if Y_CHK.state == false then
( SYmin.enabled = true
SYmax.enabled = true
)
else
(
SYmin.enabled = true
SYmax.enabled = false
)
if Z_CHK.state == false then
(
SZmin.enabled = true
SZmax.enabled = true
)
else
(
SZmin.enabled = true
SZmax.enabled = false
)
)
)
)
on POS_CHK changed state do
(
if LIC do
(
POS_ALL = state
if state == true then
(
PXmin.enabled = true
PXmax.enabled = true
PYmin.enabled = false
PYmax.enabled = false
PZmin.enabled = false
PZmax.enabled = false
)
else
(
PXmin.enabled = true
PXmax.enabled = true
PYmin.enabled = true
PYmax.enabled = true
PZmin.enabled = true
PZmax.enabled = true
)
)
)
on ROT_CHK changed state do
(
if LIC do
(
ROT_ALL = state
if state == true then
(
RXmin.enabled = true
RXmax.enabled = true
RYmin.enabled = false
RYmax.enabled = false
RZmin.enabled = false
RZmax.enabled = false
)
else
(
RXmin.enabled = true
RXmax.enabled = true
RYmin.enabled = true
RYmax.enabled = true
RZmin.enabled = true
RZmax.enabled = true
)
)
)
fn GW_displayObjectDATAS =
(
gw.setTransform (matrix3 1)
gw.setRndLimits #( ) -- draw all on top
if MAT != undefined do
(
local CNT = 25
local TheAngle = ( 360.0 / CNT ) as float
vPOS = TheViewPoint
if ToolType == "Paint" then
(
(-- CIRCLE A
local CirclePOS = #()
for v=1 to CNT do
(
local div = TheAngle*(v+1)
local X = RAD * cos( div )
local Y = RAD * sin( div )
append CirclePOS ( [X, Y,0] + [vPOS.X, vPOS.Y, 0 ] )
)
gw.setColor #line red -- setcolor light green
for n=1 to CNT - 1 do
(
local VA = CirclePOS[n]
local VB = CirclePOS[n+1]
gw.wPolyline #(VA, VB) false
)
gw.wPolyline #(CirclePOS[CNT], CirclePOS[1]) false
)
( -- Distance Number
local DISTstr = (DIST / 100.0) as string
local TXTsize = getTextExtent DISTstr
gw.wtext ([vPOS.X-(TXTsize.X/2) , vPOS.Y - RAD-5 , 0 ] ) DISTstr color:white
)
)
else if ToolType == "Drop" do
(
( -- Vertical Line
gw.setColor #line red
gw.Polyline #(MAT.pos, MAT.pos + [0,0,DropHEIGHT]) false
gw.Marker MAT.pos #circle color:red
gw.Marker (MAT.pos + [0,0,DropHEIGHT]) #circle color:red
)
( -- Assets poses
for P in DropPoses do
(
P += MAT.pos + [0,0,DropHEIGHT]
gw.Marker P #smallHollowBox color:yellow
)
)
(-- CIRCLE A
local CirclePOS = #()
for v=1 to CNT do
(
local div = TheAngle*(v+1)
local X = DropRAD * cos( div )
local Y = DropRAD * sin( div )
append CirclePOS ( [X, Y,0] + MAT.pos + [0,0,DropHEIGHT] )
)
gw.setColor #line red -- setcolor light green
for n=1 to CNT - 1 do
(
local VA = CirclePOS[n]
local VB = CirclePOS[n+1]
gw.Polyline #(VA, VB) false
)
gw.Polyline #(CirclePOS[CNT], CirclePOS[1]) false
)
( -- Count Number
local CNTstr = DropCount as string
local TXTsize = getTextExtent CNTstr
gw.text ( MAT.pos + [DropRAD + 2,0,DropHEIGHT ] ) CNTstr color:white
)
)
)
gw.enlargeUpdateRect #whole
gw.updateScreen()
)
fn DisplayVECS state =
(
if state == true then
(
unregisterRedrawViewsCallback GW_displayObjectDATAS
registerRedrawViewsCallback GW_displayObjectDATAS
redrawviews()
)
else
(
unregisterRedrawViewsCallback GW_displayObjectDATAS
redrawviews()
)
)
fn GetHighestBBvalue o SZ =
(
local BB = nodeLocalBoundingBox o
local X = ( BB[2].X - BB[1].X ) * SZ.X
local Y = ( BB[2].Y - BB[1].Y ) * SZ.Y
local Z = ( BB[2].Z - BB[1].Z ) * SZ.Z
amax #(X,Y,Z)
)
fn getObjectsARROUND_A objPOS obj GroundNODES =
(
( -- get the objects arround from viewport bounding box coords
-- local vmTM = inverse ( viewport.getTM() )
-- local bbMax = obj.max
-- local bbMin = obj.min
-- local DIST = ( (distance bbMax bbMin ) / (distance vmTM.pos objPOS) ) --; print DIST
--
-- local objsUnderCursorArr = (boxPickNode (box2 (mouse.pos - [DIST,DIST]) (mouse.pos + [DIST,DIST])) crossing:true )
-- select objsUnderCursorArr
( -- test
/*local bbMax = obj.max
local bbMin = obj.min
local DIST = (distance bbMax bbMin )
local VX = gw.getWinSizeX()
local VY = gw.getWinSizeY()
local VpointA = gw.getPointOnCP [0,0]
local VpointB = gw.getPointOnCP [VX, VY]
local VPdiagonal = distance VpointA VpointB
local ViewSZ = sqrt ( (VX)^2 + (VY)^2 )
local DIV = DIST / (VPdiagonal as float)
local ScreenSZ = (ViewSZ * DIV)
local focal_d = viewport.getFocalDistance()
local ViewDIST = distance vmTM.pos objPOS
local ScreenToView = ( mapScreenToView [ScreenSZ, ScreenSZ] focal_d ) / 10.0
*/
-- local objsUnderCursorArr = (boxPickNode (box2 (mouse.pos - [20,20]) (mouse.pos + [20,20])) crossing:true )
-- print objsUnderCursorArr.count
-- select objsUnderCursorArr
)
with undo off
(
local bbMax = obj.max
local bbMin = obj.min
gw.setTransform (Matrix3 1)
local ViewPT_A = gw.TransPoint bbMax
gw.setTransform (Matrix3 1)
local ViewPT_B = gw.TransPoint bbMin
local objsUnderCursorArr = (boxPickNode (box2 ViewPT_A ViewPT_B) crossing:true )
)
)
if objsUnderCursorArr.count > 0 then -- sort by distance
(
local ArroundDATA = for o in objsUnderCursorArr where o!=obj and finditem GroundNODES o == 0 and finditem tempLIST o != 0 collect #(o, VEC = objPOS - o.center , length VEC )
fn sortByHitDistance n1 n2 = if n1[3] < n2[3] then -1 else if n1[3] > n2[3] then 1 else 0
qsort ArroundDATA sortByHitDistance
ArroundDATA
)
else
#()
)
fn getColliders Neighbors objPOS obj =
(
with undo off
(
local MaxCNT = 4
if Neighbors.count < MaxCNT then CNTlimit = Neighbors.count else CNTlimit = MaxCNT
Colliders = #()
for o=1 to CNTlimit do
(
local N = Neighbors[o]
local Nobj = N[1]
local VEC = objPOS - Nobj.center
local DIST = length VEC
local NormVEC = normalize VEC
local MAT = matrixfromnormal NormVEC ; MAT.row4 = objPOS
local objBB = nodeGetBoundingBox obj MAT
local nBB = nodeGetBoundingBox Nobj MAT
local objH = abs (objBB[2].Z - objBB[1].Z )
local nH = abs (nBB[2].Z - nBB[1].Z )
local MinDIST = ( ( objH + nH )/2.0 ) --*1.5
if DIST < MinDIST do -- collide
(
local Diff = abs (MinDIST - DIST)
append Colliders #(Nobj, NormVEC, Diff )
)
)
)
Colliders
)
fn AvoidNodes obj viewDIR GroundNODES =
(
with undo off
(
local objPOS = obj.center
local BB = nodeLocalBoundingBox obj
local objSIZE = ( distance BB[1] BB[2] ) / 150.0 -- get the object BB size to help moving away from obstacles faster depending on their size
local Neighbors = getObjectsARROUND_A objPOS obj GroundNODES -- the 4(or less) closest objects with vectors and distances
with redraw off
(
local Colliders = getColliders Neighbors objPOS obj
while Colliders.count > 0 do
(
local objPOS = obj.center
( -- get the Colliding objects their vector and collide Distance
Colliders = getColliders Neighbors objPOS obj
)
if Colliders.count > 0 do
(
obj.pos += (normalize viewDIR ) * objSIZE
)
)
)
)
)
fn UndoNewAssets LIST theMOD =
( -- Undo test
with undo off
(
with redraw off
(
local OBJDAT = for o in LIST collect
(
local Appdata = (getAppData o 20100805)
local SourceINSTANCE = getAnimByHandle (execute Appdata)
#(o.transform , SourceINSTANCE, Appdata as string)
)
delete LIST
free LIST
LIST = #()
LIST[OBJDAT.count] = 0--initialize a 100 elements array in memory
)
)
with undo label:"PhysXPainter_ADD" on
(
with redraw off
(
for o=1 to OBJDAT.count do
(
local DAT = OBJDAT[o]
local COP = copy DAT[2] ; COP.transform = DAT[1]
OBJDAT[o][1] = COP
)
)
)
with undo off
(
with redraw off
(
for o=1 to OBJDAT.count do
(
local DAT = OBJDAT[o]
local COP = DAT[1]
COP.wirecolor = StaticCOLOR
setAppData COP 20100805 ( DAT[3] as string )
( -- Put the New Object in the Arrays
append theMOD.CopiesLIST COP
append tempLIST COP
LIST[o] = COP
)
)
free OBJDAT
)
)
gc light:true
LIST
)
fn UndoSIMAssets LIST theMOD =
( -- Undo test
if LIST.count > 0 do
(
with redraw off
(
with undo off
(
local OBJDAT = for o in LIST collect
(
local Appdata = (getAppData o 20100805)
local SourceINSTANCE = getAnimByHandle (execute Appdata)
#(o.transform , SourceINSTANCE, Appdata as string)
)
delete LIST
free LIST
LIST = #()
LIST[OBJDAT.count] = 0--initialize a 100 elements array in memory
)
with undo label:"PhysXPainter_ADD_PhysX" on
(
for o=1 to OBJDAT.count do
(
local DAT = OBJDAT[o]
local COP = copy DAT[2] ; COP.transform = DAT[1]
OBJDAT[o][1] = COP
)
)
with redraw off
(
with undo off
(
for o=1 to OBJDAT.count do
(
local DAT = OBJDAT[o]
local COP = DAT[1]
COP.wirecolor = SimCOLOR
setAppData COP 20100805 ( DAT[3] )
( -- Put the New Object in the Arrays
append theMOD.CopiesLIST COP
append tempLIST COP
LIST[o] = COP
)
COP.modifiers[MassFX_RBody].type = 1
COP.modifiers[MassFX_RBody].RBMeshRegenerate 1
)
free OBJDAT
)
)
gc light:true
)
)
LIST
)
fn UndoSIMonly LIST theMOD =
(
if LIST.count > 0 do
(
with redraw off
(
with undo label:"PhysXPainter_SimALL" on
(
for o in LIST do
(
o.transform = o.transform
)
)
gc light:true
)
)
)
fn UndoDELassets DelASSETS theMOD =
( -- Undo test
with undo off
(
with redraw off
(
unhide DelASSETS
)
)
with undo label:"PhysXPainter_DEL" on
(
with redraw off
(
delete DelASSETS
)
)
with undo off
(
with redraw off
(
free DelASSETS
)
)
gc light:true
)
on Paint_BTN pressed do -- PAINT
(
if K_ISVALID PhysXPainter_HELPER and LIC do
(
max create mode
theMOD = PhysXPainter_HELPER
if theMOD.SourceLIST.count > 0 and foo == undefined do
(
SIMALL.checked = SIMSEL.checked = false
-- if foo != undefined do ( ManualExit = true ; stoptool foo ; foo = undefined )
ITM = for o in SourceAssets where K_ISVALID o collect o
tempLIST = for o in ( theMOD.CopiesLIST as array) where K_ISVALID o collect o
theMOD.CopiesLIST = deepcopy tempLIST
join tempLIST theMOD.CollidersLIST
(
tool foo
(
local test = undefined
local OBJ = undefined
local PrevPOS
local PrevDIST
local POS
local hit_nodes
local currentSZ = 0.1
local PrevVEC = [1,0,0]
local UniqueScale = [1,1,1]
local RX, RY, RZ = 0.0
local DelASSETS = #()
local ADDmode, DELmode, RESIMmode, DISTmode, ONEmode = false
on freeMove do -- FREE
(
TheViewPoint = viewpoint
if K_ISVALID PhysXPainter_HELPER then
with undo off
(
myRay = mapScreenToWorldRay viewPoint -- make a ray from active viewport
if OverCHK.state == false then -- paint only on the ground
(
objsUnderCursorArr = (boxPickNode (box2 (mouse.pos - [2,2]) (mouse.pos + [2,2])) crossing:true )
if objsUnderCursorArr.count >0 do
(
hit_nodes = for n in objsUnderCursorArr where not n.isHidden and not n.isFrozen and finditem theMOD.CollidersLIST n !=0 and (tempRay = intersectRay n myRay )!=undefined collect
(
#( n, distance tempRay.pos myRay.pos, tempRay )
)
fn sortByHitDistance n1 n2 = if n1[2] < n2[2] then -1 else if n1[2] > n2[2] then 1 else 0
qsort hit_nodes sortByHitDistance
if hit_nodes.count > 0 then --Get the closest HIT
(
POS = hit_nodes[1][3].pos
ROT = hit_nodes[1][3].dir
)
)
)
else
(
objsUnderCursorArr = (boxPickNode (box2 (mouse.pos - [2,2]) (mouse.pos + [2,2])) crossing:true )
if objsUnderCursorArr.count >0 do
(
hit_nodes = for n in objsUnderCursorArr where not n.isHidden and not n.isFrozen and finditem tempLIST n !=0 and (tempRay = intersectRay n myRay )!=undefined collect
(
#( n, distance tempRay.pos myRay.pos, tempRay )
)
fn sortByHitDistance n1 n2 = if n1[2] < n2[2] then -1 else if n1[2] > n2[2] then 1 else 0
qsort hit_nodes sortByHitDistance
if hit_nodes.count > 0 then --Get the closest HIT
(
POS = hit_nodes[1][3].pos
ROT = hit_nodes[1][3].dir
)
)
)
if POS != undefined and ROT != undefined then -- define the visual BRUSH MATRIX
(
MAT = inverse ( viewport.getTM() )
MAT.pos = POS
)
else
MAT = undefined
)
redrawviews()
)
on mousePoint clickno do -- 1er CLIC
(
if clickno == 1 then
(
with undo off
(
if ALtKEY then ( DELmode = true ; ADDmode = RESIMmode = DISTmode = ONEmode = false ) -- DELmode
else
(
if CtrlKEY and not ShiftKEY then -- RESIMmode
(
RESIMmode = true ; DELmode = ADDmode = DISTmode = ONEmode = false
)
else if ShiftKEY and not CtrlKEY then -- paint One Asset : ADDmode
(
ADDmode = ONEmode = true ; RESIMmode = DELmode = DISTmode = false
)
else if not ShiftKEY and not CtrlKEY then -- Paint Multiple : ADDmode
(
ADDmode = true ; RESIMmode = DELmode = DISTmode = ONEmode = false
)
else if ShiftKEY and CtrlKEY do -- Shift + Ctrl : Distance value
(
DISTmode = true ; ADDmode = RESIMmode = DELmode = ONEmode = false
)
)
(-- Get the Transform values from UI : do it here to take the new parameters even when brush is active
PXA = PXmin.value
PXB = PXmax.value
PYA = PYmin.value
PYB = PYmax.value
PZA = PZmin.value
PZB = PZmax.value
RXA = RXmin.value
RXB = RXmax.value
RYA = RYmin.value
RYB = RYmax.value
RZA = RZmin.value
RZB = RZmax.value
SXA = SXmin.value
if X_CHK.state == true then SXB = SXA else SXB = SXmax.value
SYA = SYmin.value
if Y_CHK.state == true then SYB = SYA else SYB = SYmax.value
SZA = SZmin.value
if Z_CHK.state == true then SZB = SZA else SZB = SZmax.value
if SCl_CHK.state == true then ( SYA = SZA = SXA ; SYB = SZB = SXB )
if POS_CHK.state == true then ( PYA = PZA = PXA ; PYB = PZB = PXB )
if ROT_CHK.state == true then ( RYA = RZA = RXA ; RYB = RZB = RXB )
)
PrevPOS = viewpoint
PrevDIST = DIST
TheViewPoint = viewpoint
CurrentCopies = for o in CurrentCopies where K_ISVALID o collect o
with redraw off
( -- RESET the SIM and set assets STATIC
PxCaptureTransform(false)
PxStopSimulation()
local EnableGravity = Gravity_BTN.checked
for Cop in CurrentCopies do --put already simulated copies to static
(
local MFXMOD = Cop.modifiers[MassFX_RBody]
MFXMOD.type = 3
(-- Remove force
MFXMOD.enableGravity = EnableGravity
MFXMOD.forcesList = #()
MFXMOD.VelocitySpeed = MFXMOD.SpinSpeed = 0.0
)
)
CurrentCopies.wirecolor = StaticCOLOR
if K_ISVALID FRC do delete FRC
-- CurrentCopies = #()
gc light:true
)
)
free CurrentCopies
with undo off
(
( -- Random Item
RNDITM = random 1 ITM.count
Source = ITM[RNDITM]
)
if K_ISVALID PhysXPainter_HELPER then --HIT pos and DIR
(
local myRay = mapScreenToWorldRay viewPoint -- make a ray from active viewport
if OverCHK.state == false then -- paint only on the ground
(
objsUnderCursorArr = (boxPickNode (box2 (mouse.pos - [20,20]) (mouse.pos + [20,20])) crossing:true )
if objsUnderCursorArr.count >0 do
(
hit_nodes = for n in objsUnderCursorArr where not n.isHidden and not n.isFrozen and finditem theMOD.CollidersLIST n !=0 and (tempRay = intersectRay n myRay )!=undefined collect
(
#( n, distance tempRay.pos myRay.pos, tempRay )
)
fn sortByHitDistance n1 n2 = if n1[2] < n2[2] then -1 else if n1[2] > n2[2] then 1 else 0
qsort hit_nodes sortByHitDistance
if hit_nodes.count > 0 then --Get the closest HIT
(
POSB = hit_nodes[1][3].pos
ROT = hit_nodes[1][3].dir
)
)
)
else -- Project pivot on other Assets
(
( -- New detection method using boxPickNode to get the objects under the cursor
objsUnderCursorArr = (boxPickNode (box2 (mouse.pos - [20,20]) (mouse.pos + [20,20])) crossing:true )
if objsUnderCursorArr.count >0 do
(
hit_nodes = for n in objsUnderCursorArr where not n.isHidden and not n.isFrozen and finditem tempLIST n !=0 and (tempRay = intersectRay n myRay )!=undefined collect
(
#( n, distance tempRay.pos myRay.pos, tempRay )
)
fn sortByHitDistance n1 n2 = if n1[2] < n2[2] then -1 else if n1[2] > n2[2] then 1 else 0
qsort hit_nodes sortByHitDistance
if hit_nodes.count > 0 then -- Get the closest HIT
(
POSB = hit_nodes[1][3].pos
ROT = hit_nodes[1][3].dir
)
)
)
)
if POSB != undefined do -- define the visual BRUSH MATRIX
(
MAT = inverse ( viewport.getTM() )
MAT.pos = POSB
)
)
if ONEmode do -- Create one Asset
(
( -- Create ASSET
-- COPY asset
OBJ = copy Source ; OBJ.wirecolor = SimCOLOR -- pas en instance sinon soucis avec le calcul du Hull
setAppData OBJ 20100805 ( (getHandleByAnim Source) as string )
( -- Put the New Object in the Arrays
if K_ISVALID OBJ then
(
append theMOD.CopiesLIST OBJ
append tempLIST OBJ
append CurrentCopies OBJ
)
)
( -- Transforms from UI
( --Calculate random screen pos
PX = random PXA PXB
PY = random PYA PYB
PZ = random PZA PZB
)
(-- SCALE values
SX = random SXA SXB
SY = random SYA SYB
SZ = random SZA SZB
if SCl_CHK.state == true do SY = SZ = SX
UniqueScale = [SX, SY, SZ]
)
(-- ROT values
RX = random RXA RXB
RY = random RYA RYB
RZ = random RZA RZB
)
in coordsys gimbal OBJ.rotation = eulerangles RX RY RZ -- Rotate the Asset ::: REMOVE this, it's just for testing. The Correct stuff is Above
OBJ.scale = UniqueScale
)
( -- PLACEMENT
if CollideCHK.checked == true then
(--Self COllide
OBJ.pos = POSB --place l'objet en position d'intersection
( -- Hit on closest Asset
local Closest = hit_nodes[1][1]
local ClosestHIT = hit_nodes[1][3]
)
(-- Avoid
( --get the lower point under 0, and move the asset allong the ray vector by this value
local myRay = mapScreenToWorldRay viewPoint -- make a ray from active viewport
local VEC = normalize ( ClosestHIT.dir - myRay.dir )
local TR = copy OBJ.transform
local ViewMAT = matrixfromnormal (normalize VEC)
ViewMAT.row4 = OBJ.pos
OBJ.transform *= inverse ViewMAT
local BB = nodeGetBoundingBox OBJ (matrix3 1)
local MinZ = amin #(BB[1].Z, BB[2].Z)
OBJ.transform = TR
move OBJ (VEC * (abs MinZ))
)
)
POS = OBJ.pos
)
else
(
OBJ.pos = POSB
)
)
if tempRay != undefined then
(
OBJ.pos.Z += PZ --Position
)
if PhysXCHK.checked and CollideCHK.checked and OverCHK.checked do
(
OBJ.modifiers[MassFX_RBody].type = 1
OBJ.modifiers[MassFX_RBody].RBMeshRegenerate 1
)
)
)
)
)
else
(--#stop
test = undefined
redrawviews()
-- START SIMULATION -- MassFX
if PhysXCHK.checked and OverCHK.checked and CollideCHK.checked and not DELmode then
(
if RESIMmode then -- reSIM
(
UndoSIMonly CurrentCopies theMOD
)
else
(
CurrentCopies = UndoSIMAssets CurrentCopies theMOD
)
with undo off
(
with redraw off
(
-- start = timeStamp()
if Attract_BTN.checked or Explode_BTN.checked then
( -- Create Attract Gravity
( -- get assets Average Position and MAX distance between them
local BoundingBoxes = #()
local AVpos= [0,0,0]
local AVsize = 0.0
for Cop in CurrentCopies do
(
AVpos += Cop.center
BB = nodeLocalBoundingBox Cop
append BoundingBoxes BB
AVsize += distance BB[1] BB[2]
)
local CNT = CurrentCopies.count
AVpos /= CNT
AVsize /= CNT
local MaxDIST = 0.0
local AVdist = 0.0
local AVtoCenterDISTS = #()
for Cop in CurrentCopies do
(
local DIST = distance AVpos Cop.center
if DIST > MaxDIST do MaxDIST = DIST
AVdist += DIST
append AVtoCenterDISTS DIST
)
AVdist /= CNT
)
( -- create a force object
if Attract_BTN.checked do
(
FRC = gravity pos:AVpos isSelected:off iconSize:30.5152 transform:(matrix3 1) gravitytype:1 strength:(PhysXPanelData.gravity * -2.5 * Force_SPN.value )
hide FRC
)
)
local ForceVAL = Force_SPN.value
local UseGravity = Gravity_BTN.checked
local UseAttract = Attract_BTN.checked
local UseExplode = Explode_BTN.checked
local GravityOBJ = nvpx.gravityObject
for o=1 to CurrentCopies.count do --put MassFX on Copies
(
local Cop = CurrentCopies[o]
local MFXMOD = Cop.modifiers[MassFX_RBody]
if MFXMOD != undefined do
(-- ADD force
MFXMOD.forcesList = #()
if UseAttract then ForceLIST = #(FRC) else ForceLIST = #()
if UseGravity and GravityOBJ != undefined then -- width Custom Gravity
(
MFXMOD.enableGravity = off -- n'utilise pas la gravity du World
append ForceLIST GravityOBJ
)
else
(
MFXMOD.enableGravity = UseGravity
)
MFXMOD.forcesList = ForceLIST
if UseExplode do
(
local VEC = Cop.center - (AVpos - [0,0,AVdist])
MFXMOD.InitialVelocityX = VEC.X
MFXMOD.InitialVelocityY = VEC.Y
MFXMOD.InitialVelocityZ = VEC.Z
MFXMOD.InitialSpinX = VEC.X
MFXMOD.InitialSpinY = VEC.Y
MFXMOD.InitialSpinZ = VEC.Z
local BB = BoundingBoxes[o]
local DIST = AVtoCenterDISTS[o]
local DistVAL = 1.0 - DIST / MaxDIST
MFXMOD.VelocitySpeed = 10.0 * ( distance BB[1] BB[2] ) * DistVAL * ForceVAL
MFXMOD.SpinSpeed = MFXMOD.VelocitySpeed * 0.7
)
)
)
)
else
(
local GravityOBJ = nvpx.gravityObject
local UseGravity = Gravity_BTN.checked
for Cop in CurrentCopies do --put MassFX on Copies
(
local MFXMOD = Cop.modifiers[MassFX_RBody]
if MFXMOD != undefined do
(-- ADD force
if UseGravity and GravityOBJ != undefined then -- Custom Gravity
(
MFXMOD.enableGravity = off -- n'utilise pas la gravity du World
MFXMOD.forcesList = #()
MFXMOD.forcesList = #( GravityOBJ )
)
else
(
MFXMOD.enableGravity = UseGravity
MFXMOD.forcesList = #()
)
)
)
)
)
-- end = timeStamp()
-- format "Processing took % seconds\n" ((end - start) / 1000.0)
-- START SIMULATION -- >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
if CurrentCopies.count > 0 do
(
nvpx.SetAnimationState(false)
PxRunSimulation()
)
)
)
else
(
if ADDmode then -- undo New assets
(
CurrentCopies = UndoNewAssets CurrentCopies theMOD
)
else if DELmode do -- undo del ASSETS
(
UndoDELassets DelASSETS theMOD
)
)
gc light:true
#stop
)
)
on mouseMove clickno do --quand la sourie bouge ou nouveaux CLIC
(
if test != undefined then -- si la sourie bouge
(
with undo off
(
if DISTmode then -- Resize Distance Value
(
DIST = PrevDIST + ( viewpoint.X - PrevPOS.X )--/100.0
if DIST <0.0 do DIST = 0.0
DistSPN.value = DIST / 100.0
redrawviews()
)
else
(
if not DELmode then -- Paint ADD assets
(
if RESIMmode and PhysXCHK.checked and CollideCHK.checked and OverCHK.checked then -- paint SIM state
(
if K_ISVALID PhysXPainter_HELPER then --HIT pos and DIR
(
local myRay = mapScreenToWorldRay viewPoint -- make a ray from active viewport
( -- New detection method using boxPickNode to get the objects under the cursor
objsUnderCursorArr = (boxPickNode (box2 (mouse.pos - [20,20]) (mouse.pos + [20,20])) crossing:true )
if objsUnderCursorArr.count > 0 do
(
hit_nodes = for n in objsUnderCursorArr where not n.isHidden and not n.isFrozen and finditem theMOD.CollidersLIST n == 0 and finditem tempLIST n != 0 and (tempRay = intersectRay n myRay )!=undefined collect
(
#( n, distance tempRay.pos myRay.pos, tempRay )
)
if hit_nodes.count > 0 do
(
fn sortByHitDistance n1 n2 = if n1[2] < n2[2] then -1 else if n1[2] > n2[2] then 1 else 0
qsort hit_nodes sortByHitDistance
if hit_nodes.count > 0 then --Get the closest HIT
(
POSB = hit_nodes[1][3].pos
ROT = hit_nodes[1][3].dir
)
if POSB != undefined do -- define the visual BRUSH MATRIX
(
MAT = inverse ( viewport.getTM() )
MAT.pos = POSB
)
local HitOBJECT = hit_nodes[1][1]
HitOBJECT.modifiers[MassFX_RBody].type = 1
HitOBJECT.wirecolor = SimCOLOR
appendifunique CurrentCopies HitOBJECT
)
)
)
)
)
else if ADDmode do-- Paint ADD
(
( --Calculate random screen pos
PX = random PXA PXB
PY = random PYA PYB
PZ = random PZA PZB
)
( -- Random Item
RNDITM = random 1 ITM.count
Source = ITM[RNDITM]
)
if K_ISVALID PhysXPainter_HELPER then --HIT pos and DIR
(
VP = [viewPoint.X+(PX*3), viewPoint.Y+(PY*3)]
myRay = mapScreenToWorldRay VP -- make a ray from active viewport
if OverCHK.state == false then --Peindre seulement sur le SOL
(
( -- New detection method using boxPickNode to get the objects under the cursor
objsUnderCursorArr = (boxPickNode (box2 (mouse.pos - [20,20]) (mouse.pos + [20,20])) crossing:true )
if objsUnderCursorArr.count > 0 do
(
hit_nodes = for n in objsUnderCursorArr where not n.isHidden and not n.isFrozen and n!=OBJ and finditem theMOD.CollidersLIST n != 0 and (tempRay = intersectRay n myRay )!=undefined collect (
#( n, distance tempRay.pos myRay.pos, tempRay )
)
fn sortByHitDistance n1 n2 = if n1[2] < n2[2] then -1 else if n1[2] > n2[2] then 1 else 0
qsort hit_nodes sortByHitDistance
if hit_nodes.count > 0 then --Get the closest HIT
(
POSB = hit_nodes[1][3].pos
ROT = hit_nodes[1][3].dir
)
)
)
)
else -- peindre sur les autres
(
( -- New detection method using boxPickNode to get the objects under the cursor
objsUnderCursorArr = (boxPickNode (box2 (mouse.pos - [20,20]) (mouse.pos + [20,20])) crossing:true )
with redraw off
(
if objsUnderCursorArr.count > 0 do
(
hit_nodes = for n in objsUnderCursorArr where not n.isHidden and not n.isFrozen and n!=OBJ and finditem tempLIST n != 0 and (tempRay = intersectRay n myRay )!=undefined collect
(
#( n, distance tempRay.pos myRay.pos, tempRay )
)
fn sortByHitDistance n1 n2 = if n1[2] < n2[2] then -1 else if n1[2] > n2[2] then 1 else 0
qsort hit_nodes sortByHitDistance
if hit_nodes.count > 0 then --Get the closest HIT
(
POSB = hit_nodes[1][3].pos
ROT = hit_nodes[1][3].dir
)
)
)
)
-- hit_nodes = for n in (intersectRayScene myRay) where not n[1].isHidden and not n[1].isFrozen and finditem tempLIST n[1] !=0 collect #(n[1], n[2], distance myRay.pos n[2].pos)
-- fn sortByHitDistance n1 n2 = if n1[3] < n2[3] then -1 else if n1[3] > n2[3] then 1 else 0
-- qsort hit_nodes sortByHitDistance
-- hit_nodes[1] -- is closest
-- if hit_nodes.count > 0 then --Get the closest HIT
-- (
-- POSB = hit_nodes[1][2].pos
-- ROT = hit_nodes[1][2].dir
-- )
)
if POSB != undefined do -- define the visual BRUSH MATRIX
(
MAT = inverse ( viewport.getTM() )
MAT.pos = POSB
)
)
if not ONEmode do
(-- SCALE values
SX = random SXA SXB
SY = random SYA SYB
SZ = random SZA SZB
if SCl_CHK.state == true do SY = SZ = SX
)
with redraw off
( -- Get the Separation Distance between the Previous Asset and the New POS
if K_ISVALID OBJ and not ONEmode then
(
local PrevSZ = GetHighestBBvalue OBJ OBJ.scale
local currentSZ = GetHighestBBvalue Source [SX, SY, SZ]
SepDIST = ( PrevSZ + currentSZ )/2.0 * (DIST/100.0)
)
else SepDIST = 0.0
)
if POS != undefined and POSB != undefined then
(
D = distance POS POSB
if D > SepDIST then -- if distance between prev OBJECT and new POS is higher than the Distance value
(
-- COPY asset
if not ONEmode do with redraw off
(
OBJ = copy Source ; OBJ.wirecolor = SimCOLOR -- pas en instance sinon soucis avec le calcul du Hull
setAppData OBJ 20100805 ( (getHandleByAnim Source) as string )
( -- Put the New Object in the Arrays
-- if K_ISVALID OBJ then
(
append theMOD.CopiesLIST OBJ
append tempLIST OBJ
append CurrentCopies OBJ
)
)
)
if not ONEmode do
(-- ROT values
RX = random RXA RXB
RY = random RYA RYB
RZ = random RZA RZB
)
if ROT != undefined then --ROTATIONS - FOLLOW et SURFACE
(
with redraw off
(
if Direct_BTN.checked then --FOLLOW
(
if Normal_BTN.checked then --ORIENT ON SURFACE
(
Z = normalize ROT
if ONEmode then
(
vec = (normalize ( POSB - POS) )
local ANG = K_GetVectorsAngle vec PrevVEC
if ANG > 5.0 and distance POSB POS > 2.0 then
(
X = vec
PrevVEC = vec
POS = POSB
)
else
(
X = PrevVEC
)
)
else
(
X = (normalize ( POSB - POS) )
)
Y = normalize (cross X Z)
Z = normalize (cross X -Y )
local theMatrix = matrix3 X -Y Z OBJ.pos
OBJ.transform = theMatrix
in coordsys local rotate OBJ (eulerangles RX RY RZ)
)
else
(
local vec = normalize ( POSB - POS )
if ONEmode then
(
local ANG = K_GetVectorsAngle vec PrevVEC
if ANG > 5.0 and distance POSB POS > 2.0 then
(
dir = vec
PrevVEC = vec
POS = POSB
)
else
(
dir = PrevVEC
)
)
else
(
dir = vec
)
X = Dir
Z = [0,0,1]
Y = normalize (cross X Z)
Z = normalize (cross X -Y )
local theMatrix = matrix3 X -Y Z OBJ.pos
OBJ.transform = theMatrix
in coordsys local rotate OBJ (eulerangles RX RY RZ)
)
)
else
(
if Normal_BTN.checked then
(
OBJ.dir = ROT
in coordsys local rotate OBJ (eulerangles RX RY RZ)
)
else
( in coordsys gimbal OBJ.rotation = eulerangles RX RY RZ )
)
)
)
with redraw off
(
if not ONEmode then OBJ.scale = [SX, SY, SZ]
else OBJ.scale = UniqueScale
)
( -- PLACEMENT
if CollideCHK.checked == true and OverCHK.checked == true then
(--Self COllide
OBJ.pos = POSB --place l'objet en position d'intersection
--choppe toutes les intersections de Bounding box
-- Colliders = for o in theMOD.CopiesLIST where o!=OBJ and isvalidnode o==true and intersects OBJ o == true collect o
-- fn GetColliders OBJ =
-- (
-- for o in theMOD.CopiesLIST where K_ISVALID o and o!=OBJ and intersects OBJ o collect o
-- )
( -- previous Method : avoid the closest object under mouse
( -- Hit on closest Asset
local Closest = hit_nodes[1][1]
local ClosestHIT = hit_nodes[1][3]
)
(-- Avoid
( --get the lower point under 0, and move the asset allong the ray vector by this value
local myRay = mapScreenToWorldRay VP -- make a ray from active viewport
with redraw off
(
local VEC = normalize ( ClosestHIT.dir - myRay.dir )
local TR = copy OBJ.transform
local ViewMAT = matrixfromnormal (normalize VEC)
ViewMAT.row4 = OBJ.pos
OBJ.transform *= inverse ViewMAT
local BB = nodeGetBoundingBox OBJ (matrix3 1)
local MinZ = amin #(BB[1].Z, BB[2].Z)
--
OBJ.transform = TR
move OBJ (VEC * (abs MinZ) )
)
)
--
-- ( --get the lower point under 0, and move the asset allong the ray vector by this value
-- local myRay = mapScreenToWorldRay VP -- make a ray from active viewport
--
-- local VEC = normalize ( ClosestHIT.dir - myRay.dir )
--
--
-- local ViewMAT = matrixfromnormal (normalize VEC)
-- ViewMAT.row4 = OBJ.pos
--
-- local BB = nodeGetBoundingBox OBJ ViewMAT
-- local MinZ = amin #(BB[1].Z, BB[2].Z)
--
--
-- move OBJ (VEC * (abs MinZ) )
-- )
)
)
local viewDIR = -myRay.dir
AvoidNodes OBJ viewDIR theMOD.CollidersLIST
)
else
(
OBJ.pos = POSB
)
if not ONEmode do
( POS = OBJ.pos )
if tempRay != undefined then with redraw off
(
OBJ.pos.Z += PZ --Position
)
if PhysXCHK.checked and CollideCHK.checked and OverCHK.checked and not ONEmode do
(-- Refresh MASSFX modifier
OBJ.modifiers[MassFX_RBody].type = 1
OBJ.modifiers[MassFX_RBody].RBMeshRegenerate 1
)
)
)
)
)
)
if DELmode do --DELETE
(
( -- New detection method using boxPickNode to get the objects under the cursor
objsUnderCursorArr = (boxPickNode (box2 (mouse.pos - [20,20]) (mouse.pos + [20,20])) crossing:true )
if objsUnderCursorArr.count >0 do
(
myRay = mapScreenToWorldRay viewPoint -- make a ray from active viewport
hit_nodes = for n in objsUnderCursorArr where not n.isHidden and not n.isFrozen and finditem theMOD.CollidersLIST n == 0 and finditem tempLIST n != 0 and (tempRay = intersectRay n myRay )!=undefined collect
(
#( n, distance tempRay.pos myRay.pos )
)
fn sortByHitDistance n1 n2 = if n1[2] < n2[2] then -1 else if n1[2] > n2[2] then 1 else 0
qsort hit_nodes sortByHitDistance
if hit_nodes.count > 0 then --Get the closest HIT
(
hitOBJ = hit_nodes[1][1]
/*
delID = finditem TempList hitOBJ
if delID != 0 do
(
deleteItem TempList delID
)
Copies = ( theMOD.CopiesLIST as array )
delID = finditem Copies hitOBJ
if delID != 0 do
(
deleteItem Copies delID
)
theMOD.CopiesLIST = Copies
delID = finditem CurrentCopies hitOBJ
if delID != 0 do
(
deleteItem CurrentCopies delID
)
*/
append DelASSETS hitOBJ
hide hitOBJ
-- delete hitOBJ
)
)
)
)
TheViewPoint = viewpoint
redrawviews()
)
)
)
else if lbutton then -- ?chaque nouveau clic
(
test = "toto"
)
else -- FREE move after 1st clic
(
TheViewPoint = viewpoint
-- nothing happens here
redrawviews()
)
)
on mouseAbort clickno do -- vrai exit
(
ManualExit = true
ToolType = undefined
DisplayVECS false
)
on start do
(
ToolType = "Paint"
DisplayVECS true
with undo off
(
ManualExit = false
)
)
on stop do
(
if ManualExit == false then
(
gc light:true
starttool foo -- restart
)
else -- vrai EXIT
(
with undo off
(
with redraw off
(
ToolType = undefined
DisplayVECS false
fn setStatic Asset =
(
local MFXMOD = Asset.modifiers[MassFX_RBody]
MFXMOD.type = 3
(-- Remove force
MFXMOD.enableGravity = Gravity_BTN.checked
MFXMOD.forcesList = #()
MFXMOD.VelocitySpeed = MFXMOD.SpinSpeed = 0.0
)
Asset.wirecolor = StaticCOLOR
)
if PhysXCHK.checked and CollideCHK.checked then
(
PxCaptureTransform(false)
PxStopSimulation()
for o in CurrentCopies where K_ISVALID o do -- set Assets to static
(
setStatic o
)
)
else
(
for o in CurrentCopies where K_ISVALID o do -- set Assets to static
(
o.wirecolor = StaticCOLOR
)
)
)
)
with undo off
(
with redraw off
(
if K_ISVALID FRC do delete FRC
( displayColor.shaded = #material )
if K_ISVALID theMOD do select theMOD
gc light:true
foo = undefined
)
)
)
)
)
( -- ADD MassFX modifiers
with undo off
( -- Add MassFX on Colliders
with redraw off
(
for o in theMOD.CollidersLIST where K_ISVALID o do
(
if o.modifiers[MassFX_RBody] == undefined do
(
MFX = MassFX_RBody()
addmodifier o ( MFX ) ui:off before:1
MFX.type = 3
MFX.meshType = 5
MFX.bounciness = 0
MFX.staticFriction = 1
MFX.dynamicFriction = 1
MFX.contactShellOverrideGlobals = off
)
)
)
)
with undo off
( -- Add MassFX on SOURCE objects
with redraw off
(
for o in theMOD.SourceLIST do
(
local theMOD = o.modifiers[#K_Hull]
if theMOD == undefined do
(-- K_HULL activation
MakeHULL #(o) VertsCNT
o.modifiers[#K_Hull].Switch_BTN = on
)
if o.modifiers[MassFX_RBody] == undefined do
( -- ADD Mass FX modifier
local MFX = MassFX_RBody()
addmodifier o ( MFX ) ui:off
MFX.meshInflation = -1.0
MFX.type = 3
MFX.meshType = 4
MFX.RBMeshRegenerate 1
MFX.bounciness = 0
MFX.staticFriction = 1
MFX.dynamicFriction = 1
MFX.contactShellOverrideGlobals = off
)
o.wirecolor = StaticCOLOR
( -- Replace all the instances by copies and recalculate Hull : usefull when the user has turned the copies to instances from the PhysX_Painter Attribute holder
NewLIST = #()
InstanceMgr.GetInstances o &instances
Instances = for i in Instances where K_ISVALID i collect i--list of the instances before switch
InstanceMgr.MakeObjectsUnique Instances #individual
for i in instances where i!=o do
(
i.wirecolor = StaticCOLOR
if PhysXCHK.checked == true do i.modifiers[1].RBMeshRegenerate 1
setAppData i 20100805 ( (getHandleByAnim o) as string )
)
)
)
( -- Turn to Low res from the K_Hull modifier
for o in theMOD.CopiesLIST where K_ISVALID o do
(
local theMOD = o.modifiers[#K_Hull]
if theMOD != undefined and theMOD.Switch_BTN == false do
(
theMOD.Switch_BTN = true
)
o.wirecolor = StaticCOLOR
MFX = o.modifiers[MassFX_RBody]
MFX.type = 3
)
theMOD.Hull_CHK = on
)
)
)
)
with undo off
( -- prepare the Assets Percentages
AssetsPercents = #()
RNDITM = random 1 ITM.count
Source = ITM[RNDITM]
Percs = #()
Total = 0.0
AssetsOK = #()
for o=1 to SourceAssets.count where K_ISVALID SourceAssets[o] do
(
P = SourcePerc[o]
Total += P
append AssetsOK SourceAssets[o]
append Percs P
)
RealPercs = #()
for o=1 to Percs.count do
(
P = ( Percs[o]*100 / Total as float ) as integer
append RealPercs P
)
ITM = #()
for o=1 to Percs.count do
(
for i=1 to Percs[o] do
(
append ITM AssetsOK[o]
)
)
Percs = undefined
AssetsOK = undefined
)
if ITM.count > 0 do
(
if UseCOL_CHK.checked do
(
with undo off
displayColor.shaded = #object
)
gc light:true
startTool foo
with undo off
(
if PhysXCHK.checked == true then
(
-- macros.run "PhysX" "PxCaptureCurrXFormMS"
-- macros.run "PhysX" "PxResetSimMS"
PxCaptureTransform(false)
PxStopSimulation()
)
)
)
)
)
)
)
on Drop_BTN pressed do -- DROP
(
if K_ISVALID PhysXPainter_HELPER and LIC do
(
max create mode
theMOD = PhysXPainter_HELPER
if theMOD.SourceLIST.count > 0 and foo==undefined do
(
SIMALL.checked = SIMSEL.checked = false
ITM = for o in SourceAssets where K_ISVALID o collect o
tempLIST = ( theMOD.CopiesLIST as array)
join tempLIST theMOD.CollidersLIST
(
tool foo
(
local test = undefined
local PrevPOS
local PrevRAD
local PrevHeight
local PrevCOUNT
on freeMove do -- FREE
(
TheViewPoint = viewpoint
if K_ISVALID PhysXPainter_HELPER then
with undo off
(
myRay = mapScreenToWorldRay viewPoint -- make a ray from active viewport
if OverCHK.state == false then -- paint only on the ground
(
objsUnderCursorArr = (boxPickNode (box2 (mouse.pos - [2,2]) (mouse.pos + [2,2])) crossing:true )
if objsUnderCursorArr.count >0 do
(
hit_nodes = for n in objsUnderCursorArr where not n.isHidden and not n.isFrozen and finditem theMOD.CollidersLIST n !=0 and (tempRay = intersectRay n myRay )!=undefined collect
(
#( n, distance tempRay.pos myRay.pos, tempRay )
)
fn sortByHitDistance n1 n2 = if n1[2] < n2[2] then -1 else if n1[2] > n2[2] then 1 else 0
qsort hit_nodes sortByHitDistance
if hit_nodes.count > 0 then --Get the closest HIT
(
POS = hit_nodes[1][3].pos
ROT = hit_nodes[1][3].dir
)
)
)
else
(
(
objsUnderCursorArr = (boxPickNode (box2 (mouse.pos - [2,2]) (mouse.pos + [2,2])) crossing:true )
if objsUnderCursorArr.count > 0 do
(
hit_nodes = for n in objsUnderCursorArr where not n.isHidden and not n.isFrozen and finditem tempLIST n !=0 and (tempRay = intersectRay n myRay )!=undefined collect
(
#( n, distance tempRay.pos myRay.pos, tempRay )
)
fn sortByHitDistance n1 n2 = if n1[2] < n2[2] then -1 else if n1[2] > n2[2] then 1 else 0
qsort hit_nodes sortByHitDistance
if hit_nodes.count > 0 then --Get the closest HIT
(
-- select hit_nodes[1][1]
POS = hit_nodes[1][3].pos
ROT = hit_nodes[1][3].dir
)
)
)
)
if POS != undefined then -- define the visual BRUSH MATRIX
(
MAT = matrixfromnormal ROT
MAT.pos = POS
)
else
MAT = undefined
)
redrawviews()
)
on mousePoint clickno do -- 1er CLIC, and each new Clic
(
if clickno == 1 then
(
with undo off
(
TheViewPoint = viewpoint
with redraw off
(
PrevPOS = TheViewPoint
PrevRAD = DropRAD
PrevHeight = DropHEIGHT
PrevCOUNT = DropCount
( -- Get the Transform values from UI
PXA = PXmin.value
PXB = PXmax.value
PYA = PYmin.value
PYB = PYmax.value
PZA = PZmin.value
PZB = PZmax.value
RXA = RXmin.value
RXB = RXmax.value
RYA = RYmin.value
RYB = RYmax.value
RZA = RZmin.value
RZB = RZmax.value
SXA = SXmin.value
if X_CHK.state == true then SXB = SXA else SXB = SXmax.value
SYA = SYmin.value
if Y_CHK.state == true then SYB = SYA else SYB = SYmax.value
SZA = SZmin.value
if Z_CHK.state == true then SZB = SZA else SZB = SZmax.value
if SCl_CHK.state == true then ( SYA = SZA = SXA ; SYB = SZB = SXB )
if POS_CHK.state == true then ( PYA = PZA = PXA ; PYB = PZB = PXB )
if ROT_CHK.state == true then ( RYA = RZA = RXA ; RYB = RZB = RXB )
)
( -- RESET the SIM and set assets STATIC
PxCaptureTransform(false)
PxStopSimulation()
for Cop in CurrentCopies where K_ISVALID Cop do --put already simulated copies to static
(
local MFXMOD = Cop.modifiers[MassFX_RBody]
(-- Remove force
MFXMOD.enableGravity = Gravity_BTN.checked
MFXMOD.forcesList = #()
)
MFXMOD.type = 3
Cop.wirecolor = StaticCOLOR
)
if K_ISVALID FRC do delete FRC
CurrentCopies = #()
)
( -- Create assets
if not ShiftKey and not AltKey and not CtrlKey and MAT != undefined do
(
for POS in DropPoses do
( -- Random Item
local RNDITM = random 1 ITM.count
local Source = ITM[RNDITM]
local OBJ = copy Source ; OBJ.wirecolor = SimCOLOR -- pas en instance sinon soucis avec le calcul du Hull
setAppData OBJ 20100805 ( (getHandleByAnim Source) as string )
( -- Put the New Object in the Arrays
append theMOD.CopiesLIST OBJ
append tempLIST OBJ
append CurrentCopies OBJ
)
(-- SCALE values
SX = random SXA SXB
SY = random SYA SYB
SZ = random SZA SZB
if SCl_CHK.state == true do SY = SZ = SX
OBJ.scale = [SX, SY, SZ]
)
( -- ROTATION
(-- ROT values
RX = random RXA RXB
RY = random RYA RYB
RZ = random RZA RZB
)
in coordsys gimbal OBJ.rotation = eulerangles RX RY RZ
)
(-- Placement on the Brush
OBJ.pos = POS + MAT.pos + [0,0,DropHEIGHT]
)
-- if PhysXCHK.checked and CollideCHK.checked and OverCHK.checked and not shiftKEY do
(-- Refresh MASSFX modifier
local MFXMOD = OBJ.modifiers[MassFX_RBody]
if MFXMOD != undefined do
(
MFXMOD.type = 1
MFXMOD.RBMeshRegenerate 1
if Gravity_BTN.checked and nvpx.gravityObject != undefined then -- Custom Gravity
(
MFXMOD.enableGravity = off -- n'utilise pas la gravity du World
MFXMOD.forcesList = #()
MFXMOD.forcesList = #(nvpx.gravityObject)
)
else
(
MFXMOD.enableGravity = Gravity_BTN.checked
MFXMOD.forcesList = #()
)
)
)
)
)
)
)
)
CurrentCopies = UndoSIMAssets CurrentCopies theMOD
( -- START SIMULATION -- MassFX
if CurrentCopies.count > 0 do
(
nvpx.SetAnimationState(false)
PxRunSimulation()
)
)
)
else
(--#stop
test = undefined
redrawviews()
#stop
)
)
on mouseMove clickno do --quand la sourie bouge ou nouveaux CLIC
(
with undo off
(
if test != undefined then -- si la sourie bouge
(
if not ShiftKey and not AltKey and not CtrlKey then -- PAINT
(
-- TheViewPoint = viewpoint
)
else if ShiftKey and CtrlKey and not AltKey then -- RADIUS
(
DropRAD = PrevRAD + ( viewpoint.X - PrevPOS.X ) / 5.0
if DropRAD <0.0 do DropRAD = 0.0
( -- get assets poses
local ML = DropMaxLEN * (SXA + SXB ) --/ 2.0
DropPoses = PackCircle DropRAD ML DropCount
)
)
else if ShiftKey and not CtrlKey and not AltKey then -- Height
(
DropHEIGHT = PrevHeight - ( viewpoint.Y - PrevPOS.Y ) / 5.0
if DropHEIGHT <0.0 do DropHEIGHT = 0.0
)
else if CtrlKey and not ShiftKey and not AltKey then -- COUNT
(
DropCount = PrevCOUNT - ( ( viewpoint.Y - PrevPOS.Y ) ) as integer
if DropCount < 1 do DropCount = 1
( -- get assets poses
local ML = DropMaxLEN * (SXA + SXB ) --/ 2.0
DropPoses = PackCircle DropRAD ML DropCount
)
)
else if AltKey and not ShiftKey and not CtrlKey do -- Delete
(
TheViewPoint = viewpoint
)
redrawviews()
)
else if lbutton then -- ?chaque nouveau clic
(
test = "toto"
)
else -- FREE move after 1st clic
(
TheViewPoint = viewpoint
-- nothing happens here
redrawviews()
)
)
)
on mouseAbort clickno do -- vrai exit
(
ManualExit = true
ToolType = undefined
DisplayVECS false
)
on start do
( --print "start Drop tool"
ToolType = "Drop"
DisplayVECS true
-- with undo off
(
ManualExit = false
)
)
on stop do
(
if ManualExit == false then
(
gc light:true
starttool foo -- restart
)
else -- vrai EXIT
(
with undo off
(
with redraw off
(
ToolType = undefined
DisplayVECS false
if PhysXCHK.checked == true then
(
PxCaptureTransform(false)
PxStopSimulation()
-- for o in theMOD.SourceLIST do -- delete the MassFX modifier on the Source Meshes
-- (
-- o.wirecolor = StaticCOLOR
-- )
)
for o in CurrentCopies where K_ISVALID o do -- replace copies by instances
(
o.modifiers[MassFX_RBody].type = 3
o.wirecolor = StaticCOLOR
)
displayColor.shaded = #material
if K_ISVALID theMOD do select theMOD
)
)
gc light:true
-- clearUndoBuffer()
foo = undefined
)
)
)
( -- ADD MassFX modifiers
with undo off
( -- Add MassFX on Colliders
with redraw off
(
for o in theMOD.CollidersLIST do
(
if o.modifiers[MassFX_RBody] == undefined do
(
MFX = MassFX_RBody()
addmodifier o ( MFX ) ui:off before:1
MFX.type = 3
MFX.meshType = 5
MFX.bounciness = 0
MFX.staticFriction = 1
MFX.dynamicFriction = 1
MFX.contactShellOverrideGlobals = off
)
)
)
)
with undo off
( -- Add MassFX on SOURCE objects
with redraw off
(
for o in theMOD.SourceLIST do
(
(-- K_HULL activation
if o.modifiers[#K_Hull] == undefined do
MakeHULL #(o) VertsCNT
if o.modifiers[#K_Hull].Switch_BTN == off do
o.modifiers[#K_Hull].Switch_BTN = on
)
if o.modifiers[MassFX_RBody] == undefined do
( -- ADD Mass FX modifier
MFX = MassFX_RBody()
addmodifier o ( MFX ) ui:off
MFX.meshInflation = -1.0
MFX.type = 3
MFX.meshType = 4
MFX.RBMeshRegenerate 1
MFX.bounciness = 0
MFX.staticFriction = 1
MFX.dynamicFriction = 1
MFX.contactShellOverrideGlobals = off
)
o.wirecolor = StaticCOLOR
( -- Replace all the instances by copies and recalculate Hull : usefull when the user has turned the copies to instances from the PhysX_Painter Attribute holder
NewLIST = #()
InstanceMgr.GetInstances o &instances
Instances --list of the instances before switch
InstanceMgr.MakeObjectsUnique Instances #individual
for i in instances where i!=o do
(
i.wirecolor = StaticCOLOR
if PhysXCHK.checked == true do i.modifiers[1].RBMeshRegenerate 1
setAppData i 20100805 ( (getHandleByAnim o) as string )
)
)
)
( -- Turn to Low res from the K_Hull modifier
for o in theMOD.CopiesLIST where K_ISVALID o do
(
local KMOD = o.modifiers[#K_Hull]
if KMOD != undefined and KMOD.Switch_BTN == off do
(
KMOD.Switch_BTN = on
)
o.wirecolor = StaticCOLOR
)
theMOD.Hull_CHK = on
)
)
)
)
with undo off
( -- prepare the Assets Percentages
AssetsPercents = #()
RNDITM = random 1 ITM.count
Source = ITM[RNDITM]
Percs = #()
Total = 0.0
AssetsOK = #()
for o=1 to SourceAssets.count where K_ISVALID SourceAssets[o] do
(
P = SourcePerc[o]
Total += P
append AssetsOK SourceAssets[o]
append Percs P
)
RealPercs = #()
for o=1 to Percs.count do
(
P = ( Percs[o]*100 / Total as float ) as integer
append RealPercs P
)
ITM = #()
for o=1 to Percs.count do
(
for i=1 to Percs[o] do
(
append ITM AssetsOK[o]
)
)
Percs = undefined
AssetsOK = undefined
)
with undo off
( -- get the maximum LENGTH, for asset spacing in the brush Circle
fn getmaxLength OBJ =
(
BB = nodeLocalBoundingBox OBJ
LenA = abs (BB[2].X - BB[1].X )
LenB = abs (BB[2].Y - BB[1].Y )
LenC = abs (BB[2].Z - BB[1].Z )
list = #(LenA, LenB, LenC)
amax list
)
local Lengths = for o=1 to SourceAssets.count where K_ISVALID SourceAssets[o] and SourcePerc[o] > 0.0 collect getmaxLength SourceAssets[o]
DropMaxLEN = ( amax Lengths ) * 0.5
-- DropMaxLEN = 0.0
-- local DropCNT = 0
-- local Lengths = for o=1 to SourceAssets.count where K_ISVALID SourceAssets[o] and SourcePerc[o] > 0.0 do DropMaxLEN += getmaxLength SourceAssets[o] ; DropCNT+=1
-- DropMaxLEN /= DropCNT
)
if ITM.count > 0 do
(
with undo off
(
-- Get Assets Spacing
local ML = DropMaxLEN * (SXA + SXB ) --/ 2.0
DropPoses = PackCircle DropRAD ML DropCount
if UseCOL_CHK.checked do ( displayColor.shaded = #object )
)
startTool foo
with undo off
(
with redraw off
(
PxCaptureTransform(false)
PxStopSimulation()
)
)
)
)
)
)
)
on SIMALL changed state do -- SIM ALL
(
if K_ISVALID PhysXPainter_HELPER and LIC do
(
local theMOD = PhysXPainter_HELPER
if theMOD.CopiesLIST.count > 0 and foo == undefined then
(
SIMSEL.checked = false
max create mode
local ITM = for o in theMOD.CopiesLIST where K_ISVALID o collect o
if state == true then
(
with undo off
(
with redraw off
(
if UseCOL_CHK.checked do ( displayColor.shaded = #object )
( -- ADD missing MassFX modifiers
( -- Add MassFX on Colliders
for o in theMOD.CollidersLIST do
(
if o.modifiers[MassFX_RBody] == undefined do
(
MFX = MassFX_RBody()
addmodifier o ( MFX ) ui:off before:1
MFX.type = 3
MFX.meshType = 5
MFX.bounciness = 0
MFX.staticFriction = 1
MFX.dynamicFriction = 1
MFX.contactShellOverrideGlobals = off
)
)
)
( -- Replace all the instances by copies and recalculate Hull : usefull when the user has turned the copies to instances from the PhysX_Painter Attribute holder
for o in theMOD.SourceLIST do
(
with redraw off
(
InstanceMgr.GetInstances o &instances
Instances --list of the instances before switch
InstanceMgr.MakeObjectsUnique Instances #individual
for i in instances where i!=o do
(
i.wirecolor = StaticCOLOR
if PhysXCHK.checked == true do i.modifiers[1].RBMeshRegenerate 1
setAppData i 20100805 ( (getHandleByAnim o) as string )
)
)
)
)
)
theMOD.Hull_CHK = on
for Cop in ITM do --put MassFX on Copies
(
(-- K_HULL activation
if Cop.modifiers[#K_Hull] == undefined do ( MakeHULL #(Cop) VertsCNT )
if Cop.modifiers[#K_Hull].Switch_BTN == off do
Cop.modifiers[#K_Hull].Switch_BTN = on
)
if Cop.modifiers[MassFX_RBody] == undefined then
(
local MFX = MassFX_RBody()
addmodifier Cop ( MFX ) ui:off
MFX.meshInflation = -1.0
MFX.type = 1
MFX.meshType = 4
MFX.RBMeshRegenerate 1
MFX.bounciness = 0
MFX.staticFriction = 1
MFX.dynamicFriction = 1
MFX.contactShellOverrideGlobals = off
)
else
(
MFX = Cop.modifiers[MassFX_RBody]
MFX.type = 1
MFX.RBMeshRegenerate 1
)
Cop.wirecolor = SimCOLOR
)
if Attract_BTN.checked or Explode_BTN.checked then
( -- Create Attract Gravity
( -- get assets Average Position and MAX distance between them
local AVpos= [0,0,0]
local AVsize = 0.0
for Cop in ITM where K_ISVALID COP do
(
AVpos += Cop.center
BB = nodeLocalBoundingBox Cop ; AVsize += distance BB[1] BB[2]
)
local CNT = ITM.count
AVpos /= CNT
AVsize /= CNT
local MaxDIST = 0.0
local AVdist = 0.0
for Cop in ITM do
(
local DIST = distance AVpos Cop.center
if DIST > MaxDIST do MaxDIST = DIST
AVdist += DIST
)
AVdist /= CNT
)
( -- create a force object
if Attract_BTN.checked do
(
FRC = gravity pos:AVpos isSelected:off iconSize:30.5152 transform:(matrix3 1) gravitytype:1 strength:(PhysXPanelData.gravity * -2.5 * Force_SPN.value )
hide FRC
)
)
local GravityOBJ = nvpx.gravityObject
local UseGravity = Gravity_BTN.checked
local UseAttraction = Attract_BTN.checked
local UseExplode = Explode_BTN.checked
for Cop in ITM do --put MassFX on Copies
(
local MFXMOD = Cop.modifiers[MassFX_RBody]
if MFXMOD != undefined do
(-- ADD force
MFXMOD.forcesList = #()
if UseAttraction then ForceLIST = #(FRC) else ForceLIST = #()
if UseGravity and GravityOBJ != undefined then
(
MFXMOD.enableGravity = off -- n'utilise pas la gravity du World
append ForceLIST GravityOBJ
)
else
(
MFXMOD.enableGravity = UseGravity
)
MFXMOD.forcesList = ForceLIST
if UseExplode do
(
local VEC = Cop.center - (AVpos - [0,0,AVdist])
MFXMOD.InitialVelocityX = VEC.X
MFXMOD.InitialVelocityY = VEC.Y
MFXMOD.InitialVelocityZ = VEC.Z
MFXMOD.InitialSpinX = VEC.X
MFXMOD.InitialSpinY = VEC.Y
MFXMOD.InitialSpinZ = VEC.Z
BB = nodeLocalBoundingBox Cop
local DIST = distance AVpos Cop.center
local DistVAL = 1.0 - ( DIST / MaxDIST )
MFXMOD.VelocitySpeed = 10.0 * ( distance BB[1] BB[2] ) * DistVAL * Force_SPN.value
MFXMOD.SpinSpeed = MFXMOD.VelocitySpeed * 0.7
)
)
)
)
else
(
local GravityOBJ = nvpx.gravityObject
local UseGravity = Gravity_BTN.checked
for Cop in ITM do --put MassFX on Copies
(
local MFXMOD = Cop.modifiers[MassFX_RBody]
if MFXMOD != undefined do
(-- ADD force
if UseGravity and GravityOBJ != undefined then -- Custom Gravity
(
MFXMOD.enableGravity = off -- n'utilise pas la gravity du World
MFXMOD.forcesList = #()
MFXMOD.forcesList = #( GravityOBJ )
)
else
(
MFXMOD.enableGravity = UseGravity
MFXMOD.forcesList = #()
)
)
)
)
)
)
UndoSIMonly ITM theMOD
(-- SIMULATE ------->>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
nvpx.SetAnimationState(false)
PxRunSimulation()
)
)
else
(
with undo off
(
with redraw off
(
PxCaptureTransform(false)
PxStopSimulation()
for o in ITM do
(
local MFXMOD = o.modifiers[MassFX_RBody]
MFXMOD.type = 3
(-- Remove force
MFXMOD.enableGravity = Gravity_BTN.checked
MFXMOD.forcesList = #()
MFXMOD.VelocitySpeed = MFXMOD.SpinSpeed = 0.0
)
o.wirecolor = StaticCOLOR
)
if K_ISVALID FRC do delete FRC
displayColor.shaded = #material
gc light:true
)
)
)
)
else
SIMALL.checked = false
)
)
on SIMSEL changed state do -- SIM SEL
(
max create mode
if K_ISVALID PhysXPainter_HELPER and LIC do
(
local theMOD = PhysXPainter_HELPER
if theMOD.CopiesLIST.count > 0 and foo==undefined then
(
SIMALL.checked = false
max create mode
local Sel = selection as array
max select none
local ITM = for o in Sel where finditem theMOD.CopiesLIST o != 0 collect o
local COPIES = for o in theMOD.CopiesLIST where K_ISVALID o collect o
if state == true then
(
with undo off
(
with redraw off
(
if UseCOL_CHK.checked do ( displayColor.shaded = #object )
( -- ADD missing MassFX modifiers
( -- Add MassFX on Colliders
for o in theMOD.CollidersLIST do
(
if o.modifiers[MassFX_RBody] == undefined do
(
MFX = MassFX_RBody()
addmodifier o ( MFX ) ui:off before:1
MFX.type = 3
MFX.meshType = 5
MFX.bounciness = 0
MFX.staticFriction = 1
MFX.dynamicFriction = 1
MFX.contactShellOverrideGlobals = off
)
)
)
( -- Replace all the instances by copies and recalculate Hull : usefull when the user has turned the copies to instances from the PhysX_Painter Attribute holder
for o in theMOD.SourceLIST do
(
InstanceMgr.GetInstances o &instances
Instances --list of the instances before switch
InstanceMgr.MakeObjectsUnique Instances #individual
for i in instances where i!=o do
(
i.wirecolor = StaticCOLOR
if PhysXCHK.checked == true do i.modifiers[1].RBMeshRegenerate 1
setAppData i 20100805 ( (getHandleByAnim o) as string )
)
)
)
)
theMOD.Hull_CHK = on
for Cop in COPIES do --put MassFX on Copies
(
(-- K_HULL activation
if Cop.modifiers[#K_Hull] == undefined do ( MakeHULL #(Cop) VertsCNT )
if Cop.modifiers[#K_Hull].Switch_BTN == off do
Cop.modifiers[#K_Hull].Switch_BTN = on
)
if Cop.modifiers[MassFX_RBody] == undefined then
(
local MFX = MassFX_RBody()
addmodifier Cop ( MFX ) ui:off
MFX.meshInflation = -1.0
MFX.type = 3
MFX.meshType = 4
MFX.RBMeshRegenerate 1
MFX.bounciness = 0
MFX.staticFriction = 1
MFX.dynamicFriction = 1
MFX.contactShellOverrideGlobals = off
)
else
(
MFX = Cop.modifiers[MassFX_RBody]
MFX.type = 3
MFX.RBMeshRegenerate 1
)
Cop.wirecolor = StaticCOLOR
)
if Attract_BTN.checked or Explode_BTN.checked then
( -- Create Attract Gravity
( -- get assets Average Position and MAX distance between them
local AVpos= [0,0,0]
local AVsize = 0.0
for Cop in ITM do
(
AVpos += Cop.center
BB = nodeLocalBoundingBox Cop ; AVsize += distance BB[1] BB[2]
)
local CNT = ITM.count
AVpos /= CNT
AVsize /= CNT
local MaxDIST = 0.0
local AVdist = 0.0
for Cop in ITM do
(
local DIST = distance AVpos Cop.center
if DIST > MaxDIST do MaxDIST = DIST
AVdist += DIST
)
AVdist /= CNT
)
( -- create a force object
if Attract_BTN.checked then
(
FRC = gravity pos:AVpos isSelected:off iconSize:30.5152 transform:(matrix3 1) gravitytype:1 strength:(PhysXPanelData.gravity * -2.5 * Force_SPN.value )
hide FRC
)
)
local GravityOBJ = nvpx.gravityObject
local UseGravity = Gravity_BTN.checked
local UseAttract = Attract_BTN.checked
local UseExplode = Explode_BTN.checked
for Cop in ITM do --put Force on Active Assets
(
local MFXMOD = Cop.modifiers[MassFX_RBody]
if MFXMOD != undefined do
(-- ADD force
MFXMOD.type = 1
MFXMOD.forcesList = #()
if UseAttract then ForceLIST = #(FRC) else ForceLIST = #()
if UseGravity and GravityOBJ != undefined then
(
MFXMOD.enableGravity = off -- n'utilise pas la gravity du World
append ForceLIST GravityOBJ
)
else
(
MFXMOD.enableGravity = UseGravity
)
MFXMOD.forcesList = ForceLIST
if UseExplode do
(
local VEC = Cop.center - (AVpos - [0,0,AVdist])
MFXMOD.InitialVelocityX = VEC.X
MFXMOD.InitialVelocityY = VEC.Y
MFXMOD.InitialVelocityZ = VEC.Z
MFXMOD.InitialSpinX = VEC.X
MFXMOD.InitialSpinY = VEC.Y
MFXMOD.InitialSpinZ = VEC.Z
BB = nodeLocalBoundingBox Cop
local DIST = distance AVpos Cop.center
local DistVAL = 1.0 - ( DIST / MaxDIST )
MFXMOD.VelocitySpeed = 10.0 * ( distance BB[1] BB[2] ) * DistVAL * Force_SPN.value
MFXMOD.SpinSpeed = MFXMOD.VelocitySpeed * 0.7
)
Cop.wirecolor = SimCOLOR
)
)
)
else
(
local GravityOBJ = nvpx.gravityObject
local UseGravity = Gravity_BTN.checked
for Cop in ITM do --put Force on Active Assets
(
local MFXMOD = Cop.modifiers[MassFX_RBody]
if MFXMOD != undefined do
(-- ADD force
MFXMOD.type = 1
if UseGravity and GravityOBJ != undefined then -- Custom Gravity
(
MFXMOD.enableGravity = off -- n'utilise pas la gravity du World
MFXMOD.forcesList = #()
MFXMOD.forcesList = #( GravityOBJ )
)
else
(
MFXMOD.enableGravity = UseGravity
MFXMOD.forcesList = #()
)
Cop.wirecolor = SimCOLOR
)
)
)
)
)
UndoSIMonly ITM theMOD
( -- SIMULATE ------->>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
-- macros.run "PhysX" "PxPlaySimMS" --SIM
nvpx.SetAnimationState(false)
PxRunSimulation()
)
)
else
(
with undo off
(
with redraw off
(
PxCaptureTransform(false)
PxStopSimulation()
local UseGravity = Gravity_BTN.checked
for o in ITM do
(
local MFXMOD = o.modifiers[MassFX_RBody]
MFXMOD.type = 3
(-- Remove force
MFXMOD.enableGravity = UseGravity
MFXMOD.forcesList = #()
MFXMOD.VelocitySpeed = MFXMOD.SpinSpeed = 0.0
)
o.wirecolor = StaticCOLOR
)
if K_ISVALID FRC do delete FRC
displayColor.shaded = #material
select ITM
gc light:true
)
)
)
)
else
SIMSEL.checked = false
)
)
on Force_SPN changed state do
(
if K_ISVALID PhysXPainter_HELPER and LIC do
(
if K_ISVALID FRC do
(
FRC.strength = (PhysXPanelData.gravity * -2.5 * Force_SPN.value )
)
)
)
on Save_BTN pressed do --SAVE Preset
(
if SaveName_EDT.text != "" and LIC then
(
if LoadPath != undefined do
(
fichier = ("/" + SaveName_EDT.text+".phxp")
out_file = ( LoadPath + fichier )
fn SavePreset out_file =
(
( -- Save Preset XML file
local xmlDoc = dotNetObject "system.xml.xmlDocument"
local root = xmlDoc.createElement "Root"
xmlDoc.appendChild root
(
local Brush_XML = xmlDoc.createElement "BrushParameters"
Brush_XML.setAttribute "DistSPN" ( DistSPN.value as string )
Brush_XML.setAttribute "OverCHK" ( OverCHK.state as string )
Brush_XML.setAttribute "CollideCHK" ( CollideCHK.state as string )
Brush_XML.setAttribute "PhysXCHK" ( PhysXCHK.state as string )
local SpinnerLIST = #(PXmin, PXmax, PYmin, PYmax, PZmin, PZmax, RXmin, RXmax, RYmin, RYmax, RZmin, RZmax, SXmin, SXmax, SYmin, SYmax, SZmin, SZmax)
for n in SpinnerLIST do
(
Brush_XML.setAttribute (n.name) (n.value as string )
)
local CheckBoxLIST = #(X_CHK, Y_CHK, Z_CHK, SCl_CHK, POS_CHK, ROT_CHK, Normal_BTN, Direct_BTN, Gravity_BTN, Attract_BTN, Explode_BTN)
for n in CheckBoxLIST do
(
Brush_XML.setAttribute (n.name) (n.state as string )
)
root.appendChild Brush_XML
)
xmlDoc.Save out_file
)
--update list
(
files = getFiles (LoadPath + "\\*.phxp")
presetLIST = #()
for f in files do
(
Filename = getFilenameFile f
append presetLIST Filename
)
Load_LIST.items = presetLIST
-- Load_LIST.selected = SaveName_EDT.text
Load_LIST.selection = finditem presetLIST (SaveName_EDT.text)
)
)
fn existFile fname = (getfiles fname).count != 0
if existFile out_file == true then
(
-- messageBox "Existing File"
if queryBox "This File exists,\n\nDo you want to replace it ?" beep:false then
(
SavePreset out_file
)
)
else
(
SavePreset out_file
)
)
)
else
(
text1 = "enter a name"
messagebox text1
)
)
on Folder_BTN pressed do
(
if LoadPath == undefined do LoadPath = "$archives"
LoadPath = getSavePath caption:"choose a preset Folder" initialDir:LoadPath
if LoadPath != undefined and LIC do
(
files = getFiles (LoadPath + "\\*.phxp")
presetLIST = #()
for f in files do
(
Filename = getFilenameFile f
append presetLIST Filename
)
Load_LIST.items = presetLIST
INIfile = ( getdir #plugcfg_ln ) + "\\KinematicLAB_PhysXPainterPreset.ini"
setINISetting INIfile "PhysXPainter" "PresetFolder" LoadPath forceUTF16:false --force ASCII
)
--
)
on Load_LIST selected i do
(
if LoadPath != undefined and LIC do
(
FileName = Load_LIST.items[i]
SaveName_EDT.text = FileName
local F = (LoadPath + "\\" + FileName + ".phxp" )
( -- Load and Apply values from XML
local xmlDoc = dotNetObject "system.xml.xmlDocument"
xmlDoc.load F
local docEle = xmlDoc.documentElement
local Brush_XML = docEle.ChildNodes.itemOf[0].attributes
local ParamsCNT = Brush_XML.Count
for o=0 to ParamsCNT-1 do
(
local ITEM = Brush_XML.ItemOf[o]
local N = ITEM.Name
local val = ITEM.Value
local valTYPE = classof (execute val)
if valTYPE == Float then
execute ("PhysXPainterROL.theSubRollout.rollouts[2]." + N + ".value = " + val)
else
execute ("PhysXPainterROL.theSubRollout.rollouts[2]." + N + ".state = " + val)
)
)
if X_CHK.state == true then
( SXmax.enabled = false )
else
( SXmax.enabled = true )
if Y_CHK.state == true then
( SYmax.enabled = false )
else
( SYmax.enabled = true )
if Z_CHK.state == true then
( SZmax.enabled = false )
else
( SZmax.enabled = true )
if SCl_CHK.state == true then
(
SXmin.enabled = true
SXmax.enabled = true
SYmin.enabled = false
SYmax.enabled = false
SZmin.enabled = false
SZmax.enabled = false
)
else
(
SXmin.enabled = true
SXmax.enabled = true
SYmin.enabled = true
SYmax.enabled = true
SZmin.enabled = true
SZmax.enabled = true
)
if POS_CHK.state == true then
(
PXmin.enabled = true
PXmax.enabled = true
PYmin.enabled = false
PYmax.enabled = false
PZmin.enabled = false
PZmax.enabled = false
)
else
(
PXmin.enabled = true
PXmax.enabled = true
PYmin.enabled = true
PYmax.enabled = true
PZmin.enabled = true
PZmax.enabled = true
)
if ROT_CHK.state == true then
(
RXmin.enabled = true
RXmax.enabled = true
RYmin.enabled = false
RYmax.enabled = false
RZmin.enabled = false
RZmax.enabled = false
)
else
(
RXmin.enabled = true
RXmax.enabled = true
RYmin.enabled = true
RYmax.enabled = true
RZmin.enabled = true
RZmax.enabled = true
)
)
)
on Reset_BTN pressed do
(
if LIC do
(
DistSPN.value = 1.0 ; DIST = 100.0
OverCHK.checked = CollideCHK.checked = PhysXCHK.checked = CollideCHK.enabled = PhysXCHK.enabled = Over = Collide = PhysX = true
StaticCOL.color = StaticCOLOR = color 30 30 30
SimCOL.color = SimCOLOR = green
( -- transforms settings
local SpinnerLIST = #(PXmin, PXmax, PYmin, PYmax, PZmin, PZmax, RXmin, RXmax, RYmin, RYmax, RZmin, RZmax)
for S in SpinnerLIST do S.value = 0.0
local SpinnerLIST = #( SXmin, SXmax, SYmin, SYmax, SZmin, SZmax)
for S in SpinnerLIST do S.value = 1.0
SCl_CHK.checked = true
POS_CHK.checked = true
ROT_CHK.checked = true
local SpinnerLIST = #(PYmin, PYmax, PZmin, PZmax, RYmin, RYmax, RZmin, RZmax, SYmin, SYmax, SZmin, SZmax)
for S in SpinnerLIST do S.enabled = false
local SpinnerLIST = #(PXmin, PXmax, RXmin, RXmax, SXmin, SXmax)
for S in SpinnerLIST do S.enabled = true
X_CHK.checked = LX = false
Y_CHK.checked = LY = false
Z_CHK.checked = LZ = false
)
Normal_BTN.checked = Direct_BTN.checked = false
Gravity_BTN.checked = true
Attract_BTN.checked = Explode_BTN.checked = false
SIMALL.checked = SIMSEL.checked = false
Force_SPN.value = 1.0
)
)
)
rollout VFBTabsRollout03 "Physics"
(
group "Gravity"
(
pickbutton Gravity_BTN "pick Custom Gravity" width:210 align:#left across:2
button DelGravity_BTN "X" width:20 align:#right
spinner Gravity_SPN "Acceleration:" range:[-100000000.0,100000000.0, 1000.0] align:#right width:100
)
group "Ground"
(
checkbox Ground_CHK "Use Ground Collisions" across:2
spinner Ground_Height "Height" range:[-10000000.0, 100000000.0, 0.0] type:#float width:80 align:#left offset:[30,0]
-- button Ground_BTN "Set Ground\nproperties" width:100 height:40 pos:[145,50]
)
spinner ContactDIST_SPN "Contact Distance : " range:[-10000.0, 10000.0, 0.1] type:#float width:140 offset:[0,10] align:#right
button OpenMassFX_BTN "Open MassFX Tools" width:230 height:30 align:#left tooltip:"some parameters can't be changed outside\nof the MassFX UI.\nYou can access it from here"
fn updateGravityValue VAL =
(
px_sdk_gravityx = 0
px_sdk_gravityy = 0
px_sdk_gravityz = 0
px_sdk_gravityz = VAL
-- if nvpx.gravityMode == #directional then
-- (
-- px_sdk_gravityz = VAL
-- )
-- else if (nvpx.gravityMode == #object) and (nvpx.gravityObject != undefined) then
-- (
-- local gravityDir = nvpx.gravityObject.strength*nvpx.gravityObject.transform.row3
-- px_sdk_gravityx = gravityDir.x
-- px_sdk_gravityy = gravityDir.y
-- px_sdk_gravityz = gravityDir.z
-- )
px_sdk_enable_gravity = physXpaneldata.enableGravity
PxUpdateGravity()
)
on VFBTabsRollout03 open do
(
if LIC do
(
if K_ISVALID PhysXPainter_HELPER and nvpx.gravityObject != undefined then
(
-- CustomGravity = PhysXPainter_HELPER.CustomGravity
Gravity_BTN.text = "Gravity : " + nvpx.gravityObject.name
Gravity_SPN.value = (nvpx.gravityObject).strength
)
else
(
Gravity_BTN.text = "pick Custom Gravity"
Gravity_SPN.value = px_sdk_gravityz
)
ContactDIST_SPN.value = px_sdk_contactDistance
( -- Ground settings
Ground_CHK.state = gPxUseGround
Ground_Height.value = gPxGroundHeight
)
)
PhysXPainterROL.height = 270
)
on Gravity_BTN picked o do
(
if classof o == Gravity and LIC then
(
-- CustomGravity = o
Gravity_BTN.text = "Gravity : " + o.name
Gravity_SPN.value = o.strength
-- if K_ISVALID PhysXPainter_HELPER do
-- ( PhysXPainter_HELPER.CustomGravity = CustomGravity )
-- PxSetProperty nvpx #gravityMode #object
PxSetProperty nvpx #gravityMode #directional
PxSetProperty nvpx #gravityObject o
px_sdk_gravityDirection = 3
-- px_sdk_gravityz = -981.0
updateGravityValue -981.0
)
)
on Gravity_SPN changed state do
(
if nvpx.gravityObject != undefined then
(
(nvpx.gravityObject).strength = state
)
else
(
updateGravityValue state
)
)
on DelGravity_BTN pressed do
(
if LIC do
(
-- CustomGravity = undefined
Gravity_BTN.text = "pick Custom Gravity"
-- if K_ISVALID PhysXPainter_HELPER do
-- ( PhysXPainter_HELPER.CustomGravity = undefined )
PxSetProperty nvpx #gravityMode #directional
PxSetProperty nvpx #gravityObject undefined
px_sdk_gravityDirection = 3
-- px_sdk_gravityz = -981.0
-- px_sdk_gravityx = 0.0
-- px_sdk_gravityy = 0.0
updateGravityValue -981.0
Gravity_SPN.value = -981.0
)
)
on Ground_CHK changed state do
(
gPxUseGround = state
)
on Ground_Height changed state do
(
gPxGroundHeight = state
)
on ContactDIST_SPN changed state do
(
px_sdk_contactDistance = state
)
on OpenMassFX_BTN pressed do
(
if LIC do ( macros.run "PhysX" "PxShowToolsWindowMS" )
)
)
rollout InfoRollout "Info"
(
label LicenceLAB "PhysX Painter 2.0 \n\nauthor : Clovis GAY\n\n?KinematicLAB 2021 \n\nwww.kinematiclab.com " height:100 width:165 align:#left
)
PhysXPainter_Rollouts = #(
#(" Source Objects ",#(VFBTabsRollout01)),
#(" Brush Options ",#(VFBTabsRollout02)),
#(" Physics ",#(VFBTabsRollout03))
)
rollout PhysXPainterROL "PhysX Painter"
(
dotNetControl dn_tabs "System.Windows.Forms.TabControl" height:20 width:420 align:#left
subRollout theSubRollout width:270 height:650 align:#center
on dn_tabs Selected itm do
(
if LastSubRollout != (itm.TabPageIndex+1) do --do not update if the same tab clicked twice
(
for subroll in PhysXPainter_Rollouts[LastSubRollout][2] do
removeSubRollout theSubRollout subroll
for subroll in PhysXPainter_Rollouts[LastSubRollout = itm.TabPageIndex+1][2] do
addSubRollout theSubRollout subroll
)
)--end tabs clicked
on PhysXPainterROL open do
(
local sel = selection as Array
if sel.count == 1 and classof sel[1] == PhysXPainter then
(
PhysXPainter_HELPER = sel[1]
LIC = PhysXPainter_HELPER.LIC
LIC = true
if LIC then
(
( -- ROL position
local RolPOS = PhysXPainter_HELPER.UIpos
if RolPOS != [0,0,0] do
(
SetDialogPos PhysXPainterROL [RolPOS.X, RolPOS.Y]
)
)
-- if K_ISVALID PhysXPainter_HELPER.CustomGravity do
-- CustomGravity = PhysXPainter_HELPER.CustomGravity
addSubRollout theSubRollout InfoRollout rolledUp:true
for aTab in PhysXPainter_Rollouts do
(
dn_tabs.TabPages.add aTab[1]
)
for subroll in PhysXPainter_Rollouts[1][2] do
addSubRollout theSubRollout subroll
SetMassFX() -- set massfx properties only if they are wrong
)
)
)
on PhysXPainterROL close do
(
if K_ISVALID PhysXPainter_HELPER and LIC do
(
local RolPOS = (GetDialogPos PhysXPainterROL )
PhysXPainter_HELPER.UIpos = [RolPOS.X, RolPOS.Y, 0]
)
)
)
createDialog PhysXPainterROL 270 490
clearlistener()
)