Looking for input on a small problem with a viewport inside a draggable window

I’ve done some cleanup and got rid of the whole GUI in my game except for three panels that are now draggable on the screen. Everything works fine except for a detail.



The viewport contained in the dragged window stays put when I grab and move said window around. I was hoping to find a move() or reset() method in the Viewport class but there is no such thing so having the preview “working” while dragging is not possible (unless a method would be implemented).



I can think of three ways to handle that.



1 - I could fake a window outline that would be dragged instead of the real one and when dropped would disappear. I could then move the old window and viewport to the new coordinates.



2 - I could grab a screenshot of the last frame of the viewport, delete the viewport, attach the output image to the panel where the viewport would normally be placed and move the window (with the fake viewport as an image) until I dropped it. Then redo the viewport at these coordinates.



3 - Delete both the window and the viewport and use an “outline” frame, like in option 1, while the dragging occurs. Once it’s dropped, move everything at the new coordinates.



I don’t think option number one would look nice. Not sure of number two’s efficiency. It would look a lot nicer than the other two options but the drawback would be that the rotation of the sun inside the viewport would reset and look slightly bad. I guess I could save the rotation but that would add to the work load. Last option I think wouldn’t be that bad.



Also, I tried using viewport.setViewPort(left, right, bottom, top) on the already set viewport (thinking it would move it there), but that didn’t do anything. I was expecting something like that.



Right now, the way it’s done is that I leave the viewport active (setEnabled(false) didn’t seem to do anything as the sun continued rotating) and destroy the viewport when the window is dropped then immediately recreate it. Needless to see it doesn’t look too good. :wink: Thus this post.



Any thoughts or suggestions?



Thanks a lot.

I don’t really understand why setViewPort() fails? I also don’t understand how are you attaching the viewport to the window, because jme3 does not provide that kind of capability. It seems like the issue might be in your code

Momoko_Fan said:
I don't really understand why setViewPort() fails?

Well, technically setViewPort(...) doesn't fail, the changes won't be applied as long as the viewport exists. If I delete the viewport then recreate it (using the saved coordinates) it is at the right place. I have traced it and setViewport(...) runs fine, no error or anything.


I also don't understand how are you attaching the viewport to the window, because jme3 does not provide that kind of capability. It seems like the issue might be in your code

It's not attached to the nifty window. The window sits above it and since it has a hole in it, we can see the viewport through it.

So you’re saying that only the first call of setViewPort() has any effect and any future calls do nothing?

If setViewPort(…) is called before the viewport exist, the next time it will be created it will be at the provided coordinates. If setViewPort(…) is called while the viewport already exist, those new coordinates will only be used after the viewport has been destroyed and then recreated.



And while I’m thinking about it, there are not “saved coordinates”. I got mixed with the window that is being moved that has its coordinates saved (so when clicked on it wouldn’t destroy/recreate the viewport if the coordinates haven’t changed).

I checked the code in RenderManager and Camera and couldn’t find anything wrong, but what do I know? :confused:



Will you take a look at it? I would prefer that option instead of having to destroy/create the viewport every time it is moved.

It works for me



[java]import com.jme3.app.SimpleApplication;

import com.jme3.light.DirectionalLight;

import com.jme3.math.ColorRGBA;

import com.jme3.math.FastMath;

import com.jme3.math.Quaternion;

import com.jme3.math.Vector3f;

import com.jme3.renderer.Camera;

import com.jme3.renderer.ViewPort;

import com.jme3.scene.Geometry;



public class TestMovingView extends SimpleApplication {



private ViewPort view2;

private Camera cam2;

private float angle = 0;



public static void main(String[] args) {

TestMovingView app = new TestMovingView();

app.start();

}



public void simpleInitApp() {

// create the geometry and attach it

Geometry teaGeom = (Geometry) assetManager.loadModel("Models/Teapot/Teapot.obj");

teaGeom.scale(3);



DirectionalLight dl = new DirectionalLight();

dl.setColor(ColorRGBA.White);

dl.setDirection(Vector3f.UNIT_XYZ.negate());



rootNode.addLight(dl);

rootNode.attachChild(teaGeom);



// Setup first view

viewPort.setBackgroundColor(ColorRGBA.Blue);

cam.setLocation(new Vector3f(3.3212643f, 4.484704f, 4.2812433f));

cam.setRotation(new Quaternion(-0.07680723f, 0.92299235f, -0.2564353f, -0.27645364f));



// Setup second view

cam2 = cam.clone();

cam2.setViewPort(.25f, 0.5f, .25f, 0.5f);

cam2.setLocation(new Vector3f(-0.10947256f, 1.5760219f, 4.81758f));

cam2.setRotation(new Quaternion(0.0010108891f, 0.99857414f, -0.04928594f, 0.020481428f));



view2 = renderManager.createMainView("Bottom Left", cam2);

view2.setClearFlags(true, true, true);

view2.attachScene(rootNode);

}



@Override

public void simpleUpdate(float tpf){

angle += tpf;

angle %= FastMath.TWO_PI;



float x = FastMath.cos(angle) * 0.10f;

float y = FastMath.sin(angle) * 0.10f;



cam2.setViewPort(0.25f + x,

0.50f + x,

0.25f + y,

0.50f + y);

}

}

[/java]

Can confirm that it works , in the gui sytem I use I have a 3dModel component, that consists of a viewport.

