private void Subdivide() { _subRegions = new BHRegion[8]; var midpoint = (Max + Min) / 2f; float3 dimension = (Max - Min) / 2f; float3 rightShift = new float3(dimension.x, 0f, 0f); float3 upShift = new float3(0f, dimension.y, 0f); float3 forwardShift = new float3(0f, 0f, dimension.z); _subRegions[0] = new BHRegion(midpoint, Max); _subRegions[1] = new BHRegion(midpoint - rightShift, Max - rightShift); _subRegions[2] = new BHRegion(midpoint - rightShift - forwardShift, Max - rightShift - forwardShift); _subRegions[3] = new BHRegion(midpoint - forwardShift, Max - forwardShift); _subRegions[4] = new BHRegion(midpoint - upShift, Max - upShift); _subRegions[5] = new BHRegion(midpoint - upShift - rightShift, Max - upShift - rightShift); _subRegions[6] = new BHRegion(midpoint - upShift - rightShift - forwardShift, Max - upShift - rightShift - forwardShift); _subRegions[7] = new BHRegion(midpoint - upShift - forwardShift, Max - upShift - forwardShift); }
private void ForceWalkTraversal(BHRegion region, Entity entity, float mass, float3 position, ref float3 resultant) { if (region == null || region.IsEmpty) { return; } BHRegion currentRegion = region; if (currentRegion.IsExternal) { if (currentRegion.CurrentRegionEntity.Value.entity != entity) { // TODO: Add gravitational stuff. var diff = currentRegion.CurrentRegionEntity.Value.position - position; var magnitude = GRAVITATIONAL_CONSTANT * (currentRegion.CurrentRegionEntity.Value.mass * mass) / math.pow(math.pow(diff.x, 2) + math.pow(diff.y, 2) + math.pow(diff.z, 2), 1.5f); resultant += magnitude * math.normalize(diff); } } else { var s = currentRegion.Dimension; var d = math.length(position - currentRegion.CenterOfMass); if (s / d < THETA) { // TODO: Add gravitational stuff; use currentRegion.TotalMass here. var diff = currentRegion.CenterOfMass - position; var magnitude = GRAVITATIONAL_CONSTANT * (currentRegion.TotalMass * mass) / math.pow(math.pow(diff.x, 2) + math.pow(diff.y, 2) + math.pow(diff.z, 2), 1.5f); resultant += magnitude * math.normalize(diff); } else { for (int i = 0; i < 8; i++) { ForceWalkTraversal(region.Subregions[i], entity, mass, position, ref resultant); } } } }
public void PreOrderTraverseTree(Action <BHRegion> action, BHRegion startRegion) { if (startRegion == null) { return; } BHRegion currentRegion = startRegion; action(currentRegion); if (currentRegion.IsExternal) { return; } else if (currentRegion.IsInternal) { for (int i = 0; i < 8; i++) { PreOrderTraverseTree(action, currentRegion.Subregions[i]); } } }
public BarnesHutTree(float3 min, float3 max) { _root = new BHRegion(min, max); }