package jp.sourceforge.acerola3d.a3;

import java.awt.*;
import java.awt.image.BufferedImage;
import javax.media.j3d.*;
import javax.vecmath.*;

import java.io.*;
import java.util.Arrays;

import javax.imageio.ImageIO;

/**
 * 
 */
public class JA3Canvas2 extends TransCanvas3D implements A3CanvasInterface {
    private static final long serialVersionUID = 1L;

    A3VirtualUniverse universe;

    /**
     * (500,500)の大きさのJA3Canvasを作成します。
     */
    public static JA3Canvas2 createJA3Canvas() {
        return createJA3Canvas(500,500);
    }

    /**
     * (w,h)の大きさのJA3Canvasを作ります。
     */
    public static JA3Canvas2 createJA3Canvas(int w,int h) {
        GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment();
        GraphicsDevice gd = ge.getDefaultScreenDevice();
        GraphicsConfigTemplate3D gct3d = new GraphicsConfigTemplate3D();
        return createJA3Canvas(gct3d,gd,w,h);
    }

    /**
     * GraphicsConfigurationオブジェクトを指定して
     * (w,h)の大きさのA3Canvasを作ります。
     */
    public static JA3Canvas2 createJA3Canvas(GraphicsConfigTemplate3D t,GraphicsDevice d,int w,int h) {
        return new JA3Canvas2(t,d,w,h);
    }

    JA3Canvas2(GraphicsConfigTemplate3D t,GraphicsDevice d,int w,int h) {
        super(t,d,false);
        setPreferredSize(new Dimension(w,h));
        setSize(w,h);
        this.canvasIF = this;
        //本当は、以下の処理はここでやりたいところだけど、
        //NullPointerExceptionが出るので、addNotifyメソッドに
        //入れてあげたらうまくいった。でも場合によってはまずいかも。
        //universe = new A3VirtualUniverse(this);
    }

    @Override
    public void addNotify() {
        super.addNotify();
        universe = new A3VirtualUniverse(this);
        enableEvents(java.awt.AWTEvent.MOUSE_EVENT_MASK);
        enableEvents(java.awt.AWTEvent.MOUSE_MOTION_EVENT_MASK);
        enableEvents(java.awt.AWTEvent.MOUSE_WHEEL_EVENT_MASK);
    }
    public TimerBehavior getTimerBehavior() {
        return universe.getTimerBehavior();
    }

    // A3Objectの追加と削除
    @Override
    public void add(A3Object a) {
        universe.add(a);
    }

    @Override
    public void del(A3Object a) {
        universe.del(a);
    }

    @Override
    public void delAll() {
        universe.delAll();
    }

    @Override
    public void delAll(int scene) {
        universe.delAll(scene);
    }

    @Override
    public void setBackground(A3Object a) {
        universe.setBackground(a);
    }

    @Override
    public void delBackground() {
        universe.delBackground();
    }

    @Override
    public void setAvatar(A3Object a) {
        universe.setAvatar(a);
    }

    @Override
    public A3Object getAvatar() {
        return universe.getAvatar();
    }

    // リスナ設定のラッパーメソッド
    @Override
    public void addA3Listener(A3Listener l) {
        universe.addA3Listener(l);
    }

    @Override
    public void removeA3Listener(A3Listener l) {
        universe.addA3Listener(l);
    }

    @Override
    public void setDefaultCameraLoc(double x,double y,double z) {
        universe.setDefaultCameraLoc(x,y,z);
    }

    @Override
    public void setDefaultCameraLoc(Vector3d loc) {
        universe.setDefaultCameraLoc(loc);
    }

    @Override
    public void setDefaultCameraQuat(double x,double y,double z,double w) {
        universe.setDefaultCameraQuat(x,y,z,w);
    }

    @Override
    public void setDefaultCameraQuat(Quat4d quat) {
        universe.setDefaultCameraQuat(quat);
    }

    @Override
    public void setDefaultCameraRot(double x,double y,double z) {
        universe.setDefaultCameraRot(x,y,z);
    }

