Subversion Repositories AndroidProjects

Rev

Blame | Last modification | View Log | RSS feed

/*
 * PROJECT: NyARToolkit on Android
 * --------------------------------------------------------------------------------
 * This work is based on the NyARToolKit developed by
 *   R.Iizuka
 * http://www.hitl.washington.edu/artoolkit/
 *
 * The NyARToolkit on Android is an Application of NyARToolkit
 * to Google Android Emulator Environment.
 * Copyright (C)2008 Shinobu Izumi
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation; either version 2
 * of the License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this framework; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 *
 * For further information please contact.
 *      <stagesp1(at)gmail.com>
 *
 */

package jp.ac.kyutech.ai.ylab.shiva;

import java.io.InputStream;

import jp.nyatla.nyartoolkit.core.NyARCode;
import jp.nyatla.nyartoolkit.jogl.utils.GLNyARParam;
import android.app.Activity;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.os.Bundle;
import android.util.Log;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.View;
import android.view.ViewGroup;
import android.view.Window;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;
import android.widget.LinearLayout;
import android.widget.TableLayout;
import android.widget.TableRow;
import android.widget.TextView;

import com.tomgibara.android.camera.CameraSource;
import com.tomgibara.android.camera.SocketCamera;

public class NyARToolkitAndroidActivity extends Activity {

        private final int WC = ViewGroup.LayoutParams.WRAP_CONTENT;
        private final int FP = ViewGroup.LayoutParams.FILL_PARENT;

        private Preview mPreview;

        private Button button;

        private boolean connected;

        private TextView infoText;

        @Override
        protected void onCreate(Bundle icicle) {
                super.onCreate(icicle);

                Log.d("trace", "onCreate");

                // Hide the window title.
                requestWindowFeature(Window.FEATURE_NO_TITLE);

                LinearLayout linearLayout = new LinearLayout(this);
                linearLayout.setOrientation(LinearLayout.VERTICAL);
                setContentView(linearLayout);

                // Create our Preview view and set it as the content of our
                // Activity
                mPreview = new Preview(this);
                linearLayout.addView(mPreview, new LinearLayout.LayoutParams(WC, WC));

                infoText = new TextView(this);
                infoText.setText("Information will be shown in here.");
                linearLayout.addView(infoText, new LinearLayout.LayoutParams(FP, WC));

                TableLayout tableLayout = new TableLayout(this);
                tableLayout.setColumnStretchable(1, true);
                linearLayout
                                .addView(tableLayout, new LinearLayout.LayoutParams(WC, WC));

                TextView hostLabel = new TextView(this);
                hostLabel.setText("Host : ");

                final EditText host = new EditText(this);
                host.setText("192.168.11.5");

                TableRow tableRow1 = new TableRow(this);
                tableRow1.addView(hostLabel);
                tableRow1.addView(host, new TableRow.LayoutParams(FP, WC));

                TextView portLabel = new TextView(this);
                portLabel.setText("Port : ");

                final EditText port = new EditText(this);
                port.setText("9889");

                TableRow tableRow2 = new TableRow(this);
                tableRow2.addView(portLabel);
                tableRow2.addView(port, new TableRow.LayoutParams(FP, WC));

                button = new Button(this);
                button.setOnClickListener(new OnClickListener() {
                        @Override
                        public void onClick(View v) {
                                if (connected) {
                                        infoText.setText("Disconnected");
                                        mPreview.pause();
                                        button.setText("Connect");
                                } else {
                                        String hostStr = host.getText().toString();
                                        String portStr = port.getText().toString();
                                        try {
                                                int p = Integer.parseInt(portStr);

                                                mPreview.set(hostStr, p);
                                        } catch (Exception e) {
                                                infoText.setText("Illegal Argument");
                                                return;
                                        }

                                        infoText.setText("Connecting to " + hostStr + " on port "
                                                        + portStr);
                                        mPreview.resume();

                                        button.setText("Disconnect");
                                }
                        }
                });
                button.setText("Connect");

                TableRow tableRow3 = new TableRow(this);
                TableRow.LayoutParams trl2 = new TableRow.LayoutParams(FP, WC);
                trl2.span = 2;
                tableRow3.addView(button, trl2);

                tableLayout.addView(tableRow1, new TableLayout.LayoutParams(FP, WC));
                tableLayout.addView(tableRow2, new TableLayout.LayoutParams(FP, WC));
                tableLayout.addView(tableRow3, new TableLayout.LayoutParams(FP, WC));

        }

        @Override
        protected void onResume() {
                Log.d("trace", "onRegume");
                // Because the CameraDevice object is not a shared resource,
                // it's very important to release it when the activity is paused.
                super.onResume();

                button.setText("Connect");
                connected = false;

        }

        @Override
        protected void onPause() {
                Log.d("trace", "onPause");
                // Start Preview again when we resume.
                super.onPause();

                mPreview.pause();
                connected = false;
        }

