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 >
Wrap
Text File
|
2002-02-13
|
21KB
|
682 lines
-- 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)
)
)
)