    @Override
    public void setDefaultCameraRot(Vector3d rot) {
        universe.setDefaultCameraRot(rot);
    }

    @Override
    public void setDefaultCameraRev(double x,double y,double z) {
        universe.setDefaultCameraRev(x,y,z);
    }

    @Override
    public void setDefaultCameraRev(Vector3d rev) {
        universe.setDefaultCameraRev(rev);
    }

    @Override
    public void setDefaultCameraScale(double s) {
        universe.setDefaultCameraScale(s);
    }

    @Override
    public void resetCamera() {
        universe.resetCamera();
    }

    @Override
    public void setCameraLoc(double x,double y,double z) {
        universe.setCameraLoc(x,y,z);
    }

    @Override
    public void setCameraLoc(Vector3d loc) {
        universe.setCameraLoc(loc);
    }

    @Override
    public void setCameraLocImmediately(double x,double y,double z) {
        universe.setCameraLocImmediately(x,y,z);
    }

    @Override
    public void setCameraLocImmediately(Vector3d loc) {
        universe.setCameraLocImmediately(loc);
    }

    @Override
    public void addCameraLoc(double x,double y,double z) {
        universe.addCameraLoc(x,y,z);
    }

    @Override
    public void addCameraLoc(Vector3d loc) {
        universe.addCameraLoc(loc);
    }

    @Override
    public void addCameraLocImmediately(double x,double y,double z) {
        universe.addCameraLocImmediately(x,y,z);
    }

    @Override
    public void addCameraLocImmediately(Vector3d loc) {
        universe.addCameraLocImmediately(loc);
    }

    @Override
    public Vector3d getCameraLoc() {
        return universe.getCameraLoc();
    }

    @Override
    public Vector3d getCameraTargetLoc() {
        return universe.getCameraTargetLoc();
    }

    @Override
    public void setCameraQuat(double x,double y,double z,double w) {
        universe.setCameraQuat(x,y,z,w);
    }

    @Override
    public void setCameraQuat(Quat4d quat) {
        universe.setCameraQuat(quat);
    }

    @Override
    public void setCameraQuatImmediately(double x,double y,double z,double w) {
        universe.setCameraQuatImmediately(x,y,z,w);
    }

    @Override
    public void setCameraQuatImmediately(Quat4d quat) {
        universe.setCameraQuatImmediately(quat);
    }

    @Override
    public void mulCameraQuat(double x,double y,double z,double w) {
        universe.mulCameraQuat(x,y,z,w);
    }

    @Override
    public void mulCameraQuat(Quat4d quat) {
        universe.mulCameraQuat(quat);
    }

    @Override
    public void mulCameraQuatImmediately(double x,double y,double z,double w) {
        universe.mulCameraQuatImmediately(x,y,z,w);
    }

    @Override
    public void mulCameraQuatImmediately(Quat4d quat) {
        universe.mulCameraQuatImmediately(quat);
    }

    @Override
    public Quat4d getCameraQuat() {
        return universe.getCameraQuat();
    }

    @Override
    public Quat4d getCameraTargetQuat() {
        return universe.getCameraTargetQuat();
    }

    @Override
    public void setCameraRot(double x,double y,double z) {
        universe.setCameraRot(x,y,z);
    }

    @Override
    public void setCameraRot(Vector3d rot) {
        universe.setCameraRot(rot);
    }

    @Override
    public void setCameraRotImmediately(double x,double y,double z) {
        universe.setCameraRotImmediately(x,y,z);
    }

    @Override
    public void setCameraRotImmediately(Vector3d rot) {
        universe.setCameraRotImmediately(rot);
    }

    @Override
    public void mulCameraRot(double x,double y,double z) {
        universe.mulCameraRot(x,y,z);
    }

    @Override
    public void mulCameraRot(Vector3d rot) {
        universe.mulCameraRot(rot);
    }

    @Override
    public void mulCameraRotImmediately(double x,double y,double z) {
        universe.mulCameraRotImmediately(x,y,z);
    }

    @Override
    public void mulCameraRotImmediately(Vector3d rot) {
        universe.mulCameraRotImmediately(rot);
    }

