package jp.sourceforge.acerola3d.a3;

import javax.imageio.ImageIO;
import javax.media.j3d.*;
import javax.vecmath.*;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Enumeration;
import java.util.Hashtable;

import jp.sourceforge.acerola3d.a3.A3Object.UpperDirection;

/**
 * 既存の仮想空間に挿入することで、既存のカメラとは
 * 別の視点からの映像を描画できる3Dキャンバスです。
 * このクラスはA3CanvasInterfaceを実装しており，
 * A3CanvasInterfaceの多くのメソッドは現在アクティブな
 * シーンのカメラやナビゲーションに対して動作するべきものですが，
 * このA3SubCanvasの場合は独自のカメラやナビゲーションモードを
 * 持っており，それに対する操作となる点に注意して下さい．
 */
public class A3SubCanvas extends Canvas3D implements A3CanvasInterface, Component2DContainerInterface {
    private static final long serialVersionUID = 1L;

    BranchGroup viewPlatformBG;
    SubCameraBehavior subCamBehavior;
    View view;
    Transform3D t;
    TransformGroup tg;
    Light headLight;
    PickingBehavior pickingBehavior;
    A3VirtualUniverse virtualUniverse;
    Hashtable<A3Object,BranchGroup> lockedA3Hash = new Hashtable<A3Object,BranchGroup>();
    BranchGroup cameraGroup;
    ArrayList<Runnable> renderingLoopTasks = new ArrayList<Runnable>();

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

    /**
     * (w,h)の大きさのA3Canvasを作ります。
     */
    public static A3SubCanvas createA3SubCanvas(int w,int h) {
        GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment();
        GraphicsDevice gd = ge.getDefaultScreenDevice();
        GraphicsConfiguration gcs[] = gd.getConfigurations();
        GraphicsConfigTemplate3D gct3d = new GraphicsConfigTemplate3D();
        GraphicsConfiguration gc = gct3d.getBestConfiguration(gcs);
        return createA3SubCanvas(gc,w,h);
    }

    /**
     * GraphicsConfigurationオブジェクトを指定して
     * (500,500)の大きさのA3SubCanvasを作ります。
     */
    public static A3SubCanvas createA3SubCanvas(GraphicsConfiguration graCon) {
        return createA3SubCanvas(graCon,500,500);
    }

    /**
     * GraphicsConfigurationオブジェクトを指定して
     * (w,h)の大きさのA3SubCanvasを作ります。
     */
    public static A3SubCanvas createA3SubCanvas(GraphicsConfiguration graCon,int w,int h) {
        return new A3SubCanvas(graCon,w,h);
    }

    A3SubCanvas(GraphicsConfiguration graCon,int w,int h) {
        //super(graCon.getDevice());
        super(graCon);
        //gc = getGraphicsContext3D();
        setSize(w,h);

        PhysicalBody pBody = new PhysicalBody();
        PhysicalEnvironment pEnv = new PhysicalEnvironment();

        viewPlatformBG = new BranchGroup();
        t = new Transform3D();
        ViewPlatform viewPlatform = new ViewPlatform();
        tg = new TransformGroup(t);
        tg.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE);
        tg.setCapability(TransformGroup.ALLOW_TRANSFORM_READ);
        tg.addChild(viewPlatform);
        viewPlatformBG.addChild(tg);
        cameraGroup = new BranchGroup();
        cameraGroup.setCapability(BranchGroup.ALLOW_DETACH);
        cameraGroup.setCapability(BranchGroup.ALLOW_CHILDREN_READ);
        cameraGroup.setCapability(BranchGroup.ALLOW_CHILDREN_EXTEND);
        cameraGroup.setCapability(BranchGroup.ALLOW_CHILDREN_WRITE);
        tg.addChild(cameraGroup);

        headLight = new DirectionalLight();
        headLight.setCapability(Light.ALLOW_STATE_WRITE);
        headLight.setInfluencingBounds(new BoundingSphere(new Point3d(0.0,0.0,0.0),Double.MAX_VALUE));
        headLight.setEnable(false);
        tg.addChild(headLight);

        view = new View();
        view.addCanvas3D(this);
        view.setPhysicalBody(pBody);
        view.setPhysicalEnvironment(pEnv);
        view.attachViewPlatform(viewPlatform);

