예제 #1
0
    private void RenderKDTree()
    {
#if UNITY_EDITOR
        grassRenderingCount = 0;
        //Debug.LogError ("RenderKDTree");
#endif

        //Clear all queue
        for (int i = 0; i < queue.Count; i++)
        {
            chunkState [queue [i]] = ChunkState.queueCache;
        }

        kdResults.Clear();
        kdQuery.Radius(kdTree, playerPos, settings.RealDisVisible, kdResults);
        int listCount = kdResults.Count;
        for (int i = 0; i < listCount; i++)
        {
            int index = kdResults [i];

            bool  canSee = false;
            var   pos    = data.chunkPos [index];
            float dis    = Vector3.Distance(pos, playerPos);
            //if (dis < settings.DisSurround || (dis < settings.RealDisVisible && Vector3.Dot (pos - playerPos, playerForward) >= -settings.backView))
            if (dis < settings.DisSurround || (dis < settings.RealDisVisible && Vector3.Angle(pos - playerPos, playerForward) <= settings.visibleAngle))
            {
                canSee = true;
            }
            if (!canSee)
            {
                continue;
            }


            if (chunkState [index] == ChunkState.idle)
            {
                Enqueue(index, ChunkState.queueView);
            }
            else if (chunkState [index] == ChunkState.queueView || chunkState [index] == ChunkState.queueCache)
            {
                chunkState [index] = ChunkState.queueView;
            }
            else if (chunkState [index] == ChunkState.done)
            {
                RendChunk(index);
            }
        }

#if UNITY_EDITOR
        //Debug.LogError ("Render grass in one frame:"+grassRenderingCount);
#endif
    }
예제 #2
0
    private void ClusterExtraction()
    {
        // KDTree
        int        maxPointsPerLeafNode = 32;
        KDTree     tree          = new KDTree(PointClouds.ToArray(), maxPointsPerLeafNode);
        KDQuery    query         = new KDQuery();
        List <int> results       = new List <int>();
        List <int> temp          = new List <int>();
        int        clusterCounts = 0;

        for (int i = 0; i < newPointCloudsNum; i++)
        {
            bool next = false;
            for (int j = 0; j < Clusters.Count; j++)
            {
                if (Clusters[j].Contains(i))
                {
                    next = true;
                    break;
                }
            }
            if (next)
            {
                continue;
            }
            results.Clear();
            temp.Clear();

            query.Radius(tree, PointClouds[i], Radius, temp);
            results.AddRange(temp);
            for (int j = 1; j < results.Count; j++)
            {
                if (results[j] < newPointCloudsNum)
                {
                    temp.Clear();
                    query.Radius(tree, PointClouds[results[j]], Radius, temp);

                    for (int k = 0; k < temp.Count; k++)
                    {
                        if (!results.Contains(temp[k]))
                        {
                            results.Add(temp[k]);
                        }
                    }
                }
            }
            Clusters.Add(new List <int>());
            Clusters[clusterCounts].AddRange(results);
            clusterCounts += 1;
        }
    }
        public List <List <int> > ExtractClusters(List <DetectedLocation> locations)
        {
            var points = new Vector3[locations.Count];
            var nodes  = new int[locations.Count];

            for (int i = 0; i < locations.Count; i++)
            {
                var loc = locations[i];
                points[i] = loc.ToPosition();
                nodes[i]  = i;
            }
            var tree = new KDTree(points, 32);
            List <List <int> > clusters = new List <List <int> >();
            var processed = new bool[locations.Count];

            for (int i = 0; i < locations.Count; i++)
            {
                if (processed[i])
                {
                    continue;
                }
                var loc = locations[i];

                var p = loc.ToPosition2D();
                var q = new Queue <int>();
                q.Enqueue(i);
                processed[i] = true;
                int index = 0;
                while (index < q.Count)
                {
                    var        targetIndex   = q.ElementAt <int>(index);
                    var        tp            = locations[targetIndex].ToPosition();
                    List <int> resultIndices = new List <int>();
                    query.Radius(tree, tp, distanceThreshold, resultIndices);
                    foreach (var neighbor in resultIndices)
                    {
                        if (processed[neighbor])
                        {
                            continue;
                        }
                        q.Enqueue(neighbor);
                        processed[neighbor] = true;
                    }
                    index++;
                }
                var l = q.ToList <int>();
                //Debug.LogFormat("cluster size={0}", l.Count);
                clusters.Add(l);
            }
            return(clusters);
        }
예제 #4
0
        long QueryRadius()
        {
            stopwatch.Reset();
            stopwatch.Start();

            float3 position = float3One() * 0.5f + RandomInsideUnitSphere();
            float  radius   = 0.25f;

            results.Clear();
            query.Radius(tree, position, radius, results);

            stopwatch.Stop();

            return(stopwatch.ElapsedMilliseconds);
        }
        // Update is called once per frame
        void Update()
        {
            //VPL.Clear();
            //VPLPoints.Clear();
            //VPLVector.Clear();
            if (type == "Point Light")
            {
                Vector3    org = this.transform.position;
                RaycastHit hit;
                for (int i = 0; i < InitVPLCount; i++)
                {
                    Vector3 checkdir      = (VPLPoints[i] - org).normalized;
                    float   checkdistance = (VPLPoints[i] - org).magnitude;
                    if (Physics.Raycast(org, checkdir, out hit, checkdistance))
                    {
                        float Rx = Random48.Get();
                        float Ry = Random48.Get();
                        float Rz = Random48.Get();
                        Rx        = halton(seedCount, 2);
                        Ry        = halton(seedCount, 3);
                        Rz        = halton(seedCount++, 4);
                        seedCount = seedCount % (maxSeed * 3);
                        Vector3 tempDir = new Vector3(Rx * 2.0f - 1.0f, Ry * 2.0f - 1.0f, Rz * 2.0f - 1.0f);
                        tempDir.Normalize();
                        //tempDir -= new Vector3(0.5f, 0.5f, 0.5f);
                        VPLVector[i] = tempDir;
                        Vector3 B   = VPLVector[i];
                        Vector3 dir = this.transform.right * B.x + this.transform.up * B.y - this.transform.forward * B.z;
                        if (Physics.Raycast(org, dir, out hit, 1000))
                        {
                            VPLPoints[i] = (hit.point);
                            VPL[i].GetComponent <Transform>().LookAt(hit.normal);
                        }

                        VPL[i].transform.position = VPLPoints[i];

                        Vector3 CubeUV = convert_xyz_to_cube_uv(B);
                        if (CubeUV.x == 0.0f)
                        {
                            VPL[i].GetComponent <Light>().color = MyCubeMap.GetPixel(CubemapFace.PositiveX, (int)(CubeUV.y * 1024.0), (int)(CubeUV.z * 1024.0));
                        }
                        if (CubeUV.x == 1.0f)
                        {
                            VPL[i].GetComponent <Light>().color = MyCubeMap.GetPixel(CubemapFace.NegativeX, (int)(CubeUV.y * 1024.0), (int)(CubeUV.z * 1024.0));
                        }
                        if (CubeUV.x == 2.0f)
                        {
                            VPL[i].GetComponent <Light>().color = MyCubeMap.GetPixel(CubemapFace.PositiveY, (int)(CubeUV.y * 1024.0), (int)(CubeUV.z * 1024.0));
                        }
                        if (CubeUV.x == 3.0f)
                        {
                            VPL[i].GetComponent <Light>().color = MyCubeMap.GetPixel(CubemapFace.NegativeY, (int)(CubeUV.y * 1024.0), (int)(CubeUV.z * 1024.0));
                        }
                        if (CubeUV.x == 4.0f)
                        {
                            VPL[i].GetComponent <Light>().color = MyCubeMap.GetPixel(CubemapFace.PositiveZ, (int)(CubeUV.y * 1024.0), (int)(CubeUV.z * 1024.0));
                        }
                        if (CubeUV.x == 5.0f)
                        {
                            VPL[i].GetComponent <Light>().color = MyCubeMap.GetPixel(CubemapFace.NegativeZ, (int)(CubeUV.y * 1024.0), (int)(CubeUV.z * 1024.0));
                        }
                    }
                }
            }
            else
            {
                Vector3    org = this.transform.position;
                RaycastHit hit;
                Texture2D  tempTex = new Texture2D(1024, 1024);
                RenderTexture.active = rendertexture;
                tempTex.ReadPixels(new UnityEngine.Rect(0, 0, 1024, 1024), 0, 0);
                Vector3 temp = (this.transform.right + this.transform.up + this.transform.forward);
                Debug.DrawLine(transform.position + transform.forward * 10, this.transform.position);
                for (int i = 0; i < InitVPLCount; i++)
                {
                    Vector3 checkdir      = (VPL[i].transform.position - org).normalized;
                    float   checkdistance = (VPL[i].transform.position - org).magnitude;
                    float   checkAngle    = Vector3.Angle(checkdir, transform.forward);

                    if (Physics.Raycast(org, checkdir, out hit, checkdistance) || checkAngle > (SpotAngle / 2.0f))
                    {
                        float Rx = Random48.Get();
                        float Ry = Random48.Get();
                        Rx        = halton(seedCount, 2);
                        Ry        = halton(seedCount++, 3);
                        seedCount = seedCount % (maxSeed * 2);
                        if (Mathf.Sqrt((Rx - 0.5f) * (Rx - 0.5f) + (Ry - 0.5f) * (Ry - 0.5f)) <= radius)
                        {
                            Vector3 B = new Vector3(Rx, Ry, 0);

                            B.x -= 0.5f;
                            B.y -= 0.5f;
                            //            float l = Vector3.Dot(B, B);
                            VPLVector[i] = B;
                            float z;
                            z = -Mathf.Tan((Fov / 2.0f) / 180.0f * 3.1415926f);

                            Vector3 dir = this.transform.right * B.x + this.transform.up * B.y - this.transform.forward * z;
                            if (Physics.Raycast(org, dir, out hit, 1000))
                            {
                                Vector3 p;
                                p.x = B.x * 1024.0f;
                                p.y = B.y * 1024.0f;

                                VPL[i].transform.position = hit.point;
                                tree.Points[i]            = hit.point;
                                VPL[i].GetComponent <Transform>().LookAt(hit.normal);
                                VPL[i].GetComponent <Light>().color = (tempTex.GetPixel((int)p.x, (int)p.y));
                            }
                        }
                    }
                }
                tree.Rebuild();
                int count = 0;
                Dictionary <int, bool> lightflag = new Dictionary <int, bool>();
                for (int i = 0; i < InitVPLCount; i++)
                {
                    if (!lightflag.ContainsKey(i))
                    {
                        count++;
                        VPL[i].GetComponent <Light>().enabled = true;
                        lightflag[i] = true;
                        var resultIndices = new List <int>();
                        query.Radius(tree, tree.Points[i], Radius, resultIndices);
                        for (int j = 0; j < resultIndices.Count; j++)
                        {
                            if (resultIndices[j] != i)
                            {
                                VPL[resultIndices[j]].GetComponent <Light>().enabled = false;
                                lightflag[resultIndices[j]] = true;
                            }
                        }
                    }
                }
                VPL_Num = count.ToString();
                Destroy(tempTex);
            }

            if (Input.GetKeyDown(KeyCode.D))
            {
                DEB = !DEB;
                CANV.SetActive(DEB);
            }

            if (Input.GetKeyDown(KeyCode.E))
            {
                SDEB = !SDEB;
                CANV2.SetActive(SDEB);
            }


            if (DEB == true)
            {
                Vector3 TP = this.GetComponent <Transform>().position;
                for (int i = 0; i < InitVPLCount; i++)
                {
                    Debug.DrawLine(TP, VPL[i].GetComponent <Transform>().position);
                }
                if (Input.GetKeyDown(KeyCode.W))
                {
                    NowSeeLight++;
                    NowSeeLight = NowSeeLight % InitVPLCount;
                    MainCam.GetComponent <Transform>().position = VPL[NowSeeLight].GetComponent <Transform>().position;
                    MainCam.GetComponent <Transform>().rotation = VPL[NowSeeLight].GetComponent <Transform>().rotation;
                    //C.transform.parent = VPL[NowSeeLight].transform;
                    C.transform.GetComponent <Transform>().rotation = VPL[NowSeeLight].GetComponent <Transform>().rotation;
                    C.transform.GetComponent <Transform>().position = VPL[NowSeeLight].GetComponent <Transform>().position;
                }

                if (Input.GetKeyDown(KeyCode.S))
                {
                    NowSeeLight--;
                    if (NowSeeLight < 0)
                    {
                        NowSeeLight += InitVPLCount;
                    }
                    NowSeeLight = NowSeeLight % InitVPLCount;
                    MainCam.GetComponent <Transform>().position = VPL[NowSeeLight].GetComponent <Transform>().position;
                    MainCam.GetComponent <Transform>().rotation = VPL[NowSeeLight].GetComponent <Transform>().rotation;
                    //C.transform.parent = VPL[NowSeeLight].transform;
                    C.transform.GetComponent <Transform>().rotation = VPL[NowSeeLight].GetComponent <Transform>().rotation;
                    C.transform.GetComponent <Transform>().position = VPL[NowSeeLight].GetComponent <Transform>().position;
                }
            }
        }