I can move it around without problems, and it uses setViewPort to change the position where it should be renderd to.

I also confirm the above work… I’ll compare this with my stuff and see the differences.

The main thing is, my previews are part of AbstractAppState and I think that’s causing the issue. I’ve quickly tried to have those updated in the state’s update loop but this will need a lot more checking into. The quick tryout I have made resolved to the same behavior but I’ll have to spend more time on this.

Some results finally!



Got it working (after redoing the whole preview system), but there’s a catch. If there’s a FilterPostProcessor, it won’t work.



Here’s the meat of it.



What I’ve done is simple. I’ve added an AppState (so it would be easier to compare/test against the way I’m doing things). Basically this worked flawlessly. But, as soon as I attached the Bloom filter to the viewport, it stops updating its position. I haven’t used a “turn off/turn on” viewport to check if upon recreation it would reposition to the right place, but as I experienced in my preview system, I’m pretty sure it would.



[java]

/*

*/

package mygame;



import com.jme3.app.SimpleApplication;

import com.jme3.light.DirectionalLight;

import com.jme3.math.ColorRGBA;

import com.jme3.math.FastMath;

import com.jme3.math.Quaternion;

import com.jme3.math.Vector2f;

import com.jme3.math.Vector3f;

import com.jme3.scene.Geometry;



/**

*

  • @author MadJack <danyrioux at danyrioux.com>
  • @creation date Jul 2, 2011, at 10:46:24 PM

    *

    /

    public class TestMovingView extends SimpleApplication {



    private float angle = 0;



    public static void main(String[] args) {

    TestMovingView app = new TestMovingView();

    app.start();

    }



    public void simpleInitApp() {

    // create the geometry and attach it

    Geometry teaGeom = (Geometry) assetManager.loadModel("Models/Teapot/Teapot.obj");

    teaGeom.scale(3);

    DirectionalLight dl = new DirectionalLight();

    dl.setColor(ColorRGBA.White);

    dl.setDirection(Vector3f.UNIT_XYZ.negate());

    rootNode.addLight(dl);

    rootNode.attachChild(teaGeom);

    // Setup first view

    viewPort.setBackgroundColor(ColorRGBA.Blue);

    cam.setLocation(new Vector3f(3.3212643f, 4.484704f, 4.2812433f));

    cam.setRotation(new Quaternion(-0.07680723f, 0.92299235f, -0.2564353f, -0.27645364f));



    ViewTwo viewTwo = new ViewTwo(assetManager, renderManager, rootNode);

    stateManager.attach(viewTwo);



    }



    @Override

    public void simpleUpdate(float tpf) {

    angle += tpf;

    angle %= FastMath.TWO_PI;

    float x = FastMath.cos(angle) * 0.10f;

    float y = FastMath.sin(angle) * 0.10f;



    stateManager.getState(ViewTwo.class).moveViewport(new Vector2f(x, y));

    }

    }

    [/java]



    [java]

    /


    */

    package mygame;



    import com.jme3.app.state.AbstractAppState;

    import com.jme3.asset.AssetManager;

    import com.jme3.math.Quaternion;

    import com.jme3.math.Vector2f;

    import com.jme3.math.Vector3f;

    import com.jme3.post.FilterPostProcessor;

    import com.jme3.post.filters.BloomFilter;

    import com.jme3.renderer.Camera;

    import com.jme3.renderer.RenderManager;

    import com.jme3.renderer.ViewPort;

    import com.jme3.scene.Node;



    /**

    *
  • @author MadJack <danyrioux at danyrioux.com>
  • @creation date Jul 3, 2011, at 1:13:00 PM

    *

    /

    public class ViewTwo extends AbstractAppState {



    private ViewPort view2;

    private Camera cam2;



    public ViewTwo(AssetManager assetManager, RenderManager renderManager, Node rootNode) {

    // Setup second view

    cam2 = new Camera(1280, 1024);

    cam2.setFrustumPerspective(90.0f, 1f, 1f, 75f);

    cam2.setViewPort(.25f, 0.5f, .25f, 0.5f);

    cam2.setLocation(new Vector3f(-0.10947256f, 1.5760219f, 4.81758f));

    cam2.setRotation(new Quaternion(0.0010108891f, 0.99857414f, -0.04928594f, 0.020481428f));



    view2 = renderManager.createMainView("Bottom Left", cam2);

    view2.setClearFlags(true, true, true);

    view2.attachScene(rootNode);



    FilterPostProcessor fpp = new FilterPostProcessor(assetManager);



    BloomFilter bf = new BloomFilter(BloomFilter.GlowMode.SceneAndObjects);

    bf.setExposurePower(1.5f);

    bf.setBloomIntensity(3f);

    bf.setBlurScale(.75f);

    bf.setExposureCutOff(.5f);



    fpp.addFilter(bf);



    /
    COMMENT/UNCOMMENT THE FOLLOWING LINE TO SEE THE RESULT */

    // view2.addProcessor(fpp);

    }



    void moveViewport(Vector2f movedTo) {

    if (movedTo != null) {

    cam2.setViewPort(.25f + movedTo.x, .5f + movedTo.x, .25f + movedTo.y, .5f + movedTo.y);

    }

    }



    @Override

    public void update(float tpf) {

    }



    }

    [/java]

Probably some caching going on in filterpostprocessor that prevents it from working correctly. Maybe @nehon can take a look at this?

I think @nehon didn’t get the name mention notification. :wink: