home *** CD-ROM | disk | FTP | other *** search
- -- UVW Mapping modifier manipulator
-
- -- This file implements manipulators for the width, length and height of the
- -- UVW mapping as well as U Tile and V Tile.
-
- -- Written by Scott Morrison, July 26, 2000
-
- Struct uvwManipUtils (
-
- -- Compute the transform matrix for the mapping gizmo. This maps gizmo space
- -- into the local coordinate space for the modifier. In gizmo space,
- -- the gizmo extends from -1 to 1 in x and y.
-
- function gizmoMatrix UVWMod =
- (
- local tm = UVWMod.gizmo.transform
-
- -- Rotate the frame for each mapping type. This step is black magic
- -- copied from MaxSDK/Samples/Modifier/MapMod.cpp.
- case UVWMod.mapType of
- (
- 0: tm = preRotateZ tm 180
- 1: tm = preRotateZ tm 90
- 2: tm = preRotateZ tm 90
- 4: tm = preRotateZ tm 180
- )
-
- -- Compensate for the specified axis of projection
- case UVWMod.axis of
- (
- 0: tm = preRotateY tm -90
- 1: tm = preRotateX tm 90
- )
-
- -- Scale by the width, length and height of the mapper
- local s = [UVWMod.width, UVWMod.length, UVWMod.height]
-
- case UVWMod.mapType of
- (
- 0: (s.x = s.x * 0.5; s.y = s.y * 0.5)
- 1: (s.x = s.x * 0.5; s.y = s.y * 0.5)
- 2: s = s * 0.5
- 4: s = s * 0.5
- )
-
- tm = preScale tm s
-
- return tm
- ),
-
- -- return the axis of the UVW Mapping gizmo
-
- function gizmoAxis UVWMod =
- (
- case UVWMod.axis of
- (
- 0: return x_axis
- 1: return y_axis
- 2: return z_axis
- )
-
- return z_axis
- ),
-
- -- Project the given screen coordinate to the gizmo plane.
- -- returns 2 values: a flag saying whether the pojection worked,
- -- and the projected point
-
- function projectPointToGizmo this m UVWMod gizmoTM =
- (
- local axis = uvwManipUtils.makeGizmoAxis gizmoTM
-
- -- Create the plane that the gizmo lies on
- local pl = manip.makePlaneFromNormal axis ([0, 0, 0] * gizmoTM)
- projectedPoint = [0,0,0]
-
- -- Compute the hit-ray in local coordinates
- local viewRay = this.getLocalViewRay m
-
- -- Intersect the plane with the view ray
- local res = pl.intersect viewRay &projectedPoint
-
- return #(res, projectedPoint)
- ),
-
- -- Returns true if the given UVWMapper uses a gizmo
-
- function usesGizmo UVWMod =
- (
- local mapType = UVWMod.mapType
- return mapType == 0 or mapType == 1 or mapType == 2 or mapType == 4
- ),
-
- -- Compute the normal of the projection axis
- function makeGizmoAxis gizmoTM =
- (
- local p0 = [-1.0, -1.0, 0.0] * gizmoTM,
- p1 = [ 1.0, -1.0, 0.0] * gizmoTM,
- p2 = [ 1.0, 1.0, 0.0] * gizmoTM
- local d1 = p2 - p1
- local d2 = p2 - p0
- return cross d1 d2
- ),
-
- -- Create a cube gizmo with the given posistion and size
-
- function makeCubeGizmo pos size =
- (
- local giz = manip.makeGizmoShape()
- local halfSize = size / 2
-
- -- The corners of the cube
- local p000 = pos + [ halfSize, halfSize, halfSize]
- local p001 = pos + [ halfSize, halfSize, -halfSize]
- local p010 = pos + [ halfSize, -halfSize, halfSize]
- local p011 = pos + [ halfSize, -halfSize, -halfSize]
- local p100 = pos + [-halfSize, halfSize, halfSize]
- local p101 = pos + [-halfSize, halfSize, -halfSize]
- local p110 = pos + [-halfSize, -halfSize, halfSize]
- local p111 = pos + [-halfSize, -halfSize, -halfSize]
-
- -- Create the top of the box
- giz.AddPoint(p000)
- giz.AddPoint(p010)
- giz.AddPoint(p011)
- giz.AddPoint(p001)
- giz.AddPoint(p000)
-
- -- Create the bottom of the box
- giz.startNewLine()
- giz.AddPoint(p100)
- giz.AddPoint(p110)
- giz.AddPoint(p111)
- giz.AddPoint(p101)
- giz.AddPoint(p100)
-
- -- Create the struts
- giz.startNewLine()
- giz.AddPoint(p000)
- giz.AddPoint(p100)
-
- giz.startNewLine()
- giz.AddPoint(p010)
- giz.AddPoint(p110)
-
- giz.startNewLine()
- giz.AddPoint(p011)
- giz.AddPoint(p111)
-
- giz.startNewLine()
- giz.AddPoint(p001)
- giz.AddPoint(p101)
-
- return giz
- ),
-
- -- return a number in the range -1 .. 2 for the value of map tiling
- -- This uses logarithmic scaling
- function relativeValue val =
- (
- local relVal = (5 + (log (val/20))) / 5
-
- -- Clamp the value
- if relVal < -1 then relVal = -1
- if relVal > 2 then relVal = 2
-
- return relVal
- ),
-
- -- Invert the formula from above
- function inverseRelativeValue relVal =
- (
- relVal = exp((relVal * 5) - 5) * 20
-
- return relVal
- )
-
- ) -- uvwManipUtils
-
-
- plugin simpleManipulator uvwMappingWidthManip
- name:"UVW Width Manip"
- invisible:true
- (
- -- Set the green and red colors for the gizmo
- local greenColor = colorMan.getColor #manipulatorsActive
- local redColor = colorMan.getColor #manipulatorsSelected
-
- -- Some useful transforms
- local gizmoTM, inverseGizmoTM
-
- -- This manipualtor manipulates any UVWMapping modifier
- on canManipulate target do
- (
- return (classOf target) == UVWMap
- )
-
- -- Create the manipulator gizmo.
- -- This is called initially and whenver the manipulator target changes
- on updateGizmos do
- (
- -- Clear the current gizmo cache
- this.clearGizmos()
-
- -- Initialize our transforms
- gizmoTM = uvwManipUtils.gizmoMatrix target
-
- local modTM = getModContextTM node target
- -- check to see if modifier is in a valid state
- if (modTM == undefined) then return ""
- modTM = inverse modTM
-
- gizmoTM = gizmoTM * modTM
-
- inverseGizmoTM = inverse gizmoTM
-
- if uvwManipUtils.usesGizmo target then
- (
-
- local p0 = [-1.0, -1.0, 0.0],
- p1 = [ 1.0, -1.0, 0.0],
- p2 = [ 1.0, 1.0, 0.0],
- p3 = [-1.0, 1.0, 0.0]
-
- local giz = manip.makeGizmoShape()
-
- -- Gizmo 0 - width
- giz.AddPoint p1
- giz.AddPoint p2
- giz.transform gizmoTM
- this.addGizmoShape giz 0 greenColor redColor
-
- giz = manip.makeGizmoShape()
-
- -- Gizmo 1 - width
- giz.AddPoint p3
- giz.AddPoint p0
- giz.transform gizmoTM
-
- this.addGizmoShape giz 0 greenColor redColor
-
- return node.name + " UVW Width: " + (target.width as string)
- ) else return ""
- )
-
- -- Compute the shift to compensate for changing the width
- -- but leaving the other side fixed
- function getShiftVector target shift =
- (
- if target.mapType == 1 or target.mapType == 2 then
- (
- case target.axis of
- (
- 0: return [0, 0, shift/2]
- 1: return [0, shift/2, 0]
- 2: return [0, shift/2, 0]
- )
- )
- else
- (
- case target.axis of
- (
- 0: return [0, 0, shift/2]
- 1: return [-shift/2, 0, 0]
- 2: return [-shift/2, 0, 0]
- )
- )
- )
-
- on mouseMove m which do
- (
- local l = uvwManipUtils.projectPointToGizmo this m target gizmoTM
-
- -- If the intersection worked, set the width
- if (l[1]) then (
- -- project the point back into gizmo space
- local p = l[2] * inverseGizmoTM
- local oldWidth = target.width
- local newWidth = abs(p.x * target.width)
- local shift = (newWidth - oldWidth) / 2
- newWidth -= shift
-
- target.width = newWidth
-
- -- Now compensate for the change by shifting the
- -- gizmo center to keep the opposite side stationary.
- if p.x < 0 then shift = -shift
- local gizmoTM = target.gizmo.transform
- local shiftVector = getShiftVector target shift
- target.gizmo.transform = preTranslate gizmoTM shiftVector
- )
- )
- )
-
- plugin simpleManipulator uvwMappingLengthManip
- name:"UVW Length Manip"
- invisible:true
- (
- -- Create the green and red colors for the gizmo
- local greenColor = colorMan.getColor #manipulatorsActive
- local redColor = colorMan.getColor #manipulatorsSelected
-
- -- Some useful transforms
- local gizmoTM, inverseGizmoTM
-
- -- This manipualtor manipulates the UVWMapping modifier for planar, cylindircal
- -- spherical or box
- on canManipulate target do
- (
- return (classOf target) == UVWMap
- )
-
- -- Create the manipulator gizmo.
- -- This is called initially and whenver the manipulator target changes
- on updateGizmos do
- (
- -- Clear the current gizmo cache
- this.clearGizmos()
-
- -- Initialize our transforms
- gizmoTM = uvwManipUtils.gizmoMatrix target
-
- local modTM = getModContextTM node target
- -- check to see if modifier is in a valid state
- if (modTM == undefined) then return ""
- modTM = inverse modTM
-
- gizmoTM = gizmoTM * modTM
-
- inverseGizmoTM = inverse gizmoTM
-
- if uvwManipUtils.usesGizmo target then
- (
- local p0 = [-1.0, -1.0, 0.0],
- p1 = [ 1.0, -1.0, 0.0],
- p2 = [ 1.0, 1.0, 0.0],
- p3 = [-1.0, 1.0, 0.0]
-
- local giz = manip.makeGizmoShape()
-
- -- Gizmo 0 - length
- giz.AddPoint p0
- giz.AddPoint p1
- giz.transform gizmoTM
- this.addGizmoShape giz 0 greenColor redColor
-
- giz = manip.makeGizmoShape()
-
- -- Gizmo 1 - length
- giz.AddPoint p2
- giz.AddPoint p3
- giz.transform gizmoTM
- this.addGizmoShape giz 0 greenColor redColor
-
- return node.name + " UVW Length: " + (target.length as string)
- ) else return ""
- )
-
- -- Compute the shift to compensate for changing the length
- -- but leaving the other side fixed
- function getShiftVector target shift =
- (
- if target.mapType == 1 or target.mapType == 2 then
- (
- case target.axis of
- (
- 0: return [-shift/2, 0, 0]
- 1: return [0, 0, shift/2]
- 2: return [-shift/2, 0, 0]
- )
- )
- else
- (
- case target.axis of
- (
- 0: return [0, -shift/2, 0]
- 1: return [0, 0, shift/2]
- 2: return [0, -shift/2, 0]
- )
- )
- )
-
- on mouseMove m which do
- (
- local l = uvwManipUtils.projectPointToGizmo this m target gizmoTM
-
- -- If the intersection worked, set the length
- if (l[1]) then (
- -- project the point back into gizmo space
- local p = l[2] * inverseGizmoTM
- local oldLength = target.length
- local newLength = abs(p.y * target.length)
- local shift = (newLength - oldLength) / 2.0
- newLength -= shift
-
- target.length = newLength
-
- -- Now compensate for the change by shifting the
- -- gizmo center to keep the opposite side stationary.
- if p.y < 0 then shift = -shift
- local gizmoTM = target.gizmo.transform
- local shiftVector = getShiftVector target shift
- target.gizmo.transform = preTranslate gizmoTM shiftVector
-
- )
- )
- )
-
- plugin simpleManipulator uvwMappingHeightManip
- name:"UVW Height Manip"
- invisible:true
- (
- -- Create the green and red colors for the gizmo
- local greenColor = colorMan.getColor #manipulatorsActive
- local redColor = colorMan.getColor #manipulatorsSelected
-
- -- Some useful transforms
- local gizmoTM, inverseGizmoTM
-
- -- This manipualtor manipulates the UVWMapping modifier for planar, cylindircal
- -- spherical or box
- on canManipulate target do
- (
- return (classOf target) == UVWMap
- )
-
- -- Create the manipulator gizmo.
- -- This is called initially and whenver the manipulator target changes
- on updateGizmos do
- (
- -- Clear the current gizmo cache
- this.clearGizmos()
-
- -- Initialize our transforms
- gizmoTM = uvwManipUtils.gizmoMatrix target
-
- local modTM = getModContextTM node target
- -- check to see if modifier is in a valid state
- if (modTM == undefined) then return ""
- modTM = inverse modTM
-
- gizmoTM = gizmoTM * modTM
-
- inverseGizmoTM = inverse gizmoTM
-
- -- Height isn't used for planar mapping
- if uvwManipUtils.usesGizmo target and target.mapType != 0 then
- (
- local p0 = [0, 0, 0],
- p1 = [0, 0, 1]
-
- if (target.mapType == 1) then p1.z = 0.5
-
- local giz = manip.makeGizmoShape()
-
- -- Gizmo 0 - length
- giz.AddPoint p0
- giz.AddPoint p1
- giz.transform gizmoTM
- this.addGizmoShape giz gizmoDontHitTest greenColor greenColor
-
- local bboxMin = getModContextBBoxMin node target
- local bboxMax = getModContextBBoxMax node target
- local size = (length (bboxMax - bboxMin)) / 25
- giz = uvwManipUtils.makeCubeGizmo (p1 * gizmoTM) size
- this.addGizmoShape giz 0 greenColor redColor
-
- return node.name + " UVW Height: " + (target.height as string)
- ) else return ""
- )
-
- -- Project the given screen coordinate to the height gizmo plane
- -- return 2 values: a flag saying whether the pjection worked,
- -- and the projected point
-
- function makeXYGizmoAxis gizmoTM =
- (
- local p0 = [-1.0, -1.0, 0.0] * gizmoTM,
- p1 = [ 1.0, -1.0, 0.0] * gizmoTM,
- p2 = [ 1.0, 1.0, 0.0] * gizmoTM
- local d1 = p2 - p1
- local d2 = p2 - p0
- return cross d1 d2
- )
-
- function makeXZGizmoAxis gizmoTM =
- (
- local p0 = [-1.0, 0.0, -1.0] * gizmoTM,
- p1 = [ 1.0, 0.0, -1.0] * gizmoTM,
- p2 = [ 1.0, 0.0, 1.0] * gizmoTM
- local d1 = p2 - p1
- local d2 = p2 - p0
- return cross d1 d2
- )
-
- function makeYZGizmoAxis gizmoTM =
- (
- local p0 = [0.0, -1.0, -1.0] * gizmoTM,
- p1 = [0.0, -1.0, 1.0] * gizmoTM,
- p2 = [0.0, 1.0, 1.0] * gizmoTM
- local d1 = p2 - p1
- local d2 = p2 - p0
- return cross d1 d2
- )
-
- function projectPointToHeightGizmo this m UVWMod gizmoTM =
- (
- local axis1, axis2
-
- -- create the two planes we can project on to
-
- case UVWMod.axis of
- (
- 0: (axis1 = makeXZGizmoAxis(gizmoTM); axis2 = makeYZGizmoAxis(gizmoTM))
- 1: (axis1 = makeYZGizmoAxis(gizmoTM); axis2 = makeXZGizmoAxis(gizmoTM))
- 2: (axis1 = makeYZGizmoAxis(gizmoTM); axis2 = makeXZGizmoAxis(gizmoTM))
- )
-
- local plane1 = manip.makePlaneFromNormal axis1 ([0, 0, 0] * gizmoTM)
- local plane2 = manip.makePlaneFromNormal axis2 ([0, 0, 0] * gizmoTM)
- local projectedPoint = [0,0,0]
-
- -- Compute the hit-ray in local coordinates
- local viewRay = this.getLocalViewRay m
-
- -- Figure out which plane is most "square" to the view ray
- local pl = plane1.mostOrthogonal viewRay plane2
-
- -- Intersect the plane with the view ray
- local res = pl.intersect viewRay &projectedPoint
-
- return #(res, projectedPoint)
- )
-
- on mouseMove m which do
- (
- local l = projectPointToHeightGizmo this m target gizmoTM
-
- -- If the intersection worked, set the height
- if (l[1]) then (
- -- project the point back into gizmo space
- local p = l[2] * inverseGizmoTM
- if (target.mapType == 1) then
- target.height = abs(p.z * target.height) * 2
- else
- target.height = abs(p.z * target.height)
- )
- )
- )
-
- plugin simpleManipulator uvwMappingUTileManip
- name:"UVW U Tile Manip"
- invisible:true
- (
- -- Create the green and red colors for the gizmo
- local greenColor = colorMan.getColor #manipulatorsActive
- local redColor = colorMan.getColor #manipulatorsSelected
-
- -- Some useful transforms
- local gizmoTM, inverseGizmoTM
-
- -- This manipualtor manipulates the UVWMapping modifier for planar, cylindircal
- -- spherical or box
-
- on canManipulate target do
- (
- return (classOf target) == UVWMap
- )
-
- -- Create the manipulator gizmo.
- -- This is called initially and whenver the manipulator target changes
- on updateGizmos do
- (
- -- Clear the current gizmo cache
- this.clearGizmos()
-
- -- Initialize our transforms
- gizmoTM = uvwManipUtils.gizmoMatrix target
-
- local modTM = getModContextTM node target
- -- check to see if modifier is in a valid state
- if (modTM == undefined) then return ""
- modTM = inverse modTM
-
- gizmoTM = gizmoTM * modTM
-
- inverseGizmoTM = inverse gizmoTM
-
- local p0 = [-1.0, -1.1, 0.0],
- p1 = [ 1.0, -1.1, 0.0]
-
- local relVal = uvwManipUtils.relativeValue target.utile
- local v = p1 - p0
- local p = p0 + relVal * v
-
- this.addGizmoMarker #circle (p * gizmoTM) 0 greenColor redColor
-
- return node.name + " U Tile: " + (target.utile as string)
- )
-
- on mouseMove m which do
- (
- local l = uvwManipUtils.projectPointToGizmo this m target gizmoTM
-
- -- If the intersection worked, set the utile
- if (l[1]) then
- (
- -- project the point back into gizmo space
- local p = l[2] * inverseGizmoTM
- local relVal = (p.x + 1) / 2
- target.utile = uvwManipUtils.inverseRelativeValue(relVal)
- )
- )
- )
-
- plugin simpleManipulator uvwMappingVTileManip
- name:"UVW V Tile Manip"
- invisible:true
- (
- -- Create the green and red colors for the gizmo
- local greenColor = colorMan.getColor #manipulatorsActive
- local redColor = colorMan.getColor #manipulatorsSelected
-
- -- Some useful transforms
- local gizmoTM, inverseGizmoTM
-
- -- This manipualtor manipulates the UVWMapping modifier for planar, cylindircal
- -- spherical or box
-
- on canManipulate target do
- (
- return (classOf target) == UVWMap
- )
-
- -- Create the manipulator gizmo.
- -- This is called initially and whenver the manipulator target changes
- on updateGizmos do
- (
- -- Clear the current gizmo cache
- this.clearGizmos()
-
- -- Initialize our transforms
- gizmoTM = uvwManipUtils.gizmoMatrix target
-
- local modTM = getModContextTM node target
- -- check to see if modifier is in a valid state
- if (modTM == undefined) then return ""
- modTM = inverse modTM
-
- gizmoTM = gizmoTM * modTM
-
- inverseGizmoTM = inverse gizmoTM
-
- local p0 = [-1.1, -1.0, 0.0],
- p1 = [-1.1, 1.0, 0.0]
-
- local relVal = uvwManipUtils.relativeValue target.vtile
- local v = p1 - p0
- local p = p0 + relVal * v
-
- this.addGizmoMarker #circle (p * gizmoTM) 0 greenColor redColor
-
- return node.name + " V Tile: " + (target.vtile as string)
- )
-
- on mouseMove m which do
- (
- local l = uvwManipUtils.projectPointToGizmo this m target gizmoTM
-
- -- If the intersection worked, set the vtile
- if (l[1]) then
- (
- -- project the point back into gizmo space
- local p = l[2] * inverseGizmoTM
- local relVal = (p.y + 1) / 2
- target.vtile = uvwManipUtils.inverseRelativeValue(relVal)
- )
- )
- )
-
-
-