예제 #1
0
    System.Collections.IEnumerator CoGorillaTest()
    {
        // https://www.jstatsoft.org/article/view/v007i03/tuftests.pdf

        // まず必要な回数乱数を呼んで溜める
        const int Shortening             = 0;
        const int stringLength           = 26 - Shortening;        // 生成する「文字列」のビット長
        const int idealMean              = 24687971 >> Shortening; // 論文から。自分で計算していない(2^26/e)
        const int idealStandardDeviation = 4170 >> Shortening;     // 論文から。自分で計算していない。
        const int bitsPerValue           = 16;
        const int stringCount            = 1 << stringLength;      // 2^26通りの文字列が生成されうるので、そのうちどれだけ出てこないかを調べる。
        const int stringMask             = stringCount - 1;
        // 乱数だけ先に別スレで呼んで並列化して高速化
        var randValueCount = stringCount + stringLength - 1;
        var values         = new int[randValueCount];
        var unit           = randValueCount / ThreadCount;
        var offset         = 0;

        for (int i = 0; i < ThreadCount; i++)
        {
            int threadIndexCaptured = i;
            int countCaptured       = (i == ThreadCount - 1) ? randValueCount : unit;
            int offsetCaptured      = offset;
            _threadPool.AddJob(() =>
            {
                for (int j = 0; j < countCaptured; j++)
                {
                    values[offsetCaptured + j] = _randoms[threadIndexCaptured].Next();
                }
            });
            randValueCount -= countCaptured;
            offset         += countCaptured;
        }
        // 終了待ち
        while (!_threadPool.IsComplete())
        {
            yield return(null);
        }

        // ビットごとに並列させる
        var counts        = new int[bitsPerValue];
        int completeCount = 0;

        for (int bitIndex = 0; bitIndex < bitsPerValue; bitIndex++)
        {
            int bitIndexCaptured = bitIndex;
            _threadPool.AddJob(() =>
            {
                int str = 0;
                // プロローグ(文字列長-1ビット生成)
                for (int position = 0; position < (stringLength - 1); position++)
                {
                    var value = values[position];
                    str     <<= 1;
                    str      |= (value >> bitIndexCaptured) & 0x1;
                }
                // 文字列生成ループ。生成された文字列にtrueをつけて回る
                var appearFlags = new bool[stringCount];
                for (int stringIndex = 0; stringIndex < stringCount; stringIndex++)
                {
                    var value        = values[stringIndex + stringLength - 1];
                    str            <<= 1;                                 // 1ビット送って
                    str             |= (value >> bitIndexCaptured) & 0x1; // 新しいビットを足し
                    str             &= stringMask;                        // 範囲外を消す
                    appearFlags[str] = true;
                }
                // 集計
                int count = 0;
                for (int stringIndex = 0; stringIndex < stringCount; stringIndex++)
                {
                    if (appearFlags[stringIndex])
                    {
                        count++;
                    }
                }
                lock (counts)                 // 配列の要素アクセスがメモリ壊すんじゃないかと心配なので同期
                {
                    counts[bitIndexCaptured] = count;
                    completeCount++;
                    Debug.Log("Gorilla test ... " + completeCount + "/" + bitsPerValue);
                }
            });
        }

        // 終了待ち
        while (!_threadPool.IsComplete())
        {
            yield return(null);
        }

        // 数えて色塗る
        int yCount = Height / 4;
        int xCount = Width / 4;

        for (int bitIndex = 0; bitIndex < bitsPerValue; bitIndex++)
        {
            int count  = counts[bitIndex];
            int yStart = (bitIndex / 4) * yCount;
            int xStart = (bitIndex % 4) * xCount;
            count = stringCount - count;             // 現れなかった数に変換
            float sdRatio = (float)(count - idealMean) / (float)idealStandardDeviation;
            Debug.Log("[gorilla test result] bitIndex: " + bitIndex + " count: " + count + "/" + stringCount + " sd: " + sdRatio);
            var color = new Color(0.5f, 0.5f, 0.5f, 1f);
            color.r += sdRatio / 8f;
            color.g -= sdRatio / 8f;
            for (int pixelY = 0; pixelY < yCount; pixelY++)
            {
                for (int pixelX = 0; pixelX < xCount; pixelX++)
                {
                    _texture.SetPixel(pixelX + xStart, pixelY + yStart, color);
                }
            }
        }
        _texture.Apply();
    }
