Hotsopt with rendered sequence

Q&A about the latest versions
Post Reply
Pato Calvelo
Posts: 3
Joined: Thu Apr 01, 2021 10:17 am

Hi!

We are rendering our images to set the Object2VR, to make it smooth we have quite some. To make a spot that is really important to us to link 360 and still on Pano2VR is a really painful and time consuming process.
Is there a way to use rendered masks to set hotspots and Areas? black and white, or RGBA or something on to that direction?

Thank you in advance!

Pato.
Christophe
Posts: 12
Joined: Wed May 25, 2016 4:09 pm

Hi Pato,

I'm not sure which 3d software you're using but I just made a maxscript to batch export hotspot locations. It can't do zone but it really sped up our hotspot creation.
I'm happy to send it your way if you're interested.

Chris
mostah
Posts: 17
Joined: Wed Jun 16, 2021 5:51 pm

Hello Christophe,

Is it true you created a script to export poly hotspot from 3dsMax?
It would so usefull as I have tons of complicated hotspots to draw by hand on each frames, can you please send it to me also?
One good thing for object2vr would be the possibility to import fbx for this kind of task.
Stéphane
Posts: 10
Joined: Wed Nov 10, 2021 12:08 pm

Christophe wrote: Thu Sep 29, 2022 6:33 pm Hi Pato,

I'm not sure which 3d software you're using but I just made a maxscript to batch export hotspot locations. It can't do zone but it really sped up our hotspot creation.
I'm happy to send it your way if you're interested.

Chris
Hi Christopher !

That's great ! Can you make your maxscript available to the community ?
This could save everyone a lot of time !

For hotspots in polygons, the idea of doing it with a state with a transparent png is interesting !
To see if we can superimpose several states ?

Nice continuation !
Thanks !
_
Christophe
Posts: 12
Joined: Wed May 25, 2016 4:09 pm

Hi everyone,

sorry totally forgot about this until I just came back on this forum to ask a question.

Are you still interested in the script?

Chris
Stéphane
Posts: 10
Joined: Wed Nov 10, 2021 12:08 pm

Hi Christopher!

Yes, I am super interested! :D

Thank you very much!
_
Stéphane
Posts: 10
Joined: Wed Nov 10, 2021 12:08 pm

Hi all !

I'm afraid we'll have a solution in 2026 !
If Christopher comes by, don't hesitate to put your script !
GGnome team is working on a solution, but we have no visibility, but hope! :D

Thanks everyone !
_
Christophe
Posts: 12
Joined: Wed May 25, 2016 4:09 pm

Sorry everyone,

Clearly I am not following this forum very closely and I don't get notifications either... Someone just sent me a private message and hurray I got the notification. BTW I have no idea how to reply to you Thomas for some reason the message I received in my email is nowhere to be seen on the forum...

Anyways, after a long long time, see the script below:

I have not used it in a while so it may have bugs or require tweaking.
The basic idea is that you can add/remove objects with the +/- buttons to the list and then organize them up and down (the order they are in the list will match the order they are when imported in object2vr)
You can then select either to export to xml (you would paste the output in the xml file produced by obj2vr) or export to obj2vr (in this case you would open your obj2vr scene in a file editor and paste the code there)

When you click on do the thing, the script will go through your timeline (assuming that you have a camera rotating 360 around your objects) and place a hotspot for each object in the list for each frame.

When it's done it'll copy the output in the clipboard and you can paste it like I mentioned either in the xml or the obj2vr file.

Two notes:
-there are times when you want to hide hotspots because they may be behind another object. Since I couldn't figure out how to automatcially manage occlusions you can just animate the object's visiblity. If the visibility is 1 then the hotspot will be visible, anything lower than that and it'll be skipped.
-you can also set states with the state thing

Let me know if you have questions and hopefully I answer soon...


Code: Select all