        subCamBehavior = new SubCameraBehavior(tg);
        viewPlatformBG.addChild(subCamBehavior);
        subCamBehavior.setSchedulingBounds(new BoundingSphere(new Point3d(0.0,0.0,0.0),Double.MAX_VALUE));
    }

    // SubCanvas用インタフェース
    @Override
    public BranchGroup getBranchGroupForViewPlatform() {
        return viewPlatformBG;
    }

    @Override
    public void setPickingBehavior(PickingBehavior pb) {
        pickingBehavior = pb;
        viewPlatformBG.addChild(pb);
    }

    @Override
    public void setVirtualUniverse(A3VirtualUniverse vu) {
        virtualUniverse = vu;
        subCamBehavior.setA3VirtualUniverse(vu);
    }

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

    //カメラ制御
    @Override
    public void setDefaultCameraLoc(double x,double y,double z) {
        subCamBehavior.setDefaultCameraLoc(x,y,z);
    }

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    @Override
    public void setCameraLookAtPoint(Vector3d lookAt) {
        Vector3d up = new Vector3d();
        if (upperDirection==UpperDirection.Y)
            up.y = 1.0;
        else if (upperDirection==UpperDirection.Z)
            up.z = 1.0;
        subCamBehavior.setCameraLookAtPoint(lookAt,up);
    }

    @Override
    public void setCameraLookAtPoint(double x, double y, double z) {
        Vector3d up = new Vector3d();
        if (upperDirection==UpperDirection.Y)
            up.y = 1.0;
        else if (upperDirection==UpperDirection.Z)
            up.z = 1.0;
        subCamBehavior.setCameraLookAtPoint(x,y,z,up);
    }

    @Override
    public void setCameraLookAtPointImmediately(Vector3d lookAt) {
        Vector3d up = new Vector3d();
        if (upperDirection==UpperDirection.Y)
            up.y = 1.0;
        else if (upperDirection==UpperDirection.Z)
            up.z = 1.0;
        subCamBehavior.setCameraLookAtPointImmediately(lookAt,up);
    }

    @Override
    public void setCameraLookAtPointImmediately(double x, double y, double z) {
        Vector3d up = new Vector3d();
        if (upperDirection==UpperDirection.Y)
            up.y = 1.0;
        else if (upperDirection==UpperDirection.Z)
            up.z = 1.0;
        subCamBehavior.setCameraLookAtPointImmediately(x,y,z,up);
    }

