Ejemplo n.º 1
0
        internal HitTestResultBehavior RaiseCallback(HitTestResultCallback resultCallback,
                                                     HitTestFilterCallback filterCallback,
                                                     HitTestResultBehavior lastResult,
                                                     double distanceAdjustment)
        {
            results.Sort(RayHitTestResult.CompareByDistanceToRayOrigin);

            for (int i = 0, count = results.Count; i < count; i++)
            {
                RayHitTestResult result = results[i];

                result.SetDistanceToRayOrigin(result.DistanceToRayOrigin + distanceAdjustment);

                Viewport2DVisual3D viewport2DVisual3D = result.VisualHit as Viewport2DVisual3D;
                if (viewport2DVisual3D != null)
                {
                    Point  intersectionPoint;
                    Visual viewport2DVisual3DChild = viewport2DVisual3D.Visual;

                    if (viewport2DVisual3DChild != null)
                    {
                        if (Viewport2DVisual3D.GetIntersectionInfo(result, out intersectionPoint))
                        {
                            // convert the resulting point to visual coordinates
                            Point            visualPoint = Viewport2DVisual3D.TextureCoordsToVisualCoords(intersectionPoint, viewport2DVisual3DChild);
                            GeneralTransform gt          = viewport2DVisual3DChild.TransformToOuterSpace().Inverse;

                            Point pointOnChild;
                            if (gt != null && gt.TryTransform(visualPoint, out pointOnChild))
                            {
                                HitTestResultBehavior behavior2D = viewport2DVisual3DChild.HitTestPoint(filterCallback,
                                                                                                        resultCallback,
                                                                                                        new PointHitTestParameters(pointOnChild));

                                if (behavior2D == HitTestResultBehavior.Stop)
                                {
                                    return(HitTestResultBehavior.Stop);
                                }
                            }
                        }
                    }
                }

                HitTestResultBehavior behavior = resultCallback(results[i]);

                if (behavior == HitTestResultBehavior.Stop)
                {
                    return(HitTestResultBehavior.Stop);
                }
            }

            return(lastResult);
        }
Ejemplo n.º 2
0
        /// <summary>
        /// Returns true and the intersection point for the given rayHitResult if there is an intersection,
        /// and false otherwise.
        /// </summary>
        /// <param name="rayHitResult"></param>
        /// <param name="outputPoint">The output point if there was an intersection</param>
        /// <returns>
        /// Returns the point of intersection in outputPoint if there is one, and returns true
        /// to indicate this.
        /// </returns>
        internal static bool GetIntersectionInfo(RayHitTestResult rayHitResult, out Point outputPoint)
        {
            bool success = false;

            outputPoint = new Point();

            // try to cast to a RaymeshGeometry3DHitTestResult
            RayMeshGeometry3DHitTestResult rayMeshResult = rayHitResult as RayMeshGeometry3DHitTestResult;

            if (rayMeshResult != null)
            {
                // we can now extract the mesh and visual for the object we hit
                MeshGeometry3D geom = rayMeshResult.MeshHit;

                // pull the barycentric coordinates of the intersection point
                double vertexWeight1 = rayMeshResult.VertexWeight1;
                double vertexWeight2 = rayMeshResult.VertexWeight2;
                double vertexWeight3 = rayMeshResult.VertexWeight3;

                // the indices in to where the actual intersection occurred
                int index1 = rayMeshResult.VertexIndex1;
                int index2 = rayMeshResult.VertexIndex2;
                int index3 = rayMeshResult.VertexIndex3;

                PointCollection textureCoordinates = geom.TextureCoordinates;

                // texture coordinates of the three vertices hit
                // in the case that no texture coordinates are supplied we will simply
                // treat it as if no intersection occurred
                if (textureCoordinates != null &&
                    index1 < textureCoordinates.Count &&
                    index2 < textureCoordinates.Count &&
                    index3 < textureCoordinates.Count)
                {
                    Point texCoord1 = textureCoordinates[index1];
                    Point texCoord2 = textureCoordinates[index2];
                    Point texCoord3 = textureCoordinates[index3];

                    // get the final uv values based on the barycentric coordinates
                    outputPoint = new Point(texCoord1.X * vertexWeight1 +
                                            texCoord2.X * vertexWeight2 +
                                            texCoord3.X * vertexWeight3,
                                            texCoord1.Y * vertexWeight1 +
                                            texCoord2.Y * vertexWeight2 +
                                            texCoord3.Y * vertexWeight3);
                    success = true;
                }
            }

            return(success);
        }