예제 #2
0
        public void Start()
        {
            stopped = false;
            mappingStrategy.Load();
            pool = new ThreadPool("AGIServer", poolSize);
#if LOGGER
            logger.Info("Thread pool started.");
#endif
            try
            {
                var ipAddress = IPAddress.Parse(address);
                serverSocket = new ServerSocket(port, ipAddress, SocketEncoding);
            }
            catch (IOException ex)
            {
#if LOGGER
                logger.Error("Unable start AGI Server: cannot to bind to " + address + ":" + port + ".", ex);
#endif
                throw ex;
            }
            finally
            {
                if (serverSocket != null)
                {
                    serverSocket.Close();
                    serverSocket = null;
                }

                pool.Shutdown();
#if LOGGER
                logger.Info("AGIServer shut down.");
#endif
            }

#if LOGGER
            logger.Info("Listening on " + address + ":" + port + ".");
#endif

            try
            {
                SocketConnection socket;
                while ((socket = serverSocket.Accept()) != null)
                {
#if LOGGER
                    logger.Info("Received connection.");
#endif
                    var connectionHandler = new AGIConnectionHandler(socket, mappingStrategy, SC511_CAUSES_EXCEPTION,
                                                                     SCHANGUP_CAUSES_EXCEPTION);
                    pool.AddJob(connectionHandler);
                }
            }
            catch (IOException ex)
            {
                if (!stopped)
                {
#if LOGGER
                    logger.Error("IOException while waiting for connections (1).", ex);
#endif
                    throw ex;
                }
            }
            finally
            {
                if (serverSocket != null)
                {
                    try
                    {
                        serverSocket.Close();
                    }
#if LOGGER
                    catch (IOException ex)
                    {
                        logger.Error("IOException while waiting for connections (2).", ex);
                    }
#else
                    catch { }
#endif
                }
                serverSocket = null;
                pool.Shutdown();
#if LOGGER
                logger.Info("AGIServer shut down.");
#endif
            }
        }
예제 #3
0
    void Update()
    {
        float dt = Time.deltaTime;

        debugUi.ManualUpdate(dt);
        if (Input.GetKeyDown(KeyCode.Space))
        {
            Fire();
        }
        // テキトーに的を動かす
        var p  = target.transform.localPosition;
        var dp = p - targetOrigin;

        targetVelocity *= 1f - targetDamping;
        targetVelocity -= dp * targetStiffness * dt;
        p += targetVelocity * dt;
        target.transform.localPosition = p;

        gunPoint.LookAt(p);

        for (int i = 0; i < beams.Length; i++)
        {
            if (beams[i].time >= 0)
            {
                UpdateBeam(beams[i]);
            }
        }
        UnityEngine.Profiling.Profiler.BeginSample("Main.Update.UpdateParticles");

        var transform     = mainCamera.gameObject.transform;
        var forwardVector = transform.forward;
        var upVector      = transform.up;
        // TODO: 右ベクタ、上ベクタは前計算可能
        // 右ベクタ、上ベクタを生成 axisX = cross(axisY, axisZ)
        Vector3 right = Vector3.Cross(upVector, forwardVector);

        right.Normalize();
        // ビルボード空間の上ベクタを計算
        Vector3 up = Vector3.Cross(forwardVector, right);

        int rest = particles.Length;
        int unit = rest / jobs.Length;

        if ((rest - (unit * jobs.Length)) > 0)
        {
            unit += 1;
        }
        int begin = 0;

        for (int i = 0; i < jobs.Length; i++)
        {
            int count = (rest >= unit) ? unit : rest;
            jobs[i].Set(begin, count, dt, ref up, ref right);
            particleRenderers[i].Mesh.SetTexture(texture);
            if (threadEnabled)
            {
                threadPool.AddJob(jobs[i]);
            }
            else
            {
                jobs[i].Execute();
            }
            rest  -= count;
            begin += count;
        }
        UnityEngine.Profiling.Profiler.EndSample();

        var tp = target.transform.position;
        var gp = gunPoint.position;

        cameraController.FitByMove2PointVertical(
            gp,
            tp,
            Vector3.up,
            cameraPositionParameter,
            cameraMargin);
        cameraController.Stiffness = cameraStiffness;
        cameraController.ManualUpdate(dt);
    }