230 lines
7.0 KiB
Plaintext
Executable File
230 lines
7.0 KiB
Plaintext
Executable File
-- Cloth manipulator
|
|
-- Written by Kevin Rose
|
|
|
|
-- This "manipulator" doesn't actually manipulate anything, it is just a way
|
|
-- to view the cloth values on each vertex
|
|
filein "pipeline/helpers/cloth_helpers.ms"
|
|
filein "pipeline/util/drawablelod.ms"
|
|
filein "pipeline/helpers/models/BoundingBox.ms"
|
|
|
|
plugin simpleManipulator clothManip
|
|
name:"ClothManip"
|
|
invisible:true
|
|
(
|
|
local iDataChannel
|
|
|
|
on canManipulateNode thenode do
|
|
(
|
|
if( undefined==RAGEClothEditorFloater or not RAGEClothEditorFloater.open ) then
|
|
(
|
|
print("Open the cloth editor to view values")
|
|
return false
|
|
)
|
|
if not ((classof thenode.baseObject == Editable_Mesh) or (classof thenode.baseObject == Editable_Poly)) then
|
|
(
|
|
-- print (thenode as string+" is not a valid baseobject "+(classof thenode.baseObject) as string)
|
|
return false
|
|
)
|
|
|
|
|
|
local msg = "No error"
|
|
if undefined==GetValidObjectSelection msg:&msg then
|
|
(
|
|
return false
|
|
)
|
|
|
|
return true
|
|
)
|
|
|
|
-- Create the manipulator gizmo.
|
|
-- This is called initially and whenever the manipulator target changes
|
|
on updateGizmos do
|
|
(
|
|
-- Clear the current gizmo cache
|
|
this.clearGizmos()
|
|
if( RAGEClothEditorFloater.open == false ) then
|
|
(
|
|
print ("Open the cloth editor to view values")
|
|
return false
|
|
)
|
|
|
|
-- print("iSelectedChannel = "+ (iSelectedChannel as string))
|
|
local iSelectedChannel = ::RageClothChannelDisplay.channelDrop.selection
|
|
if(iSelectedChannel == -1) then
|
|
(
|
|
return false
|
|
)
|
|
iDataChannel = RsGetClothTuningChannel iSelectedChannel
|
|
|
|
-- Get number of verts
|
|
iNumOfVerts = getNumVerts target
|
|
local flags = 0 --gizmoUseScreenSpace
|
|
|
|
|
|
local interfaze = RsMeshPolyOp target
|
|
local selverts = #{}
|
|
if polyop==interfaze then
|
|
selverts = interfaze.GetVertselection target
|
|
else
|
|
selverts = getVertSelection target
|
|
|
|
-- Clear the current gizmo cache
|
|
this.clearGizmos()
|
|
local mappingDistManip = (iSelectedChannel == 8)
|
|
for i = 1 to iNumOfVerts do
|
|
(
|
|
local vertPos = (interfaze.getVert target i) * (inverse target.transform)
|
|
if ( interfaze.getVDataChannelSupport target iDataChannel ) then
|
|
(
|
|
-- Get value
|
|
fPinValue = interfaze.getVDataValue target iDataChannel i
|
|
|
|
-- Calc color
|
|
fR = 0.0
|
|
fB = 0.0
|
|
if(fPinValue < 0.5) then
|
|
(
|
|
fR = fPinValue * 2.0
|
|
fB = 1.0
|
|
)
|
|
else
|
|
(
|
|
fR = 1.0
|
|
fB = 1.0 - ((fPinValue - 0.5) * 2.0)
|
|
)
|
|
|
|
-- Add point
|
|
case of
|
|
(
|
|
mappingDistManip:
|
|
(
|
|
-- Set the radius of circle gizmo a little bigger than thetarget radius
|
|
-- local dummyPoint = gw.wTransPoint (vertPos + [fPinValue,0,0])
|
|
-- local screenvertPos = gw.wTransPoint vertPos
|
|
-- dummyPoint -= screenvertPos
|
|
-- giz = manip.makeCircle screenvertPos (dummyPoint.x) 28
|
|
|
|
local tempFlags = flags
|
|
|
|
if ::RageClothChannelDisplay.chckShowOnlySel.checked and not selverts[i] then
|
|
(
|
|
fPinValue = 0.0
|
|
tempFlags = gizmoDontHitTest
|
|
)
|
|
|
|
giz = manip.makeCircle vertPos fPinValue 28
|
|
|
|
-- Add the circle to the manipulator
|
|
this.addGizmoShape giz flags white black
|
|
)
|
|
default:
|
|
(
|
|
if not ::RageClothChannelDisplay.chckShowOnlySel.checked or selverts[i] then
|
|
-- Add text
|
|
(
|
|
this.addGizmoText (fPinValue as string) vertPos flags [0,fR,fB] [0,fR,fB]
|
|
this.addGizmoMarker #smallCircle vertPos flags [0,fR,fB] [0,fR,fB]
|
|
)
|
|
)
|
|
)
|
|
)
|
|
else if not mappingDistManip then
|
|
(
|
|
this.addGizmoText "n/a" vertPos flags [1,1,1] [1,1,1]
|
|
this.addGizmoMarker #smallCircle vertPos flags [1,1,1] [1,1,1]
|
|
)
|
|
)
|
|
|
|
local renderMesh = RsLodDrawable_GetRenderModel target
|
|
if mappingDistManip and undefined!=renderMesh then
|
|
(
|
|
local renderMeshInterfaze = RsMeshPolyOp renderMesh
|
|
local affectedVerts = GetAffectedVerts target renderMesh onlySelectedVerts:true
|
|
for vi in (affectedVerts as array) do
|
|
(
|
|
local vertPos = renderMeshInterfaze.getVert renderMesh vi
|
|
this.addGizmoMarker #smallCircle vertPos flags [0,1,0] [0,1,0]
|
|
)
|
|
)
|
|
|
|
-- add visual link to render/simulation mesh link
|
|
-- check for existing maxscripts
|
|
local renderLink = RageClothChannelDisplay.chckRenderMeshDebugDraw.state
|
|
if false -- (renderLink and (getFiles ((GetDir #scripts)+"pipeline/util/drawablelod.ms")).count>0)
|
|
then
|
|
(
|
|
local simOrRenderMesh = RageClothChannelTuning.curObjSel
|
|
if undefined!=simOrRenderMesh then
|
|
(
|
|
local connectedMesh = RsLodDrawable_GetRenderModel simOrRenderMesh
|
|
if undefined==connectedMesh then connectedMesh = RsLodDrawable_GetSimulationModel simOrRenderMesh
|
|
if undefined!=connectedMesh then
|
|
(
|
|
local thecoodsys = (matrix3 1)--(inverse (getViewTM()))
|
|
local bbs = #()
|
|
local posDiffs = #()
|
|
append bbs (nodeGetBoundingBox simOrRenderMesh thecoodsys)
|
|
append bbs (nodeGetBoundingBox connectedMesh thecoodsys)
|
|
append posDiffs (bbs[1][1] - simOrRenderMesh.pos)
|
|
append posDiffs (bbs[2][1] - simOrRenderMesh.pos)
|
|
local colour = [0,1,0]--random (color 0 0 0) (color 1 1 1)
|
|
for bbi=1 to bbs.count do
|
|
(
|
|
bb = bbs[bbi]
|
|
posDiff = posDiffs[bbi]
|
|
local offset = RageClothChannelDisplay.spnRenderMeshDebugDrawOffset.value
|
|
local offsetPoint = (point3 offset offset offset)
|
|
bb[1] = bb[1] - offsetPoint
|
|
bb[2] = bb[2] + offsetPoint
|
|
local diff = bb[2] - bb[1]
|
|
posDiff = posDiff + (diff/2) - offsetPoint
|
|
local boundbox = manip.makeBox posDiff diff.y diff.x diff.z 1 1 1
|
|
local nodeXForm = (inverse node.transform)
|
|
nodeXForm.translation = [0,0,0]
|
|
for vi=1 to boundbox.verts.count do
|
|
(
|
|
local v = getvert boundbox vi
|
|
v = v * nodeXForm
|
|
setvert boundbox vi v
|
|
)
|
|
this.addGizmoMesh boundbox 0 colour colour
|
|
)
|
|
)
|
|
)
|
|
)
|
|
-- return the ToolTip string
|
|
return node.name
|
|
)
|
|
|
|
on mouseMove m which do
|
|
(
|
|
if undefined==iDataChannel then
|
|
return false
|
|
local interfaze = RsMeshPolyOp target
|
|
if (iDataChannel == 17) and (interfaze.getnumverts target)>which then
|
|
(
|
|
-- Create the XY plane.
|
|
-- manip.makePlaneFromNormal takes a normal vector and a point
|
|
-- and creates a plane passing through the point with the given normal
|
|
local obj = target --RageClothChannelTuning.curObjSel
|
|
which += 1
|
|
local vertPos = (interfaze.getvert obj which) * (inverse target.transform)
|
|
if undefined==vertPos then
|
|
return false
|
|
local pl = manip.makePlaneFromNormal z_axis vertPos,
|
|
projectedPoint = [0,0,0]
|
|
-- Compute the hit-ray in local coordinates
|
|
viewRay = this.getLocalViewRay m
|
|
-- Intersect the plane with the view ray
|
|
res = pl.intersect viewRay &projectedPoint
|
|
-- If the intersection worked, set the radius
|
|
local dist = length (vertPos - projectedPoint)
|
|
if (res) then
|
|
(
|
|
--target.radius = (length projectedPoint) / 1.01
|
|
SetChannelValue obj iDataChannel which dist
|
|
)
|
|
)
|
|
)
|
|
)
|