/// <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); }
//**************************************************************** // 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); }
/// <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. 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.RectanglesIntersect(Bounds, 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); }
/// <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; }
//**************************************************************** // 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; }
/// <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; }
/// <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.RectanglesIntersect(Bounds, 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; }