    @Override
    public Vector3d getCameraRot() {
        return universe.getCameraRot();
    }

    @Override
    public Vector3d getCameraTargetRot() {
        return universe.getCameraTargetRot();
    }

    @Override
    public void setCameraRev(double x,double y,double z) {
        universe.setCameraRev(x,y,z);
    }

    @Override
    public void setCameraRev(Vector3d rev) {
        universe.setCameraRev(rev);
    }

    @Override
    public void setCameraRevImmediately(double x,double y,double z) {
        universe.setCameraRevImmediately(x,y,z);
    }

    @Override
    public void setCameraRevImmediately(Vector3d rev) {
        universe.setCameraRevImmediately(rev);
    }

    @Override
    public void mulCameraRev(double x,double y,double z) {
        universe.mulCameraRev(x,y,z);
    }

    @Override
    public void mulCameraRev(Vector3d rev) {
        universe.mulCameraRev(rev);
    }

    @Override
    public void mulCameraRevImmediately(double x,double y,double z) {
        universe.mulCameraRevImmediately(x,y,z);
    }

    @Override
    public void mulCameraRevImmediately(Vector3d rev) {
        universe.mulCameraRevImmediately(rev);
    }

    @Override
    public Vector3d getCameraRev() {
        return universe.getCameraRev();
    }

    @Override
    public Vector3d getCameraTargetRev() {
        return universe.getCameraTargetRev();
    }

    @Override
    public void setCameraScale(double s) {
        universe.setCameraScale(s);
    }

    @Override
    public void setCameraScaleImmediately(double s) {
        universe.setCameraScaleImmediately(s);
    }

    @Override
    public void mulCameraScale(double s) {
        universe.mulCameraScale(s);
    }

    @Override
    public void mulCameraScaleImmediately(double s) {
        universe.mulCameraScaleImmediately(s);
    }

    @Override
    public double getCameraScale() {
        return universe.getCameraScale();
    }

    @Override
    public double getCameraTargetScale() {
        return universe.getCameraTargetScale();
    }

    @Override
    public void setCameraLookAtPoint(Vector3d lookAt) {
        universe.setCameraLookAtPoint(lookAt);
    }

    @Override
    public void setCameraLookAtPointImmediately(Vector3d lookAt) {
        universe.setCameraLookAtPointImmediately(lookAt);
    }

    @Override
    public void setCameraLookAtPoint(double x,double y,double z) {
        universe.setCameraLookAtPoint(x,y,z);
    }

    @Override
    public void setCameraLookAtPointImmediately(double x,double y,double z) {
        universe.setCameraLookAtPointImmediately(x,y,z);
    }

    @Override
    public void setCameraLookAtPoint(Vector3d lookAt,Vector3d up) {
        universe.setCameraLookAtPoint(lookAt,up);
    }

    @Override
    public void setCameraLookAtPointImmediately(Vector3d lookAt,Vector3d up) {
        universe.setCameraLookAtPointImmediately(lookAt,up);
    }

    @Override
    public void setCameraLookAtPoint(double x,double y,double z,Vector3d up) {
        universe.setCameraLookAtPoint(x,y,z,up);
    }

    @Override
    public void setCameraLookAtPointImmediately(double x,double y,double z,Vector3d up) {
        universe.setCameraLookAtPointImmediately(x,y,z,up);
    }


    @Override
    public void setHeadLightEnable(boolean b) {
        universe.setHeadLightEnable(b);
    }
    // マウスナビゲーションのモード設定
    @Override
    public void setNavigationMode(NaviMode m,Object...params) {
        universe.setNavigationMode(m,params);
    }

    @Override
    public void setNavigationSpeed(double s) {
        universe.setNavigationSpeed(s);
    }

    @Override
    public double getNavigationSpeed() {
        return universe.getNavigationSpeed();
    }

    @Override
    public void setA3Controller(A3Controller c) {
        universe.setA3Controller(c);
    }
//  ----------座標変換とピッキングのためのラッパーメソッド---------
    @Override
    public Point3d canvasToVirtualCS(int x,int y) {
        return universe.canvasToVirtualCS(x,y);
    }

