Skip to content
Julien Gouesse edited this page May 10, 2013 · 3 revisions
/**
 * N.B: This source code uses an obsolete unmaintained version of JOGL and isn't compatible with ardor3d-jogl
 * since its version 0.9
 */
public class Ardor3DLayer extends AbstractLayer implements Scene {
    private Node node = null;
    private final boolean useTextures = true;
    private CanvasRenderer renderer = null;
    private WWModel3D model = null;
    private boolean maitainConstantSize = true;
    private double size = 1;
 
    public void addModel(final WWModel3D model) {
        this.model = model;
    }
 
    @Override
    protected void doRender(final DrawContext dc) {
        initializeArdorSystem(dc);
 
        if (node == null) {
            initialize(dc); // set the local variable node
        }
 
        if (node != null) {
 
            final GL gl = dc.getGL();
            // before draw
            gl.glPushAttrib(GL.GL_TEXTURE_BIT | GL.GL_ENABLE_BIT | GL.GL_CURRENT_BIT | GL.GL_TRANSFORM_BIT);
            if (!dc.isPickingMode()) {
                gl.glEnable(GL.GL_BLEND);
                gl.glBlendFunc(GL.GL_SRC_ALPHA, GL.GL_ONE_MINUS_SRC_ALPHA);
            }
 
            gl.glMatrixMode(javax.media.opengl.GL.GL_MODELVIEW);
            // gl.glPushAttrib(
            // GL.GL_TEXTURE_BIT |
            // GL.GL_LIGHTING_BIT);
 
            if (useTextures) {
                gl.glEnable(GL.GL_TEXTURE_2D);
                gl.glEnable(GL.GL_BLEND);
                gl.glEnable(GL.GL_RESCALE_NORMAL);
            } else {
                gl.glDisable(GL.GL_TEXTURE_2D);
                gl.glDisable(GL.GL_BLEND);
            }
            final Position pos = model.getPosition();
            final Vec4 loc = dc.getGlobe().computePointFromPosition(pos);
            size = computeSize(dc, loc);
            dc.getView().pushReferenceCenter(dc, loc);
 
            gl.glRotated(pos.getLongitude().degrees, 0, 1, 0);
            gl.glRotated(-pos.getLatitude().degrees, 1, 0, 0);
            gl.glScaled(size, size, size);
            node.draw(renderer.getRenderer());
            renderer.getRenderer().renderBuckets();
            // after draw
            gl.glMatrixMode(javax.media.opengl.GL.GL_MODELVIEW);
            gl.glPopMatrix();
            gl.glPopAttrib();
        }
 
    }
 
    private double computeSize(final DrawContext dc, final Vec4 loc) {
        if (maitainConstantSize) {
            return size;
        }
 
        if (loc == null) {
            System.err.println("Null location when computing size of model");
            return 1;
        }
        final double d = loc.distanceTo3(dc.getView().getEyePoint());
        double currentSize = 60 * dc.getView().computePixelSizeAtDistance(d);
        if (currentSize < 2) {
            currentSize = 2;
        }
 
        return currentSize;
    }
 
    public static void initializeArdorSystem(final DrawContext dc) {
 
        if (ContextManager.getContextForKey("HACKED CONTEXT") != null) {
            final RenderContext rc = ContextManager.switchContext("HACKED CONTEXT");
            return;
        }
 
        final JoglContextCapabilities caps = new JoglContextCapabilities(dc.getGL());
        final RenderContext rc = new RenderContext(dc.getGLContext(), caps);
 
        ContextManager.addContext("HACKED CONTEXT", rc);
        ContextManager.switchContext("HACKED CONTEXT");
        final Camera cam = new Camera() {
            @Override
            public FrustumIntersect contains(BoundingVolume bound) {
                return FrustumIntersect.Inside;
            }
        };
        ContextManager.getCurrentContext().setCurrentCamera(cam);
        AWTImageLoader.registerLoader();
    }
 
    public static Node loadColladaModel(final String modelFileStr) throws Exception {
 
        final Node root = new Node("rootNode");
        final int a = modelFileStr.lastIndexOf("/");
        String modelDirStr = modelFileStr.substring(0, a);
        final String modelNameStr = modelFileStr.substring(modelFileStr.lastIndexOf("/") + 1);
 
        final File modelDir = new File(modelDirStr);
        modelDirStr = modelDir.getAbsolutePath();
 
        final ColladaImporter importer = new ColladaImporter();
 
        final SimpleResourceLocator modelLocator = new SimpleResourceLocator(new URL("file:" + modelDirStr));
        final SimpleResourceLocator textureLocator = new SimpleResourceLocator(new URL("file:" + modelDirStr));
        importer.setModelLocator(modelLocator);
        importer.setTextureLocator(textureLocator);
 
        ResourceLocatorTool.addResourceLocator(ResourceLocatorTool.TYPE_MODEL, modelLocator);
        ResourceLocatorTool.addResourceLocator(ResourceLocatorTool.TYPE_TEXTURE, textureLocator);
 
        final ColladaStorage storage = importer.load(modelNameStr);
        root.attachChild(storage.getScene());
 
        root.updateGeometricState(0);
        return root;
    }
 
    private void initialize(final DrawContext dc) {
        try {
            node = loadColladaModel(model.getPath());
            renderer = new JoglCanvasRenderer(this) {
                JoglRenderer joglRenderer = new JoglRenderer();
 
                @Override
                public Renderer getRenderer() {
                    return joglRenderer;
                }
            };
 
            TextureRendererFactory.INSTANCE.setProvider(new JoglTextureRendererProvider());
 
        } catch (final Exception e) {
            e.printStackTrace();
        }
    }
 
    @Override
    public PickResults doPick(final Ray3 arg0) {
        // TODO Auto-generated method stub
        return null;
    }
 
    @Override
    public boolean renderUnto(final Renderer arg0) {
        GameTaskQueueManager.getManager(ContextManager.getCurrentContext()).getQueue(GameTaskQueue.RENDER).execute(
                renderer.getRenderer());
 
        renderer.draw();
        return true;
    }
 
    public void setMaitainConstantSize(final boolean maitainConstantSize) {
        this.maitainConstantSize = maitainConstantSize;
    }
 
    public void setSize(final double size) {
        this.size = size;
    }
}