Skip to main content

How to rotate View, but *not* rotate ViewPlatform? Head rotate?

25 replies [Last post]
drpaul
Offline
Joined: 2006-02-04
Points: 0

I have a nice little KeyNavigatorBehavior that rotates and translates the ViewPlatform and lets me move in the x, y, and z directions. I can also rotate about the y axis to make left or right turns and then move along the new direction. No problem there.

The problem comes when I rotate up or down (about the x axis.) If I rotate up, and then try to move forward, I move along the upward line of sight and fly off the ground. How can I 'look up' but still keep my feet on the ground when I move?

It seems like I want to rotate View instead of ViewPlatform. But I don't know how to access or set View's transform.

I thought I was on to something with the PhysicalBody methods get/setHeadToHeadTrackerTransform(Transform t). But that transform is supposed to be some kind of constant calibration tied to some sort of head-tracking sensor. That's getting me into an area I know absolutely nothing about. I just want to make it respond to the pageUp and pageDn keys.

Am I going about this all wrong? Is there a simple way to do this?

Thanks.

Reply viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.
kcr
Offline
Joined: 2004-03-17
Points: 0

You can do anything you want in terms of view manipulation by moving/rotating the ViewPlatform (which *is* how you rotate the view in Java 3D). What you are trying to do should not invlolve the PhysicalBody or head-tracker methods. You just need to manipulate the ViewPlatform differently than what you are doing. You can either use multiple transforms or keep your own information to do the rotations about the desired axis and look at the scene from the desired direction. There are several packages that should help you, including Java 3D Fly-Through (j3dfly). There should be some utilities on j3d.org, too.

-- Kevin

drpaul
Offline
Joined: 2006-02-04
Points: 0

Hey Kevin,

Thanks for your reply. But I don't get it.

Sure, I can rotate the ViewPlatform to 'look' in any direction, but if I then want to move about in the xy plane while still looking up, the translation becomes very complicated.

For example, I'm looking straight ahead, parallel to the floor. I rotate up about the x-axis - now I'm looking up. Next, I want to move forward along the floor (while still looking up.) If I were not looking 'up' I would simply increment z in the vp transform. But now, since my vp is rotated, it'll also raise me off the floor. To counter that, I would have to calculate the sine of the angle I'm making with the floor and decrement the y-coordinate in the transform proportionally with the sine and increment the z-coordinate proportional to 1/cosine. Are you saying that's what I have to do? That could get pretty messy. Seems like it should be such a simple thing.

jaakko777
Offline
Joined: 2005-06-20
Points: 0

Hi,

You could do two things in my opinion.

One solution would be to have a transformgroup for your position and apply all Z translations and Y rotations on that, then add your ViewPlatform as a child to it and apply all X rotations on that.

Another solution would be to keep track of your X rotation and everytime you want to translate on Z you first rotate X back by the inverse of your current rotation (looking back straigt ahead) then translate Z and finally rotate back you X to look in the direction you were looking at.

;) Hope this helps,
Jaakko

drpaul
Offline
Joined: 2006-02-04
Points: 0

Hi Jaakko

Your first suggestion sounds a lot like what I want to do. I didn't try it yet because I don't know how to slip another transform group above the ViewPlatformTransform yet. Probably because I only have experience with the SimpleUniverse.

I guess I will have to read up on how to construct the view side without using SimpleUniverse and maybe I can separate the tilt and translate transforms, as you suggest.

Paul

hood
Offline
Joined: 2006-02-05
Points: 0

[My original reply seemed to go another thread...]

The issue is just in the order in which the transforms are computed.
If V is your ViewPlatform's localToVworld, and T is your desired
translation (say [0 0 10]), then:

V x T moves your ViewPlatform with respect to the ViewPlatform's local
coordinate axes -- if you're looking up, you'll travel in that upward
direction 10 units along the ViewPlatform's Z axis, which is what
you're trying to avoid.

T x V moves your ViewPlatform with respect to the virtual world -- if
you're looking up, you'll still travel 10 units along the Z axis in
vworld coordinates, which is what you're trying to do.

-- Mark

drpaul
Offline
Joined: 2006-02-04
Points: 0

Hi Mark,

I hope I understand your suggestion correctly.

Presently, I have only one transform group above the ViewPlatform. Because of that, the order of my transformations will only make a difference on the first transformation (I think). So this probably isn't what you mean.

You refer to a transformation with respect to the virtual world and another with respect to the ViewPlatform's local coordinates. Am I correct in assuming that, in order to do that, I need two transform groups? The ViewPlatform should be a child of a rotation group and the rotation group should be a child of a translation group. Yes?

Since my view side was constructed with SimpleUniverse, my viewPlatformTransform is already a child of the view Branch. So I can't give it a new translation group parent.

I *think* what I have to do is construct a view side from scratch. Then (I think) I can perform a translation with respect to the virtualWorld coordinates and a rotation in the local coordinates. Is this what you mean? I think this is also what Jaakko suggested.

Unfortunately, the Sun Java3D Tutorial simply says that setting up the view side is complicated and from there on it always assumes a SimpleUniverse view side.

If this is what I must do, are you aware of any good tutorials or example for setting up the view side? Or am I misunderstanding you?

Mark Hood

> Date: Thu, 16 Mar 2006 08:47:49 PST
> [Message sent by forum member 'drpaul' (drpaul)]
>
> I hope I understand your suggestion correctly.

I think you got it mostly.

> Presently, I have only one transform group above the ViewPlatform. Because
> of that, the order of my transformations will only make a difference on the
> first transformation (I think). So this probably isn't what you mean.

I was referring to modifying the transform group's Transform3D directly, since
you didn't want to put another transform group above the view platform. Use
the getViewPlatformTransform() method of the ViewingPlatform set up by
SimpleUniverse to get the TransformGroup, and then extract the Transform3D from
that. If that's V, and your translation is T, and then V.mul(T, V) will do
what you want.

> You refer to a transformation with respect to the virtual world and another
> with respect to the ViewPlatform's local coordinates. Am I correct in
> assuming that, in order to do that, I need two transform groups? The
> ViewPlatform should be a child of a rotation group and the rotation group
> should be a child of a translation group. Yes?

That would be the equivalent, yes. The transforms are composited in order from
the root of the scenegraph down, so if V is a child of T, then the effective
transform is T x V from the leaf node to vworld coordinates.

> Since my view side was constructed with SimpleUniverse, my
> viewPlatformTransform is already a child of the view Branch. So I can't give
> it a new translation group parent.

You could use one of the SimpleUniverse constructors that has the numTransforms
parameter. This will provide a ViewingPlatform with that number of transforms
above the ViewPlatform node itself (note that ViewingPlatform is the utility
class -- an extension of BranchGroup -- and ViewPlatform is a core Java 3D
scenegraph node). Then you can use the getMultiTransformGroup() method of
ViewingPlatform to get the MultiTransformGroup -- this is essentially an array
of TransformGroups chained from one to the next, with the TG at index 0 being
the "topmost" and the TG at the end being the one directly above the
ViewPlatform itself.

-- Mark

---------------------------------------------------------------------
To unsubscribe, e-mail: interest-unsubscribe@java3d.dev.java.net
For additional commands, e-mail: interest-help@java3d.dev.java.net

drpaul
Offline
Joined: 2006-02-04
Points: 0

Mark,

Thank you so much for your patience with me on this problem. I am making progress! I tried the first solution you recomended with mul(V,T). It worked just like you predicted.

It does have an unintended consequence, however. I can now tilt up or down without flying off the ground, but when I turn left or right (rotation about y) it no longer moves me in the direction I'm facing. (There's a lesson in 'Be careful what you wish for' in there somewhere.) I figured that I ought to spend the weekend trying to figure a way around this problem before I bug you for yet another solution.

I'm thinking that maybe your other suggestion of setting up a MultiTransformGroup might be the way to go. Maybe I could have one group for left-right rotations another for up-down and a third for translations.

But it seems like there's probably still a way to do it with a more creative use of mul(V,T) etc. I'll try that for a while first.

Thanks a lot for opening my eyes on this stuff. I was unaware that I could use two arguments in mul() and of the getMultiTransformGroup method in in ViewingPlatform().

drpaul
Offline
Joined: 2006-02-04
Points: 0

I just wanted to let everyone know that I got this navigation problem working and thank everyone for their help.

As I mentioned in my last post, I was able to tilt the view up or down yet still translate in the virtual world xz plane (not fly off the ground). I could do that by translating first and then rotating. But this has the unwelcome side-effect of not allowing left/right steering. In order for the steering to work, the rotatation must be performed first and then the translation. Unfortunately, I can't do it both ways at once.

What I ended up doing is keeping track of my tiltAngle. When it's time to translate, I .rotX(-tiltAngle), perform the translation then .rotX(tileAngle) back to where it was. I have to do a similar trick before makeing the rotY rotation.

Anyway, the result is a really nice and simple key navigator. The whole code is barely a hundred lines and with just the arrow and shift keys it can move forward and back, turn left and right, slide left and right, and pan up or down. When I clean it up and put in some comments I'll post it, in case someone wants an easy navigator the behaves like this one. It's also not a CPU hog like KeyNavigatorBehavior is.

Thanks again for all the help.

adamtdisplay
Offline
Joined: 2011-02-02
Points: 0

drpaul,

I have been trying the same for sometime now. Any chance of you sending the final code over that worked?

Thanks

drpaul
Offline
Joined: 2006-02-04
Points: 0

KeyNavBehavior4()

drpaul
Offline
Joined: 2006-02-04
Points: 0