    @Override
    public Point3d canvasToVirtualCS(int x,int y,double dis) {
        return universe.canvasToVirtualCS(x,y,dis);
    }

    @Override
    public Point3d canvasToPhysicalCS(int x,int y) {
        return universe.canvasToPhysicalCS(x,y);
    }

    @Override
    public Point3d canvasToPhysicalCS(int x,int y,double dis) {
        return universe.canvasToPhysicalCS(x,y,dis);
    }

    @Override
    public Vector3d physicalCSToVirtualCS(Vector3d v) {
        return universe.physicalCSToVirtualCS(v);
    }

    @Override
    public Point physicalCSToCanvas(Point3d p) {
        return universe.physicalCSToCanvas(p);
    }

    @Override
    public Point virtualCSToCanvas(Point3d p) {
        return universe.virtualCSToCanvas(p);
    }

    @Override
    public Vector3d virtualCSToPhysicalCS(Vector3d v) {
        return universe.virtualCSToPhysicalCS(v);
    }

    @Override
    public Vector3d getCameraUnitVecX() {
        return universe.getCameraUnitVecX();
    }

    @Override
    public Vector3d getCameraUnitVecY() {
        return universe.getCameraUnitVecY();
    }

    @Override
    public Vector3d getCameraUnitVecZ() {
        return universe.getCameraUnitVecZ();
    }

    @Override
    public A3Object pickA3(int x,int y) {
        return universe.pickingBehavior.pickA3(x,y);
    }

    @Override
    public A3Object pick(Vector3d origin,Vector3d dir) {
        return universe.pickingBehavior.pickA3(origin,dir);
    }
//  ----------J3DGraphics2D(文字描画など)---------
    @Override
    public void add(Component2D c) {
        universe.add(c);
    }

    @Override
    public void del(Component2D c) {
        universe.del(c);
    }

    @Override
    public void add(Component2D c,int scene) {
        universe.add(c,scene);
    }

    @Override
    public void del(Component2D c,int scene) {
        universe.del(c,scene);
    }

    @Override
    public void paintComponent(Graphics g) {
        super.paintComponent(g);
        Component2D cs[] = universe.getComponents2D().toArray(new Component2D[0]);
        for (Component2D c: cs) {
            c.calPhysicalZ(this);
        }
        Arrays.sort(cs,Component2DComparator.comparator);
        Graphics2D gg = (Graphics2D)g;
        for (Component2D c : cs) {
            if (c.z>0.0)
                continue;
            c.paint(gg,this);
        }
        if (Component2D.advertisement!=null) {
            Component2D.advertisement.paint(gg,this);
        }
        //gg.flush(true);

        //FPSのための計算
        fpsCounter++;
        long l = System.currentTimeMillis()-fpsStartTime;
        if (l>1000) {
            fps = (int)((1000*fpsCounter)/l);
            fpsCounter=0;
            fpsStartTime = System.currentTimeMillis();
        }
    }
    long fpsStartTime;
    int fpsCounter=0;
    int fps;
    @Override
    public int getFPS() {
        return fps;
    }

    @Override
    public void setUpdateInterval(long l) {
        universe.setUpdateInterval(l);
    }

    @Override
    public long getUpdateInterval() {
        return universe.getUpdateInterval();
    }

    @Override
    public void waitForUpdate(long timeout) {
        universe.waitForUpdate(timeout);
    }

    @Override
    public void insertTaskIntoRenderingLoop(Runnable task) {
        super.insertTaskIntoRenderingLoop(task);
    }

    @Override
    public void removeTaskFromRenderingLoop(Runnable task) {
        super.removeTaskFromRenderingLoop(task);
    }

    @Override
    public void insertTaskIntoTimerLoop(Runnable task) {
        universe.insertTaskIntoTimerLoop(task);
    }

    @Override
    public void removeTaskFromTimerLoop(Runnable task) {
        universe.removeTaskFromTimerLoop(task);
    }

    @Override
    public void setCameraInterpolateRatio(double ir) {
        universe.setCameraInterpolateRatio(ir);
    }