예제 #6
0
        private void OnDrawGizmos()
        {
            if (query == null)
            {
                return;
            }

            Vector3 size = 0.2f * Vector3.one;

            for (int i = 0; i < pointCloud.Length; i++)
            {
                Gizmos.DrawCube(pointCloud[i], size);
            }

            var resultIndices = new List <int>();

            Color markColor = Color.red;

            markColor.a  = 0.5f;
            Gizmos.color = markColor;

            switch (QueryType)
            {
            case QType.ClosestPoint: {
                query.ClosestPoint(tree, transform.position, resultIndices);
            }
            break;

            case QType.KNearest: {
                query.KNearest(tree, transform.position, K, resultIndices);
            }
            break;

            case QType.Radius: {
                query.Radius(tree, transform.position, Radius, resultIndices);

                Gizmos.DrawWireSphere(transform.position, Radius);
            }
            break;

            case QType.Interval: {
                query.Interval(tree, transform.position - IntervalSize / 2f, transform.position + IntervalSize / 2f, resultIndices);

                Gizmos.DrawWireCube(transform.position, IntervalSize);
            }
            break;

            default:
                break;
            }

            for (int i = 0; i < resultIndices.Count; i++)
            {
                Gizmos.DrawCube(pointCloud[resultIndices[i]], 2f * size);
            }

            Gizmos.color = Color.green;
            Gizmos.DrawCube(transform.position, 4f * size);

            if (DrawQueryNodes)
            {
                query.DrawLastQuery();
            }
        }
