public void Store(CompressedPhoton a) { bBoxMax = new PhotonVector3(a.Position.X < bBoxMax.X ? bBoxMax.X : a.Position.X, a.Position.Y < bBoxMax.Y ? bBoxMax.Y : a.Position.Y, a.Position.Z < bBoxMax.Z ? bBoxMax.Z : a.Position.Z); bBoxMin = new PhotonVector3(a.Position.X > bBoxMin.X ? bBoxMin.X : a.Position.X, a.Position.Y > bBoxMin.Y ? bBoxMin.Y : a.Position.Y, a.Position.Z > bBoxMin.Z ? bBoxMin.Z : a.Position.Z); //store.Add(a); AddPhoton(a); }
public CompressedPhoton FindPhotonAt(PhotonVector3 location, out int comparisons) { comparisons = 0; Node <CompressedPhoton> cur = root; while (cur != null) { if (cur.Current.position[cur.Axis] == location[cur.Axis]) { if (cur.Current.position == location) { return(cur.Current); } else { cur = cur.Right; } } else if (location[cur.Axis] < cur.Current.position[cur.Axis]) { cur = cur.Left; } else { cur = cur.Right; } comparisons++; } return(null); }
public RetrievedPhotons RetrieveNearestNeighbors(PhotonVector3 point, float distanceSquared, int maxPhotons, Vector3 normal) { RetrievedPhotons _retrieved = new RetrievedPhotons(maxPhotons); LocatePhotons(root, point, distanceSquared, ref _retrieved, normal); return(_retrieved); }
public void Store(Photon photon) { CompressedPhoton a = new CompressedPhoton(); if (photon.position != PhotonVector3.Empty) { a.position[0] = photon.position[0]; a.position[1] = photon.position[1]; a.position[2] = photon.position[2]; for (int x = 0; x < 3; x++) { a.Power[x] = photon.Power[x]; } int theta = (int)(Math.Acos(photon.Direction[2]) * (256 / Math.PI)); if (theta > 255) { a.Theta = 255; } else { a.Theta = (byte)theta; } int phi = (int)(Math.Atan2(photon.Direction[1], photon.Direction[0]) * (256 / Math.PI)); if (phi > 255) { a.Phi = 255; } else { a.Phi = (byte)phi; } a.Direction = (Vector3)photon.Direction; for (int x = 0; x < 3; x++) { a.Power[x] = photon.Power[x]; } bBoxMax = new PhotonVector3(a.Position.X < bBoxMax.X ? bBoxMax.X : a.Position.X, a.Position.Y < bBoxMax.Y ? bBoxMax.Y : a.Position.Y, a.Position.Z < bBoxMax.Z ? bBoxMax.Z : a.Position.Z); bBoxMin = new PhotonVector3(a.Position.X > bBoxMin.X ? bBoxMin.X : a.Position.X, a.Position.Y > bBoxMin.Y ? bBoxMin.Y : a.Position.Y, a.Position.Z > bBoxMin.Z ? bBoxMin.Z : a.Position.Z); //a.LightmapIndex = photon.LightmapIndex; //a.MaterialIndex = photon.MaterialIndex; if (a == null) { System.Diagnostics.Debugger.Break(); } //this.store.Add(a); AddPhoton(a); } else { System.Diagnostics.Debugger.Break(); } }
//List<CompressedPhoton> _retrieved; //PhotonVector3 _p; float _distSquared; public List <CompressedPhoton> RetrieveNearestNeighbors(PhotonVector3 point, float distanceSquared, int maxPhotons) { List <CompressedPhoton> _retrieved = new List <CompressedPhoton>(); LocatePhotons(root, point, distanceSquared, ref _retrieved); for (int x = 0; x < _retrieved.Count; x++) { } return(_retrieved); }
//int rejected = 0; public void LocatePhotons(Node <CompressedPhoton> node, PhotonVector3 _p, float _distSquared, ref List <CompressedPhoton> _retrieved) { if (node == null) { return; } // Step 1: Check distance between current node and point. If it's within radius, add it. PhotonVector3 difference = node.Current.position - _p; float dist2 = difference[0] * difference[0]; dist2 += difference[1] * difference[1]; dist2 += difference[2] * difference[2]; if (dist2 < _distSquared) { if (node.Current != null) { _retrieved.Add(node.Current); } } // Step 2: Is the point greater or lesser than the current node? Go left or right depending. if (difference[node.Axis] >= 0) { LocatePhotons(node.Right, _p, _distSquared, ref _retrieved); if (difference[node.Axis] * difference[node.Axis] < _distSquared) { LocatePhotons(node.Left, _p, _distSquared, ref _retrieved); } } else { LocatePhotons(node.Left, _p, _distSquared, ref _retrieved); if (difference[node.Axis] * difference[node.Axis] < _distSquared) { LocatePhotons(node.Right, _p, _distSquared, ref _retrieved); } } // Step 3: Does the radius extend past the splitting plane? If so, check the other side. }
public void LocatePhotons(Node <CompressedPhoton> node, PhotonVector3 _p, float _distSquared, ref RetrievedPhotons _retrieved, Vector3 normal) { if (node == null) { return; } // Step 1: Check distance between current node and point. If it's within radius, add it. PhotonVector3 difference = node.Current.position - _p; float dist2 = difference[0] * difference[0]; dist2 += difference[1] * difference[1]; dist2 += difference[2] * difference[2]; if (dist2 < _distSquared) { if ((node.Current != null) && (Vector3.Dot(node.Current.Direction, normal) < 0)) { _retrieved.AddIfClosest(node.Current, dist2); } } // Step 2: Is the point greater or lesser than the current node? Go left or right depending. if (difference[node.Axis] >= 0) { LocatePhotons(node.Right, _p, _distSquared, ref _retrieved, normal); if (difference[node.Axis] * difference[node.Axis] < _distSquared) { LocatePhotons(node.Left, _p, _distSquared, ref _retrieved, normal); } } else { LocatePhotons(node.Left, _p, _distSquared, ref _retrieved, normal); if (difference[node.Axis] * difference[node.Axis] < _distSquared) { LocatePhotons(node.Right, _p, _distSquared, ref _retrieved, normal); } } }
private Node <CompressedPhoton> BalanceSegment(int start, int length, PhotonVector3 bBoxMax, PhotonVector3 bBoxMin) { #region special case if (length <= 0) { return(null); } #endregion #region select dimension float distanceX = bBoxMax[0] - bBoxMin[0]; float distanceY = bBoxMax[1] - bBoxMin[1]; float distanceZ = bBoxMax[2] - bBoxMin[2]; int axis = 2; float distance = bBoxMax[2] - bBoxMin[2]; if (bBoxMax[1] - bBoxMin[1] > distance) { distance = bBoxMax[1] - bBoxMin[1]; axis = 1; } if (bBoxMax[0] - bBoxMin[0] > distance) { axis = 0; } #endregion int firstAxis = axis; begin: #region Special case if (length == 1) { Node <CompressedPhoton> phot = new Node <CompressedPhoton>(store[start]); phot.Axis = (short)axis; return(phot); } #endregion #region find the median int median = start + (length >> 1); // divide by two if (length > 0) { //LimitedList<CompressedPhoton> newStore = new LimitedList<CompressedPhoton>(store, start, length); HeapSort.NewSort(store, axis, start, length); } /*else * QuickSort.Sort(store, start, start + length - 1, axis);*/ /*LimitedList<CompressedPhoton> newStore = new LimitedList<CompressedPhoton>(store, start, length); * HeapSort.NewSort(newStore, axis);*/ //else //InsertionSort.Sort(store, 0, store.Count) // Anything that is above or equal to the median needs to be on the right side of the root node. // What we are doing here is starting at the median and looking for another axis-position of the same degree to the left of the median. int newMedian = median; for (int j = median - 1; j >= start; j--) { if (store[median].position[axis] == store[j].position[axis]) { newMedian = j; } } median = newMedian; Progress += length; #endregion #region special case /*if (length == 2) * { * Node<CompressedPhoton> parent = new Node<CompressedPhoton>(store[median]); * parent.Axis = (short)axis; * parent.Left = new Node<CompressedPhoton>(store[start]); * // TODO: Make sure this is the best way * parent.Left.Axis = (short)axis; * return parent; * }*/ #endregion Node <CompressedPhoton> phot1 = new Node <CompressedPhoton>(store[median]); phot1.Axis = (short)axis; if (median - start > 0) { float tmp = bBoxMax[axis]; bBoxMax[axis] = store[median].Position[axis]; phot1.Left = BalanceSegment(start, median - start, bBoxMax, bBoxMin); bBoxMax[axis] = tmp; } if (median + 1 < start + length) { if (length + start - median - 1 > 0) { if (median == start) { axis = (axis + 1) % 3; if (axis != firstAxis) { Progress -= length; goto begin; } } float tmp1 = bBoxMin[axis]; bBoxMin[axis] = store[median].Position[axis]; phot1.Right = BalanceSegment(median + 1, length + start - median - 1, bBoxMax, bBoxMin); bBoxMin[axis] = tmp1; } } return(phot1); }
public CompressedPhoton[] SortPhotons(List <CompressedPhoton> photons, Vector3 point, int maxCount) { WrapperPhoton[] array = new WrapperPhoton[(maxCount < photons.Count) ? maxCount : photons.Count]; PhotonVector3 photonPoint = point.ToPhotonVector(); int end = 0; for (int x = 0; x < photons.Count; x++) { float dist = (photons[x].position - photonPoint).ToVector3().LengthSq(); if (end == maxCount) { // insert int y; for (y = 0; y < end; y++) { if (array[y].dist2 > dist) { break; } } if (y >= end) { continue; } WrapperPhoton tempA, tempB; tempB = new WrapperPhoton(); tempB.p = photons[x]; tempB.dist2 = dist; for (y++; y < end; y++) { tempA = array[y]; array[y] = tempB; tempB = tempA; } } else if (end == 0) { array[end] = new WrapperPhoton(); array[end].dist2 = dist; array[end].p = photons[x]; end++; } else { int y; for (y = 0; y < end; y++) { if (array[y].dist2 > dist) { break; } } if (y >= end) { if (end != maxCount) { array[end] = new WrapperPhoton(); array[end].dist2 = dist; array[end].p = photons[x]; end++; } continue; } WrapperPhoton tempA, tempB; tempB = new WrapperPhoton(); tempB.p = photons[x]; tempB.dist2 = dist; for (y++; y < end; y++) { tempA = array[y]; array[y] = tempB; tempB = tempA; } if (end != maxCount) { array[end] = tempB; end++; } } } CompressedPhoton[] result = new CompressedPhoton[end]; for (int x = 0; x < end; x++) { result[x] = array[x].p; } array = null; //photons.Clear(); return(result); }