internal Vector3 ConstrainLineToTwistedPlane(Vector3 lineStart, Vector3 lineEnd, float lineLength, ref bool bExtendPlaneBeyondStart, bool bExtendPlaneBeyondEnd, out bool bHitPointFound) { Vector3 newLineEnd; Vector3 lineVector = Vector3.Normalize(lineEnd - lineStart); bHitPointFound = false; // create a normal plane approximation to determine side, not the most accurate but close enough Vector3 planeRightVector = Vector3.Normalize(firstVector + secondVector); Vector3 planeUpVector = Vector3.Normalize(Vector3.Cross(planeRightVector, forwardVector)); Plane upPlane = new Plane(planeUpVector, firstOrigin + forwardVector / 2); bool bAbovePlane = upPlane.GetSide(lineEnd); if (!bAbovePlane) { bExtendPlaneBeyondStart = false; return(lineEnd); } bool bIntersectFound = this.IntersectLineOnTwistedPlane(lineStart, lineEnd, bExtendPlaneBeyondStart, bExtendPlaneBeyondEnd, out Vector3 hitPoint, out Vector3 lineForwardVector, out float distanceToEdgeOfPlane); if (!bIntersectFound) { bExtendPlaneBeyondStart = false; return(lineEnd); } double hitDistance = Vector3.Distance(hitPoint, lineStart); if (hitDistance > lineLength) { bExtendPlaneBeyondStart = false; return(lineEnd); } double angleLineToPlane = (double)MathHelpers.DegToRad(Vector3.Angle(lineVector, -lineForwardVector)); MathHelpers.SolveSSATriangle(lineLength, hitDistance, angleLineToPlane, out double distanceAlongPlane, out _, out _); if (!bExtendPlaneBeyondEnd) { if (distanceAlongPlane > distanceToEdgeOfPlane) { newLineEnd = hitPoint + distanceToEdgeOfPlane * lineForwardVector; newLineEnd = lineStart + Vector3.Normalize(newLineEnd - lineStart) * lineLength; bExtendPlaneBeyondStart = true; return(newLineEnd); } } newLineEnd = hitPoint + (float)distanceAlongPlane * lineForwardVector; bHitPointFound = true; bExtendPlaneBeyondStart = false; return(newLineEnd); }
private List <Vector3> AdjustDanPointsToTargets(Vector3 danLookTarget, Vector3 danEndTarget, float danLength, float danDistanceToTarget) { List <Vector3> adjustedDanPoints = new List <Vector3>(); foreach (var point in m_danPoints.danPoints) { adjustedDanPoints.Add(point.transform.position); } Vector3 outsideVector = Vector3.Normalize(danLookTarget - adjustedDanPoints[0]); Vector3 insideVector = Vector3.Normalize(danEndTarget - danLookTarget); bool singleVector = false; if (!m_bpDanPointsFound) { insideVector = outsideVector = Vector3.Normalize(danEndTarget - adjustedDanPoints[0]); singleVector = true; } else if (MathHelpers.VectorsEqual(outsideVector, insideVector, 0.001f) || danLength <= danDistanceToTarget) { insideVector = outsideVector; singleVector = true; } float danSegmentLength = danLength / (adjustedDanPoints.Count - 1); for (int point = 1; point < adjustedDanPoints.Count; point++) { float outsideDistance = danDistanceToTarget - danSegmentLength * (point - 1); if (singleVector || outsideDistance < 0.001) { adjustedDanPoints[point] = adjustedDanPoints[point - 1] + insideVector * danSegmentLength; } else if (outsideDistance < (danSegmentLength - 0.001)) { double angleOutsideToInside = (double)MathHelpers.DegToRad(Vector3.Angle(outsideVector, -insideVector)); MathHelpers.SolveSSATriangle(danSegmentLength, outsideDistance, angleOutsideToInside, out double distanceAlongInside, out _, out _); adjustedDanPoints[point] = danLookTarget + insideVector * (float)distanceAlongInside; } else { adjustedDanPoints[point] = adjustedDanPoints[point - 1] + outsideVector * danSegmentLength; } } return(adjustedDanPoints); }