/// <summary>
		/// Traverse from the bottom right of the scene graph (top visible node)
		/// up the tree determining which parent nodes are occluded by their children
		/// nodes.
		/// </summary>
		/// <param name="n">The node to find occlusions for.</param>
		/// <param name="pickPath">
		/// A pick path representing the bounds of <c>n</c> in parent coordinates.
		/// </param>
		/// <remarks>
		/// Note that this is only detecting a subset of occlusions (parent, child),
		/// others such as overlapping siblings or cousins are not detected.
		/// </remarks>
		public void DetectOcclusions(PNode n, PPickPath pickPath) {
			if (n.FullIntersects(pickPath.PickBounds)) {
				pickPath.PushMatrix(n.MatrixReference);
		
				int count = n.ChildrenCount;
				for (int i = count - 1; i >= 0; i--) {
					PNode each = n[i];
					if (n.Occluded) {
						// if n has been occluded by a previous decendent then
						// this child must also be occluded
						each.Occluded = true;
					} else {
						// see if child each occludes n
						DetectOcclusions(each, pickPath);
					}
				}

				// see if n occludes it's parents		
				if (!n.Occluded) {
					if (n.Intersects(pickPath.PickBounds)) {
						if (n.IsOpaque(pickPath.PickBounds)) {
							PNode p = n.Parent;
							while (p != null && !p.Occluded) {
								p.Occluded = true;
							}
						}
					}
				}
	
				pickPath.PopMatrix(n.MatrixReference);
			}				
		}
示例#2
0
		/// <summary>
		/// Try to pick this node and all of its descendents.
		/// </summary>
		/// <param name="pickPath">The pick path to add the node to if its picked.</param>
		/// <returns>True if this node or one of its descendents was picked; else false.</returns>
		/// <remarks>
		/// <b>Notes to Inheritors:</b>  Most subclasses should not need to override this
		/// method. Instead they should override <c>Pick</c> or <c>PickAfterChildren</c>.
		///	</remarks>
		public virtual bool FullPick(PPickPath pickPath) {
			if ((Pickable || ChildrenPickable) && FullIntersects(pickPath.PickBounds)) {
				pickPath.PushNode(this);
				pickPath.PushMatrix(matrix);
			
				bool thisPickable = Pickable && pickPath.AcceptsNode(this);

				if (thisPickable && Pick(pickPath)) {
					return true;
				}

				if (ChildrenPickable) {
					int count = ChildrenCount;
					for (int i = count - 1; i >= 0; i--) {
						if (children[i].FullPick(pickPath)) {
							return true;
						}
					}				
				}

				if (thisPickable && PickAfterChildren(pickPath)) {
					return true;
				}

				pickPath.PopMatrix(matrix);
				pickPath.PopNode(this);
			}

			return false;
		}
示例#3
0
		/// <summary>
		/// Overridden.  After the direct children of the camera have been given a chance
		/// to be picked objects viewed by the camera are given a chance to be picked.
		/// </summary>
		/// <param name="pickPath">The pick path used for the pick operation.</param>
		/// <returns>
		/// True if an object viewed by the camera was picked; else false.
		/// </returns>
		protected override bool PickAfterChildren(PPickPath pickPath) {
			if (Intersects(pickPath.PickBounds)) {
				pickPath.PushMatrix(viewMatrix);

				if (PickCameraView(pickPath)) {
					return true;
				}

				pickPath.PopMatrix(viewMatrix);
				return true;
			}
			return false;
		}
示例#4
0
		/// <summary>
		/// Overridden.  Only picks this node's children if the pick bounds intersects the
		/// clip.
		/// </summary>
		/// <param name="pickPath">The pick path to add the node to if its picked.</param>
		/// <returns>
		/// True if this node or one of its descendents was picked; else false.
		/// </returns>
		public override bool FullPick(PPickPath pickPath) {
			if (Pickable && FullIntersects(pickPath.PickBounds)) {
				pickPath.PushNode(this);
				pickPath.PushMatrix(MatrixReference);
			
				if (Pick(pickPath)) {
					return true;
				}

				if (ChildrenPickable && PUtil.PathIntersectsRect(PathReference, pickPath.PickBounds)) { 		
					int count = ChildrenCount;
					for (int i = count - 1; i >= 0; i--) {
						PNode each = this.GetChild(i);
						if (each.FullPick(pickPath))
							return true;
					}				
				}

				if (PickAfterChildren(pickPath)) {
					return true;
				}

				pickPath.PopMatrix(MatrixReference);
				pickPath.PopNode(this);
			}

			return false;
		}
示例#5
0
		//****************************************************************
		// Picking - Methods for picking the camera and it's view.
		//****************************************************************

		/// <summary>
		/// Generate and return a PPickPath for the point x,y specified in the local
		/// coordinate system of this camera.
		/// </summary>
		/// <param name="x">The x coordinate of the pick point.</param>
		/// <param name="y">The y coordinate of the pick point.</param>
		/// <param name="halo">
		/// The value to use for the width and height of the rectangle used for picking.
		/// </param>
		/// <returns>A PPickPath for the given point.</returns>
		/// <remarks>
		/// Picking is done with a rectangle, halo specifies how large that rectangle
		/// will be.
		/// </remarks>
		public virtual PPickPath Pick(float x, float y, float halo) {
			RectangleF b = PUtil.InflatedRectangle(new PointF(x, y), halo, halo);
			PPickPath result = new PPickPath(this, b);

			FullPick(result);
			
			// make sure this camera is pushed.
			if (result.NodeStackReference.Count == 0) {
				result.PushNode(this);
				result.PushMatrix(MatrixReference);
			}

			return result;
		}