(
	UIAccessor.SetWindowText  (dotNetClass "Autodesk.Max.GlobalInterface").Instance.TheListener.EditBox ""	
	frameStart = (substring (animationrange.start as string) 1 ((animationrange.start as string).count - 1)) as integer
	frameEnd=(substring (animationrange.end as string) 1 ((animationrange.end as string).count - 1)) as integer

	halfFrames = false
	hotspotsLocation=#()
	hotspotsName=#()
	safeframe_w=0
	safeframe_h=0
	gw.setTransform (matrix3 1)
	--objectSelected = selection
	viewportViewSize = getViewSize()
	forXML = true
	
	rollout object2vrCreator "Object2VR hotspot exporter" width:487 height:453
	(
		Multilistbox lstSelection "List of objects" pos:[20,20] width:148 height:13 align:#left
		

		
		button bAdd "+" pos:[180,40] width:36 height:22 align:#left
		button bRemove "-" pos:[180,70] width:36 height:22 align:#left
		
		button bMoveUp "Up" pos:[180,100] width:36 height:22 align:#left
		button bMoveDown "Down" pos:[180,130] width:36 height:22 align:#left
		label tSpinnerLabel "State" pos:[180,160]
		spinner sState  pos:[180,180] range:[0,100,0] width:40 type:#integer

		radiobuttons rForXML pos:[20,220] labels:#("For XML", "For OBJ2VR")

		button bDoTheWork "Do the thing" pos:[20,240] width:202 height:22 align:#left
		

		local objectList = #()

		fn updateListBox =
		(
			lstSelection.items = objectList as array
		)

		on bAdd pressed do
		(
			local selectedObjects = selection as array
			for obj in selectedObjects do
			(
				if findItem objectList obj.name == 0 do
					append objectList obj.name
			)
			updateListBox()
		)

		on bRemove pressed do
		(
			local selectedItem = lstSelection.selection as array
			if selectedItem.count > 0 do
			(
				for item in selectedItem do
					deleteItem objectList item
				updateListBox()
			)
		)

		on bMoveUp pressed do MoveItem lstSelection dir:-1
		on bMoveDown pressed do MoveItem lstSelection dir:1


		

		fn getObjectLocationInViewport =
		(
			
			--Break this function into smaller chunks since we don't really need to run it at every frame
			--To Do
			
			viewSize = [gw.getWinSizeX(), gw.getWinSizeY()] 
			renderSize = [renderWidth, renderHeight]

			local viewAspect = viewSize.x as float / viewSize.y
			local renderAspect = renderSize.x as float / renderSize.y

			local x, y
			if (viewAspect > renderAspect) then
			(       
				safeframe_h = viewSize.y
				safeframe_w = (safeframe_h * renderAspect) as integer
				y = 0
				x = (viewSize.x - safeframe_w) / 2
			)
			else
			(
				safeframe_w = viewSize.x
				safeframe_h = (safeframe_w / renderAspect) as integer
				x = 0
				y = (viewSize.y - safeframe_h) / 2        
			)
			
			
		)
		fn getObjectScreenLocation obj =(
			
			objectScreenPos= undefined
			gw.setTransform (matrix3 1)
			objectScreenPos= gw.transpoint obj.position
			
			posX = ((objectScreenPos.x/viewportViewSize.x))
			posY = ((objectScreenPos.y/viewportViewSize.y)) 
			if (forXML) then
			(
				newX = (objectScreenPos.x - (viewportViewSize.x- safeframe_w )/ 2)/safeframe_w
				newY = (objectScreenPos.y - (viewportViewSize.y- safeframe_h )/ 2)/safeframe_h
			)
			else
			(
				newX = (objectScreenPos.x - (viewportViewSize.x- safeframe_w )/ 2) * renderWidth/safeframe_w 
				newY = (objectScreenPos.y - (viewportViewSize.y- safeframe_h )/ 2) * renderHeight/safeframe_h
			)
			print sliderTime
			print [newX,newY]
			return [newX,newY]
		)
		fn printHotspot hotspotList hotspotName forXml =
		(
			hIndex = finditem  lstSelection.items hotspotName
			currColumn=0
			hotspotsInfo = ""
			if (forXml) then
			(
				
				hIndex = finditem hotspotList hotspotName
				hotspotsInfo += "<hotspot title=\"\" target=\"\" skinid=\"\" url=\"\" id=\""
				hotspotsInfo += hotspotList[hIndex]
				hotspotsInfo +=  "\" reuse=\"0\">\n"
				
				for hotspot in hotspotsLocation[hIndex] do
				(
					
					if (hotspot!=undefined) then
					(
						
						 hotspotsInfo +=  ("	<location x=\""+((hotspot[1] as  Float) as String) +"\" y=\""+((hotspot[2] as  Float) as String) +"\" row=\"0\" column=\""+(currColumn as String)+"\" state=\""+sState.value as String+"\"/>\n")		
						
					)
					currColumn+=1
				)
				hotspotsInfo +=  "</hotspot>\n"
			)
			else
			(
				hotspotsInfo+= "<hotspot>\n\t<type>point</type>\n\t<id>"
				hotspotsInfo+= lstSelection.items[hIndex]
				hotspotsInfo+= "</id>\n\t<title></title>\n\t<skinid></skinid>\n"
				for hotspot in hotspotsLocation[hIndex] do
				(
					if (hotspot!=undefined) then
					(
						hotspotsInfo+= "\t<pointitem>\n"
						hotspotsInfo+= ("\t\t<column>"+(currColumn as String)+"</column>\n")
						hotspotsInfo+= "\t\t<row>0</row>\n"
						hotspotsInfo+= "\t\t<state>"+sState.value as String+"</state>\n"
						hotspotsInfo+= ("\t\t<xpos>"+((hotspot[1] as  integer) as String) +"</xpos>\n")
						hotspotsInfo+= ("\t\t<ypos>"+ ((hotspot[2] as integer) as String) +"</ypos>\n")
						hotspotsInfo+= "\t</pointitem>\n"
						
					)
					currColumn+=1
				)
				hotspotsInfo+= "</hotspot>\n"
			)
			return hotspotsInfo
			
		)
		fn machintest=(
			getObjectLocationInViewport()
			caca = getObjectScreenLocation $
			
		)
		on object2vrCreator open do(
			--machintest()
			
		)
		fn doWork forXML=(
			if (lstSelection.selection.count>0) then
			(
				getObjectLocationInViewport()
				currHotspot=1
				
				for o in lstSelection.items do
				(
					
					hotspotsLocation[currHotspot]=#()
					currHotspot+=1
				)
				--sliderTime = frameStart as time
				for i = frameStart to frameEnd do 
				(
					sliderTime = i as time
					if ((halfFrames AND (mod i 2)==0) OR (NOT halfFrames)) then (
						currHotspot=1
						for objName in lstSelection.items do
						(
							obj = getNodeByName objName
							if (obj.visibility) then
							(
								screenPos = getObjectScreenLocation obj
									 
	 
								if (( forXML AND screenPos[1]>=0 AND screenPos[1]<=1 AND screenPos[2]>=0 AND screenPos[2]<=1) OR ( NOT forXML AND screenPos[1]>=0 AND screenPos[1]<=renderWidth AND screenPos[2]>=0 AND screenPos[2]<=renderHeight)) then
								append hotspotsLocation[currHotspot] screenPos
								else append hotspotsLocation[currHotspot] undefined
							)
							
							else
							append hotspotsLocation[currHotspot] undefined
							currHotspot+=1
						)
					)
					
					
				)

				dataToClipboard = ""	
					
				allObjects = object2vrCreator.lstSelection.items
				for hotspot in allObjects do
				(
					
					dataToClipboard+= printHotspot allObjects hotspot forXML
				)		
				setClipboardText dataToClipboard 
			)



		)
		on bDoTheWork pressed do
		(
		
		if (rForXML.state==2) then forXML = false
		doWork(forXML)
	)
	)
	


	


	

	

	
	fn MoveItem ctrl dir:1 =
	(
		if ctrl.selection.numberset == 1 do
		(
			local arr = ctrl.items
			sel = (ctrl.selection as array)[1]
			
			if case dir of
			(
				(-1):sel > 1
				( 1):sel < arr.count
			)
			do
			(
				swap arr[sel] arr[sel+dir]
				ctrl.items = arr
				ctrl.selection = sel+dir
			)
		)
	)
	



	-- Create the rollout window
	createdialog object2vrCreator 250 280

)
Stéphane
Posts: 10
Joined: Wed Nov 10, 2021 12:08 pm

Hi Christophe!

This is so cool! I have to test this! It takes the pivot of the 3D object, and it creates a hotspot in point?
A lot of time saved if it works, at worst you will have to take an old version of Max, do you remember which one it was?

Thank you very much!
Have a nice day!
_
Post Reply