Exemple #1
0
        //private static FieldOctree<GravityCell> BuildFieldSprtNode_OLD(List<GravityCell> allLeaves, MapOctree[] ancestors, double[] ancestorMasses, MapOctree node)
        //{
        //    #region Add up mass

        //    // Add up all the mass sitting in the ancestors
        //    double massFromAbove = 0d;
        //    if (ancestorMasses != null)
        //    {
        //        for (int cntr = 0; cntr < ancestorMasses.Length; cntr++)
        //        {
        //            // Each child shares 1/8th of the parent's mass + 1/64th of the grandparents, etc
        //            // (these masses directly at each ancestor is of the objects that are straddling the lines between nodes)
        //            massFromAbove += ancestorMasses[cntr] * Math.Pow(.125d, ancestorMasses.Length - cntr);
        //        }
        //    }

        //    double massOfNode = 0d;
        //    if (node.Items != null)
        //    {
        //        foreach (MapObjectInfo item in node.Items)
        //        {
        //            massOfNode += item.Mass;
        //        }
        //    }

        //    #endregion

        //    if (!node.HasChildren)
        //    {
        //        #region Leaf

        //        // Exit Function
        //        GravityCell cell = new GravityCell(massFromAbove + massOfNode, node.CenterPoint);
        //        allLeaves.Add(cell);
        //        return new FieldOctree<GravityCell>(node.MinRange, node.MaxRange, node.CenterPoint, cell);

        //        #endregion
        //    }

        //    // Make the return node
        //    FieldOctree<GravityCell> retVal = new FieldOctree<GravityCell>(node.MinRange, node.MaxRange, node.CenterPoint);

        //    #region Build ancestor arrays

        //    // Create new arrays that hold this node's values (to pass to the children)
        //    MapOctree[] ancestorsNew = null;
        //    double[] ancestorMassesNew = null;
        //    if (ancestors == null)
        //    {
        //        // This is the root
        //        ancestorsNew = new MapOctree[] { node };
        //        ancestorMassesNew = new double[] { massOfNode };
        //    }
        //    else
        //    {
        //        // This is a middle ancestor
        //        ancestorsNew = new MapOctree[ancestors.Length + 1];
        //        Array.Copy(ancestors, ancestorsNew, ancestors.Length);
        //        ancestorsNew[ancestorsNew.Length - 1] = node;

        //        ancestorMassesNew = new double[ancestorMasses.Length + 1];
        //        Array.Copy(ancestorMasses, ancestorMassesNew, ancestorMasses.Length);
        //        ancestorMassesNew[ancestorMassesNew.Length - 1] = massOfNode;
        //    }

        //    #endregion

        //    #region Add the children

        //    //NOTE: The map's octree will leave children null if there are no items in them.  But this tree always has all 8 children

        //    if (node.X0_Y0_Z0 == null)
        //    {
        //        retVal.X0_Y0_Z0 = BuildFieldSprtNode(allLeaves, massFromAbove + massOfNode, new Point3D(node.MinRange.X, node.MinRange.Y, node.MinRange.Z), new Point3D(node.CenterPoint.X, node.CenterPoint.Y, node.CenterPoint.Z));
        //    }
        //    else
        //    {
        //        retVal.X0_Y0_Z0 = BuildFieldSprtNode(allLeaves, ancestorsNew, ancestorMassesNew, node.X0_Y0_Z0);
        //    }

        //    if (node.X0_Y0_Z1 == null)
        //    {
        //        retVal.X0_Y0_Z1 = BuildFieldSprtNode(allLeaves, massFromAbove + massOfNode, new Point3D(node.MinRange.X, node.MinRange.Y, node.CenterPoint.Z), new Point3D(node.CenterPoint.X, node.CenterPoint.Y, node.MaxRange.Z));
        //    }
        //    else
        //    {
        //        retVal.X0_Y0_Z1 = BuildFieldSprtNode(allLeaves, ancestorsNew, ancestorMassesNew, node.X0_Y0_Z1);
        //    }

        //    if (node.X0_Y1_Z0 == null)
        //    {
        //        retVal.X0_Y1_Z0 = BuildFieldSprtNode(allLeaves, massFromAbove + massOfNode, new Point3D(node.MinRange.X, node.CenterPoint.Y, node.MinRange.Z), new Point3D(node.CenterPoint.X, node.MaxRange.Y, node.CenterPoint.Z));
        //    }
        //    else
        //    {
        //        retVal.X0_Y1_Z0 = BuildFieldSprtNode(allLeaves, ancestorsNew, ancestorMassesNew, node.X0_Y1_Z0);
        //    }

        //    if (node.X0_Y1_Z1 == null)
        //    {
        //        retVal.X0_Y1_Z1 = BuildFieldSprtNode(allLeaves, massFromAbove + massOfNode, new Point3D(node.MinRange.X, node.CenterPoint.Y, node.CenterPoint.Z), new Point3D(node.CenterPoint.X, node.MaxRange.Y, node.MaxRange.Z));
        //    }
        //    else
        //    {
        //        retVal.X0_Y1_Z1 = BuildFieldSprtNode(allLeaves, ancestorsNew, ancestorMassesNew, node.X0_Y1_Z1);
        //    }

        //    if (node.X1_Y0_Z0 == null)
        //    {
        //        retVal.X1_Y0_Z0 = BuildFieldSprtNode(allLeaves, massFromAbove + massOfNode, new Point3D(node.CenterPoint.X, node.MinRange.Y, node.MinRange.Z), new Point3D(node.MaxRange.X, node.CenterPoint.Y, node.CenterPoint.Z));
        //    }
        //    else
        //    {
        //        retVal.X1_Y0_Z0 = BuildFieldSprtNode(allLeaves, ancestorsNew, ancestorMassesNew, node.X1_Y0_Z0);
        //    }

        //    if (node.X1_Y0_Z1 == null)
        //    {
        //        retVal.X1_Y0_Z1 = BuildFieldSprtNode(allLeaves, massFromAbove + massOfNode, new Point3D(node.CenterPoint.X, node.MinRange.Y, node.CenterPoint.Z), new Point3D(node.MaxRange.X, node.CenterPoint.Y, node.MaxRange.Z));
        //    }
        //    else
        //    {
        //        retVal.X1_Y0_Z1 = BuildFieldSprtNode(allLeaves, ancestorsNew, ancestorMassesNew, node.X1_Y0_Z1);
        //    }

        //    if (node.X1_Y1_Z0 == null)
        //    {
        //        retVal.X1_Y1_Z0 = BuildFieldSprtNode(allLeaves, massFromAbove + massOfNode, new Point3D(node.CenterPoint.X, node.CenterPoint.Y, node.MinRange.Z), new Point3D(node.MaxRange.X, node.MaxRange.Y, node.CenterPoint.Z));
        //    }
        //    else
        //    {
        //        retVal.X1_Y1_Z0 = BuildFieldSprtNode(allLeaves, ancestorsNew, ancestorMassesNew, node.X1_Y1_Z0);
        //    }

        //    if (node.X1_Y1_Z1 == null)
        //    {
        //        retVal.X1_Y1_Z1 = BuildFieldSprtNode(allLeaves, massFromAbove + massOfNode, new Point3D(node.CenterPoint.X, node.CenterPoint.Y, node.CenterPoint.Z), new Point3D(node.MaxRange.X, node.MaxRange.Y, node.MaxRange.Z));
        //    }
        //    else
        //    {
        //        retVal.X1_Y1_Z1 = BuildFieldSprtNode(allLeaves, ancestorsNew, ancestorMassesNew, node.X1_Y1_Z1);
        //    }

        //    #endregion

        //    // Exit Function
        //    return retVal;
        //}

        #endregion

        private static FieldOctree <GravityCell> BuildField_Node(List <GravityCell> allLeaves, double mass, Point3D min, Point3D max)
        {
            Point3D center = new Point3D((min.X + max.X) * .5d, (min.Y + max.Y) * .5d, (min.Z + max.Z) * .5d);

            GravityCell cell = new GravityCell(mass, center);

            allLeaves.Add(cell);
            return(new FieldOctree <GravityCell>(min, max, center, cell));
        }