예제 #7
0
        void Update()
        {
            Debug.Log(checkObject.transform.position);
            for (int i = 0; i < tree.Count; i++)
            {
                tree.Points[i].Position += LorenzStep(tree.Points[i].Position) * Time.deltaTime * 0.01f;
                var gobj = (GameObject)tree.Points[i].UserObject;
                gobj.GetComponent <Renderer>().material.color = Color.white;
            }


            tree.Rebuild();

            if (query == null)
            {
                return;
            }



            Vector3 size = 0.2f * Vector3.one;

            var resultIndices = new List <int>();

            Color markColor = Color.red;

            markColor.a  = 0.5f;
            Gizmos.color = markColor;

            switch (QueryType)
            {
            case QType.ClosestPoint: {
                query.ClosestPoint(tree, checkObject.transform.position, resultIndices);
            }
            break;

            case QType.KNearest: {
                query.KNearest(tree, checkObject.transform.position, K, resultIndices);
            }
            break;

            case QType.Radius: {
                query.Radius(tree, checkObject.transform.position, Radius, resultIndices);
            }
            break;

            case QType.Interval: {
                query.Interval(tree, checkObject.transform.position - IntervalSize / 2f, checkObject.transform.position + IntervalSize / 2f, resultIndices);
            }
            break;

            default:
                break;
            }

            for (int i = 0; i < resultIndices.Count; i++)
            {
                var gobj = (GameObject)tree.Points[resultIndices[i]].UserObject;
                gobj.GetComponent <Renderer>().material.color = Color.red;
            }
        }