Ejemplo n.º 3
0
 internal static int CompareByDistanceToRayOrigin(RayHitTestResult x, RayHitTestResult y)
 {
     return Math.Sign(x.DistanceToRayOrigin - y.DistanceToRayOrigin);
 }
        /// <summary>
        /// Returns true and the intersection point for the given rayHitResult if there is an intersection,
        /// and false otherwise.
        /// </summary>
        /// <param name="rayHitResult"></param>
        /// <param name="outputPoint">The output point if there was an intersection</param>
        /// <returns>
        /// Returns the point of intersection in outputPoint if there is one, and returns true
        /// to indicate this.
        /// </returns>
        internal static bool GetIntersectionInfo(RayHitTestResult rayHitResult, out Point outputPoint)
        {
            bool success = false;
            outputPoint = new Point();

            // try to cast to a RaymeshGeometry3DHitTestResult
            RayMeshGeometry3DHitTestResult rayMeshResult = rayHitResult as RayMeshGeometry3DHitTestResult;
            if (rayMeshResult != null)
            {
                // we can now extract the mesh and visual for the object we hit
                MeshGeometry3D geom = rayMeshResult.MeshHit;

                // pull the barycentric coordinates of the intersection point
                double vertexWeight1 = rayMeshResult.VertexWeight1;
                double vertexWeight2 = rayMeshResult.VertexWeight2;
                double vertexWeight3 = rayMeshResult.VertexWeight3;

                // the indices in to where the actual intersection occurred
                int index1 = rayMeshResult.VertexIndex1;
                int index2 = rayMeshResult.VertexIndex2;
                int index3 = rayMeshResult.VertexIndex3;

                PointCollection textureCoordinates = geom.TextureCoordinates;

                // texture coordinates of the three vertices hit
                // in the case that no texture coordinates are supplied we will simply
                // treat it as if no intersection occurred
                if (textureCoordinates != null &&
                    index1 < textureCoordinates.Count &&
                    index2 < textureCoordinates.Count &&
                    index3 < textureCoordinates.Count)
                {
                    Point texCoord1 = textureCoordinates[index1];
                    Point texCoord2 = textureCoordinates[index2];
                    Point texCoord3 = textureCoordinates[index3];

                    // get the final uv values based on the barycentric coordinates
                    outputPoint = new Point(texCoord1.X * vertexWeight1 +
                                            texCoord2.X * vertexWeight2 +
                                            texCoord3.X * vertexWeight3,
                                            texCoord1.Y * vertexWeight1 +
                                            texCoord2.Y * vertexWeight2 +
                                            texCoord3.Y * vertexWeight3);
                    success = true;
                }
            }

            return success;
        }
Ejemplo n.º 5
0
        public HitTestResultBehavior resultCallback(HitTestResult result)
        {
            rayResult = result as RayHitTestResult;
            if (rayResult != null)
            {
                // Did we hit a MeshGeometry3D?
                RayMeshGeometry3DHitTestResult rayMeshResult =
                    rayResult as RayMeshGeometry3DHitTestResult;

            }

            return HitTestResultBehavior.Stop;
        }
 internal static int CompareByDistanceToRayOrigin(RayHitTestResult x, RayHitTestResult y)
 {
     return(Math.Sign(x.DistanceToRayOrigin - y.DistanceToRayOrigin));
 }
        /// <summary>
        /// Returns the intersection info for the given rayHitResult.  Intersection info
        /// only exists for an InteractiveModelVisual3D, so if an InteractiveModelVisual3D
        /// is not hit, then the return value is null.
        /// </summary>
        /// <param name="rayHitResult"></param>
        /// <returns>
        /// Returns ClosestIntersectionInfo if an InteractiveModelVisual3D is hit, otherwise
        /// returns null.
        /// </returns>
        private ClosestIntersectionInfo GetIntersectionInfo(RayHitTestResult rayHitResult)
        {
            ClosestIntersectionInfo isectInfo = null;

            // try to cast to a RaymeshGeometry3DHitTestResult
            RayMeshGeometry3DHitTestResult rayMeshResult = rayHitResult as RayMeshGeometry3DHitTestResult;
            if (rayMeshResult != null)
            {
                // see if we hit an InteractiveVisual3D
                InteractiveVisual3D imv3D = rayMeshResult.VisualHit as InteractiveVisual3D;
                if (imv3D != null)
                {
                    // we can now extract the mesh and visual for the object we hit
                    MeshGeometry3D geom = rayMeshResult.MeshHit;
                    UIElement uiElem = imv3D.InternalVisual;
                
                    if (uiElem != null)
                    {
                        // pull the barycentric coordinates of the intersection point
                        double vertexWeight1 = rayMeshResult.VertexWeight1;
                        double vertexWeight2 = rayMeshResult.VertexWeight2;
                        double vertexWeight3 = rayMeshResult.VertexWeight3;

                        // the indices in to where the actual intersection occurred
                        int index1 = rayMeshResult.VertexIndex1;
                        int index2 = rayMeshResult.VertexIndex2;
                        int index3 = rayMeshResult.VertexIndex3;

                        // texture coordinates of the three vertices hit
                        // in the case that no texture coordinates are supplied we will simply
                        // treat it as if no intersection occurred
                        if (geom.TextureCoordinates != null &&
                            index1 < geom.TextureCoordinates.Count &&
                            index2 < geom.TextureCoordinates.Count &&
                            index3 < geom.TextureCoordinates.Count)
                        {
                            Point texCoord1 = geom.TextureCoordinates[index1];
                            Point texCoord2 = geom.TextureCoordinates[index2];
                            Point texCoord3 = geom.TextureCoordinates[index3];

                            // get the final uv values based on the barycentric coordinates
                            Point finalPoint = new Point(texCoord1.X * vertexWeight1 +
                                                         texCoord2.X * vertexWeight2 +
                                                         texCoord3.X * vertexWeight3,
                                                         texCoord1.Y * vertexWeight1 +
                                                         texCoord2.Y * vertexWeight2 +
                                                         texCoord3.Y * vertexWeight3);

                            // create and return a valid intersection info
                            isectInfo = new ClosestIntersectionInfo(finalPoint,
                                                                    uiElem,
                                                                    imv3D);
                        }
                    }
                }
            }

            return isectInfo;
        }
