示例#1
0
    // Update is called once per frame
    void Update()
    {
        if (menuvisible | helpvisible | chooser.enabled)
        {
            return;
        }

        //処理開始
        interval += Time.deltaTime;
        if (interval > 0.1f & ready & !chooser.getEnabled())
        {
            //終了時刻よりあとの時刻か
            if (current.CompareTo(finish) > 0)
            {
                if (shadowrenderer.getMode() == UmbralShadowRenderer.RECORDMODE)
                {
                    String filename = EclipseCalendar.getDateString(start.Year, start.Month, start.Day);

                    currenteclipsedata.writeJSON(filename + ".json");
                    saveTexture(filename, result);
                    if (umbralshadow != null)
                    {
                        saveTexture(filename + "_umbra", umbralshadow);
                    }
                    return;

                    ready    = false;
                    interval = 0.0f;
                }
                else if (shadowrenderer.getMode() == UmbralShadowRenderer.PLAYMODE)
                {
                    current = new DateTime(start.Year, start.Month, start.Day, start.Hour, start.Minute, 0, DateTimeKind.Utc);
                }
            }

            clock.setTime(current);
            //影描画
            shadowrenderer.drawLines(current);

            //テクスチャに結果を描き込む
            if (shadowrenderer.getMode() == UmbralShadowRenderer.RECORDMODE)
            {
                writeResult(earthshadow, result);
            }

            //地球の昼夜を描く
            currenteclipsedata.getPositions(current, posdata);
            shadowrenderer.drawNightSide(posdata);

            earthshadow.Apply();
            //時間を一つ進める
            current = current.AddMinutes(1.0);

            interval = 0.0f;
        }

        if (Application.platform == RuntimePlatform.Android & !chooser.enabled & !helpvisible)
        {
            // エスケープキー取得
            if (Input.GetKeyDown(KeyCode.Escape))
            {
                // アプリケーション終了処理
                Application.Quit();
                return;
            }
        }
    }