//  ----------座標変換のラッパーメソッド---------
    @Override
    public Point3d canvasToVirtualCS(int x, int y) {
        if (avatar==null)
            return null;
        Vector3d v1 = avatar.getLoc();
        Vector3d v2 = subCamBehavior.getCameraLoc();
        Vector3d v = new Vector3d();
        v.sub(v1,v2);
        Vector3d p = virtualCSToPhysicalCS(v);
        return canvasToVirtualCS(x,y,p.z);
    }

    @Override
    public Point3d canvasToVirtualCS(int x,int y,double dis) {
        Point3d p = canvasToPhysicalCS(x,y,dis);
        tg.getTransform(t);
        t.transform(p);
        return p;
    }

    @Override
    public Point3d canvasToPhysicalCS(int x, int y) {
        if (avatar==null)
            return null;
        Vector3d v1 = avatar.getLoc();
        Vector3d v2 = subCamBehavior.getCameraLoc();
        Vector3d v = new Vector3d();
        v.sub(v1,v2);
        Vector3d p = virtualCSToPhysicalCS(v);
        return canvasToPhysicalCS(x,y,p.z);
    }

    @Override
    public Point3d canvasToPhysicalCS(int x,int y,double dis) {
        int dw = this.getWidth();
        int dh = this.getHeight();
        double ww = this.getPhysicalWidth();
        double hh = this.getPhysicalHeight();
        double tt = view.getFieldOfView();//スクリーンの左右の画角

        // dx,dy,dz:スクリーン上での座標(物理座標系で)
        double dx =  ((double)x)*ww/((double)dw)-ww/2.0;
        double dy = -((double)y)*hh/((double)dh)+hh/2.0;
        double dz = -ww/2.0/Math.tan(tt/2.0);

        if (view.getProjectionPolicy()==View.PARALLEL_PROJECTION) {
            double s = view.getScreenScale();
            double sw = this.getScreen3D().getPhysicalScreenWidth();
            //double sh = this.getScreen3D().getPhysicalScreenHeight();
            //return new Point3d(dx/s*(sw/ww),dy/s*(sh/hh),-dis); //どうやらこっちじゃないみたい
            return new Point3d(dx/s*(sw/ww),dy/s*(sw/ww),-dis);
        }

        double s = dis/(-dz);
        return new Point3d(s*dx,s*dy,s*dz);
    }

    @Override
    public Vector3d physicalCSToVirtualCS(Vector3d v) {
        Point3d p = new Point3d(v);
        tg.getTransform(t);
        t.transform(p);
        return new Vector3d(p);
    }

    @Override
    public Point physicalCSToCanvas(Point3d p) {
        int dw = this.getWidth();
        int dh = this.getHeight();
        double ww = this.getPhysicalWidth();
        double hh = this.getPhysicalHeight();

        double tt = view.getFieldOfView();
        tt = ww/2.0/Math.tan(tt/2.0); // 視点とスクリーンの距離
        double zz = -p.z;

        Point ret = new Point();
        if (view.getProjectionPolicy()==View.PARALLEL_PROJECTION) {
            double s = view.getScreenScale();
            double sw = this.getScreen3D().getPhysicalScreenWidth();
            //double sh = virtualUniverse.canvas3d.getScreen3D().getPhysicalScreenHeight();
            ret.x = (int)(( p.x*(dw/((double)ww)))*s*ww/sw+dw/2);
            ret.y = (int)((-p.y*(dh/((double)hh)))*s*ww/sw+dh/2);
        } else {
            ret.x = (int)( p.x*(dw/((double)ww))/(zz/tt))+dw/2;
            ret.y = (int)(-p.y*(dh/((double)hh))/(zz/tt))+dh/2;
        }
        return ret;
    }

    @Override
    public Point virtualCSToCanvas(Point3d p) {
        tg.getTransform(t);
        t.invert();
        t.transform(p);
        return physicalCSToCanvas(p);
    }

    @Override
    public Vector3d virtualCSToPhysicalCS(Vector3d v) {
        Point3d p = new Point3d(v);
        tg.getTransform(t);
        t.invert();
        t.transform(p);
        return new Vector3d(p);
    }

    @Override
    public Vector3d getCameraUnitVecX() {
        Vector3d v = physicalCSToVirtualCS(new Vector3d(1.0,0.0,0.0));
        v.sub(subCamBehavior.cameraNowV);
        return v;
    }

    @Override
    public Vector3d getCameraUnitVecY() {
        Vector3d v = physicalCSToVirtualCS(new Vector3d(0.0,1.0,0.0));
        v.sub(subCamBehavior.cameraNowV);
        return v;
    }

    @Override
    public Vector3d getCameraUnitVecZ() {
        Vector3d v = physicalCSToVirtualCS(new Vector3d(0.0,0.0,1.0));
        v.sub(subCamBehavior.cameraNowV);
        return v;
    }

    @Override
    public void setProjectionMode(ProjectionMode m) {
        if (m==ProjectionMode.PERSPECTIVE) {
            view.setProjectionPolicy(javax.media.j3d.View.PERSPECTIVE_PROJECTION );
            view.setScreenScalePolicy(View.SCALE_SCREEN_SIZE);
        } else if (m==ProjectionMode.PARALLEL) {
            view.setProjectionPolicy(javax.media.j3d.View.PARALLEL_PROJECTION);
            view.setScreenScalePolicy(View.SCALE_EXPLICIT);
        }
    }

    @Override
    public void setCanvasWidthInPWorld(double s) {
        double psw = this.getScreen3D().getPhysicalScreenWidth();
        view.setScreenScale(psw/s);
    }

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

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

    @Override
    public A3Object pick(Vector3d origin,Vector3d dir) {
        return pickingBehavior.pickA3(origin,dir);
    }

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

    @Override
    public void cleanUp() {
        ;
    }

    //CameraInterface
    @Override
    public TransformGroup getTransformGroupForViewPlatform() {
        return tg;
    }
    @Override
    public Canvas3D getCanvas3D() {
        return this;
    }

    A3Object avatar;
    @Override
    public void setAvatar(A3Object a3) {
        avatar = a3;
    }

    @Override
    public A3Object getAvatar() {
        return avatar;
    }

    A3Controller controller = null;
    void setA3Controller0(A3Controller c) {
        if (c!=null)
            c.setA3CanvasInterface(this);
        if (controller!=null) {
            this.removeA3Listener(controller);
            this.removeKeyListener(controller);
            controller.stop();
        }
        controller = c;
        if (controller!=null) {
            this.addA3Listener(controller);
            this.addKeyListener(controller);
            controller.init();
        }
    }

    @Override
    public void setA3Controller(A3Controller c) {
        naviMode = NaviMode.USER;
        setA3Controller0(c);
    }

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

    double naviSpeed = 1.0;
    @Override
    public double getNavigationSpeed() {
        return naviSpeed;
    }

    UpperDirection upperDirection = UpperDirection.Y;
    @Override
    public UpperDirection getUpperDirection() {
        return upperDirection;
    }

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

    @Override
    public void setHeadLightEnable(boolean b) {
        headLight.setEnable(b);
    }

    NaviMode naviMode = NaviMode.NONE;
    @Override
    public void setNavigationMode(NaviMode m,Object...params) {
        naviMode = m;
        if (naviMode == NaviMode.NONE)
            setA3Controller0(new NoneController());
        else if (naviMode == NaviMode.WALK)
            setA3Controller0(new WalkController());
        else if (naviMode == NaviMode.FLY)
            setA3Controller0(new FlyController());
        else if (naviMode == NaviMode.EXAMINE)
            setA3Controller0(new ExamController());
        else if (naviMode == NaviMode.EDIT)
            setA3Controller0(new EditController());
        else if (naviMode == NaviMode.SIMPLE)
            setA3Controller0(new SimpleController(params));
        else if (naviMode == NaviMode.CHASE)
            setA3Controller0(new ChaseController(params));
    }

    @Override
    public synchronized void postRender() {
        //J3DGraphics2D gg = (J3DGraphics2D)getGraphics();
        Component2D cs[] = components2D.toArray(new Component2D[0]);
        for (Component2D c: cs) {
            c.calPhysicalZ(this);
        }
        Arrays.sort(cs,Component2DComparator.comparator);
        J3DGraphics2D gg = getGraphics2D();
        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 setNavigationSpeed(double s) {
        naviSpeed = s;
    }

    @Override
    public void setUpperDirection(UpperDirection d) {
        upperDirection = d;
    }

//  ----------おまけ機能---------
    volatile boolean check = false;
    GraphicsContext3D gc;
    Raster readRaster;

    @Override
    public void postSwap() {
        super.postSwap();
        if (check) {
            gc.readRaster(readRaster);
            check = false;
        }
        synchronized(renderingLoopTasks) {
            for (Runnable r:renderingLoopTasks) {
                r.run();
            }
        }
    }

    @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 addLockedA3(A3Object a) {
        if (lockedA3Hash.containsKey(a))
            return;
        a.setComponent2DContainerInterface(this);
        a.lockedA3=true;
        a.init();
        A3BranchGroup bg = a.getA3BranchGroup();
        cameraGroup.addChild(bg);
        lockedA3Hash.put(a,bg);
    }

    @Override
    public void delAllLockedA3() {
        Enumeration<A3Object> e = lockedA3Hash.keys();
        while (e.hasMoreElements()) {
            A3Object a3 = e.nextElement();
            BranchGroup bg = lockedA3Hash.get(a3);
            bg.detach();
            a3.dispose();
        }
        lockedA3Hash.clear();
    }

    @Override
    public void delLockedA3(A3Object a) {
        BranchGroup bg = lockedA3Hash.get(a);
        if (bg==null)
            return;
        bg.detach();
        a.dispose();
        lockedA3Hash.remove(a);
    }

    @Override
    public A3VirtualUniverse getA3VirtualUniverse() {
        return virtualUniverse;
    }

    ArrayList<Component2D> components2D = new ArrayList<Component2D>();
    @Override
    public void add(Component2D c) {
        synchronized (components2D) {
            if (!components2D.contains(c))
                components2D.add(c);
        }
    }

    @Override
    public void del(Component2D c) {
        synchronized (components2D) {
            components2D.remove(c);
        }
    }

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

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

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


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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    @Override
    public void insertTaskIntoRenderingLoop(Runnable task) {
        synchronized(renderingLoopTasks) {
            renderingLoopTasks.add(task);
        }
    }

    @Override
    public void removeTaskFromRenderingLoop(Runnable task) {
        synchronized(renderingLoopTasks) {
            renderingLoopTasks.remove(task);
        }
    }

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

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

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

    @Override
    public void setDepthBufferFreezeTransparent(boolean b) {
        view.setDepthBufferFreezeTransparent(b);
    }
}
