Custom input handler / view only mode

Hello,

we would like to bring the viewport in a “look only” mode. We already have deactivated selection etc. but the problem that remains is the need to press Alt to move the camera. We need a solution where moving the camera is the default. How can we achieve that?

Thanks for your help

Carl

You could implement your own camera manipulator using omni.kit.manipulator.camera as a guide. Which camera movements do you want? You can already pan with only middle-click and look around with only right-click.

I mati,

I’ve already seen this extension. But I hoped there is a way to configure that extension in a way to satisfy my needs instead of building an own extension.

We would like to have a pure and simple viewer; Pan with scroll wheel (pinch gesture in touch mode) and tuble mode with left klick… nothing more… no selection, not movement of objects etc.

But at the end I think we will have an own scene manipulator (because we want to enable moving objects etc. in the next step, and we would like to show information like sizes etc.). So I think a good straing point would be to just copy the manipulator extension and reduct it to our needs. But how to deactive the original manipulator then? Can you give me some hint of how we would do that?

Thanks

Carl

I also took a look at “hacking” the behavior you want with the current implementation, but I think it’d be cleaner and safer to re-implement.

I think you’re going to want to disable these extensions:

omni.kit.manipulator.prim
omni.kit.manipulator.transform
omni.kit.manipulator.camera
omni.kit.manipulator.viewport

These may be brought in automatically by omni.kit.viewport.bundle, so you’ll want to disable that one, look at what it’s dependencies are and pick and choose the extensions you actually need for your app.

Hi Mati,

that sounds very good. but I have a small problem… currently non of the extensions you mentioned are enabled in my app.

These are the enabled extensions:
“omni.hydra.rtx” = {}
“omni.kit.asset_converter” = {}
“omni.kit.capture.viewport” = {}
“omni.kit.registry.nucleus” = {}
“omni.kit.renderer.capture” = {}
“omni.kit.uiapp” = {}
“omni.kit.window.viewport” = {}
“omni.kit.widget.stage” = {}
“omni.kit.widget.viewport” = {}
“omni.renderer” = { tag = “rtx” }
“omni.services.core” = {}
“omni.services.diomex.framework.kitagent” = {}
“omni.services.transport.server.http” = {}
“omni.usd” = {}

The extensions you mentioned are all disabled:

But moving objects and manipulating the camera does work?!

Is it possible that I use some kind of old viewport-exntenions or something like that?

Carl

You’re not on Viewport Legacy, are you?

Hi Mati,

yes you are right… I was still on legacy viewport and now I currently switching to the new stuff. Now I can disable the manipulators and write my own in the next steps. But currently I’m stuck with porting my existing code to the new api.

I’m really missing “viewportWindow.set_camera_position”. Currently I’, trying to replace that with
cameraState.set_position_world. But those two methods to not behave the same way (or the combination with the new manipulators results in a different result).

But anyway, I have to implement my own camera manipulator in any case, so I can port my currently code over to that own manipulator.

Thanks for your help

Carl

Hi Mati,

now I´ve tried to get “my own” camera manipulator up and running, by…

…disabling all the default manipulators
…then I copied the original camera manipulator and renamed it
…then I enabled the “new”, renamed manipulator extension

The renamed extension is loaded, but it looks like the manipulator is not attached. because I still can´t move the camera. My expectation was at this step the camera movement would work like with the original manipulator… can you help?

And while I was working on this, the question if this is the right way came more and more in my mind…

I would like to achieve the following three results:

  1. Limit the movement to tumble and zoom
  2. Make it tumble just with the left mouse button (no modifiers etc.)
  3. Limit the camera movement to a given area (to prevent the user to move the camera out of the room)

As I understand 1 and 2 should be possible with the original manipulator (but I have no clue how to change the bindings, perhaps you could provide a sample for that)

Wouldn´t it make sense to extend the functionality of the default manipulator for nr. 3? Limiting camera movement should be required in many cases. Perhaps it would be possible to provide an event that is fired with the new coordinates BEVOR the camera position is updated. Then I could catch that event and override the new coordinates… or just make it possible to specify a bounding box to the manipulator to prevent moving the camera out of the bounding box.

There is a car configurator sample from Nvidia… in this sample the camera movement is limited too… that more or less what I want to achieve…

Implementing my own manipulator based on the original one would cut my of of future developments…

As always… thank you very much for your help

Carl

Hi Mati,

I think I`ve found why my own camera manipulator does not work… the omni.kit.viewport.window-extension does access the camera manipulator extension directly (have a look at camera.py line 31).

But when I just copy the camera manipulator extension and load that too, I get a warning but “my” extension is used… so far so good.

But to be honest my python / 3D-math skills are to limited to get this working. Here is what I’ve got so far:

I’ve changed the code in gesturebase.py for _accumulate_values like this:

def _accumulate_values(self, key: str, x: float, y: float, z: float):
	item = _accumulate_values(self.model, key, x, y, z)

	if item:
		last_transform = self.last_transform

		position = last_transform.ExtractTranslation()
		rotation = last_transform.ExtractRotation()
	
		if (position[1] < 0):
			position[1] = 0
			xxx = last_transform.SetTranslate(position)
			#xxx = last_transform.SetLookAt(position, self.center_of_interest, Gf.Vec3d(0, 1, 0))
		
			data = [xxx[0][0], xxx[0][1], xxx[0][2], xxx[0][3], xxx[1][0], xxx[1][1], xxx[1][2], xxx[1][3], xxx[2][0], xxx[2][1], xxx[2][2], xxx[2][3], xxx[3][0], xxx[3][1], xxx[3][2], xxx[3][3]]
			self.model.set_floats('transform', data)

		self.model._item_changed(None if self.__keyboard else item)

My “goal” here was to prevent to camera to be moved below the plane (y < 0)… but I have ne clue how to override the transform matrix here. Can you help?

Thanks

Carl

Hi Carl. I’m still checking with the dev team to see if they have any other recommendation for this.

Hi Mati,

thank you for the update. I’ve made some progress in the meantime, but I’ve still some problems with the respositioning of the camera when it is outside the limiting bounds. My last attemp was to “zoom” it into the bounds when it is outside, but my problem is that this changes the “center of intereset” and I don´t have a clue how to prevent this. Perhaps one of the devs could have a look at my current code to speed things up…

def _accumulate_values(self, key: str, x: float, y: float, z: float):
	item = _accumulate_values(self.model, key, x, y, z)

	print(self.center_of_interest)

	if item:
		self.model._item_changed(None if self.__keyboard else item)

		if self.cameraAreaBoundingBoxAligned != None:
			lastTransform = self.last_transform
			cameraPosition = lastTransform.Transform(Gf.Vec3d())

			if (self.cameraAreaBoundingBoxAligned.Contains(cameraPosition) == False):
				cameraRay = Gf.Ray()
				#cameraRay.SetEnds(cameraPosition, self.center_of_interest)
				cameraRay.SetEnds(cameraPosition, Gf.Vec3d())
				
				cameraRayIntersection = cameraRay.Intersect(self.cameraAreaBoundingBoxAligned)					

				#if cameraRayIntersection[0] == False:
				#	cameraRay.SetEnds(cameraPosition, self.cameraAreaBoundingBoxAligned.GetMidpoint())
				#	cameraRayIntersection = cameraRay.Intersect(self.cameraAreaBoundingBoxAligned)

				if cameraRayIntersection[0]:
					print("outside")
					newCameraPosition = cameraRay.GetPoint(cameraRayIntersection[1])

					direction = self.center_of_interest.GetNormalized()
					distance = (newCameraPosition - cameraPosition).GetLength()

					amount = direction * distance
					item = _accumulate_values(self.model, 'move', amount[0], amount[1], amount[2])

					#self.model.set_floats('center_of_interest', [0, 0, self.center_of_interest[2] + distance])

					if item:
						self.model._item_changed(None if self.__keyboard else item)

I’ve attached the whole file, I’ve modified to this post too. When the a gesture starts it searches for a prim that has the name of the current camera + “Area” at the end. If such a prim is found, its bounding box is the limit for the camera… hope that helps.

gesturebase.py (10.0 KB)

@c.bickmeier Dev team has confirmed that creating your own camera manipulator is the recommended approach currently. In a future release, you may be able to just subclass from the default camera manipulator to roll your own.

How are you doing with this? I’m catching up on what you have so far.

Hi @mati-nvidia,

thanks for the response. I hadn´d really time to work on this the last days. Still have to problem that my solution (that one I posted here) changes the center of interest when I zoom the camera to fall into the bounds… I hoped that one of your dev could give me hint base on my current solution…

Hi @mati-nvidia ,

I’ve solved the problem by myself… stoppting and starting the interaction before and after zooming did the trick.

Carl

1 Like

Sweet! Glad to hear it.

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.