Callback on viewport/camera move?


#1

I wrote a (terrible) script controller a ways back that was supposed to keep the selection facing the camera (I’ve switched computers since then and can’t even find it anymore). But one thing I do remember was that it used registerRedrawViewsCallback.

I’m planning on rewriting that from scratch now that I know (a little bit) more about MaxScript, and was thinking that there must be a better way to keep the rotation updated. Is there any kind of “on viewport camera moved/rotated” callback, or workaround to achieve same effect?


#2

callbacks -> general event -> #viewportChange


#3

Okay, that definitely works, thanks!

Next question, to make it even better… is there any kind of a track for the viewport that could be used as a variable in a script controller?


#4

if viewport is not a node (camera, light, etc.) it doesn’t have any transform controller. But in the script controller you have access to any viewport’s parameter (getTM, getFOV, etc.).


#5

I see. Yeah, I guess I’m going to have to use a workaround for this… What I’m working with right now is:

callbacks.removeScripts #viewportChange; for o in objects do delete o

viewTM = point pos:[0,0,0] size:1 name:"viewTM" isHidden:true; myText = text name:"myText"

$myText.kerning.controller = float_script()
$myText.kerning.controller.script = "dependsOn $viewTM; $myText.dir = (Inverse(getViewTM()))[3]; 0"

callbacks.addScript #viewportChange "viewTM.dir = (Inverse(getViewTM()))[3]"

There’s also currently a flipping issue that I was never able to fixed last time I wrote a script for this (you’ll see what I mean if you run the script)


#6

your solution looks too complicated for me if you just want to have an object all time faced to the active view:


  with redraw off 
(
	callbacks.removeScripts [b]id:#camFace[/b]
	delete objects
	fn cameraFaced node: = if isvalidnode node do 
	(
		ntm = node.transform
		vtm = getViewTM()
		node.transform = translate (rotate (scalematrix ntm.scale) (inverse vtm.rotation)) ntm.pos
	)
	myText = text name:"myText" isselected:on
	cameraFaced node:myText
	
	callbacks.addScript #viewportChange "cameraFaced node:myText"[b] id:#camFace[/b]
)
  

PS. when you add and remove callback scripts use unique ID to be sure that you are removing only yours own.


#7

Well, it’s actually not just one object I’m going to have facing the viewport, but more like several dozen dynamically generated objects. That was why I figured it would be best to just use the callback on the point, and leave that as a permanent part of the scene, and make the dynamic objects follow suit.

I tried running your script and got “MAXScript Callback script Exception --Type error: Call needs function of class, got: undefined.” I don’t have time to figure out what the problem is right now, but I will definitely look at the script more carefully later. At any rate, thanks for the advice!


#8

it was my bad. the callback function has to be global:


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
)



Rotate Text Toward Camera + keep the same screen text size
#9

This thread has been automatically closed as it remained inactive for 12 months. If you wish to continue the discussion, please create a new thread in the appropriate forum.