示例#2
0
    void Update()
    {
        //画角値の確認
        if (!calibrated)
        {
            if (Calibration.calibrated)
            {
                horizontalFOV           = Calibration.horizontal;
                verticalFOV             = Calibration.vertical;
                calibrated_orientation  = (int)Calibration.deviceOrientation;
                appdata.HorizontalAngle = horizontalFOV;
                appdata.VerticalAngle   = verticalFOV;
                appdata.saveApplicationData();
                calibrated = true;
            }
            else
            {
#if UNITY_ANDROID
                // Javaのオブジェクトを作成
                AndroidJavaClass nativeDialog = new AndroidJavaClass("studio.beautifulworld.dialoglibrary.MenuDialog");

                // Context(Activity)オブジェクトを取得する
                AndroidJavaClass  unityPlayer = new AndroidJavaClass("com.unity3d.player.UnityPlayer");
                AndroidJavaObject context     = unityPlayer.GetStatic <AndroidJavaObject>("currentActivity");

                // AndroidのUIスレッドで動かす
                context.Call("runOnUiThread", new AndroidJavaRunnable(() => {
                    // ダイアログ表示のstaticメソッドを呼び出す
                    nativeDialog.CallStatic(
                        "showMessages",
                        context,
                        "お知らせ",
                        "画角の値が記録されていません。\nキャリブレーションを実行します。");
                }));
#endif
                moveToCalibration();
            }
        }

        //データ選択・又は地点選択の場合、以後の処理はしない
        if (chooser.enabled | pointchooser.enabled | helpvisible)
        {
            return;
        }

        //処理開始
        interval += Time.deltaTime;
        if (interval > 0.1f & ready)
        {
            currenteclipsedata.getPositions(current, posdata);
            clock.setTime(current);

            if (!Input.location.isEnabledByUser)
            {
                state = LOCATION_UNAVAILABLE;
            }
            else
            {
                LocationInfo locinfo = Input.location.lastData;
                magnetism = false;
                if (locinfo.longitude > 122.5f & locinfo.longitude <150.0f& locinfo.latitude> 23.0f & locinfo.latitude < 45.5f)
                {
                    magnetism = true;
                    //磁気偏角計算
                    float declination_angle = TerrestrialMagnetism.getMagneticDeclination(locinfo.longitude, locinfo.latitude);
                    declination = Quaternion.Euler(0.0f, declination_angle, 0.0f);
                }

                float height = 0;//高度
                if (locationmode == CURRENT_LOCATION)
                {
                    longitude = locinfo.longitude;
                    latitude  = locinfo.latitude;
                    height    = locinfo.altitude;
                }
                float[,] matrix  = caliculation.getMatrix(longitude, latitude, height);
                float[,] inverse = caliculation.getInverseMatrix(matrix);

                //debug

                /*
                 *  //分、秒を含めて時間で表す
                 *  double hour = current.Hour +9+ current.Minute / 60.0 + current.Second / 3600.0;
                 *  double T = StarPosition.getTime(current.Year, current.Month, current.Day, hour);
                 * //太陽の黄経を計算するelon:ecliptic longitude
                 *  double elon = StarPosition.getSunEclipticLongitude(T);
                 *  //黄道傾角を計算する
                 *  double e = StarPosition.getInclination(T);//
                 *  //太陽の赤経に変換
                 *  double asc = StarPosition.getRightAscension(elon, e);//
                 *  //太陽の赤緯に変換
                 *  double dec = StarPosition.getDeclination(elon, e);//   //恒星時を計算する
                 *  double phai0 = StarPosition.getSidereal(T, hour / 24.0, longitude);//経過時間を引く必要があるので時間を別に与える
                 */
                //食分計算
                //VesselElements ve = new VesselElements(posdata[EclipseData.SUN_ASC], posdata[EclipseData.SUN_DEC], posdata[EclipseData.SUN_DIST],
                //posdata[EclipseData.MOON_ASC], posdata[EclipseData.MOON_DEC], posdata[EclipseData.MOON_DIST], current);

                double phai = posdata[EclipseData.PHAI] + longitude;// longitude;//地方恒星時=グリニッジ恒星時+経度。恒星時は反時計回り、経度は時計回り

                //太陽の方位・高度を計算する
                sun_direction = StarPosition.getSunDirection(posdata[EclipseData.SUN_ASC], posdata[EclipseData.SUN_DEC], latitude, phai);
                sun_altitude  = StarPosition.getSunAltitude(posdata[EclipseData.SUN_ASC], posdata[EclipseData.SUN_DEC], latitude, phai);

                //コンパス空間に写像する
                //太陽の方向ベクトルを求める
                double sunz = Math.Sin(sun_altitude / RadToDeg);
                double suny = Math.Cos(sun_altitude / RadToDeg);
                double sunx = suny * Math.Cos((90.0 - sun_direction) / RadToDeg);
                suny = suny * Math.Sin((90.0 - sun_direction) / RadToDeg);

                double[] sun_vector = new double[] { sunx, suny, sunz };//角度から算出したベクトルなので、現在位置は引く必要はない

                //太陽への方向ベクトル単位化
                double norm = Math.Sqrt(sun_vector[0] * sun_vector[0] + sun_vector[1] * sun_vector[1] + sun_vector[2] * sun_vector[2]);
                sun_vector[0] /= norm;
                sun_vector[1] /= norm;
                sun_vector[2] /= norm;

                //太陽の方向が地平線の下
                if (sun_vector[2] < 0.0f)
                {
                    state = UNDER_HORIZON;
                }
                else
                {
                    //デバイスの向きを検出する
                    Quaternion gyro = Input.gyro.attitude;
                    camrotation.Set(-gyro.x, -gyro.y, gyro.z, gyro.w);

                    camrotation = Quaternion.Euler(90.0f, 0.0f, 0.0f) * camrotation;
                    //向き検出・終わり

                    //デバイス座標系に変換
                    Quaternion inverseQ   = Quaternion.Inverse(camrotation);
                    Vector3[]  sunandmoon = new Vector3[2];

                    sunandmoon[0] = inverseQ * new Vector3((float)sun_vector[0], (float)sun_vector[2], (float)sun_vector[1]);
                    //sunandmoon[1] = inverseQ * new Vector3((float)moon_vector[0], (float)moon_vector[2], (float)moon_vector[1]);

                    //最後に有効になったデバイス向きを取得する
                    DeviceOrientation orientation = camview.getLastOrienation();

                    //画角とタンジェント値を得る
                    float[] viewangles = new float[2];
                    getViewAngle(orientation, viewangles);
                    float verticalFOV               = viewangles[1] / RadToDeg;
                    float horizontalFOV             = viewangles[0] / RadToDeg;
                    float screen_tangent_horizontal = Mathf.Tan(horizontalFOV);
                    float screen_tangent_vertical   = Mathf.Tan(verticalFOV);
                    float ratio = 0.5f / (screen_tangent_vertical * 2);

                    for (int i = 0; i < 1; i++)
                    {
                        //磁気補正
                        if (magnetism)
                        {
                            sunandmoon[i] = declination * sunandmoon[i];
                        }

                        //後ろの場合も見えないので、手順をスキップする。
                        float x_angle = Mathf.Atan(sunandmoon[i].x / sunandmoon[i].z);
                        float y_angle = Mathf.Atan(sunandmoon[i].y / sunandmoon[i].z);

                        if (Mathf.Abs(x_angle) < horizontalFOV & Mathf.Abs(y_angle) < verticalFOV & sunandmoon[i].z > 0)
                        {
                            float screenX = Mathf.Tan(x_angle) / screen_tangent_horizontal * Screen.width / 2 + Screen.width / 2 - images[SUNIMAGE].width / 2;
                            float screenY = Screen.height / 2 - Mathf.Tan(y_angle) / screen_tangent_vertical * Screen.height / 2 - images[SUNIMAGE].height / 2;
                            //datas.targetposition.Set(x, y, targetbox.width, targetbox.height);

                            switch (i)
                            {
                            case 0: state = INSIDE_SCREEN; sunrect.Set(screenX, screenY, images[SUNIMAGE].width * ratio, images[SUNIMAGE].height * ratio); break;
                                //case 1: moonSeeable = true; moonrect.Set(screenX, screenY, moonbox.width * ratio, moonbox.height * ratio); break;
                            }

                            blink         = true;
                            blinkinterval = 0.0f;
                        }
                        else
                        {
                            state = OUTSIDE_SCREEN;
                            //太陽の位置を示すアイコンを決める
                            getGuideImage(sunandmoon[0]);
                        }
                    }//for終わり
                }
                //デバイス座標系に変換・終わり
            }


            //時間を一つ進める
            current = current.AddMinutes(1.0);
            //終了時刻よりあとの時刻か
            if (current.CompareTo(finish) > 0)
            {
                current = new DateTime(start.Year, start.Month, start.Day, start.Hour, start.Minute, 0, DateTimeKind.Utc);
            }
            //
            interval = 0.0f;
        }

        //アプリケーションの終了
        if (Application.platform == RuntimePlatform.Android)
        {
            // エスケープキー取得
            if (Input.GetKeyDown(KeyCode.Escape))
            {
                Input.gyro.enabled = false;
                Input.location.Stop();
                Input.compass.enabled = false;
                // アプリケーション終了処理
                Application.Quit();
                return;
            }
        }
    }
