public bool IntersectsPrincipalRectangle( PrincipalSpace3D principalSpace3D, PrincipalTrajectory principalTrajectory, Vector2 principalTargetPosition, Matrix4x4 localToWorldMatrix, Vector3 boundsCenter, Vector3 boundsExtents, float marginDistance, ref Matrix4x4 localToPrincipalMatrix) { _localToWorldMatrix = localToWorldMatrix; Vector3 axisZ = Vector3.Cross(principalSpace3D.xAxis, principalSpace3D.yAxis); // Get the non-uniform scale of the matrix based on the bounding box size // and marginDistance Vector3 scale = GetMarginMatrixScale(boundsExtents, marginDistance); // Get the data necessary to get the z component in principal space // of any local vertex (not considering translation yet). localToPrincipalMatrix.m20 = DotMatrixColumn0(axisZ) * scale.x; localToPrincipalMatrix.m21 = DotMatrixColumn1(axisZ) * scale.y; localToPrincipalMatrix.m22 = DotMatrixColumn2(axisZ) * scale.z; Vector3 relBoundsCenter = _localToWorldMatrix.MultiplyPoint(boundsCenter) - principalSpace3D.p0; float principalBoundsCenterZ = Vector3.Dot(relBoundsCenter, axisZ); // Get the bounding box size projected onto the principal z axis float extentsZ = Mathf.Abs(localToPrincipalMatrix.m20) * boundsExtents.x + Mathf.Abs(localToPrincipalMatrix.m21) * boundsExtents.y + Mathf.Abs(localToPrincipalMatrix.m22) * boundsExtents.z; if (Mathf.Abs(principalBoundsCenterZ) > extentsZ) { return false; // bounding box doens't intersect the principal plane } // Get the data necessary to get the x component in principal space // of any local vertex (not considering translation yet). localToPrincipalMatrix.m00 = DotMatrixColumn0(principalSpace3D.xAxis) * scale.x; localToPrincipalMatrix.m01 = DotMatrixColumn1(principalSpace3D.xAxis) * scale.y; localToPrincipalMatrix.m02 = DotMatrixColumn2(principalSpace3D.xAxis) * scale.z; // Test the bounding box projected on the x axis of the principal space // against the initial (i.e. min) and target (i.e. max) x interval. float principalBoundsCenterX = Vector3.Dot(relBoundsCenter, principalSpace3D.xAxis); float extentsX = Mathf.Abs(localToPrincipalMatrix.m00) * boundsExtents.x + Mathf.Abs(localToPrincipalMatrix.m01) * boundsExtents.y + Mathf.Abs(localToPrincipalMatrix.m02) * boundsExtents.z; if (principalBoundsCenterX + extentsX < 0 || principalBoundsCenterX - extentsX > principalTargetPosition.x) { return false; } // Get the data necessary to get the y component in principal space // of any local vertex (not considering translation yet). localToPrincipalMatrix.m10 = DotMatrixColumn0(principalSpace3D.yAxis) * scale.x; localToPrincipalMatrix.m11 = DotMatrixColumn1(principalSpace3D.yAxis) * scale.y; localToPrincipalMatrix.m12 = DotMatrixColumn2(principalSpace3D.yAxis) * scale.z; // Test the bounding box projected on the y axis of the principal space // against the min and max y interval. float principalBoundsCenterY = Vector3.Dot(relBoundsCenter, principalSpace3D.yAxis); float extentsY = Mathf.Abs(localToPrincipalMatrix.m10) * boundsExtents.x + Mathf.Abs(localToPrincipalMatrix.m11) * boundsExtents.y + Mathf.Abs(localToPrincipalMatrix.m12) * boundsExtents.z; if (principalBoundsCenterY + extentsY < Mathf.Min(0.0f, principalTargetPosition.y) || principalBoundsCenterY - extentsY > principalTrajectory.PositionAtTime( principalTrajectory.GetTimeAtMaximumHeight()).y) { return false; } // Get the data necessary to do the translation part from local to // principal space Vector3 delta = new Vector3(_localToWorldMatrix.m03 - principalSpace3D.p0.x, _localToWorldMatrix.m13 - principalSpace3D.p0.y, _localToWorldMatrix.m23 - principalSpace3D.p0.z); localToPrincipalMatrix.m03 = Vector3.Dot(delta, principalSpace3D.xAxis); localToPrincipalMatrix.m13 = Vector3.Dot(delta, principalSpace3D.yAxis); localToPrincipalMatrix.m23 = Vector3.Dot(delta, axisZ); // No projection components localToPrincipalMatrix.m30 = 0; localToPrincipalMatrix.m31 = 0; localToPrincipalMatrix.m32 = 0; localToPrincipalMatrix.m33 = 1; return true; }