/// <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);
			}				
		}
		/// <summary>
		/// Overridden.  Returns true if this node or any pickable descendends are picked.
		/// </summary>
		/// <remarks>
		/// If a pick occurs the pickPath is modified so that this node is always returned as
		/// the picked node, even if it was a decendent node that initialy reported the pick.
		/// </remarks>
		/// <param name="pickPath"></param>
		/// <returns>True if this node or any descendents are picked; false, otherwise.</returns>
		public override bool FullPick(PPickPath pickPath) {
			if (base.FullPick(pickPath)) {
				PNode picked = pickPath.PickedNode;
			
				// this code won't work with internal cameras, because it doesn't pop
				// the cameras view transform.
				while (picked != this) {
					pickPath.PopMatrix(picked.MatrixReference);
					pickPath.PopNode(picked);
					picked = pickPath.PickedNode;
				}
			
				return true;
			}
			return false;
		}
Beispiel #3
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;
		}
Beispiel #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;
		}
Beispiel #5
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;
		}