Wierd behavior?

I have some test application.

I draw one Box:


@Override
public void simpleSetup()
{
Color bg = Color.GRAY;
renderer.setBackgroundColor(makeColorRGBA(bg));

cam.setParallelProjection(true);
cam.setFrustum(0.1f, 1000, 0, width, -height, 0);

ZBufferState zbuf = renderer.createZBufferState();
zbuf.setWritable(false);
zbuf.setEnabled(true);
zbuf.setFunction(ZBufferState.TestFunction.LessThanOrEqualTo);

b =
new Box("My Box", new Vector3f(-50, -50, -50), new Vector3f(50,
50, 50));

b.setModelBound(new BoundingBox());
b.updateModelBound();
rootNode.attachChild(b);
rootNode.updateModelBound();
};



So, I have one Box.
In simple update I am moving that box:


        float dx = 0;

@Override
public void simpleUpdate()
{
System.out.println(dx);
b.setLocalTranslation(dx / 2, -dx, 0);
rootNode.updateModelBound();
dx += 0.01;
}


Here is what is strange.
Box starts to move, and when dx reach 80 (or 90), all scene disappears!

Here are 2 images. First one where dx is 40, and second where dx is greater than 80 (you can notice that all other elements are gone - grid and purple line???).

I just noticed (debug) that when scene are erased rootNodes's property  frustrumIntersects is 'outside' (otherwise is intersects)…

Do the other things in the scene have their own bounding boxes?

No, they don't.

I removed line:

b.setModelBound(new BoundingBox());



and all become normal…



Is this OK?

Why is that? Can I work with picking without Bounding?

try without the  rootNode.updateModelBound(); in simpleUpdate(), its not needed

Also I'd try giving those other things bounding boxes. That way they should be culled correctly.

OK, I removed rootNode.updateModelBound() from simpleUpdate and still nothing…

Now, I do not have any other objects in scene but the Box… And still nothing.

When dx is above 80 box disappears.

Here is my whole implementator:



class MyImplementor extends SimpleCanvasImpl implements MouseListener
{

private final Point screenPos = new Point(); // Global Variable

private final Vector2f screenPosVector = new Vector2f();

private final Ray pickRay = new Ray();

Box b;

PickResults pickResults;

public MyImplementor(int width, int height)
{
super(width, height);
rootNode = new Node("rootNode");
pickResults = new TrianglePickResults();
System.out.println(width + " " + height);
}

@Override
public void simpleSetup()
{
System.out.println("MyImplementor.simpleSetup()");
Color bg = Color.GRAY;
renderer.setBackgroundColor(makeColorRGBA(bg));

rootNode.setLightCombineMode(Spatial.LightCombineMode.Off);

cam.setParallelProjection(true);

cam.setFrustum(0.1f, 1000, 0, width, -height, 0);

ZBufferState zbuf = renderer.createZBufferState();
zbuf.setWritable(false);
zbuf.setEnabled(true);
zbuf.setFunction(ZBufferState.TestFunction.LessThanOrEqualTo);

b =
new Box("My Box", new Vector3f(-50, -50, -50), new Vector3f(50,
50, 50));

b.setRandomColors();
b.setModelBound(new BoundingSphere());
b.updateModelBound();
rootNode.attachChild(b);
rootNode.updateModelBound();
isInitialized = true;
fireMonkeyCanvasInitialized(new MonkeyCanvasEvent(new Object()));

};

float dx = 0;

@Override
public void simpleUpdate()
{
System.out.println(dx);
b.setLocalTranslation(dx / 2, -dx, 0);
b.updateModelBound();
dx += 0.01;
}

public void mouseClicked(MouseEvent e)
{
if (e.getButton() == MouseEvent.BUTTON1) {
screenPos.setLocation(MouseInfo.getPointerInfo().getLocation());

screenPosVector.set(screenPos.x, screenPos.y);

DisplaySystem.getDisplaySystem().getPickRay(screenPosVector,
true, pickRay);

pickResults.clear();
rootNode.findPick(pickRay, pickResults);

System.out.println(pickResults.getNumber());
for (int i = 0; i < pickResults.getNumber(); i++) {
System.out.println("name: "
+ pickResults.getPickData(i).getTargetMesh().getName());
System.out.println("parent node: "
+ pickResults.getPickData(i).getTargetMesh()
.getParent().getName());
}

}

}

public void mouseEntered(MouseEvent e)
{
// TODO Auto-generated method stub

}

public void mouseExited(MouseEvent e)
{
// TODO Auto-generated method stub

}

public void mousePressed(MouseEvent e)
{
// TODO Auto-generated method stub

}

public void mouseReleased(MouseEvent e)
{
// TODO Auto-generated method stub

}

}

/**
* @return
*/
public boolean isInitialized()
{
return isInitialized;
}




The rootNode doesn't have a model bound attached to it (in simple game there is never one attached)…



Try removing the call to update the rootNode model bound, and put model bounds on your other objects; OR try setting the cullHint to never:

box.setCullHint( Node.CullHint.Never );

