[Closed] View Aligned Node: Trick with Simple Manipulator
Many times in different threads people asked and showed some solutions how to make View Aligned (billboard) Node.
The basic idea is to use #viewportChange event or registered RedrawViewsCallback.
For example:
with redraw off
(
callbacks.removeScripts id:#camFace
delete objects
global cameraFaced
fn cameraFaced node: = if isvalidnode node do
(
ntm = node.transform
vtm = getViewTM()
node.transform = translate (rotate (scalematrix ntm.scale) (inverse vtm.rotation)) ntm.pos
)
global myText = text name:"myText" isselected:on
cameraFaced node:myText
callbacks.addScript #viewportChange "cameraFaced node:myText" id:#camFace
)
It works but there are some problems with registering new nodes, adding scripts on startup, saving the setup with file using of persistent event scripts, etc.
Here is another way of doing the tick.
I’m using the fact that for every view change a Scripted Manipulator is called to update its gizmo. So we can use it to change the dependent node’s transform. In the sample I’m changing the node’s transform directly, but you can use scripted controllers with notifyDependents method (see mxs for details).
-- by denisT
plugin simpleManipulator ViewWatcher
name:"ViewWatcher"
classID:#(0xb58aefb, 0x160048d9)
--invisible:on
--silentErrors:on
category:"Manipulators"
(
local c = colorMan.getColor #manipulatorsInactive
local node, giz
tool create
(
on mousePoint click do
(
nodeTM.translation = gridPoint
#stop
)
)
on canmanipulate target do return false
on updateGizmos do
(
if not isvalidnode node do node = refs.dependentnodes this firstOnly:on
ntm = node.transform
vtm = getViewTM()
node.transform = translate (rotate (scalematrix ntm.scale) (inverse vtm.rotation)) ntm.pos
if giz == undefined do
(
giz = manip.makeCircle [0,0,0] 10 24
this.addGizmoShape giz (gizmoActiveViewportOnly + gizmoDontHitTest) c c
)
)
)
with redraw off
(
delete objects
in (vw = ViewWatcher isselected:on)
(
tx = text text:"View Watcher" size:10
tx.position.controller = Position_Constraint relative:off
tx.position.controller.appendTarget vw 100.
tx.rotation.controller = Orientation_Constraint relative:off
tx.rotation.controller.appendTarget vw 100.
)
)
The ViewWatcher no needs to manipulate anything, it can be used as parent and constraint controller target for any other nodes (text shape in my sample).
Here you are…
any questions are welcome
Denis,
This is an interesting idea! Will it also work/update correctly on rendertime in a camera view?
Thanks,
-Johan