예제 #1
0
        void Awake()
        {
            pointCloud = new Vector3[20000];

            query = new KDQuery();

            for (int i = 0; i < pointCloud.Length; i++)
            {
                pointCloud[i] = new Vector3(

                    (1f + Random.value * 0.25f),
                    (1f + Random.value * 0.25f),
                    (1f + Random.value * 0.25f)
                    );
            }

            for (int i = 0; i < pointCloud.Length; i++)
            {
                for (int j = 0; j < i; j++)
                {
                    pointCloud[i] += LorenzStep(pointCloud[i]) * 0.01f;
                }
            }

            tree = new KDTree(pointCloud, 32);
        }
예제 #2
0
        /// <summary>
        /// Returns closest to position point from array
        /// </summary>
        /// <param name="position"></param>
        /// <param name="points"></param>
        /// <returns></returns>
        private Vector3 GetClosestPoint(Vector3 position, Vector3[] points)
        {
            var tree    = new KDTree(points, 8);
            var query   = new KDQuery();
            var results = new List <int>();

            query.ClosestPoint(tree, position, results);

            return(points[results.First()]);
        }
예제 #3
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;
        }
    }
예제 #4
0
 void Start()
 {
     particles = new List <Particle>();
     for (int x = -4; x <= 4; x++)
     {
         for (int y = -4; y <= 4; y++)
         {
             for (int z = -4; z <= 4; z++)
             {
                 particles.Add(new Particle(new Vector3(x, y, z)));
             }
         }
     }
     tree           = new KDTree(particles.Select(x => x.position).ToArray(), 64);
     query_thread0  = new KDQuery();
     trails         = particleSys.trails;
     cursorTracking = cursor.GetComponent <CursorTracking>();
 }
