Notifications
Clear all

[Closed] transform matrix / in coordsys / at time Question

hi i am writing a script to show the 2d trajectory of an object in 2d screenspace.
the script analyses the position of an object on every frame in relation to the active camera and then transforms its position into screenspace coordinates with gw.transpoint. in theory at least.
its not working any ideas why
thank you very much

this is the code:

macroScript Show_Trajectory_on_selected
category:“Animation”
buttontext:“Show_Trajectory_on_selected”
toolTip:“Show_Trajectory_on_selected”
(
local SpeedShow = false
local lastviewport
global Laca_callbacks
global redrawscr_laca()

fn redrawscr_laca = gw.updatescreen()

fn show_PlaneSpeed =
(
try (
if viewport.activeViewport != lastviewport do
(
completeredraw()
lastViewport = viewport.activeViewport
)
posarr = #()
obj = selection[1]
cam = viewport.getcamera ()
camCT = at time currenttime (cam.transform)

             for t = animationrange.start to animationrange.end do
                 (
                 
                     at time t
                         (
                         camT = cam.transform
                         objT = obj.transform
                         camP = cam.position
                         objP = obj.position
                         rel    =  (in coordsys (at time t (cam.transform)) objT.position)
                         )
                     pos = at time currenttime (in coordsys (cam) ([0,0,0] + (rel)))
                     append     posarr (gw.transpoint pos)
                 )

             gw.setTransform (matrix3 1)
             

             gw.setcolor #line white

             for p = 1 to posarr.count do
                 (
                 gw.wtext posarr[p] (".") color:[255,255,255]
                 )
             posarr = #()

         
                
         gw.enlargeupdaterect #whole
         )
     catch()
 )

on ischecked return SpeedShow

on Execute do (
if SpeedShow then (
Laca_callbacks -= 1
unregisterRedrawviewscallback show_PlaneSpeed
if Laca_callbacks == 0 then unregisterRedrawViewsCallback redrawscr_laca
)
else (
if Laca_callbacks != undefined then Laca_callbacks += 1
if Laca_callbacks == undefined then Laca_callbacks = 1
registerRedrawviewscallback show_PlaneSpeed
unregisterRedrawviewsCallback redrawscr_laca
registerRedrawviewsCallback redrawscr_laca
)
SpeedShow = not SpeedShow
forcecompleteredraw()
updateToolbarbuttons()
)
)

6 Replies

It may not be you. Historically, the D3D driver has done a poor job of rendering gw text calls.

For example, the following works just fine for me in Max2009 using the OpenGL driver, but it flickers and often fails to render anything when the mouse is stationary when I switch to the D3D9 or D3D10 driver.

A while back Bobo posted code that converts to screen space gw.wText to try and work around the problem. Check out his post to this thread: http://forums.cgsociety.org/showthread.php?f=98&t=630988

Sadly, I never had much luck with that trick either. I typically give up on the ‘gw’ stuff and render debug lines into the scene.

macroScript Show_Trajectory_on_selected
category:"Animation"
buttontext:"Show_Trajectory_on_selected"
toolTip:"Show_Trajectory_on_selected"
(
	local SpeedShow = false

	fn show_PlaneSpeed =
	(
		gw.setTransform (matrix3 1)
		for t = animationrange.start to animationrange.end do at time t 
		(
			for obj in selection do
			(
				gw.Text obj.pos "." color:white
			)
		)
		
		gw.enlargeupdaterect #whole
		gw.updateScreen()
	)

	on isChecked return SpeedShow

	on Execute do (
		unregisterRedrawviewscallback show_PlaneSpeed
		SpeedShow = not SpeedShow
		if SpeedShow do
		(
			registerRedrawviewscallback show_PlaneSpeed
		)
		setNeedsRedraw complete:true
	)
)

.biddle

is there any reason to use Text for gw draw? you can use hMarker:


...
gw.hMarker (gw.hTranspoint obj.pos) #point color:white
...

it might be a little faster than Text…

other thing is that all gw functions are pretty fast but cause a lot of memory leaking when they called from gw structure. It’s better to put them first in local variables:


...
	local hTranspoint = gw.hTranspoint
	local hMarker = gw.hMarker
	
	fn show_PlaneSpeed =
	(
		gw.setTransform (matrix3 1)
		for t = animationrange.start to animationrange.end do at time t 
		(
			for obj in selection do 
			(
				hMarker (hTranspoint obj.pos) #point color:white
			)
		)
		gw.enlargeupdaterect #whole
		gw.updateScreen()
	)
...

I see the difference of using Text and Marker. It seams like only Text draw supports Z-sorting. I forgot it.

tnx for your replies

the thing i am trying to archive is to show the screenspace trajectory of an object. i want to read out the screenspace position of an object per frame. e.g. at frame 10 the position of an object in camera space. doing this for every frame and then showing this curve in viewport. its helpful for animators to see the trajectory in screenspace of the animation camera and not in worldspace. its complicated to explain, so maybe this makes it more understandable: if you link the target of a targetcamera to an moving object, the screenspace trajectory of that object would always be a single dot.
any help would be appreciated

I think I see what you mean.

See if this will do the trick for you: Rather than worrying about projecting into screen space it is enough to collect the positions (over time) in the local space of the camera and then use gw.transform to render your text in camera space.

macroScript Show_Trajectory_on_selected
category:"Animation"
buttontext:"Show_Trajectory_on_selected"
toolTip:"Show_Trajectory_on_selected"
(
	local SpeedShow = false

	fn show_PlaneSpeed =
	(
		local cam, camSpacePositions, invCameraTM
		
		cam = getActiveCamera()
		if cam != undefined do 
		(
			camSpacePositions = #()
			-- Transform all object positions into the local camera space 'at time t'
			for t = animationrange.start to animationrange.end do at time t 
			(
				invCameraTM = (inverse cam.transform)
				for obj in selection do
				(
					append camSpacePositions (obj.pos * invCameraTM)
				)
			)
			
			-- Set gw transform so that draw calls will be made in the local space of the camera (at the current time)
			gw.setTransform (cam.Transform)
			for csp in camSpacePositions do
			(
				gw.Text csp "." color:green
			)
			
			gw.enlargeupdaterect #whole
			gw.updateScreen()
		)
		
	)

	on isChecked return SpeedShow

	on Execute do (
		unregisterRedrawviewscallback show_PlaneSpeed
		SpeedShow = not SpeedShow
		if SpeedShow do
		(
			registerRedrawviewscallback show_PlaneSpeed
		)
		setNeedsRedraw complete:true
	)
)

My earlier comment regarding using the openGL driver still applies!

–I finally got to use a non-identity gw.transform

.biddle

hi biddle

thank you very much. this is exactly what i wanted.

tnx boris