-- 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 ) ) ) )