예제 #8
0
    public void tick(KDTree tree, KDQuery query, int index, List <Particle> particles, Transform cursor, SettingsMenu settings, ParticleController.State state)
    {
        switch (state)
        {
        case ParticleController.State.Boid:
            tree.Points[index] = position;
            List <int> neighbors = new List <int>();
            query.Radius(tree, position, 1f, neighbors);
            if (neighbors.Count() == 0)
            {
                break;
            }

            Vector3 avgPosition = Vector3.zero, avgHeading = Vector3.zero, awayHeading = Vector3.zero;
            foreach (int idx in neighbors)
            {
                if (idx == index)
                {
                    continue;
                }
                Particle neighbor = particles[idx];
                avgPosition += neighbor.position;
                avgHeading  += neighbor.velocity;
                awayHeading += (position - neighbor.position).normalized / ((position - neighbor.position).magnitude + 0.01f);
            }

            Vector3 desiredVelocity = Vector3.zero;

            // separation: steer to avoid crowding local flockmates
            desiredVelocity += awayHeading * settings.separation.value;                                                   //0.01
            // alignment : steer towards the average heading of local flockmates
            desiredVelocity += avgHeading.normalized * settings.alignment.value;                                          //0.05
            // cohesion : steer to move towards the average position(center of mass) of local flockmates
            desiredVelocity += ((avgPosition / (neighbors.Count() - 1)) - position).normalized * settings.cohesion.value; //0.01

            // boundry : steer towards player if outside boundary sphere
            // TODO : make radius a param
            Vector3 boundaryBearing = cursor.position - position;
            int     radius          = 15;
            if (boundaryBearing.magnitude > radius)
            {
                desiredVelocity += boundaryBearing.normalized * 0.1f;
                // position = position.normalized * -radius;
            }

            // acceleration += desiredVelocity - velocity;
            acceleration += desiredVelocity * 0.01f;

            if (acceleration.magnitude > settings.agility.value)
            {
                acceleration = acceleration.normalized * settings.agility.value;
            }

            if (velocity.magnitude > settings.speed.value)
            {
                velocity = velocity.normalized * settings.speed.value;
            }

            break;

        default:
        case ParticleController.State.FreeFly:
            velocity -= 0.005f * velocity;     //todo make this a param
            break;
        }

        velocity    += acceleration;
        position    += velocity;
        acceleration = Vector3.zero;
    }
예제 #9
0
    // This is the method that performs weighted sample elimination.
    static void DoEliminate(
        float2[]         inputPoints,
        float2[]         outputPoints,
        float d_max,
        Func <float2, float2, float, float, float, float> weightFunction,
        Func <float2, float> density
        )
    {
        // Build a k-d tree for samples
        var kdtree = new KDTree(inputPoints);
        var query  = new KDQuery();

        var dmax2 = d_max * d_max;

        // Assign weights to each sample
        float[] weights   = new float[inputPoints.Length];
        float[] densities = new float[inputPoints.Length];
        for (int i = 0; i < inputPoints.Length; i++)
        {
            var point = inputPoints[i];
            densities[i] += density(point);
            foreach (var(qi, d2) in query.Radius(kdtree, inputPoints[i], d_max))
            {
                var otherPoint = inputPoints[qi];
                weights[i] += weightFunction(point, otherPoint, d2, d_max, densities[i]);
            }
        }

        // Build a heap for the samples using their weights
        MaxHeap <int> heap = new MaxHeap <int>(inputPoints.Length);

        for (int i = 0; i < inputPoints.Length; i++)
        {
            heap.PushObj(i, weights[i]);
        }

        // While the number of samples is greater than desired
        int sampleCount = inputPoints.Length;

        while (sampleCount > outputPoints.Length)
        {
            // Pull the top sample from heap
            var elim  = heap.PopObj();
            var pElim = inputPoints[elim];
            // For each sample around it, remove its weight contribution and update the heap
            foreach (var(qi, d2) in query.Radius(kdtree, pElim, d_max))
            {
                var point = inputPoints[qi];
                weights[qi] -= weightFunction(point, pElim, d2, d_max, densities[qi]);
                heap.SetValue(qi, weights[qi]);
            }
            sampleCount--;
        }

        var outputIndex = 0;

        foreach (var i in heap.FlushResult())
        {
            outputPoints[outputIndex++] = inputPoints[i];
        }
    }