Skip to main content

A newbie question about ViewPlatformBehavior

No replies
lordsurya08
Offline
Joined: 2011-11-20
Points: 0

I'm trying to create a TBS in which the keyboard is used to manipulate the ViewPlatform. The idea is to have the view platform up in the air looking down at an angle on a wide landscape. Hitting the arrow keys moves the view platform but preserves the angled view. To give you a better idea, I am trying to replicate this:

http://www.youtube.com/watch?v=hDmPQQJm2ts (just watch the first few seconds)

So here is how I designed it:

1. the landscape runs along the XY plane, with the Z axis pointing towards the sky.

2. a KeyBehavior class (extending ViewPlatformBehavior) controls the view platform.

3. in KeyBehavior's constructor, the view platform's TransformGroup (TG) is rotated by a certain angle to give it that angled view.

4. Moving the arrow keys should modify the X and Y coordinates while not changing the rotation or the Z coordinate; this preserves the angled view.

The problem is, moving the arrow keys changes the Z coordinate too due the the rotation; pressing the W key, for example, moves forward but raises the elevation as well, which is undesirable. I can't understand why this should happen. If anyone can suggest a solution, I would appreciate it very much.

____

edit: couldn't upload the file so I just copy and pasted:

package graphics;

import java.awt.AWTEvent;

import java.awt.AWTEvent.*;

import java.awt.event.*;

import java.util.ArrayList;

import java.util.Enumeration;

import javax.media.j3d.*;

import javax.vecmath.*;

import com.sun.j3d.utils.universe.*;

import com.sun.j3d.utils.behaviors.vp.*;

/**

* Creates a KeyBehavior object, which responds to the key presses as follows: <br>

* <br>

* WASD keys - moves the viewer's position and the point the viewer is looking at.

* The speed at which tbe viewpoint moves is proportional to the Z coordinate i.e.

* level of zoom. The viewpoint is moved in a way such that the angle of elevation of

* the viewpoint remains constant. <br>

* <br>

* Middle mouse wheel - zooms in and out. Zooming increases the Z coordinate as well as

* modifying the Y coordinate to maintain a constant angle of elevation. Zoom speed is

* proportional to the square of the current Z coordinate.

*/

public class KeyBehavior extends ViewPlatformBehavior