예제 #5
0
        void Awake()
        {
            pointCloud = new List <KDGameObject>(600);
            for (int i = 0; i < 600; i++)
            {
                // create a unity-gameobject at random position...
                var sphere = GameObject.CreatePrimitive(PrimitiveType.Sphere);
                sphere.name = "obj_" + i;
                sphere.transform.localScale = Vector3.one * 0.1f;
                sphere.transform.position   = new Vector3(
                    (1f + Random.value * 5f),
                    (1f + Random.value * 5f),
                    (1f + Random.value * 5f)
                    );
                sphere.transform.position += LorenzStep(sphere.transform.position) * 0.01f;

                // ...and wrap it an KDGameObject
                pointCloud.Add(new KDGameObject(sphere));
            }

            query = new KDQuery <KDGameObject>();
            tree  = new KDTree <KDGameObject>(pointCloud, 32);
        }
        // Start is called before the first frame update
        void Start()
        {
            query     = new KDQuery();
            VPLVector = new Vector3[InitVPLCount];
            VPLPoints = new Vector3[InitVPLCount];
            SpotAngle = GetComponent <Light>().spotAngle;
            if (type == "Point Light")
            {
                Vector3    org = this.transform.position;
                RaycastHit hit;
                parent = new GameObject();
                for (int i = 0; i < InitVPLCount; i++)
                {
                    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   = tempDir;
                    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);
                    }
                    GameObject temp = new GameObject();
                    temp.transform.parent   = parent.transform;
                    temp.transform.position = VPLPoints[i];
                    temp.AddComponent <Light>();
                    temp.GetComponent <Light>().shadows          = LightShadows.Hard;
                    temp.GetComponent <Light>().shadowBias       = 0;
                    temp.GetComponent <Light>().shadowNormalBias = 0;
                    temp.GetComponent <Light>().shadowNearPlane  = 0.2f;
                    Vector3 CubeUV = convert_xyz_to_cube_uv(B);
                    if (CubeUV.x == 0.0f)
                    {
                        temp.GetComponent <Light>().color = MyCubeMap.GetPixel(CubemapFace.PositiveX, (int)(CubeUV.y * 1024.0), (int)(CubeUV.z * 1024.0));
                    }
                    if (CubeUV.x == 1.0f)
                    {
                        temp.GetComponent <Light>().color = MyCubeMap.GetPixel(CubemapFace.NegativeX, (int)(CubeUV.y * 1024.0), (int)(CubeUV.z * 1024.0));
                    }
                    if (CubeUV.x == 2.0f)
                    {
                        temp.GetComponent <Light>().color = MyCubeMap.GetPixel(CubemapFace.PositiveY, (int)(CubeUV.y * 1024.0), (int)(CubeUV.z * 1024.0));
                    }
                    if (CubeUV.x == 3.0f)
                    {
                        temp.GetComponent <Light>().color = MyCubeMap.GetPixel(CubemapFace.NegativeY, (int)(CubeUV.y * 1024.0), (int)(CubeUV.z * 1024.0));
                    }
                    if (CubeUV.x == 4.0f)
                    {
                        temp.GetComponent <Light>().color = MyCubeMap.GetPixel(CubemapFace.PositiveZ, (int)(CubeUV.y * 1024.0), (int)(CubeUV.z * 1024.0));
                    }
                    if (CubeUV.x == 5.0f)
                    {
                        temp.GetComponent <Light>().color = MyCubeMap.GetPixel(CubemapFace.NegativeZ, (int)(CubeUV.y * 1024.0), (int)(CubeUV.z * 1024.0));
                    }
                    VPL.Add(temp);
                }
            }
            else
            {
                int        PassCount = 0;
                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);
                parent = new GameObject();
                Debug.DrawLine(transform.position + transform.forward * 10, this.transform.position);
                while (PassCount != InitVPLCount)
                {
                    //float Rx = ((float)Random.Range(0, 1024)) / 1024.0f;
                    //float Ry = ((float)Random.Range(0, 1024)) / 1024.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 Vector2(Rx, Ry);
                        B.x -= 0.5f;
                        B.y -= 0.5f;
                        VPLVector[PassCount] = B;
                        //            float l = Vector3.Dot(B, 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;

                            GameObject temp = new GameObject();
                            temp.transform.parent   = parent.transform;
                            temp.transform.position = hit.point;
                            temp.AddComponent <Light>();
                            temp.GetComponent <Light>().color   = (tempTex.GetPixel((int)p.x, (int)p.y));
                            temp.GetComponent <Light>().shadows = LightShadows.Hard;
                            VPL.Add(temp);
                            VPLPoints[PassCount] = hit.point;
                            PassCount++;
                        }
                        else
                        {
                            continue;
                        }
                    }
                }
                int a = 1;
                tree = new KDTree(VPLPoints, 16);
            }
        }
예제 #7
0
//	/// <summary>
//	/// Need to be fixed
//	/// </summary>
//	public void IsOnGrass(Vector3 pos)
//	{
//		kdResults.Clear ();
//		float halfsize = builder.CalChunkSize () * 0.5f;
//
//		List<int> ids = new List<int> ();
//		List<float> dis = new List<float> ();
//		kdQuery.ClosestPoint (kdTree, pos,ids,dis);
//		var chunk = chunks [ids [0]];
//		//chunk.
//
//		//Debug.Log (halfsize + " " + dis [0]);
//
//		var gDis = float.MaxValue;
//		foreach (var item in chunk.data) {
//			var _gDis = Vector3.Distance(new Vector2(pos.x,pos.z),new Vector2(item.pos[0].x,item.pos[0].z));
//			Debug.Log ("pos:"+pos +" "+"pos:"+item.pos[0]);
//
//			if (_gDis < gDis)
//				gDis = _gDis;
//		}
//		Debug.Log ("gDis"+gDis);
//	}


    void InitKDTree()
    {
        kdTree    = new KDTree(data.chunkPos);
        kdQuery   = new KDQuery();
        kdResults = new List <int> ();
    }
예제 #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];
        }
    }