    @Override
    public void setDepthBufferFreezeTransparent(boolean b) {
        universe.setDepthBufferFreezeTransparent(b);
    }
//  ----------おまけ機能---------
    volatile boolean check = false;
    GraphicsContext3D gc;
    Raster readRaster;

    public void postSwap() {
        //super.postSwap();
        if (check) {
            gc.readRaster(readRaster);
            check = false;
        }
    }

    @Override
    public void saveImage(File file) throws IOException {
        int width = getWidth();
        int height = getHeight();
        BufferedImage bImage = new BufferedImage(
                               width,height,BufferedImage.TYPE_INT_RGB);
        ImageComponent2D ic2d = new ImageComponent2D(
                                ImageComponent.FORMAT_RGB,bImage);
        //DepthComponentFloat dcf = new DepthComponentFloat(width,height);
        readRaster = new Raster(new Point3f(0.0f,0.0f,0.0f),
                            Raster.RASTER_COLOR,0,0,width,height,
                            ic2d,null);
        check = true;
        while(check) {
            try{Thread.sleep(300);}catch(Exception e){;}
        }

        ImageComponent2D ic = readRaster.getImage();
        BufferedImage image = ic.getImage();

        ImageIO.write(image,"png",file);
//        FileOutputStream out = new FileOutputStream(file);
//        JPEGImageEncoder e = JPEGCodec.createJPEGEncoder(out);
//        e.encode(image);
//        out.close();
    }

    @Override
    public BufferedImage snapshot() {
        int width = getWidth();
        int height = getHeight();
        BufferedImage bImage = new BufferedImage(
                               width,height,BufferedImage.TYPE_INT_RGB);
        ImageComponent2D ic2d = new ImageComponent2D(
                                ImageComponent.FORMAT_RGB,bImage);
        //DepthComponentFloat dcf = new DepthComponentFloat(width,height);
        readRaster = new Raster(new Point3f(0.0f,0.0f,0.0f),
                            Raster.RASTER_COLOR,0,0,width,height,
                            ic2d,null);
        check = true;
        while(check) {
            try{Thread.sleep(300);}catch(Exception e){;}
        }

        ImageComponent2D ic = readRaster.getImage();
        BufferedImage image = ic.getImage();

        return image;
    }

//  ----------シーン関係のメソッド---------
    @Override
    public void prepareScene(int scene) {
        universe.prepareScene(scene);
    }

    @Override
    public void changeActiveScene(int s) {
        universe.changeActiveScene(s);
    }

    @Override
    public void add(A3Object a,int s) {
        universe.add(a,s);
    }

    @Override
    public void del(A3Object a,int s) {
        universe.add(a,s);
    }

    @Override
    public void setDefaultCameraLoc(double x,double y,double z,int scene) {
        universe.setDefaultCameraLoc(x,y,z);
    }

    @Override
    public void setDefaultCameraLoc(Vector3d loc,int scene) {
        universe.setDefaultCameraLoc(loc,scene);
    }

    @Override
    public void setDefaultCameraQuat(double x,double y,double z,double w,int scene) {
        universe.setDefaultCameraQuat(x,y,z,w,scene);
    }

    @Override
    public void setDefaultCameraQuat(Quat4d quat,int scene) {
        universe.setDefaultCameraQuat(quat,scene);
    }

    @Override
    public void setDefaultCameraRot(double x,double y,double z,int scene) {
        universe.setDefaultCameraRot(x,y,z,scene);
    }

    @Override
    public void setDefaultCameraRot(Vector3d rot,int scene) {
        universe.setDefaultCameraRot(rot,scene);
    }

    @Override
    public void setDefaultCameraRev(double x,double y,double z,int scene) {
        universe.setDefaultCameraRev(x,y,z,scene);
    }

    @Override
    public void setDefaultCameraRev(Vector3d rev,int scene) {
        universe.setDefaultCameraRev(rev,scene);
    }

    @Override
    public void setDefaultCameraScale(double s,int scene) {
        universe.setDefaultCameraScale(s,scene);
    }

