home *** CD-ROM | disk | FTP | other *** search
/ GameStar Special 2002 April / GSSH42002.iso / EDITOREN / DS / gmax / gmaxinst_1-1.exe / gmaxsetup11.cab / uvwmanip.ms < prev    next >
Text File  |  2002-02-13  |  21KB  |  682 lines

  1. -- UVW Mapping modifier manipulator
  2.  
  3. -- This file implements manipulators for the width, length and height of the
  4. -- UVW mapping as well as U Tile and V Tile.
  5.  
  6. -- Written by Scott Morrison, July 26, 2000
  7.  
  8. Struct uvwManipUtils (
  9.   
  10.     -- Compute the transform matrix for the mapping gizmo.  This maps gizmo space
  11.     -- into the local coordinate space for the modifier.  In gizmo space,
  12.     -- the gizmo extends from -1 to 1 in x and y.
  13.  
  14.     function gizmoMatrix UVWMod  = 
  15.     (
  16.         local tm = UVWMod.gizmo.transform
  17.     
  18.         -- Rotate the frame for each mapping type.  This step is black magic
  19.         -- copied from MaxSDK/Samples/Modifier/MapMod.cpp.
  20.         case UVWMod.mapType of 
  21.         (
  22.              0: tm = preRotateZ tm 180
  23.              1: tm = preRotateZ tm  90
  24.              2: tm = preRotateZ tm  90
  25.              4: tm = preRotateZ tm 180
  26.         )
  27.     
  28.         -- Compensate for the specified axis of projection
  29.         case UVWMod.axis of
  30.         (
  31.              0: tm = preRotateY tm -90
  32.              1: tm = preRotateX tm  90
  33.         )
  34.     
  35.         -- Scale by the width, length and height of the mapper
  36.         local s = [UVWMod.width, UVWMod.length, UVWMod.height]
  37.     
  38.         case UVWMod.mapType of 
  39.         (
  40.              0: (s.x = s.x * 0.5; s.y = s.y * 0.5)
  41.              1: (s.x = s.x * 0.5; s.y = s.y * 0.5)
  42.              2: s = s * 0.5
  43.              4: s = s * 0.5
  44.         )
  45.         
  46.         tm = preScale tm s
  47.     
  48.         return tm
  49.     ),
  50.     
  51.     -- return the axis of the UVW Mapping gizmo
  52.     
  53.     function gizmoAxis UVWMod =
  54.     (
  55.         case UVWMod.axis of
  56.         (
  57.              0: return x_axis
  58.              1: return y_axis
  59.              2: return z_axis
  60.         )
  61.     
  62.         return z_axis
  63.     ),
  64.     
  65.     -- Project the given screen coordinate to the gizmo plane.
  66.     -- returns 2 values: a flag saying whether the pojection worked,
  67.     -- and the projected point
  68.     
  69.     function projectPointToGizmo this m UVWMod gizmoTM =
  70.     (
  71.         local axis = uvwManipUtils.makeGizmoAxis gizmoTM
  72.     
  73.         -- Create the plane that the gizmo lies on
  74.         local pl = manip.makePlaneFromNormal axis ([0, 0, 0] * gizmoTM)
  75.               projectedPoint = [0,0,0]
  76.     
  77.         -- Compute the hit-ray in local coordinates
  78.         local viewRay = this.getLocalViewRay m
  79.     
  80.         -- Intersect the plane with the view ray
  81.         local res = pl.intersect viewRay &projectedPoint
  82.     
  83.         return #(res, projectedPoint)
  84.     ),
  85.     
  86.     -- Returns true if the given UVWMapper uses a gizmo
  87.     
  88.     function usesGizmo UVWMod =
  89.     (
  90.         local mapType = UVWMod.mapType
  91.         return mapType == 0 or mapType == 1 or mapType == 2 or mapType == 4
  92.     ),
  93.  
  94.     -- Compute the normal of the projection axis
  95.     function makeGizmoAxis gizmoTM = 
  96.     (
  97.         local p0 = [-1.0, -1.0, 0.0] * gizmoTM,
  98.               p1 = [ 1.0, -1.0, 0.0] * gizmoTM,
  99.               p2 = [ 1.0,  1.0, 0.0] * gizmoTM
  100.         local d1 = p2 - p1
  101.         local d2 = p2 - p0
  102.         return cross d1 d2
  103.     ),
  104.     
  105.     -- Create a cube gizmo with the given posistion and size
  106.     
  107.     function makeCubeGizmo pos size =
  108.     (
  109.         local giz = manip.makeGizmoShape()
  110.         local halfSize = size / 2
  111.     
  112.         -- The corners of the cube
  113.         local p000 = pos + [ halfSize,  halfSize,  halfSize]
  114.         local p001 = pos + [ halfSize,  halfSize, -halfSize]
  115.         local p010 = pos + [ halfSize, -halfSize,  halfSize]
  116.         local p011 = pos + [ halfSize, -halfSize, -halfSize]
  117.         local p100 = pos + [-halfSize,  halfSize,  halfSize]
  118.         local p101 = pos + [-halfSize,  halfSize, -halfSize]
  119.         local p110 = pos + [-halfSize, -halfSize,  halfSize]
  120.         local p111 = pos + [-halfSize, -halfSize, -halfSize]
  121.     
  122.         -- Create the top of the box
  123.         giz.AddPoint(p000)
  124.         giz.AddPoint(p010)
  125.         giz.AddPoint(p011)
  126.         giz.AddPoint(p001)
  127.         giz.AddPoint(p000)
  128.     
  129.         -- Create the bottom of the box
  130.         giz.startNewLine()
  131.         giz.AddPoint(p100)
  132.         giz.AddPoint(p110)
  133.         giz.AddPoint(p111)
  134.         giz.AddPoint(p101)
  135.         giz.AddPoint(p100)
  136.     
  137.         -- Create the struts
  138.         giz.startNewLine()
  139.         giz.AddPoint(p000)
  140.         giz.AddPoint(p100)
  141.     
  142.         giz.startNewLine()
  143.         giz.AddPoint(p010)
  144.         giz.AddPoint(p110)
  145.     
  146.         giz.startNewLine()
  147.         giz.AddPoint(p011)
  148.         giz.AddPoint(p111)
  149.     
  150.         giz.startNewLine()
  151.         giz.AddPoint(p001)
  152.         giz.AddPoint(p101)
  153.     
  154.         return giz    
  155.     ),
  156.     
  157.     -- return a number in the range -1 .. 2 for the value of map tiling
  158.     -- This uses logarithmic scaling
  159.     function relativeValue val = 
  160.     (
  161.         local relVal = (5 + (log (val/20))) / 5
  162.     
  163.         -- Clamp the value
  164.         if relVal < -1 then relVal = -1
  165.         if relVal > 2 then relVal = 2
  166.     
  167.         return relVal
  168.     ),
  169.     
  170.     -- Invert the formula from above
  171.     function inverseRelativeValue relVal = 
  172.     (
  173.         relVal = exp((relVal * 5) - 5) * 20
  174.     
  175.         return relVal
  176.     )
  177.  
  178. )  -- uvwManipUtils
  179.  
  180.  
  181. plugin simpleManipulator uvwMappingWidthManip
  182.     name:"UVW Width Manip"
  183.     invisible:true
  184. (
  185.     -- Set the green and red colors for the gizmo
  186.     local greenColor =  colorMan.getColor #manipulatorsActive
  187.     local redColor =    colorMan.getColor #manipulatorsSelected
  188.  
  189.     -- Some useful transforms
  190.     local gizmoTM, inverseGizmoTM
  191.  
  192.     -- This manipualtor manipulates any UVWMapping modifier
  193.     on canManipulate target do
  194.     (
  195.         return (classOf target) == UVWMap
  196.     )
  197.  
  198.     -- Create the manipulator gizmo.
  199.     -- This is called initially and whenver the manipulator target changes
  200.     on updateGizmos do
  201.     (
  202.         -- Clear the current gizmo cache
  203.         this.clearGizmos()
  204.  
  205.         -- Initialize our transforms
  206.         gizmoTM = uvwManipUtils.gizmoMatrix target 
  207.  
  208.         local modTM = getModContextTM node target
  209.         -- check to see if modifier is in a valid state
  210.         if (modTM == undefined) then return ""
  211.         modTM = inverse modTM
  212.  
  213.         gizmoTM = gizmoTM * modTM
  214.  
  215.         inverseGizmoTM = inverse gizmoTM
  216.  
  217.         if uvwManipUtils.usesGizmo target then
  218.         (
  219.     
  220.             local p0 = [-1.0, -1.0, 0.0],
  221.                   p1 = [ 1.0, -1.0, 0.0],
  222.                   p2 = [ 1.0,  1.0, 0.0],
  223.                   p3 = [-1.0,  1.0, 0.0]
  224.             
  225.             local giz = manip.makeGizmoShape()
  226.     
  227.             -- Gizmo 0 - width
  228.             giz.AddPoint p1
  229.             giz.AddPoint p2
  230.             giz.transform gizmoTM
  231.             this.addGizmoShape giz 0 greenColor redColor
  232.     
  233.             giz = manip.makeGizmoShape()
  234.     
  235.             -- Gizmo 1 - width
  236.             giz.AddPoint p3
  237.             giz.AddPoint p0
  238.             giz.transform gizmoTM
  239.           
  240.             this.addGizmoShape giz 0 greenColor redColor
  241.     
  242.             return node.name + " UVW Width: " + (target.width as string)
  243.        ) else return ""
  244.     )
  245.  
  246.    -- Compute the shift to compensate for changing the width
  247.    -- but leaving the other side fixed
  248.    function getShiftVector target shift =
  249.    (
  250.        if target.mapType == 1 or target.mapType == 2 then 
  251.        (
  252.            case target.axis of 
  253.            (
  254.                0: return [0, 0, shift/2]
  255.                1: return [0, shift/2, 0]
  256.                2: return [0, shift/2, 0]
  257.            )
  258.        )
  259.        else
  260.        (
  261.            case target.axis of
  262.            (
  263.                0: return [0, 0,  shift/2]
  264.                1: return [-shift/2, 0, 0]
  265.                2: return [-shift/2, 0, 0]
  266.            )
  267.        )
  268.    )
  269.  
  270.     on mouseMove m which do
  271.     (
  272.         local l = uvwManipUtils.projectPointToGizmo this m target gizmoTM
  273.  
  274.         -- If the intersection worked, set the width
  275.         if (l[1]) then (
  276.             -- project the point back into gizmo space
  277.             local p = l[2] * inverseGizmoTM
  278.             local oldWidth = target.width
  279.             local newWidth = abs(p.x * target.width)
  280.             local shift = (newWidth - oldWidth) / 2
  281.             newWidth -= shift
  282.  
  283.             target.width  = newWidth
  284.  
  285.             -- Now compensate for the change by shifting the
  286.             -- gizmo center to keep the opposite side stationary.
  287.             if p.x < 0 then shift = -shift
  288.             local gizmoTM = target.gizmo.transform
  289.             local shiftVector = getShiftVector target shift
  290.             target.gizmo.transform = preTranslate gizmoTM shiftVector
  291.         )   
  292.     )
  293. )
  294.  
  295. plugin simpleManipulator uvwMappingLengthManip
  296.     name:"UVW Length Manip"
  297.     invisible:true
  298. (
  299.     -- Create the green and red colors for the gizmo
  300.     local greenColor =  colorMan.getColor #manipulatorsActive
  301.     local redColor =    colorMan.getColor #manipulatorsSelected
  302.  
  303.     -- Some useful transforms
  304.     local gizmoTM, inverseGizmoTM
  305.  
  306.     -- This manipualtor manipulates the UVWMapping modifier for planar, cylindircal
  307.     -- spherical or box
  308.     on canManipulate target do
  309.     (
  310.         return (classOf target) == UVWMap
  311.     )
  312.  
  313.     -- Create the manipulator gizmo.
  314.     -- This is called initially and whenver the manipulator target changes
  315.     on updateGizmos do
  316.     (
  317.         -- Clear the current gizmo cache
  318.         this.clearGizmos()
  319.  
  320.         -- Initialize our transforms
  321.         gizmoTM = uvwManipUtils.gizmoMatrix target 
  322.  
  323.         local modTM = getModContextTM node target
  324.         -- check to see if modifier is in a valid state
  325.         if (modTM == undefined) then return ""
  326.         modTM = inverse modTM
  327.  
  328.         gizmoTM = gizmoTM * modTM
  329.  
  330.         inverseGizmoTM = inverse gizmoTM
  331.  
  332.         if uvwManipUtils.usesGizmo target then
  333.         (
  334.             local p0 = [-1.0, -1.0, 0.0],
  335.                   p1 = [ 1.0, -1.0, 0.0],
  336.                   p2 = [ 1.0,  1.0, 0.0],
  337.                   p3 = [-1.0,  1.0, 0.0]
  338.             
  339.             local giz = manip.makeGizmoShape()
  340.     
  341.             -- Gizmo 0 - length
  342.             giz.AddPoint p0
  343.             giz.AddPoint p1
  344.             giz.transform gizmoTM
  345.             this.addGizmoShape giz 0 greenColor redColor
  346.     
  347.             giz = manip.makeGizmoShape()
  348.     
  349.             -- Gizmo 1 - length
  350.             giz.AddPoint p2
  351.             giz.AddPoint p3
  352.             giz.transform gizmoTM
  353.             this.addGizmoShape giz 0 greenColor redColor
  354.     
  355.             return node.name + " UVW Length: " + (target.length as string)
  356.        ) else return ""
  357.     )
  358.  
  359.    -- Compute the shift to compensate for changing the length
  360.    -- but leaving the other side fixed
  361.    function getShiftVector target shift =
  362.    (
  363.        if target.mapType == 1 or target.mapType == 2 then 
  364.        (
  365.            case target.axis of 
  366.            (
  367.                0: return  [-shift/2, 0, 0]
  368.                1: return  [0, 0,  shift/2]
  369.                2: return  [-shift/2, 0, 0]
  370.            )
  371.        )
  372.        else
  373.        (
  374.            case target.axis of
  375.            (
  376.                0: return [0, -shift/2, 0]
  377.                1: return [0, 0,  shift/2]
  378.                2: return [0, -shift/2, 0]
  379.            )
  380.        )
  381.    )
  382.  
  383.     on mouseMove m which do
  384.     (
  385.         local l = uvwManipUtils.projectPointToGizmo this m target gizmoTM
  386.  
  387.         -- If the intersection worked, set the length
  388.         if (l[1]) then (
  389.             -- project the point back into gizmo space
  390.             local p = l[2] * inverseGizmoTM
  391.             local oldLength = target.length
  392.             local newLength = abs(p.y * target.length)
  393.             local shift = (newLength - oldLength) / 2.0
  394.             newLength -= shift
  395.  
  396.             target.length  = newLength
  397.  
  398.             -- Now compensate for the change by shifting the
  399.             -- gizmo center to keep the opposite side stationary.
  400.             if p.y < 0 then shift = -shift
  401.             local gizmoTM = target.gizmo.transform
  402.             local shiftVector = getShiftVector target shift
  403.             target.gizmo.transform = preTranslate gizmoTM shiftVector
  404.  
  405.         )
  406.     )
  407. )
  408.  
  409. plugin simpleManipulator uvwMappingHeightManip
  410.     name:"UVW Height Manip"
  411.     invisible:true
  412. (
  413.     -- Create the green and red colors for the gizmo
  414.     local greenColor =  colorMan.getColor #manipulatorsActive
  415.     local redColor =    colorMan.getColor #manipulatorsSelected
  416.  
  417.     -- Some useful transforms
  418.     local gizmoTM, inverseGizmoTM
  419.  
  420.     -- This manipualtor manipulates the UVWMapping modifier for planar, cylindircal
  421.     -- spherical or box
  422.     on canManipulate target do
  423.     (
  424.         return (classOf target) == UVWMap
  425.     )
  426.  
  427.     -- Create the manipulator gizmo.
  428.     -- This is called initially and whenver the manipulator target changes
  429.     on updateGizmos do
  430.     (
  431.         -- Clear the current gizmo cache
  432.         this.clearGizmos()
  433.  
  434.         -- Initialize our transforms
  435.         gizmoTM = uvwManipUtils.gizmoMatrix target 
  436.  
  437.         local modTM = getModContextTM node target
  438.         -- check to see if modifier is in a valid state
  439.         if (modTM == undefined) then return ""
  440.         modTM = inverse modTM
  441.  
  442.         gizmoTM = gizmoTM * modTM
  443.  
  444.         inverseGizmoTM = inverse gizmoTM
  445.  
  446.         -- Height isn't used for planar mapping
  447.         if uvwManipUtils.usesGizmo target and target.mapType != 0 then
  448.         (
  449.             local p0 = [0, 0, 0],
  450.                   p1 = [0, 0, 1]
  451.  
  452.             if (target.mapType == 1) then p1.z = 0.5
  453.  
  454.             local giz = manip.makeGizmoShape()
  455.     
  456.             -- Gizmo 0 - length
  457.             giz.AddPoint p0
  458.             giz.AddPoint p1
  459.             giz.transform gizmoTM
  460.             this.addGizmoShape giz gizmoDontHitTest greenColor greenColor
  461.  
  462.             local bboxMin = getModContextBBoxMin node target
  463.             local bboxMax = getModContextBBoxMax node target
  464.             local size = (length (bboxMax - bboxMin)) / 25
  465.             giz = uvwManipUtils.makeCubeGizmo (p1 * gizmoTM) size
  466.             this.addGizmoShape giz 0 greenColor redColor
  467.     
  468.             return node.name + " UVW Height: " + (target.height as string)
  469.        ) else return ""
  470.     )
  471.  
  472.     -- Project the given screen coordinate to the height gizmo plane
  473.     -- return 2 values: a flag saying whether the pjection worked,
  474.     -- and the projected point
  475.     
  476.     function makeXYGizmoAxis gizmoTM = 
  477.     (
  478.         local p0 = [-1.0, -1.0, 0.0] * gizmoTM,
  479.               p1 = [ 1.0, -1.0, 0.0] * gizmoTM,
  480.               p2 = [ 1.0,  1.0, 0.0] * gizmoTM
  481.         local d1 = p2 - p1
  482.         local d2 = p2 - p0
  483.         return cross d1 d2
  484.     )
  485.  
  486.     function makeXZGizmoAxis gizmoTM = 
  487.     (
  488.         local p0 = [-1.0, 0.0, -1.0] * gizmoTM,
  489.               p1 = [ 1.0, 0.0, -1.0] * gizmoTM,
  490.               p2 = [ 1.0, 0.0,  1.0] * gizmoTM
  491.         local d1 = p2 - p1
  492.         local d2 = p2 - p0
  493.         return cross d1 d2
  494.     )
  495.  
  496.     function makeYZGizmoAxis gizmoTM = 
  497.     (
  498.         local p0 = [0.0, -1.0, -1.0] * gizmoTM,
  499.               p1 = [0.0, -1.0,  1.0] * gizmoTM,
  500.               p2 = [0.0,  1.0,  1.0] * gizmoTM
  501.         local d1 = p2 - p1
  502.         local d2 = p2 - p0
  503.         return cross d1 d2
  504.     )
  505.  
  506.     function projectPointToHeightGizmo this m UVWMod gizmoTM =
  507.     (
  508.         local axis1, axis2
  509.     
  510.         -- create the two planes we can project on to
  511.         
  512.         case UVWMod.axis of
  513.         (
  514.              0: (axis1 = makeXZGizmoAxis(gizmoTM); axis2 = makeYZGizmoAxis(gizmoTM))
  515.              1: (axis1 = makeYZGizmoAxis(gizmoTM); axis2 = makeXZGizmoAxis(gizmoTM))
  516.              2: (axis1 = makeYZGizmoAxis(gizmoTM); axis2 = makeXZGizmoAxis(gizmoTM))
  517.         )
  518.         
  519.         local plane1 = manip.makePlaneFromNormal  axis1 ([0, 0, 0] * gizmoTM)
  520.         local plane2 = manip.makePlaneFromNormal  axis2 ([0, 0, 0] * gizmoTM)
  521.         local projectedPoint = [0,0,0]
  522.     
  523.         -- Compute the hit-ray in local coordinates
  524.         local viewRay = this.getLocalViewRay m
  525.     
  526.         -- Figure out which plane is most "square" to the view ray
  527.         local pl = plane1.mostOrthogonal viewRay plane2
  528.     
  529.         -- Intersect the plane with the view ray
  530.         local res = pl.intersect viewRay &projectedPoint
  531.     
  532.         return #(res, projectedPoint)
  533.     )
  534.     
  535.     on mouseMove m which do
  536.     (
  537.         local l = projectPointToHeightGizmo this m target gizmoTM 
  538.  
  539.         -- If the intersection worked, set the height
  540.         if (l[1]) then (
  541.             -- project the point back into gizmo space
  542.             local p = l[2] * inverseGizmoTM
  543.             if (target.mapType == 1) then 
  544.                 target.height  = abs(p.z * target.height) * 2
  545.             else
  546.                 target.height  = abs(p.z * target.height) 
  547.         )
  548.     )
  549. )
  550.  
  551. plugin simpleManipulator uvwMappingUTileManip
  552.     name:"UVW U Tile Manip"
  553.     invisible:true
  554. (
  555.     -- Create the green and red colors for the gizmo
  556.     local greenColor =  colorMan.getColor #manipulatorsActive
  557.     local redColor =    colorMan.getColor #manipulatorsSelected
  558.  
  559.     -- Some useful transforms
  560.     local gizmoTM, inverseGizmoTM
  561.  
  562.     -- This manipualtor manipulates the UVWMapping modifier for planar, cylindircal
  563.     -- spherical or box
  564.  
  565.     on canManipulate target do
  566.     (
  567.         return (classOf target) == UVWMap
  568.     )
  569.  
  570.     -- Create the manipulator gizmo.
  571.     -- This is called initially and whenver the manipulator target changes
  572.     on updateGizmos do
  573.     (
  574.         -- Clear the current gizmo cache
  575.         this.clearGizmos()
  576.  
  577.         -- Initialize our transforms
  578.         gizmoTM = uvwManipUtils.gizmoMatrix target 
  579.  
  580.         local modTM = getModContextTM node target
  581.         -- check to see if modifier is in a valid state
  582.         if (modTM == undefined) then return ""
  583.         modTM = inverse modTM
  584.  
  585.         gizmoTM = gizmoTM * modTM
  586.  
  587.         inverseGizmoTM = inverse gizmoTM
  588.  
  589.         local p0 = [-1.0, -1.1, 0.0],
  590.               p1 = [ 1.0, -1.1, 0.0]
  591.  
  592.         local relVal = uvwManipUtils.relativeValue target.utile
  593.         local v = p1 - p0
  594.         local p = p0 + relVal * v
  595.  
  596.         this.addGizmoMarker #circle (p * gizmoTM) 0 greenColor redColor
  597.     
  598.         return node.name + " U Tile: " + (target.utile as string)
  599.     )
  600.  
  601.     on mouseMove m which do
  602.     (
  603.         local l = uvwManipUtils.projectPointToGizmo this m target gizmoTM 
  604.  
  605.         -- If the intersection worked, set the utile
  606.         if (l[1]) then 
  607.         (
  608.             -- project the point back into gizmo space
  609.             local p = l[2] * inverseGizmoTM
  610.             local relVal = (p.x + 1) / 2
  611.             target.utile = uvwManipUtils.inverseRelativeValue(relVal)
  612.         )        
  613.     )
  614. )
  615.  
  616. plugin simpleManipulator uvwMappingVTileManip
  617.     name:"UVW V Tile Manip"
  618.     invisible:true
  619. (
  620.     -- Create the green and red colors for the gizmo
  621.     local greenColor =  colorMan.getColor #manipulatorsActive
  622.     local redColor =    colorMan.getColor #manipulatorsSelected
  623.  
  624.     -- Some useful transforms
  625.     local gizmoTM, inverseGizmoTM
  626.  
  627.     -- This manipualtor manipulates the UVWMapping modifier for planar, cylindircal
  628.     -- spherical or box
  629.  
  630.     on canManipulate target do
  631.     (
  632.         return (classOf target) == UVWMap
  633.     )
  634.  
  635.     -- Create the manipulator gizmo.
  636.     -- This is called initially and whenver the manipulator target changes
  637.     on updateGizmos do
  638.     (
  639.         -- Clear the current gizmo cache
  640.         this.clearGizmos()
  641.  
  642.         -- Initialize our transforms
  643.         gizmoTM = uvwManipUtils.gizmoMatrix target 
  644.  
  645.         local modTM = getModContextTM node target
  646.         -- check to see if modifier is in a valid state
  647.         if (modTM == undefined) then return ""
  648.         modTM = inverse modTM
  649.  
  650.         gizmoTM = gizmoTM * modTM
  651.  
  652.         inverseGizmoTM = inverse gizmoTM
  653.  
  654.         local p0 = [-1.1, -1.0, 0.0],
  655.               p1 = [-1.1,  1.0, 0.0]
  656.  
  657.         local relVal = uvwManipUtils.relativeValue target.vtile
  658.         local v = p1 - p0
  659.         local p = p0 + relVal * v
  660.  
  661.         this.addGizmoMarker #circle (p * gizmoTM) 0 greenColor redColor
  662.     
  663.         return node.name + " V Tile: " + (target.vtile as string)
  664.     )
  665.  
  666.     on mouseMove m which do
  667.     (
  668.         local l = uvwManipUtils.projectPointToGizmo this m target gizmoTM 
  669.  
  670.         -- If the intersection worked, set the vtile
  671.         if (l[1]) then 
  672.         (
  673.             -- project the point back into gizmo space
  674.             local p = l[2] * inverseGizmoTM
  675.             local relVal = (p.y + 1) / 2
  676.             target.vtile = uvwManipUtils.inverseRelativeValue(relVal)
  677.         )        
  678.     )
  679. )
  680.  
  681.  
  682.