Exemple #1
0
        /// <inheritdoc cref="NotuiElement"/>
        public override IntersectionPoint PureHitTest(Touch touch, bool prevpos, out IntersectionPoint persistentIspoint)
        {
            touch.GetPreviousWorldPosition(Context, out var popos, out var pdir);
            var sizetr = Matrix4x4.CreateScale(Size);
            //var invsizetr = Matrix4x4.CreateScale(Vector3.One/Size);
            var scldisp = sizetr * DisplayMatrix;

            Matrix4x4.Invert(scldisp, out var invdispmat);
            var trelpos = Vector3.Transform(prevpos ? popos : touch.WorldPosition, invdispmat);
            var treldir = Vector3.TransformNormal(prevpos ? pdir : touch.ViewDir, invdispmat);

            IntersectionPoint ispoint = null;
            float             d       = float.MaxValue;

            for (int i = 0; i < 6; i++)
            {
                var pmat = Matrix4x4.CreateWorld(_planeCenters[i] * -0.5f, _planeCenters[i], _planeUps[i]);
                var hit  = Intersections.PlaneRay(trelpos, treldir, pmat, out var aispos, out var pispos);
                if (!hit)
                {
                    continue;
                }
                hit = pispos.X <= 0.5 && pispos.X >= -0.5 &&
                      pispos.Y <= 0.5 && pispos.Y >= -0.5;
                if (!hit)
                {
                    continue;
                }
                var diff = aispos - trelpos;
                if (Vector3.Dot(Vector3.Normalize(diff), treldir) < 0)
                {
                    continue;
                }
                if (diff.Length() >= d)
                {
                    continue;
                }

                var locmat = pmat * scldisp;

                //TODO: create a more analitical method for scale correction, this is dumb
                Matrix4x4.Decompose(locmat, out var locscl, out var qdummy, out var tdummy);
                var invlocscl = Vector3.One / (locscl / DisplayTransformation.Scale);

                var smat = Matrix4x4.CreateScale(invlocscl) * Matrix4x4.CreateTranslation(pispos) * locmat;
                ispoint = new IntersectionPoint(Vector3.Transform(aispos, scldisp), aispos, pispos, smat, this, touch);
                d       = diff.Length();
            }

            persistentIspoint = ispoint;
            return(ispoint);
        }
        /// <summary>
        /// Get the planar velocity of a touch and its current and previous intersection-point in the selected plane's space
        /// </summary>
        /// <param name="touch"></param>
        /// <param name="plane">Arbitrary matrix of the XY plane to do the intersection with</param>
        /// <param name="context">Notui context to provide screen space/alignment information</param>
        /// <param name="currpos">Current intersection point in the space of the plane</param>
        /// <param name="prevpos">Previous intersection point in the space of the plane</param>
        /// <returns>Velocity of the touch relative to the space of the plane</returns>
        public static Vector3 GetPlanarVelocity(this TouchContainer touch, Matrix4x4 plane, NotuiContext context, out Vector3 currpos, out Vector3 prevpos)
        {
            // get planar coords for current touch position
            var hit = Intersections.PlaneRay(touch.WorldPosition, touch.ViewDir, plane, out var capos, out var crpos);

            currpos = crpos;

            // get planar coords for the previous touch position
            touch.GetPreviousWorldPosition(context, out var popos, out var pdir);
            var phit = Intersections.PlaneRay(popos, pdir, plane, out var papos, out var prpos);

            prevpos = prpos;
            return(crpos - prpos);
        }
        /// <summary>
        /// General Hittesting on the infinite plane defined by the element transforms
        /// </summary>
        /// <param name="touch">The touch to be tested</param>
        /// <param name="prevpos">Calculate Intersection point for previous position</param>
        /// <returns>If the touch hits then an Intersection point otherwise null</returns>
        public IntersectionPoint PreparePlanarShapeHitTest(Touch touch, bool prevpos)
        {
            // when first hit consider the display transformation then
            // for the rest of the interaction consider the interaction transform
            touch.GetPreviousWorldPosition(Context, out var popos, out var pdir);
            var hit = Intersections.PlaneRay(
                prevpos ? popos : touch.WorldPosition,
                prevpos ? pdir : touch.ViewDir,
                DisplayMatrix,
                out var ispoint,
                out var planarpoint);

            return(hit ? new IntersectionPoint(ispoint, planarpoint, this, touch)
            {
                SurfaceSpace = planarpoint * 2
            } : null);
        }