{

private TransformGroup viewTG;

private WakeupOr wakeupOr;

private ArrayList<Integer> keyPressedList = new ArrayList<Integer>();

private static final double ANGLE_OF_ELEVATION = -Math.PI / 6;

private static final double INIT_POSN_Z = 15;

private static final double MOVE_STEP = 0.2;

private static final double ALT_MODIFIER = 5;

private static final int MOVE_RATE_DURING_REPEAT_PAUSE = 24;

private static final Vector3d LEFT = new Vector3d(-MOVE_STEP, 0, 0);

private static final Vector3d RIGHT = new Vector3d(MOVE_STEP, 0, 0);

private static final Vector3d UP = new Vector3d(0, MOVE_STEP, 0);

private static final Vector3d DOWN = new Vector3d(0, -MOVE_STEP, 0);

private static final double ZOOM_SPEED_MULTIPLIER = 8;

private static final double ZOOM_IN = -MOVE_STEP * ZOOM_SPEED_MULTIPLIER;

private static final double ZOOM_OUT = MOVE_STEP * ZOOM_SPEED_MULTIPLIER;

private static final double ZOOM_MAX = 200;

private static final double ZOOM_MIN = 3;

private static final Vector3d ALT_LEFT = new Vector3d(-MOVE_STEP * ALT_MODIFIER, 0, 0);

private static final Vector3d ALT_RIGHT = new Vector3d(MOVE_STEP * ALT_MODIFIER, 0, 0);

private static final Vector3d ALT_UP = new Vector3d(0, MOVE_STEP * ALT_MODIFIER, 0);

private static final Vector3d ALT_DOWN = new Vector3d(0, -MOVE_STEP * ALT_MODIFIER, 0);

private final int forwardKey = KeyEvent.VK_W;

private final int backKey = KeyEvent.VK_S;

private final int leftKey = KeyEvent.VK_A;

private final int rightKey = KeyEvent.VK_D;

private static Point3d lookAt = new Point3d(0, 0, 0.1);

private static final Vector3d normal = new Vector3d(0, 0, 1);

private Vector3d move = new Vector3d();

private Vector3d positionVec = new Vector3d();

private Transform3D t3d = new Transform3D();

private Transform3D move3d = new Transform3D();

private double zoom;

public KeyBehavior(TransformGroup viewTG)

{

double initY = -INIT_POSN_Z / Math.tan(ANGLE_OF_ELEVATION);

this.viewTG = viewTG;

viewTG.getTransform(t3d);

t3d.setTranslation(new Vector3d(0, 0, INIT_POSN_Z));

viewTG.setTransform(t3d);

viewTG.getTransform(t3d);

t3d.rotX(0.5);

viewTG.setTransform(t3d);

WakeupCriterion[] wakeupCriterion = new WakeupCriterion[3];

wakeupCriterion[0] = new WakeupOnAWTEvent(KeyEvent.KEY_PRESSED);

wakeupCriterion[1] = new WakeupOnAWTEvent(KeyEvent.KEY_RELEASED);

wakeupCriterion[2] = new WakeupOnElapsedTime(MOVE_RATE_DURING_REPEAT_PAUSE);

wakeupOr = new WakeupOr(wakeupCriterion);

}

public void initialize()

{

wakeupOn(wakeupOr);

}

public void processStimulus(Enumeration criteria)

{

int keyCode = -1;

int keyCodeIndex;

WakeupCriterion wakeup;

AWTEvent[] event;

while (criteria.hasMoreElements()) {

wakeup = (WakeupCriterion) criteria.nextElement();

if (wakeup instanceof WakeupOnAWTEvent) {

event = ((WakeupOnAWTEvent) wakeup).getAWTEvent();

for (int i = 0; i < event.length; i++) {

if(event[i] instanceof KeyEvent) {

keyCode = ((KeyEvent) event[i]).getKeyCode();

keyCodeIndex = keyPressedList.indexOf(keyCode);

switch(event[i].getID()) {

case KeyEvent.KEY_PRESSED:

if(keyCodeIndex == -1) {

keyPressedList.add(keyCode);

}

processKeyEvents();

break;

case KeyEvent.KEY_RELEASED:

if(keyCodeIndex != -1) {

keyPressedList.remove(keyCodeIndex);

}

break;

}

}

}

} else if(wakeup instanceof WakeupOnElapsedTime) {

if(!keyPressedList.isEmpty()) {

processKeyEvents();

}

}

}

wakeupOn(wakeupOr);

}

private void processKeyEvents()

{

move.set(0, 0, 0);

for(Integer keyCode : keyPressedList) {

switch(keyCode) {

case forwardKey:

move.add(UP);

break;

case backKey:

move.add(DOWN);

break;

case leftKey:

move.add(LEFT);

break;

case rightKey:

move.add(RIGHT);

break;

}

}

move.scale(getZ() / INIT_POSN_Z);

moveTG(move);

}

private void moveTG(Vector3d move)

{

double zoom = getZ();

if(zoom + move.z > ZOOM_MAX) {

move.z = 200 - zoom;

} else if (zoom + move.z < ZOOM_MIN) {

move.z = 5 - zoom;

}

targetTG.getTransform(t3d);

move3d.setTranslation(move);

t3d.mul(move3d);

targetTG.setTransform(t3d);

System.out.println(getPositionVec());

}

public void handleZoomEvent(MouseWheelEvent zoomEvent)

{

zoom = zoomEvent.getWheelRotation() == -1 ? ZOOM_IN : ZOOM_OUT;

zoom *= Math.pow(getZ() / INIT_POSN_Z, 1);

move.set(new Vector3d(0, 0, zoom));

//move.add(new Vector3d(0, zoom * Math.tan(ANGLE_OF_ELEVATION), 0));

moveTG(move);

}

private Vector3d getPositionVec()

{

targetTG.getTransform(t3d);

t3d.get(positionVec);

return positionVec;

}

private Point3d getPositionPoint()

{

positionVec = getPositionVec();

return new Point3d(positionVec.x, positionVec.y, positionVec.z);

}

private double getZ()

{

return getPositionVec().getZ();

}

}