Esempio n. 1
0
 private bool GetLeafNode(OpenBveApi.Math.Vector3 position, GridNode node, out GridLeafNode leaf)
 {
     if (node != null) {
         if (
             position.X >= node.Rectangle.Left &
             position.X <= node.Rectangle.Right &
             position.Z >= node.Rectangle.Near &
             position.Z <= node.Rectangle.Far
         ) {
             if (node is GridInternalNode) {
                 GridInternalNode intern = (GridInternalNode)node;
                 for (int i = 0; i < intern.Children.Length; i++) {
                     if (GetLeafNode(position, intern.Children[i], out leaf)) {
                         return true;
                     }
                 }
                 leaf = null;
                 return false;
             } else if (node is GridLeafNode) {
                 leaf = (GridLeafNode)node;
                 return true;
             } else {
                 throw new InvalidOperationException();
             }
         } else {
             leaf = null;
             return false;
         }
     } else {
         leaf = null;
         return false;
     }
 }
Esempio n. 2
0
 /// <summary>Creates the visibility list for the specified leaf node.</summary>
 /// <param name="leaf">The leaf node for which to create its visibility list.</param>
 /// <param name="viewingDistance">The viewing distance.</param>
 private void CreateVisibilityList(GridLeafNode leaf, double viewingDistance)
 {
     List<GridPopulatedLeafNode> nodes = new List<GridPopulatedLeafNode>();
     CreateVisibilityList(leaf, this.Root, nodes, viewingDistance);
     leaf.VisibleLeafNodes = nodes.ToArray();
 }
Esempio n. 3
0
 /// <summary>Creates the visibility list for the specified leaf node.</summary>
 /// <param name="leaf">The leaf node for which to create its visibility list.</param>
 /// <param name="node">The node to potentially include in the visiblity list if visible.</param>
 /// <param name="nodes">The list of visible leaf nodes.</param>
 /// <param name="viewingDistance">The viewing distance.</param>
 private void CreateVisibilityList(GridLeafNode leaf, GridNode node, List<GridPopulatedLeafNode> nodes, double viewingDistance)
 {
     if (node != null) {
         bool visible;
         if (
             leaf.BoundingRectangle.Left <= node.BoundingRectangle.Right &
             leaf.BoundingRectangle.Right >= node.BoundingRectangle.Left &
             leaf.BoundingRectangle.Near <= node.BoundingRectangle.Far &
             leaf.BoundingRectangle.Far >= node.BoundingRectangle.Near
         ) {
             /*
              * If the bounding rectangles intersect directly, the node is
              * definately visible from at least some point inside the leaf.
              * */
             visible = true;
         } else if (
             leaf.BoundingRectangle.Left - viewingDistance <= node.BoundingRectangle.Right &
             leaf.BoundingRectangle.Right + viewingDistance >= node.BoundingRectangle.Left &
             leaf.BoundingRectangle.Near - viewingDistance <= node.BoundingRectangle.Far &
             leaf.BoundingRectangle.Far + viewingDistance >= node.BoundingRectangle.Near
         ) {
             /*
              * If the leaf bounding rectangle extended by the viewing distance
              * in all directions intersects with the node bounding rectangle,
              * visibility is at least a possibility.
              * */
             if (
                 leaf.BoundingRectangle.Left <= node.BoundingRectangle.Right &
                 leaf.BoundingRectangle.Right >= node.BoundingRectangle.Left |
                 leaf.BoundingRectangle.Near <= node.BoundingRectangle.Far &
                 leaf.BoundingRectangle.Far >= node.BoundingRectangle.Near
             ) {
                 /*
                  * The bounding rectangles intersect, but either only on
                  * the x-axis, or on the y-axis. This case is always visible
                  * given that the above constraint (extension by viewing
                  * distance) is also met.
                  * */
                 visible = true;
             } else {
                 /*
                  * The bounding rectangles don't intersect on either axis.
                  * Visibility is given if the smallest vertex-to-vertex
                  * distance is smaller than the viewing distance.
                  * */
                 if (leaf.BoundingRectangle.Right <= node.BoundingRectangle.Left) {
                     if (leaf.BoundingRectangle.Far <= node.BoundingRectangle.Near) {
                         double x = leaf.BoundingRectangle.Right - node.BoundingRectangle.Left;
                         double y = leaf.BoundingRectangle.Far - node.BoundingRectangle.Near;
                         visible = x * x + y * y <= viewingDistance * viewingDistance;
                     } else {
                         double x = leaf.BoundingRectangle.Right - node.BoundingRectangle.Left;
                         double y = leaf.BoundingRectangle.Near - node.BoundingRectangle.Far;
                         visible = x * x + y * y <= viewingDistance * viewingDistance;
                     }
                 } else {
                     if (leaf.BoundingRectangle.Far <= node.BoundingRectangle.Near) {
                         double x = leaf.BoundingRectangle.Left - node.BoundingRectangle.Right;
                         double y = leaf.BoundingRectangle.Far - node.BoundingRectangle.Near;
                         visible = x * x + y * y <= viewingDistance * viewingDistance;
                     } else {
                         double x = leaf.BoundingRectangle.Left - node.BoundingRectangle.Right;
                         double y = leaf.BoundingRectangle.Near - node.BoundingRectangle.Far;
                         visible = x * x + y * y <= viewingDistance * viewingDistance;
                     }
                 }
             }
         } else {
             /*
              * If the leaf bounding rectangle extended by the viewing distance
              * in all directions doesn't intersect with the node bounding rectangle,
              * visibility is not possible.
              * */
             visible = false;
         }
         if (visible) {
             /*
              * The node is visible and is either added to the list of visible nodes if
              * a leaf node, or recursively processed for all children if an internal node.
              * */
             if (node is GridInternalNode) {
                 GridInternalNode intern = (GridInternalNode)node;
                 for (int i = 0; i < intern.Children.Length; i++) {
                     CreateVisibilityList(leaf, intern.Children[i], nodes, viewingDistance);
                 }
             } else if (node is GridPopulatedLeafNode) {
                 nodes.Add((GridPopulatedLeafNode)node);
             }
         }
     }
 }
Esempio n. 4
0
 /// <summary>Gets the leaf node for a specified position.</summary>
 /// <param name="position">The position.</param>
 /// <param name="leaf">Receives the leaf node on success.</param>
 /// <returns>The success of the operation.</returns>
 internal bool GetLeafNode(OpenBveApi.Math.Vector3 position, out GridLeafNode leaf)
 {
     return GetLeafNode(position, this.Root, out leaf);
 }