public bool Intersects(XMVector origin, XMVector direction, out float distance) { Debug.Assert(Internal.XMVector3IsUnit(direction), "Reviewed"); // Load the box. XMVector v_center = this.center; XMVector v_extents = this.extents; // Adjust ray origin to be relative to center of the box. XMVector t_origin = v_center - origin; // Compute the dot product againt each axis of the box. // Since the axii are (1,0,0), (0,1,0), (0,0,1) no computation is necessary. XMVector axisDotOrigin = t_origin; XMVector axisDotDirection = direction; // if (fabs(AxisDotDirection) <= Epsilon) the ray is nearly parallel to the slab. XMVector isParallel = XMVector.LessOrEqual(axisDotDirection.Abs(), CollisionGlobalConstants.RayEpsilon); // Test against all three axii simultaneously. XMVector inverseAxisDotDirection = axisDotDirection.Reciprocal(); XMVector t1 = (axisDotOrigin - v_extents) * inverseAxisDotDirection; XMVector t2 = (axisDotOrigin + v_extents) * inverseAxisDotDirection; // Compute the max of min(t1,t2) and the min of max(t1,t2) ensuring we don't // use the results from any directions parallel to the slab. XMVector t_min = XMVector.Select(XMVector.Min(t1, t2), CollisionGlobalConstants.FltMin, isParallel); XMVector t_max = XMVector.Select(XMVector.Max(t1, t2), CollisionGlobalConstants.FltMax, isParallel); // t_min.x = maximum( t_min.x, t_min.y, t_min.z ); // t_max.x = minimum( t_max.x, t_max.y, t_max.z ); t_min = XMVector.Max(t_min, XMVector.SplatY(t_min)); // x = max(x,y) t_min = XMVector.Max(t_min, XMVector.SplatZ(t_min)); // x = max(max(x,y),z) t_max = XMVector.Min(t_max, XMVector.SplatY(t_max)); // x = min(x,y) t_max = XMVector.Min(t_max, XMVector.SplatZ(t_max)); // x = min(min(x,y),z) // if ( t_min > t_max ) return false; XMVector noIntersection = XMVector.Greater(XMVector.SplatX(t_min), XMVector.SplatX(t_max)); // if ( t_max < 0.0f ) return false; noIntersection = XMVector.OrInt(noIntersection, XMVector.Less(XMVector.SplatX(t_max), XMGlobalConstants.Zero)); // if (IsParallel && (-Extents > AxisDotOrigin || Extents < AxisDotOrigin)) return false; XMVector parallelOverlap = axisDotOrigin.InBounds(v_extents); noIntersection = XMVector.OrInt(noIntersection, XMVector.AndComplementInt(isParallel, parallelOverlap)); if (!Internal.XMVector3AnyTrue(noIntersection)) { // Store the x-component to *pDist t_min.StoreFloat(out distance); return(true); } distance = 0.0f; return(false); }
public static XMVector Ln(XMVector q) { XMVector oneMinusEpsilon = XMVector.FromFloat(1.0f - 0.00001f, 1.0f - 0.00001f, 1.0f - 0.00001f, 1.0f - 0.00001f); XMVector qw = XMVector.SplatW(q); XMVector q0 = XMVector.Select(XMGlobalConstants.Select1110, q, XMGlobalConstants.Select1110); XMVector controlW = qw.InBounds(oneMinusEpsilon); XMVector theta = qw.ACos(); XMVector sinTheta = theta.Sin(); XMVector s = XMVector.Divide(theta, sinTheta); XMVector result = XMVector.Multiply(q0, s); result = XMVector.Select(q0, result, controlW); return(result); }