Still the same… Maybe it would be easier if I give you SimpleGame example:



import java.awt.Color;

import com.jme.app.SimpleGame;
import com.jme.bounding.BoundingSphere;
import com.jme.math.Vector3f;
import com.jme.scene.Node;
import com.jme.scene.Spatial;
import com.jme.scene.shape.Box;
import com.jme.scene.state.ZBufferState;

public class TestGame extends SimpleGame
{

Box b;

@Override
protected void simpleInitGame()
{
rootNode.setLightCombineMode(Spatial.LightCombineMode.Off);
cam.setParallelProjection(true);
cam.setFrustum(0.1f, 1000, 0, 500, -500, 0);

ZBufferState zbuf = display.getRenderer().createZBufferState();
zbuf.setWritable(false);
zbuf.setEnabled(true);
zbuf.setFunction(ZBufferState.TestFunction.LessThanOrEqualTo);

b =
new Box("My Box", new Vector3f(-50, -50, -50), new Vector3f(50, 50,
50));

b.setRandomColors();
b.setModelBound(new BoundingSphere());
b.updateModelBound();
b.setCullHint( Node.CullHint.Never );
rootNode.attachChild(b);


}

float dx = 0;

@Override
protected void simpleUpdate()
{
super.simpleUpdate();
System.out.println(dx);
b.setLocalTranslation(dx / 2, -dx, 0);
dx += 0.01;
}

public static void main(String[] args)
{
TestGame app = new TestGame();
app.setConfigShowMode(ConfigShowMode.AlwaysShow);
app.start();

}

}


The Box disappears after a while....

yup :slight_smile:



(thats how to get good help alrighty)



Here's you problem:



SimpleGame Camera Parallel Method:


        cam.setParallelProjection( true );
        float aspect = (float) display.getWidth() / display.getHeight();
        cam.setFrustum( -100, 1000, -50 * aspect, 50 * aspect, -50, 50 );
        cam.update();



Your Camera Parallel Method:


        cam.setParallelProjection( true );
        cam.setFrustum( 0.1f, 1000, 0, 500, -500, 0 );



Once I changed the frustum everything seemed good...

Thanks!  :slight_smile:

It works now!



Is it possible to set that coordinate (0,0) on upperLeft corner, and negative y axis to go from up to the bottom.

Also, when canvas size is changed I don't need any transformations on my scene (example: when application is maximized I need Box to be same size as before maximization).



I tried some changes on frustum parameters but I did not succeed.

Is it possible to set that coordinate (0,0) on upperLeft corner, and negative y axis to go from up to the bottom.

I don't think so, the issue is that Java starts at the upper left corner, and openGL starts at the lower left corner...
(although its really simple math to invert the y-axis)

when application is maximized I need Box to be same size as before maximization

This is due to the frustum size change alright, I actually need the same logic in my windowed application also.  I have yet to implement it (a LOT of other things to do), but I think you just shrink or expand the viewport with:

camera.setViewPort( left, right, bottom, top);



I found a way how to move (0,0) coordinate in upper left corner and to invert y-axis:


            float aspect = (float) canvas.getWidth() / canvas.getHeight();    
    rootNode.setLocalTranslation(-50 * aspect, 50, 0);
    rootNode.setLocalScale(new Vector3f(1, -1, 1));    
    cam.setParallelProjection(true);
    cam.setFrustum(-100, 1000, -50 * aspect, 50 * aspect, -50, 50);
    cam.update();



I am doing a translation of root node to the (0,0) coordinate, and than scaling with rootNode.setLocalScale(new Vector3f(1, -1, 1)) wich invert y-axis...

Is that correct?
rootNode.setLocalScale(new Vector3f(1, -1, 1));


Yes, scaling by a -1 is a pure openGL trick that might work; BBBBUUUTTTT there is 2 application layers between you and openGL (jME then lwjgl/jogl), therefore the results of scaling by -1 (for jME at least) are not 'guaranteed'.  (although for a simple quad you might be okay)
Yes, scaling by a -1 is a pure openGL trick that might work; BBBBUUUTTTT there is 2 application layers between you and openGL (jME then lwjgl/jogl), therefore the results of scaling by -1 (for jME at least) are not 'guaranteed'.  (although for a simple quad you might be okay)

If the transforms are converted into matrices (which any sane renderer would do) then it would result in the following transform matrix:


1  0  0  0
0 -1  0  0
0  0  1  0
0  0  0  1


which is completely valid. It would flip the Y vertices, causing the model to appear upside down. Even if it doesn't use transform matrices, it probably just multiplies the input vertex by the scale, which would have the same result.

(lol, matrix arithmetic takes me back to the smell of chalk dust ;))



I talked to irrisor about a year ago about the same thing and his words were basically the results are not guaranteed…

(a heads up he was kind enough to give me when I started having problems using this exact technique in jME with an actual model and was simply trying to return the favor)



(face winding is a good example of why this approach is not guaranteed, YES it works and for a simple quad there is generally no problem; but for more complex geometry a little more work is generally needed;  normals are another issue to consider…)