MousePressedBehavior()

drpaul
Offline
Joined: 2006-02-04
Points: 0

MouseNavBehavior()

drpaul
Offline
Joined: 2006-02-04
Points: 0

I figured, the easiest way to present this mouse/key navigation system was to upload a very simple class I call "TheConstruct()". LIke the 'construct' in The Matrix, it is an otherwise empty space in which you can insert anything you want. TheConstruct() is simply a MainFrame with a 3DCanvas to which I have implemented the mouse and key navigation behaviors into the top BranchGroup(). I inserted a ColorCube() object into the scene as so that you can see your movement by referenceing to it.

The three behaviors which make up the navigation controls are: KeyNavBehavior4(), MouseNavBehavior() and MousePressedBehavior(). MouseNavBehavior() wakes up when MousePressedBehavior() detects a right-mouse-click. MouseNavBehavior() rotates the view left, right, up or down, corresponding to mouse movement. KeyNavBehavior4() moves the viewpoint forward or backward along the view direction, but motion is in the x-y plane only. If your view is tilted upward, it does not fly you off the ground. KeyNavBehavior4() will also move the view point left or right, perpendicular to the view direction and in the x-y plane. The controls are W, S, A, D for forward, back, left, right. The arrow keys also work. You can also raise or lower the view point with the Shift or Ctrl keys. The Home key returns the view point to the initial location and rotation. The '<' and '>' keys will produce 90 degree left or right rotation.

I would like to add that the KeyNavBehavior4() was based on something called PlotKeyNavigatorBehavior() by Joy Kyriakopulos in 2001. It provided a means of capturing the key strokes without gobbling up 100% of the CPU like the standard KeyNaveBehavior does.

I have never tried attaching files before, and don't know if I can attach all four to one post, so I'll just attach one file to this post and then attach the remaining three to subsequent posts. They are all small files. First, The Construct():

drpaul
Offline
Joined: 2006-02-04
Points: 0

Instead of a robot to hold the key down, I think a more elegant (and efficient) solution would be to replace the "MOUSE_PRESSED" field variable in the MousePressed() behavior with "MOUSE_MOVED".

adamtdisplay
Offline
Joined: 2011-02-02
Points: 0

Don't worry, i got around it by creating a robot that holds down the mouse button.

Thanks once again

adamtdisplay
Offline
Joined: 2011-02-02
Points: 0

drpaul

That works, perfectly. Thank you so much

Do you think it is possible to rotate the view without having to click the mouse? The simple action of moving the mouse/cursor on it's own is sufficient.

drpaul
Offline
Joined: 2006-02-04
Points: 0

Thanks for your interest in my code. I'd be happy to send or post it. I should have done that way back when.

Since it's been some years since I even looked at it, give me a little time to put the various classes together. I am all tied up today, but I'am pretty sure I can post it tomorrow.

adamtdisplay
Offline
Joined: 2011-02-02
Points: 0
adamtdisplay
Offline
Joined: 2011-02-02
Points: 0

That would be fantastic! I look forward to reading it tomorrow.

I'll try and fix another problem i have today.....Keeping the player/camera within 'bounds' without using collision.

ps.Do you know how to use mouserotate without having to use the left mouse button? eg. rotating the view just by mouse position alone

drpaul
Offline
Joined: 2006-02-04
Points: 0

Using the mouse to rotate...Yes. In fact, the scheme I eventuall came up with uses the following controls:

rotate view left or right via mouse movement left or right.

rotate view up or down via mouse movement forward or back

move forward or back with "w" or "s" keys or with forward / backward arrow keys

slide left or right with "a" or "d" keys or with left / right arrow keys.

Basically, steering is done with the mouse and translations with keys. This is similar to first-person-shooter controls on old PC games.

I did, at one time have an keyboard-only navigation system. If that's what you want, it will take me longer to find it. But if the combination, mouse for steering and keys for moving is good for you, I can get that together sooner because it's the one I always use.

adamtdisplay
Offline
Joined: 2011-02-02
Points: 0

drPaul,

I was just wondering if you were able to find the code?

Thanks

adamtdisplay
Offline
Joined: 2011-02-02
Points: 0

The problem i have is the same as you did originally.

If i look up by using the mouserotate, and then move forward with the keyboard, i fly off the ground. I need the navigation with the keyboard to be unrelated to the view direction. Enabling someone to look to their left whilst walking forward.

adamtdisplay
Offline
Joined: 2011-02-02
Points: 0

The combination of mouse and keyboard sounds perfect.

So if we could give that a go first (eg. the one yo uusually use) that would be good. I will have to integrate it with the java file i have already created which prints out the users position every second

drpaul
Offline
Joined: 2006-02-04
Points: 0

I posted my simple class TheConstruct() to your initial post. I posted this because it shows shows examples of constructers and uses for each which was simplier for me to do than to write it out. I hope this works for you.