Example #1
0
        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);
 }