Пример #1
0
            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);
            }