        class Preview extends SurfaceView implements SurfaceHolder.Callback {
                SurfaceHolder mHolder;
                private PreviewThread mPreviewThread;
                private boolean mHasSurface;

                private GLNyARParam ar_param = new GLNyARParam();
                private NyARCode ar_code = new NyARCode(16, 16);

                // String host = "133.17.159.104";
                String host = "192.168.11.5";

                int port = 9889;

                private Bitmap fixedBitmap;

                public void set(String host, int port) {
                        this.host = host;
                        this.port = port;
                }

                Preview(Context context) {
                        super(context);

                        // Install a SurfaceHolder.Callback so we get notified when the
                        // underlying surface is created and destroyed.
                        mHolder = getHolder();
                        mHolder.addCallback(this);
                        mHasSurface = false;

                        // In this example, we hardcode the size of the preview. In a real
                        // application this should be more dynamic. This guarantees that
                        // the uderlying surface will never change size.
                        mHolder.setFixedSize(320, 240);

                        InputStream in = getResources().openRawResource(R.raw.marker);
                        fixedBitmap = BitmapFactory.decodeStream(in);

                        // NyARToolkitの準備
                        try {
                                ar_param.loadFromARFile(getResources().openRawResource(
                                                R.raw.camera_para));
                                ar_param.changeSize(320, 240);
                                ar_code.loadFromARFile(getResources().openRawResource(
                                                R.raw.patt));
                                Log.i("nyar", "resources have been loaded");
                        } catch (Exception e) {
                                Log.e("nyar", "resource loading failed", e);
                        }
                }

                public void resume() {
                        // We do the actual acquisition in a separate thread. Create it now.
                        if (mPreviewThread == null) {
                                mPreviewThread = new PreviewThread();
                                // If we already have a surface, just start the thread now too.
                                if (mHasSurface == true) {
                                        mPreviewThread.start();
                                }
                                connected = true;
                        }

                }

                public void pause() {
                        // Stop Preview.
                        if (mPreviewThread != null) {
                                mPreviewThread.requestExitAndWait();
                                mPreviewThread = null;

                                connected = false;
                        }
                }

                public void surfaceCreated(SurfaceHolder holder) {
                        // The Surface has been created, start our main acquisition thread.
                        mHasSurface = true;
                        if (mPreviewThread != null) {
                                mPreviewThread.start();
                        }
                }

                public void surfaceDestroyed(SurfaceHolder holder) {
                        // Surface will be destroyed when we return. Stop the preview.
                        mHasSurface = false;
                        pause();
                }

                public void surfaceChanged(SurfaceHolder holder, int format, int w,
                                int h) {
                        // Surface size or format has changed. This should not happen in
                        // this
                        // example.
                }

                // ----------------------------------------------------------------------

                class PreviewThread extends Thread {
                        private boolean mDone;

                        PreviewThread() {
                                super();
                                mDone = false;
                        }

                        @Override
                        public void run() {
                                // We first open the CameraDevice and configure it.
                                // CameraDevice camera = CameraDevice.open();
                                // if (camera != null) {
                                // CameraDevice.CaptureParams param = new
                                // CameraDevice.CaptureParams();
                                // param.type = 1; // preview
                                // param.srcWidth = 1280;
                                // param.srcHeight = 960;
                                // param.leftPixel = 0;
                                // param.topPixel = 0;
                                // param.outputWidth = 320;
                                // param.outputHeight = 240;
                                // param.dataFormat = 2; // RGB_565
                                // camera.setCaptureParams(param);
                                // }

                                Log.d("trace", "connecting to host " + host + "  port" + +port);
                                CameraSource cs = new SocketCamera(host, port, 320, 240, true,
                                                ar_param, ar_code, mHolder, fixedBitmap);
                                if (!cs.open()) {
                                        /* deal with failure to obtain camera */
                                        Log.d("trace", "couldn'd open camera source");
                                        return;
                                }
                                // This is our main acquisition thread's loop, we go until
                                // asked to quit.
                                SurfaceHolder holder = mHolder;
                                while (!mDone) {
                                        // Lock the surface, this returns a Canvas that can
                                        // be used to render into.
                                        Canvas canvas = holder.lockCanvas();

                                        // // Capture directly into the Surface
                                        // if (camera != null) {
                                        // camera.capture(canvas);
                                        // }

                                        if (cs != null) {
                                                cs.capture(canvas); // capture the frame onto the canvas
                                        }

                                        // And finally unlock and post the surface.
                                        holder.unlockCanvasAndPost(canvas);
                                }

                                // Make sure to release the CameraDevice
                                if (cs != null) {
                                        cs.close();
                                }
                        }

                        public void requestExitAndWait() {
                                // don't call this from PreviewThread thread or it a guaranteed
                                // deadlock!
                                mDone = true;
                                try {
                                        join();
                                } catch (InterruptedException ex) {
                                }
                        }
                }
        }
}