Ejemplo n.º 8
0
 private static HitTestResultBehavior ResultCallback(HitTestResult result)
 {
     rayResult = result as RayHitTestResult;
     return HitTestResultBehavior.Stop; // Nearest
 }
Ejemplo n.º 9
0
        /// <summary>
        /// Perform a hit test in the 3DView.
        /// A negative value for the coordinates defaults to the screen centre (camera view).
        /// </summary>
        /// <param name="shapeName">The 3DView object.</param>
        /// <param name="x">The x coordinate in the GraphicsWindow coordinates within the 3DView.</param>
        /// <param name="y">The y coordinate in the GraphicsWindow coordinates within the 3DView.</param>
        /// <returns>An array with the hit object name and its distance or "" for no hit.</returns>
        public static Primitive HitTest(Primitive shapeName, Primitive x, Primitive y)
        {
            UIElement obj;

            try
            {
                if (_objectsMap.TryGetValue((string)shapeName, out obj))
                {
                    InvokeHelperWithReturn ret = new InvokeHelperWithReturn(delegate
                    {
                        try
                        {
                            if (obj.GetType() == typeof(Viewport3D))
                            {
                                Viewport3D viewport3D = (Viewport3D)obj;
                                ProjectionCamera camera = (ProjectionCamera)viewport3D.Camera;

                                ModelVisual3D modelVisual3D = (ModelVisual3D)viewport3D.Children[0];
                                Model3DGroup model3DGroup = (Model3DGroup)modelVisual3D.Content;

                                if (x < 0) x = viewport3D.Width / 2;
                                if (y < 0) y = viewport3D.Height / 2;

                                PointHitTestParameters hitParams = new PointHitTestParameters(new Point(x, y));
                                rayResult = null;
                                VisualTreeHelper.HitTest(viewport3D, null, ResultCallback, hitParams);

                                if (null != rayResult)
                                {
                                    RayMeshGeometry3DHitTestResult rayResultMesh = rayResult as RayMeshGeometry3DHitTestResult;
                                    string result = "";
                                    foreach (Geometry i in Geometries)
                                    {
                                        if (i.geometryModel3D == rayResultMesh.ModelHit)
                                        {
                                            result += "1=" + i.name + ";";
                                            break;
                                        }
                                    }
                                    result += "2=" + Utilities.ArrayParse(rayResultMesh.DistanceToRayOrigin.ToString(CultureInfo.InvariantCulture)) + ";";
                                    return result;
                                }
                                return "";
                            }
                        }
                        catch (Exception ex)
                        {
                            Utilities.OnError(Utilities.GetCurrentMethod(), ex);
                        }
                        return "";
                    });
                    return FastThread.InvokeWithReturn(ret).ToString();
                }
                else
                {
                    Utilities.OnShapeError(Utilities.GetCurrentMethod(), shapeName);
                }
            }
            catch (Exception ex)
            {
                Utilities.OnError(Utilities.GetCurrentMethod(), ex);
            }
            return "";
        }