示例#3
0
    //地球に写る月の影の輪郭を描く
    public void drawLines(DateTime utc)
    {
        EquatorialCoordinate sun  = new EquatorialCoordinate();
        EquatorialCoordinate moon = new EquatorialCoordinate();

        double[] result   = new double[3];
        double[] result2  = new double[3];
        double[] dataset  = new double[7];
        double[] location = new double[2];
        double   asc      = 0.0;
        double   dec      = 0.0;
        double   moonasc  = 0.0;
        double   moondec  = 0.0;
        double   phai0;

        if (mode == PLAYMODE)
        {
            dataholder.getPositions(utc, dataset);
            asc = dataset[0];
            dec = dataset[1];
            sun.setRightAscension(dataset[0]);
            sun.setCelestialDeclination(dataset[1]);
            sun.setDistance(dataset[2]);

            moon.setRightAscension(dataset[3]);
            moon.setCelestialDeclination(dataset[4]);
            moon.setDistance(dataset[5]);
            moonasc = dataset[3];
            moondec = dataset[4];
            phai0   = dataset[6];
        }
        else if (mode == RECORDMODE)
        {
            try
            {
                SunAndMoon.getSunRightAscension(utc, result);
                asc = result[0];
                dec = result[1];
                sun.setRightAscension(result[0]);
                sun.setCelestialDeclination(result[1]);
                sun.setDistance(result[2]);

                SunAndMoon.getMoonRightAscension(utc, result);
                moon.setRightAscension(result[0]);
                moon.setCelestialDeclination(result[1]);
                moon.setDistance(result[2]);
                moonasc = result[0];
                moondec = result[1];
            }
            catch (Exception) { /* Debug.Log("Exception1 ");*/ return; }
            phai0 = Almanac.getGreenidgeSiderealTime(utc);//グリニッジ恒星時
            //記録する
            dataholder.setPositions(asc, dec, sun.getDistance(), moonasc, moondec, moon.getDistance(), phai0, utc);
        }
        else
        {
            return;
        }

        //輪郭の描画
        //ベッセル数
        VesselElements ve = new VesselElements(sun, moon, utc);

        // SolarEclipse.getD(ve, 143.009267, 42.7396185, 0);
        SolarEclipse.getCrossPoint(ve, result, result2);
        //月影と地球外円との交点を調べる
        double maxQ = SolarEclipse.getPenumbralQ(ve, result);
        double minQ = SolarEclipse.getPenumbralQ(ve, result2);

        //Debug.Log("MaxQ = " + maxQ + " minQ = " + minQ);

        //半影の描画
        if (Double.IsNaN(maxQ) && Double.IsNaN(minQ))
        {
            clearTexture();
            //交点が存在しない場合。月影がすべて地球上に投射されている。
            double last_longitude;
            double last_latitude;
            Color  gray = new Color(0, 0, 0, 0.4f);

            //初期の点
            SolarEclipse.getPenumbralOutline(ve, 0.0, result);
            Coordinate.transformICRStoGCS(ve, result, location);
            last_longitude = location[0];
            last_latitude  = location[1];
            double max_lat = -90, min_lat = 90;
            double east_lon = location[0];
            double west_lon = double.NaN;

            //bool
            for (double i = 1.0; i <= 360.0; i += 1.0)
            {
                SolarEclipse.getPenumbralOutline(ve, i, result2);
                if (Double.IsNaN(result[0]) | Double.IsNaN(result[1]) | Double.IsNaN(result[2]))
                {
                    continue;//NaNが含まれていたらスキップする
                }
                Coordinate.transformICRStoGCS(ve, result2, location);

                if (double.IsNaN(location[0]) | double.IsNaN(location[1]))
                {
                    continue;
                }
                //値の取得で例外が発生したら、処理をスキップする
                try
                {
                    drawOutline(last_longitude, last_latitude, location[0], location[1], shadow, sunoutline);
                }
                catch (Exception ex) { continue; }

                last_longitude = location[0];
                last_latitude  = location[1];
                if (i == 180.0)
                {
                    west_lon = location[0];
                }
                if (max_lat < last_latitude)
                {
                    max_lat = last_latitude;
                }
                if (min_lat > last_latitude)
                {
                    min_lat = last_latitude;
                }
            }

            if (!double.IsNaN(west_lon) & !double.IsNaN(east_lon))
            {
                if (west_lon > east_lon)
                {
                    east_lon += 360.0;
                }

                Point paintpoint = getScreenPoint((east_lon + west_lon) / 2, (max_lat + min_lat) / 2);
                fillShadowEx(paintpoint.x, paintpoint.y, shadow, shadowcolor);
                // Debug.Log("west= " + west_lon + " east=" +east_lon) ;
            }
        }
        else if (!Double.IsNaN(maxQ) && !Double.IsNaN(minQ))//交点が存在する
        {
            double first_longitude;
            double first_latitude;
            double last_longitude;
            double last_latitude;

            clearTexture();
            Color gray = new Color(0, 0, 0, 0.4f);
            if ((maxQ - minQ) >= 0.0)
            {
                maxQ -= 360.0;
            }
            SolarEclipse.getPenumbralOutline(ve, maxQ, result);
            Coordinate.transformICRStoGCS(ve, result, location);
            //Debug.Log("MaxQ :" + location[0] + ":" + location[1]+ ":" + maxQ);
            SolarEclipse.getPenumbralOutline(ve, minQ, result);
            Coordinate.transformICRStoGCS(ve, result, location);

            //初期の点
            double delta = 0.0;
            while (true)
            {
                SolarEclipse.getPenumbralOutline(ve, maxQ + delta, result);
                if (Double.IsNaN(result[0]) | Double.IsNaN(result[1]) | Double.IsNaN(result[2]))
                {
                    delta += 0.1;
                }
                else
                {
                    break;
                }
                if (delta > 5.0)
                {
                    break;
                }
            }

            Coordinate.transformICRStoGCS(ve, result, location);
            first_longitude = last_longitude = location[0];
            first_latitude  = last_latitude = location[1];
            // double max_lon = 0, max_lat = -90, min_lon = 360, min_lat = 90;

            for (double i = maxQ + delta + 0.5; i < minQ; i += 0.5)
            {
                SolarEclipse.getPenumbralOutline(ve, i, result2);
                if (Double.IsNaN(result2[0]) | Double.IsNaN(result2[1]) | Double.IsNaN(result2[2]))
                {
                    continue;//NaNが含まれていたらスキップする
                }
                Coordinate.transformICRStoGCS(ve, result2, location);

                //値の取得で例外が発生したら、処理をスキップする
                if (double.IsNaN(location[0]) | double.IsNaN(location[1]))
                {
                    continue;
                }
                try
                {
                    drawOutline(last_longitude, last_latitude, location[0], location[1], shadow, sunoutline);
                }
                catch (Exception e) { continue; }

                last_longitude = location[0];
                last_latitude  = location[1];
            }

            SolarEclipse.getPenumbralOutline(ve, minQ, result);
            if (!Double.IsNaN(result[0]) & !Double.IsNaN(result[1]) & !Double.IsNaN(result[2]))
            {
                Coordinate.transformICRStoGCS(ve, result, location);
                if (!double.IsNaN(location[0]) & !double.IsNaN(location[1]))
                {
                    drawOutline(last_longitude, last_latitude, location[0], location[1], shadow, sunoutline);
                    last_longitude = location[0];
                    last_latitude  = location[1];
                }
            }

            //同時線を描く
            {
                //日の出・日の入りの同時線を描く
                int alllength = getSunLine(sun, phai0);

                //終点から同時線までの最短の線を描く
                Point  pnt           = getScreenPoint(last_longitude, last_latitude);
                double leastdistance = double.MaxValue;
                int    finishindex   = -1; //終点と最も近い点のインデックス
                if (pnt.x < 0)
                {
                    pnt.x += shadow.width;
                }
                else if (pnt.x >= shadow.width)
                {
                    pnt.x -= shadow.width;
                }
                if (pnt.y < 0)
                {
                    pnt.y = 0;
                }
                else if (pnt.y >= shadow.width)
                {
                    pnt.y = shadow.width;
                }

                for (int i = 0; i < alllength; i++)
                {
                    double xdiff = Math.Abs(pnt.x - sunline[i * 2]);
                    if (xdiff > shadow.width / 2)
                    {
                        xdiff = shadow.width - xdiff;
                    }
                    double ydiff  = pnt.y - sunline[i * 2 + 1];
                    double length = Math.Sqrt(xdiff * xdiff + ydiff * ydiff);
                    if (length < leastdistance)
                    {
                        leastdistance = length; finishindex = i;
                    }
                }
                if (finishindex != -1 & leastdistance != double.MaxValue)
                {
                    if (!double.IsNaN(last_longitude) & !double.IsNaN(last_latitude))
                    {
                        drawScreenOutline(pnt.x, pnt.y, sunline[finishindex * 2], sunline[finishindex * 2 + 1], sunoutline);
                    }
                }

                //開始点から同時線までの最短の線を描く
                pnt           = getScreenPoint(first_longitude, first_latitude);
                leastdistance = double.MaxValue;
                int startindex = -1; //始点と最も近い点のインデックス
                if (pnt.x < 0)
                {
                    pnt.x += shadow.width;
                }
                else if (pnt.x >= shadow.width)
                {
                    pnt.x -= shadow.width;
                }
                if (pnt.y < 0)
                {
                    pnt.y = 0;
                }
                else if (pnt.y >= shadow.width)
                {
                    pnt.y = shadow.width;
                }

                for (int i = 0; i < alllength; i++)
                {
                    double xdiff = Math.Abs(pnt.x - sunline[i * 2]);
                    if (xdiff > shadow.width / 2)
                    {
                        xdiff = shadow.width - xdiff;
                    }
                    double ydiff  = pnt.y - sunline[i * 2 + 1];
                    double length = Math.Sqrt(xdiff * xdiff + ydiff * ydiff);
                    if (length < leastdistance)
                    {
                        leastdistance = length; startindex = i;
                    }
                }
                if (startindex != -1 & leastdistance != double.MaxValue)
                {
                    if (!double.IsNaN(last_longitude) & !double.IsNaN(last_latitude))
                    {
                        drawScreenOutline(pnt.x, pnt.y, sunline[startindex * 2], sunline[startindex * 2 + 1], sunoutline);
                    }
                }
                //判定を正確にするため、同時線は最後に描く。alllengthは要素数だから、マイナスしない
                for (int i = 0; i < alllength; i++)
                {
                    drawScreenPixel(sunline[i * 2], sunline[i * 2 + 1], boundscolor);
                }

                //影の中を塗る
                int middlepoint = -1;
                if (Math.Abs(finishindex - startindex) > (alllength / 2))
                {
                    middlepoint = (finishindex + startindex + alllength) / 2;
                    if (middlepoint >= alllength)
                    {
                        middlepoint -= alllength;
                    }
                    else if (middlepoint < 0)
                    {
                        middlepoint += alllength;
                    }
                }
                else
                {
                    middlepoint = (finishindex + startindex) / 2;
                }
                getInnerPoint(sunline[middlepoint * 2], sunline[middlepoint * 2 + 1], shadow);//塗の指示
            }//同時線の描画の終わり
        } //半影の描画の終わり
        else if (!Double.IsNaN(maxQ) | !Double.IsNaN(minQ)) /*Debug.Log("minQ or maxQ is NaN");*/ } {
示例#4
0
    // Update is called once per frame
    void Update()
    {
        if (datachooser.enabled | helpvisible)
        {
            return;
        }

        //処理開始
        interval += Time.deltaTime;
        if (interval > 0.1f & ready)
        {
            currenteclipsedata.getPositions(current, posdata);

            //影描画
            shadowrenderer.drawLines(current);
            earthshadow.Apply();

            //時計に時間を通知
            clock.setTime(current);

            //太陽位置を計算してライトの位置と向きを変更する
            {
                //恒星時をもとに、背景の回転を行う(恒星時は春分点の時角)
                Material skybox = RenderSettings.skybox;
                skybox.SetFloat("_Rotation", (float)-posdata[EclipseData.PHAI]);//時角のマイナス方向に回転。skyboxのマテリアルは左右が逆

                //赤緯・赤経は北極から見て時計回り。時角、恒星時は反時計回り。時角に合わせて計算する
                //float ramda = -(float)((-asc + phai0) * DegToRad);これを書き換えて下の式になる
                float ramda       = (float)((posdata[EclipseData.SUN_ASC] - posdata[EclipseData.PHAI]) * DegToRad);
                float psy         = (float)(posdata[EclipseData.SUN_DEC] * DegToRad);
                float sundistance = 400;
                float x           = Mathf.Cos(psy) * Mathf.Cos(ramda) * sundistance;
                float y           = Mathf.Cos(psy) * Mathf.Sin(ramda) * sundistance;
                float z           = Mathf.Sin(psy) * sundistance;

                Vector3 sunpos = sunlight.transform.position;
                sunpos.Set(x, z, y);
                sunlight.transform.position = sunpos;
                sunpos.Normalize();
                sunpos *= -1;
                sunlight.transform.forward = sunpos;
            }

            //時間を一つ進める
            current = current.AddMinutes(1.0);
            //終了時刻よりあとの時刻か
            if (current.CompareTo(finish) > 0)
            {
                current = new DateTime(start.Year, start.Month, start.Day, start.Hour, start.Minute, 0, DateTimeKind.Utc);
            }
            interval = 0.0f;
        }

        //ピンチ操作
        //タッチによるスワイプを取得する
        //画面の縮小拡大を取得する
        if (Application.platform == RuntimePlatform.Android)
        {
            if (Input.touchCount == 0)
            {
                //windows の場合はコメントアウト
                if (pinch)
                {
                    pinch = false;
                }
                if (pressed)
                {
                    pressed = false;
                }
            }
            else if (Input.touchCount == 1 & lastTouchCount > 1)
            {
                if (pinch)
                {
                    pinch = false;
                }
                Touch[] touches   = Input.touches;
                Vector2 fingerpos = touches[0].position;
                lastx          = fingerpos.x;
                lasty          = fingerpos.y; //画面は左上が原点、マウスは左下が原点。なぜかタッチは左上原点のようだ。
                pressed        = true;
                lastTouchCount = Input.touchCount;
            }
            else if (Input.touchCount > 1)
            {
                if (pressed)
                {
                    pressed = false;
                }
                if (!pinch)
                {
                    pinch = true; lastRadius = 0.0f; lastTouchCount = Input.touchCount;
                }

                float Xamount = 0.0f;
                float Yamount = 0.0f;

                Touch[] alltouch = Input.touches;

                foreach (Touch t in alltouch)
                {
                    Vector2 pos = t.position;
                    Xamount += pos.x;
                    Yamount += pos.y;
                }
                float Xcenter       = Xamount / Input.touchCount;
                float Ycenter       = Yamount / Input.touchCount;
                float largestRadius = 0.0f;

                foreach (Touch t in alltouch)
                {
                    Vector2 pos    = t.position;
                    float   xdiff  = pos.x - Xcenter;
                    float   ydiff  = pos.y - Ycenter;
                    float   length = Mathf.Sqrt(xdiff * xdiff + ydiff * ydiff);
                    if (length > largestRadius)
                    {
                        largestRadius = length;
                    }
                }

                if (lastRadius != 0.0f & lastTouchCount == Input.touchCount)
                {
                    //カメラ画角の変更
                    float angleaddition = (lastRadius - largestRadius) * 0.05f;
                    maincam.fieldOfView = maincam.fieldOfView + angleaddition;
                    //画角の最小・最大角度はここでコントロールする
                    if (maincam.fieldOfView <= leastAngle)
                    {
                        maincam.fieldOfView = leastAngle;
                    }
                    else if (maincam.fieldOfView >= largestAngle)
                    {
                        maincam.fieldOfView = largestAngle;
                    }
                }
                lastTouchCount = Input.touchCount;
                lastRadius     = largestRadius;
            }
        }
        //ピンチ操作・終わり

        //マウス検知
        if (Input.GetMouseButtonDown(0))
        {
            Vector3 mousepos = Input.mousePosition;
            float   x        = mousepos.x;
            float   y        = Screen.height - mousepos.y; //画面は左上が原点、マウス(タッチ)は左下が原点

            if (!pressed)
            {
                pressed = true;
            }
            lastx = mousepos.x;
            lasty = mousepos.y;
        }

        //左ボタン上がった
        if (Input.GetMouseButtonUp(0))
        {
            if (pressed)
            {
                pressed = false;
            }
            //if (slidertapped) slidertapped = false;
        }

        if (pressed)
        {
            float xdiff = Input.mousePosition.x - lastx;
            float ydiff = Input.mousePosition.y - lasty;

            if (xdiff != 0.0f | ydiff != 0.0f)
            {
                positionUpdated(xdiff, ydiff);
            }

            lastx = Input.mousePosition.x;
            lasty = Input.mousePosition.y;
        }

        if (Application.platform == RuntimePlatform.Android)
        {
            // エスケープキー取得
            if (Input.GetKeyDown(KeyCode.Escape))
            {
                // アプリケーション終了処理
                Application.Quit();
                return;
            }
        }
    }