    @Override
    public void resetCamera(int scene) {
        universe.resetCamera(scene);
    }

    @Override
    public void setCameraLoc(double x,double y,double z,int scene) {
        universe.setCameraLoc(x,y,z,scene);
    }

    @Override
    public void setCameraLoc(Vector3d loc,int scene) {
        universe.setCameraLoc(loc,scene);
    }

    @Override
    public void setCameraLocImmediately(double x,double y,double z,int scene) {
        universe.setCameraLocImmediately(x,y,z,scene);
    }

    @Override
    public void setCameraLocImmediately(Vector3d loc,int scene) {
        universe.setCameraLocImmediately(loc,scene);
    }

    @Override
    public void addCameraLoc(double x,double y,double z,int scene) {
        universe.addCameraLoc(x,y,z,scene);
    }

    @Override
    public void addCameraLoc(Vector3d loc,int scene) {
        universe.addCameraLoc(loc,scene);
    }

    @Override
    public void addCameraLocImmediately(double x,double y,double z,int scene) {
        universe.addCameraLocImmediately(x,y,z,scene);
    }

    @Override
    public void addCameraLocImmediately(Vector3d loc,int scene) {
        universe.setCameraLocImmediately(loc,scene);
    }

    @Override
    public Vector3d getCameraLoc(int scene) {
        return universe.getCameraLoc(scene);
    }

    @Override
    public Vector3d getCameraTargetLoc(int scene) {
        return universe.getCameraTargetLoc(scene);
    }

    @Override
    public void setCameraQuat(double x,double y,double z,double w,int scene) {
        universe.setCameraQuat(x,y,z,w,scene);
    }

    @Override
    public void setCameraQuat(Quat4d quat,int scene) {
        universe.setCameraQuat(quat,scene);
    }

    @Override
    public void setCameraQuatImmediately(double x,double y,double z,double w,int scene) {
        universe.setCameraQuatImmediately(x,y,z,w,scene);
    }

    @Override
    public void setCameraQuatImmediately(Quat4d quat,int scene) {
        universe.setCameraQuatImmediately(quat,scene);
    }

    @Override
    public void mulCameraQuat(double x,double y,double z,double w,int scene) {
        universe.mulCameraQuat(x,y,z,w,scene);
    }

    @Override
    public void mulCameraQuat(Quat4d quat,int scene) {
        universe.mulCameraQuat(quat,scene);
    }

    @Override
    public void mulCameraQuatImmediately(double x,double y,double z,double w,int scene) {
        universe.mulCameraQuatImmediately(x,y,z,w,scene);
    }

    @Override
    public void mulCameraQuatImmediately(Quat4d quat,int scene) {
        universe.mulCameraQuatImmediately(quat,scene);
    }

    @Override
    public Quat4d getCameraQuat(int scene) {
        return universe.getCameraQuat(scene);
    }

    @Override
    public Quat4d getCameraTargetQuat(int scene) {
        return universe.getCameraTargetQuat(scene);
    }

    @Override
    public void setCameraRot(double x,double y,double z,int scene) {
        universe.setCameraRot(x,y,z,scene);
    }

    @Override
    public void setCameraRot(Vector3d rot,int scene) {
        universe.setCameraRot(rot,scene);
    }

    @Override
    public void setCameraRotImmediately(double x,double y,double z,int scene) {
        universe.setCameraRotImmediately(x,y,z,scene);
    }

    @Override
    public void setCameraRotImmediately(Vector3d rot,int scene) {
        universe.setCameraRotImmediately(rot,scene);
    }

    @Override
    public void mulCameraRot(double x,double y,double z,int scene) {
        universe.mulCameraRot(x,y,z,scene);
    }

    @Override
    public void mulCameraRot(Vector3d rot,int scene) {
        universe.mulCameraRot(rot,scene);
    }

    @Override
    public void mulCameraRotImmediately(double x,double y,double z,int scene) {
        universe.mulCameraRotImmediately(x,y,z,scene);
    }

    @Override
    public void mulCameraRotImmediately(Vector3d rot,int scene) {
        universe.setCameraRotImmediately(rot,scene);
    }