Exemple #2
0
        public Vector3D GetForce(Point3D point)
        {
            Vector3D retVal = new Vector3D(0, 0, 0);

            // If there is a swirl, then calculate it for this point
            SwirlField swirl = this.Swirl;              // can only hit the property once, it could be swapped out at any moment

            if (swirl != null)
            {
                retVal += swirl.GetForce(point);
            }

            // Boundry field
            BoundryField boundry = this.Boundry;

            if (boundry != null)
            {
                retVal += boundry.GetForce(point);
            }

            // Grab the root for the remainder of this method (the public one could swap out at any moment)
            var root = _fieldRoot;

            if (root == null)
            {
                return(retVal);
            }

            if (!Math3D.IsInside_AABB(root.MinRange, root.MaxRange, point))
            {
                // The point is outside the root, so just assume no gravity (the root should have been big enough to surround all objects, so there shouldn't
                // be any requests outside the root)
                return(retVal);
            }

            // Recurse down, and get the leaf for this point
            GravityCell cell = root.GetLeaf(point);

            if (cell == null)
            {
                // There should be a leaf for all points within the tree.  But rather than an exception, just assume zero force
                return(retVal);
            }

            // Exit Function
            return(retVal + cell.Force);
        }
Exemple #3
0
        private static FieldOctree <GravityCell> BuildField_Node(List <GravityCell> allLeaves, MapOctree[] ancestors, MapOctree node)
        {
            #region Add up mass

            double massOfNode = 0d;
            if (node.Items != null)
            {
                foreach (MapObjectInfo item in node.Items)
                {
                    massOfNode += item.Mass;
                }
            }

            #endregion

            if (!node.HasChildren)
            {
                #region Leaf

                // Exit Function
                GravityCell cell = new GravityCell(BuildField_NodeSprtAncestorMass(ancestors, node.MinRange, node.MaxRange) + massOfNode, node.CenterPoint);
                allLeaves.Add(cell);
                return(new FieldOctree <GravityCell>(node.MinRange, node.MaxRange, node.CenterPoint, cell));

                #endregion
            }

            // Make the return node
            FieldOctree <GravityCell> retVal = new FieldOctree <GravityCell>(node.MinRange, node.MaxRange, node.CenterPoint);

            #region Build ancestor arrays

            // Create new arrays that hold this node's values (to pass to the children)
            MapOctree[] ancestorsNew = null;
            if (ancestors == null)
            {
                // This is the root
                ancestorsNew = new MapOctree[] { node };
            }
            else
            {
                // This is a middle ancestor
                ancestorsNew = new MapOctree[ancestors.Length + 1];
                Array.Copy(ancestors, ancestorsNew, ancestors.Length);
                ancestorsNew[ancestorsNew.Length - 1] = node;
            }

            #endregion

            #region Add the children

            //NOTE: The map's octree will leave children null if there are no items in them.  But this tree always has all 8 children

            if (node.X0_Y0_Z0 == null)
            {
                Point3D childMin = new Point3D(node.MinRange.X, node.MinRange.Y, node.MinRange.Z);
                Point3D childMax = new Point3D(node.CenterPoint.X, node.CenterPoint.Y, node.CenterPoint.Z);
                retVal.X0_Y0_Z0 = BuildField_Node(allLeaves, BuildField_NodeSprtAncestorMass(ancestors, childMin, childMax) + massOfNode, childMin, childMax);
            }
            else
            {
                retVal.X0_Y0_Z0 = BuildField_Node(allLeaves, ancestorsNew, node.X0_Y0_Z0);
            }

            if (node.X0_Y0_Z1 == null)
            {
                Point3D childMin = new Point3D(node.MinRange.X, node.MinRange.Y, node.CenterPoint.Z);
                Point3D childMax = new Point3D(node.CenterPoint.X, node.CenterPoint.Y, node.MaxRange.Z);
                retVal.X0_Y0_Z1 = BuildField_Node(allLeaves, BuildField_NodeSprtAncestorMass(ancestors, childMin, childMax) + massOfNode, childMin, childMax);
            }
            else
            {
                retVal.X0_Y0_Z1 = BuildField_Node(allLeaves, ancestorsNew, node.X0_Y0_Z1);
            }

            if (node.X0_Y1_Z0 == null)
            {
                Point3D childMin = new Point3D(node.MinRange.X, node.CenterPoint.Y, node.MinRange.Z);
                Point3D childMax = new Point3D(node.CenterPoint.X, node.MaxRange.Y, node.CenterPoint.Z);
                retVal.X0_Y1_Z0 = BuildField_Node(allLeaves, BuildField_NodeSprtAncestorMass(ancestors, childMin, childMax) + massOfNode, childMin, childMax);
            }
            else
            {
                retVal.X0_Y1_Z0 = BuildField_Node(allLeaves, ancestorsNew, node.X0_Y1_Z0);
            }

            if (node.X0_Y1_Z1 == null)
            {
                Point3D childMin = new Point3D(node.MinRange.X, node.CenterPoint.Y, node.CenterPoint.Z);
                Point3D childMax = new Point3D(node.CenterPoint.X, node.MaxRange.Y, node.MaxRange.Z);
                retVal.X0_Y1_Z1 = BuildField_Node(allLeaves, BuildField_NodeSprtAncestorMass(ancestors, childMin, childMax) + massOfNode, childMin, childMax);
            }
            else
            {
                retVal.X0_Y1_Z1 = BuildField_Node(allLeaves, ancestorsNew, node.X0_Y1_Z1);
            }

            if (node.X1_Y0_Z0 == null)
            {
                Point3D childMin = new Point3D(node.CenterPoint.X, node.MinRange.Y, node.MinRange.Z);
                Point3D childMax = new Point3D(node.MaxRange.X, node.CenterPoint.Y, node.CenterPoint.Z);
                retVal.X1_Y0_Z0 = BuildField_Node(allLeaves, BuildField_NodeSprtAncestorMass(ancestors, childMin, childMax) + massOfNode, childMin, childMax);
            }
            else
            {
                retVal.X1_Y0_Z0 = BuildField_Node(allLeaves, ancestorsNew, node.X1_Y0_Z0);
            }

            if (node.X1_Y0_Z1 == null)
            {
                Point3D childMin = new Point3D(node.CenterPoint.X, node.MinRange.Y, node.CenterPoint.Z);
                Point3D childMax = new Point3D(node.MaxRange.X, node.CenterPoint.Y, node.MaxRange.Z);
                retVal.X1_Y0_Z1 = BuildField_Node(allLeaves, BuildField_NodeSprtAncestorMass(ancestors, childMin, childMax) + massOfNode, childMin, childMax);
            }
            else
            {
                retVal.X1_Y0_Z1 = BuildField_Node(allLeaves, ancestorsNew, node.X1_Y0_Z1);
            }

            if (node.X1_Y1_Z0 == null)
            {
                Point3D childMin = new Point3D(node.CenterPoint.X, node.CenterPoint.Y, node.MinRange.Z);
                Point3D childMax = new Point3D(node.MaxRange.X, node.MaxRange.Y, node.CenterPoint.Z);
                retVal.X1_Y1_Z0 = BuildField_Node(allLeaves, BuildField_NodeSprtAncestorMass(ancestors, childMin, childMax) + massOfNode, childMin, childMax);
            }
            else
            {
                retVal.X1_Y1_Z0 = BuildField_Node(allLeaves, ancestorsNew, node.X1_Y1_Z0);
            }

            if (node.X1_Y1_Z1 == null)
            {
                Point3D childMin = new Point3D(node.CenterPoint.X, node.CenterPoint.Y, node.CenterPoint.Z);
                Point3D childMax = new Point3D(node.MaxRange.X, node.MaxRange.Y, node.MaxRange.Z);
                retVal.X1_Y1_Z1 = BuildField_Node(allLeaves, BuildField_NodeSprtAncestorMass(ancestors, childMin, childMax) + massOfNode, childMin, childMax);
            }
            else
            {
                retVal.X1_Y1_Z1 = BuildField_Node(allLeaves, ancestorsNew, node.X1_Y1_Z1);
            }

            #endregion

            // Exit Function
            return(retVal);
        }