Problem with billboard node

There seems to be a problem with the billboard node when viewed from around (0,1,0).  I have written a test method to demonstrate:





move closer a tiny bit to see the original

Strafe left or right while the billboard (red) torus is visible to see what I think is a bug.





Also, turning on bounding boxes helps show whats going on.






private void testBillBoardSwitchNode() {

        Spatial realObject = new Torus( "", 40, 40, 2, 5 );
        Spatial billboardObject = new Torus( "", 40, 40, 2, 5 );
       
        Utils.color( realObject, ColorRGBA.white, 128 );
        Utils.color( billboardObject, ColorRGBA.red, 128 );
       
        realObject.setModelBound( new BoundingBox() );
        realObject.updateModelBound();
       
       
       
        billboardObject.setModelBound( new BoundingBox() );
        billboardObject.updateModelBound();
       
        ZBufferState buf = display.getRenderer().createZBufferState();
        buf.setEnabled( true );
        buf.setFunction( ZBufferState.CF_LEQUAL );
       
       
        billboardObject.setRenderState(buf);
        billboardObject.setRenderState( lightState );
        billboardObject.updateRenderState();
       
       
        ImposterNode iNode = new ImposterNode("model imposter", 50, 512, 512 );
        iNode.attachChild( billboardObject );
       
        iNode.setCameraDistance( 50 );
        iNode.setRedrawRate( 0.05f );
       
        BillboardNode bnode = new BillboardNode("imposter bbnode");
        bnode.setAlignment(BillboardNode.SCREEN_ALIGNED);
        bnode.attachChild(iNode);
       
       
        DistanceSwitchModel switchModel = new DistanceSwitchModel( 2 );
        switchModel.setModelDistance( 0, 0, 50 );
        switchModel.setModelDistance( 1, 50, 1000 );
       
       
        DiscreteLodNode gfxModel = new DiscreteLodNode( "Gfx Table", switchModel );
       
       
        gfxModel.attachChild( realObject );
        gfxModel.attachChild( bnode );
        gfxModel.setActiveChild( 0 );
       
       
        cam.getLocation().set( billboardObject.getLocalTranslation().clone().add( 0, -70, 0 ) );
        cam.lookAt( gfxModel.getLocalTranslation(), Vector3f.UNIT_Y );
       
        rootNode.attachChild(gfxModel);
}

After thinking about it the problem must be in the imposterNode; if it was in the Billboard the image would appear to shear as the quad rotated incorrectly.



So, the imposter then?



looking at the updateCamera() method I think its it may be in the newPos caculation, but nothing jumps out at me.  Maybe someone else will see it…






   public void updateCamera(Vector3f eyeLocation) {
      float vDist = eyeLocation.distance(standIn.getCenter());
      float ratio = cameraDistance / vDist;
      Vector3f newPos = (eyeLocation.subtract(standIn.getCenter()))
            .multLocal(ratio).addLocal(standIn.getCenter());
      tRenderer.getCamera().setLocation(newPos);
      tRenderer.getCamera().lookAt(standIn.getCenter(), worldUpVector);
   }



I will get pics up tomorrow, however it is much clearer to see the issue in action with the above example.

So maybe this picture is clear enough…









Again, I set up a test (1st post) to show and play with this  behavior.  When viewed at a horizontal angle the imposter works like a charm, looking vertically (or any angle that is not flat) there seems to be an issue.

The problem is the lookAt combined with an upVector of 0,1,0…  Basically you get to a point where your directional vector and up vector are the same (see also gimbal lock)

Ah yes, I see that now.





Out of curiosity, why use not use a quaternion to set the camera rotation rather than vectors?  Would that fix the issue?

Well, the 3 vectors include position information which a quaternion could not provide.  I suppose we could use a quaternion and a position vector, but I'm (personally) not sure if it would be worth the pain to change at this point.