    @Override
    public Vector3d getCameraRot(int scene) {
        return universe.getCameraRot();
    }

    @Override
    public Vector3d getCameraTargetRot(int scene) {
        return universe.getCameraTargetRot();
    }

    @Override
    public void setCameraRev(double x,double y,double z,int scene) {
        universe.setCameraRev(x,y,z,scene);
    }

    @Override
    public void setCameraRev(Vector3d rev,int scene) {
        universe.setCameraRev(rev,scene);
    }

    @Override
    public void setCameraRevImmediately(double x,double y,double z,int scene) {
        universe.setCameraRevImmediately(x,y,z,scene);
    }

    @Override
    public void setCameraRevImmediately(Vector3d rev,int scene) {
        universe.setCameraRevImmediately(rev,scene);
    }

    @Override
    public void mulCameraRev(double x,double y,double z,int scene) {
        universe.mulCameraRev(x,y,z,scene);
    }

    @Override
    public void mulCameraRev(Vector3d rev,int scene) {
        universe.mulCameraRev(rev,scene);
    }

    @Override
    public void mulCameraRevImmediately(double x,double y,double z,int scene) {
        universe.mulCameraRevImmediately(x,y,z,scene);
    }

    @Override
    public void mulCameraRevImmediately(Vector3d rev,int scene) {
        universe.setCameraRevImmediately(rev,scene);
    }

    @Override
    public Vector3d getCameraRev(int scene) {
        return universe.getCameraRev();
    }

    @Override
    public Vector3d getCameraTargetRev(int scene) {
        return universe.getCameraTargetRev();
    }

    @Override
    public void setCameraScale(double s,int scene) {
        universe.setCameraScale(s,scene);
    }

    @Override
    public void setCameraScaleImmediately(double s,int scene) {
        universe.setCameraScaleImmediately(s,scene);
    }

    @Override
    public void mulCameraScale(double s,int scene) {
        universe.mulCameraScale(s,scene);
    }

    @Override
    public void mulCameraScaleImmediately(double s,int scene) {
        universe.mulCameraScaleImmediately(s,scene);
    }

    @Override
    public double getCameraScale(int scene) {
        return universe.getCameraScale(scene);
    }

    @Override
    public double getCameraTargetScale(int scene) {
        return universe.getCameraTargetScale(scene);
    }

    @Override
    public void setCameraLookAtPoint(Vector3d lookAt,int scene) {
        universe.setCameraLookAtPoint(lookAt,scene);
    }

    @Override
    public void setCameraLookAtPointImmediately(Vector3d lookAt,int scene) {
        universe.setCameraLookAtPointImmediately(lookAt,scene);
    }

    @Override
    public void setCameraLookAtPoint(double x,double y,double z,int scene) {
        universe.setCameraLookAtPoint(x,y,z,scene);
    }

    @Override
    public void setCameraLookAtPointImmediately(double x,double y,double z,int scene) {
        universe.setCameraLookAtPointImmediately(x,y,z,scene);
    }

    @Override
    public void setCameraLookAtPoint(Vector3d lookAt,Vector3d up,int scene) {
        universe.setCameraLookAtPoint(lookAt,up,scene);
    }

    @Override
    public void setCameraLookAtPointImmediately(Vector3d lookAt,Vector3d up,int scene) {
        universe.setCameraLookAtPointImmediately(lookAt,up,scene);
    }

    @Override
    public void setCameraLookAtPoint(double x,double y,double z,Vector3d up,int scene) {
        universe.setCameraLookAtPoint(x,y,z,up,scene);
    }

    @Override
    public void setCameraLookAtPointImmediately(double x,double y,double z,Vector3d up,int scene) {
        universe.setCameraLookAtPointImmediately(x,y,z,up,scene);
    }

    @Override
    public void setNavigationMode(NaviMode m,int scene,Object...params) {
        universe.setNavigationMode(m,scene,params);
    }

    @Override
    public void setNavigationSpeed(double s,int scene) {
        universe.setNavigationSpeed(s,scene);
    }

