Hello group members,

has anybody of you successfully extended ViewPlatformAWTBehavior
to handle KeyEvents and is willing to share hints or code?

I'm trying to implement a simple Quake style behavior, where the
mouse controls the view direction and some keys (say CURSOR UP/DOWN
and LEFT/RIGHT) move the ViewPlatform forward/reverse and left/right
(called 'strafing' in Quake) with respect to the current view
direction. Needless to say, that the horizon shall remain
horizontally, ever :-).

This works, in principal.

The problem is: since I started to respect deltaTime (via
System.currentTimeMillis() as in KeyNavigatorBehavior) my
Behavior became really worse:

most notably, instead of accelerating smoothly to the desired
maximum speed ever, it shows 3 different real behaviors randomly:

- sometimes it only moves the VP in much too small steps, not
  accelerating at all, while the accelerating key is held down.
  When it is released, the VP suddenly has the maximum speed
  (decelerating then, as wanted, immediately).

- most times it almost accelerates just fine to the desired
  speed, but in all the motion, when the framerate drops (i.e.
  due to new objects coming into view) the motion TOO is affected.
  Which should not be the case at all, as I'm respecting
  deltaTime from the last frame and that should compensate by
  moving the VP farther, when deltaTime is high. Besides, my
  deltaTimes are almost ever 10, 20, 30 ... milli seconds, due
  to the bad PC time resolution, possibly I should integrate
  that, but then, how does the KeyNavigatorBehavior class
  deal with that, I couldn't find any special code?

- sometimes the final speed seems to be about double of the
  desired speed, then the movement seems to be smooth.


My Pseudo-Code is as follows:

  protected synchronized void
      processAWTEvents(final AWTEvent[] events)
  {
    motion = false;
    // set motion = true, if some acc/decelerating
    // or movement is in progress
    if ...  motion = true;
    // handle all AWT events
    ...
    processKeyEvent(event)
    ...
  }

  protected void processKeyEvent(final KeyEvent evt) {
    // record key states into instance variable(s)
    // and set motion = true on any recognized key event
    ...
  }

  protected synchronized void integrateTransforms() {
    // Check if the transform has been changed by another behavior
    targetTG.getTransform(currentTransform) ;
    if (! targetTransform.equals(currentTransform)) {
      resetView();
    }

    calcSpeed();

    // modify the target transform, this simply works
    ...
  }

  private void calcSpeed() {
    long now = System.currentTimeMillis();
    long deltaTime = now - lastTime;
    lastTime = now;

    // check for too old time sample
    if (deltaTime > 2000)  deltaTime = 1;

    // protect against 0 deltaTime, this happens sometimes
    if (deltaTime < 1)  deltaTime = 1;

    float dt = (float)deltaTime / 1000f;

    // exploit key states and then
    // integrate acceleration/drag over dt
    ...
    // integrate velocity over dt
    ...
    // set instance members for integrateTransforms()
    ...
  }

Any hints are VERY welcome

thanks

Georg
 ___   ___
| + | |__    Georg Rehfeld      Woltmanstr. 12     20097 Hamburg
|_|_\ |___   [EMAIL PROTECTED]           +49 (40) 23 53 27 10

===========================================================================
To unsubscribe, send email to [EMAIL PROTECTED] and include in the body
of the message "signoff JAVA3D-INTEREST".  For general help, send email to
[EMAIL PROTECTED] and include in the body of the message "help".

Reply via email to