Notifications
Clear all

[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

2 Replies
 JHN

Denis,

This is an interesting idea! Will it also work/update correctly on rendertime in a camera view?

Thanks,
-Johan

1 Reply
(@denist)
Joined: 2 years ago

Posts: 0

i don’t think so. on render time the system probably shouldn’t rebuild gizmos.