    @Override
    public double getNavigationSpeed(int scene) {
        return universe.getNavigationSpeed(scene);
    }

    @Override
    public void setA3Controller(A3Controller c,int scene) {
        universe.setA3Controller(c,scene);
    }

    @Override
    public void setBackground(A3Object a,int scene) {
        universe.setBackground(a,scene);
    }

    @Override
    public void delBackground(int scene) {
        universe.delBackground(scene);
    }

    @Override
    public void setAvatar(A3Object a,int scene) {
        universe.setAvatar(a,scene);
    }

    @Override
    public A3Object getAvatar(int scene) {
        return universe.getAvatar(scene);
    }
//  ---------- LockedA3の処理 ----------
    @Override
    public void addLockedA3(A3Object a) {
        universe.addLockedA3(a);
    }

    @Override
    public void delLockedA3(A3Object a) {
        universe.delLockedA3(a);
    }

    @Override
    public void delAllLockedA3() {
        universe.delAllLockedA3();
    }

    @Override
    public void addLockedA3(A3Object a,int scene) {
        universe.addLockedA3(a,scene);
    }

    @Override
    public void delLockedA3(A3Object a,int scene) {
        universe.delLockedA3(a,scene);
    }

    @Override
    public void delAllLockedA3(int scene) {
        universe.delAllLockedA3(scene);
    }

    @Override
    public void setUpperDirection(A3Object.UpperDirection d) {
        universe.setUpperDirection(d);
    }

    @Override
    public void setUpperDirection(A3Object.UpperDirection d,int scene) {
        universe.setUpperDirection(d,scene);
    }

    @Override
    public A3Object.UpperDirection getUpperDirection() {
        return universe.getUpperDirection();
    }

    @Override
    public A3Object.UpperDirection getUpperDirection(int scene) {
        return universe.getUpperDirection(scene);
    }

    @Override
    public Dimension getCanvasSize() {
        return this.getSize();
    }

    @Override
    public void cleanUp() {
        ;
    }

    @Override
    public void addA3SubCanvas(A3CanvasInterface sc) {
        universe.addA3SubCanvas(sc);
    }

    @Override
    public void setProjectionMode(ProjectionMode m) {
        universe.setProjectionMode(m);
    }

    @Override
    public void setCanvasWidthInPWorld(double s) {
        universe.setCanvasWidthInPWorld(s);
    }

    @Override
    public void setFieldOfView(double f) {
        universe.setFieldOfView(f);
    }

    @Override
    public TransformGroup getTransformGroupForViewPlatform() {
        return universe.getTransformGroupForViewPlatform();
    }

    @Override
    public Canvas3D getCanvas3D() {
        return super.getOffscreenCanvas3D();
    }

    @Override
    public void setSoundGain(double g) {
        universe.setSoundGain(g);
    }

    @Override
    public double getSoundGain() {
        return universe.getSoundGain();
    }

    /**
     * このメソッドはダミーのメソッドなので使用しないで下さい。
     * アプリケーション側のプログラム互換性のために導入されましたが、
     * 後のバージョンでは廃止する予定です。
     */
    @Override
    public BranchGroup getBranchGroupForViewPlatform() {
        // TODO Version3系列ではこのメソッドが削除できるようにすべし。
        return null;
    }

    /**
     * このメソッドはダミーのメソッドなので使用しないで下さい。
     * アプリケーション側のプログラム互換性のために導入されましたが、
     * 後のバージョンでは廃止する予定です。
     */
    @Override
    public void setPickingBehavior(PickingBehavior pb) {
        // TODO Version3系列ではこのメソッドが削除できるようにすべし。
        
    }

    /**
     * このメソッドはダミーのメソッドなので使用しないで下さい。
     * アプリケーション側のプログラム互換性のために導入されましたが、
     * 後のバージョンでは廃止する予定です。
     */
    @Override
    public void setVirtualUniverse(A3VirtualUniverse vu) {
        // TODO Version3系列ではこのメソッドが削除できるようにすべし。
        
    }

    @Override
    public A3VirtualUniverse getVirtualUniverse() {
        return universe;
    }
}
