MarcFisher
06-23-2009, 07:21 AM
I'm trying to build a script which aligns a fixed size uvw planar map to the face of a poly, where the top of the uvw gizmo faces an edge that a user selects and it it would align the side of the gizmo to a vertex that a user can also select.
I already have the script in place that lets the user quickly select the edge and vertex. From that I've tryed building upon the script from this thread http://forums.cgsociety.org/showthread.php?f=98&t=425252
But that doesn't always seem to align the gizmo to the selected edge when the object has some kind of rotation.
I don't have a lot of knowledge on transforms and matrices so i figured I would just align the gizmo to a vertex by taking the position of the gizmo and putting it on the position of the vertex, but that doesn't work properly since the gizmo is in object space.
Is there a way to figure out the transform of a vertex so that you can get the position of it in object space (or is that even the right way to go about this).
This is what I had so far, script from that thread, the last lines were mine, which obviously don't work.
fn getLocalFaceBounds theObj theFace = (
local bigNum = 999999.9
local bbMin = [bigNum, bigNum, bigNum]
local bbMax = [-bigNum, -bigNum, -bigNum]
local verts = (polyOp.getVertsUsingFace theObj theFace) as Array
for vIndex in verts do (
local v = in coordsys theObj (polyOp.getVert theObj vIndex)
if v.x < bbMin.x do bbMin.x = v.x
if v.y < bbMin.y do bbMin.y = v.y
if v.z < bbMin.z do bbMin.z = v.z
if v.x > bbMax.x do bbMax.x = v.x
if v.y > bbMax.y do bbMax.y = v.y
if v.z > bbMax.z do bbMax.z = v.z
)
return #(bbMin, bbMax)
)
fn alignUVGizmo theObj theFace theEdge theVertex gizmoLength gizmoWidth =
(
gizmoLengthOver2 = float(gizmoLength) / 2.0
case (classof theObj) of (
editable_mesh: (
faceNormal = in coordsys theObj (getFaceNormal theObj theFace)
verts = (meshop.getVertsUsingEdge theObj theEdge) as array
v2 = in coordsys theObj (getVert theObj verts[2])
v1 = in coordsys theObj (getVert theObj verts[1])
)
editable_poly: (
faceNormal = in coordsys theObj (polyop.getFaceNormal theObj theFace)
verts = in coordsys theObj (polyop.getVertsUsingEdge theObj theEdge) as array
v2 = in coordsys theObj (polyop.getVert theObj verts[2])
v1 = in coordsys theObj (polyop.getVert theObj verts[1])
)
)
bounds = getLocalFaceBounds theObj theFace
bbMin = bounds[1]
bbMax = bounds[2]
bbCenter = (bbMin + bbMax) / 2
faceNormal = normalize faceNormal
edgeVector = normalize (v2 - v1)
rightVector = normalize (cross edgeVector faceNormal)
edgeCenter = (v1 + v2) / 2.0
gizmoEdgeCenter = bbCenter + rightVector * gizmoLengthOver2
bbCenterToEdgeCenter = edgeCenter - bbCenter
bbCenterToGizmoEdgeCenter = gizmoEdgeCenter - bbCenter
offset = bbCenterToEdgeCenter - bbCenterToGizmoEdgeCenter
if (dot rightVector (normalize bbCenterToEdgeCenter)) > 0 do (
rightVector = -rightVector
)
theMatrix = matrix3 edgeVector rightVector faceNormal offset
undo "Align Gizmo" on (
theMap = Uvwmap()
modPanel.addModToSelection theMap ui:on
theMap.maptype = 0
theMap.length = gizmoLength
theMap.width = gizmoWidth
theMap.mapChannel = 2
theMap.gizmo.transform = theMatrix
--in coordsys #local theMap.gizmo.pos = polyop.getVert theObj theVertex
--in coordsys #local theMap.gizmo.pos += [(gizmoWidth / 2),(gizmoLength / 2),0]
)
)
I already have the script in place that lets the user quickly select the edge and vertex. From that I've tryed building upon the script from this thread http://forums.cgsociety.org/showthread.php?f=98&t=425252
But that doesn't always seem to align the gizmo to the selected edge when the object has some kind of rotation.
I don't have a lot of knowledge on transforms and matrices so i figured I would just align the gizmo to a vertex by taking the position of the gizmo and putting it on the position of the vertex, but that doesn't work properly since the gizmo is in object space.
Is there a way to figure out the transform of a vertex so that you can get the position of it in object space (or is that even the right way to go about this).
This is what I had so far, script from that thread, the last lines were mine, which obviously don't work.
fn getLocalFaceBounds theObj theFace = (
local bigNum = 999999.9
local bbMin = [bigNum, bigNum, bigNum]
local bbMax = [-bigNum, -bigNum, -bigNum]
local verts = (polyOp.getVertsUsingFace theObj theFace) as Array
for vIndex in verts do (
local v = in coordsys theObj (polyOp.getVert theObj vIndex)
if v.x < bbMin.x do bbMin.x = v.x
if v.y < bbMin.y do bbMin.y = v.y
if v.z < bbMin.z do bbMin.z = v.z
if v.x > bbMax.x do bbMax.x = v.x
if v.y > bbMax.y do bbMax.y = v.y
if v.z > bbMax.z do bbMax.z = v.z
)
return #(bbMin, bbMax)
)
fn alignUVGizmo theObj theFace theEdge theVertex gizmoLength gizmoWidth =
(
gizmoLengthOver2 = float(gizmoLength) / 2.0
case (classof theObj) of (
editable_mesh: (
faceNormal = in coordsys theObj (getFaceNormal theObj theFace)
verts = (meshop.getVertsUsingEdge theObj theEdge) as array
v2 = in coordsys theObj (getVert theObj verts[2])
v1 = in coordsys theObj (getVert theObj verts[1])
)
editable_poly: (
faceNormal = in coordsys theObj (polyop.getFaceNormal theObj theFace)
verts = in coordsys theObj (polyop.getVertsUsingEdge theObj theEdge) as array
v2 = in coordsys theObj (polyop.getVert theObj verts[2])
v1 = in coordsys theObj (polyop.getVert theObj verts[1])
)
)
bounds = getLocalFaceBounds theObj theFace
bbMin = bounds[1]
bbMax = bounds[2]
bbCenter = (bbMin + bbMax) / 2
faceNormal = normalize faceNormal
edgeVector = normalize (v2 - v1)
rightVector = normalize (cross edgeVector faceNormal)
edgeCenter = (v1 + v2) / 2.0
gizmoEdgeCenter = bbCenter + rightVector * gizmoLengthOver2
bbCenterToEdgeCenter = edgeCenter - bbCenter
bbCenterToGizmoEdgeCenter = gizmoEdgeCenter - bbCenter
offset = bbCenterToEdgeCenter - bbCenterToGizmoEdgeCenter
if (dot rightVector (normalize bbCenterToEdgeCenter)) > 0 do (
rightVector = -rightVector
)
theMatrix = matrix3 edgeVector rightVector faceNormal offset
undo "Align Gizmo" on (
theMap = Uvwmap()
modPanel.addModToSelection theMap ui:on
theMap.maptype = 0
theMap.length = gizmoLength
theMap.width = gizmoWidth
theMap.mapChannel = 2
theMap.gizmo.transform = theMatrix
--in coordsys #local theMap.gizmo.pos = polyop.getVert theObj theVertex
--in coordsys #local theMap.gizmo.pos += [(gizmoWidth / 2),(gizmoLength / 2),0]
)
)
