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); }
/// <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()]); }
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; } }
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>(); }
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); } }
// /// <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> (); }
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; }
// 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]; } }