dMatrix clSpline::GetCoordinates(const dMatrix &uSpec) { dMatrix coord; if(uSpec.GetNumberColumns() != 1 || uSpec.GetNumberRows() == 0) { throw clException("clSpline", "GetCoordinates", "Invalid dimensions of matrix uSpec."); } else { coord.SetNumberRows(uSpec.GetNumberRows()); coord.SetNumberColumns(3); if(!initialised) { Initialise(); } // Do for all specified u's for(int i=1; i<=uSpec.GetNumberRows(); i++) { if(uSpec(i, 1) < 0 || uSpec(i, 1) > 1) { throw clException("clSpline", "GetCoordinates", "Invalid value for uSpec."); } else { // Now find the position of uSpec double uu = uSpec(i, 1)*GetSplineLength(); int j = 1; while((uu - u(j+1, 1) > 0) && (j<u.GetNumberRows()-1)) { j++; } // Now calculate the coefficients double A = (u(j+1, 1)-uu)/(u(j+1, 1)-u(j,1)); double B = 1-A; double C = (A*A*A-A)/6 * (u(j+1, 1)-u(j, 1))*(u(j+1, 1)-u(j, 1)); double D = (B*B*B-B)/6 * (u(j+1, 1)-u(j, 1))*(u(j+1, 1)-u(j, 1)); // Finally calculate the coordinates coord.SetElement(i, 1, A*X(j, 1) + B*X(j+1, 1) + C*X2(j, 1) + D*X2(j+1, 1)); coord.SetElement(i, 2, A*Y(j, 1) + B*Y(j+1, 1) + C*Y2(j, 1) + D*Y2(j+1, 1)); coord.SetElement(i, 3, A*Z(j, 1) + B*Z(j+1, 1) + C*Z2(j, 1) + D*Z2(j+1, 1)); } } } return (coord); }
FVector USplineComponent::GetWorldDirectionAtTime(float Time, bool bUseConstantVelocity) const { if (Duration == 0.0f) { return FVector::ZeroVector; } if (bUseConstantVelocity) { return GetWorldDirectionAtDistanceAlongSpline(Time / Duration * GetSplineLength()); } const float TimeMultiplier = (SplineInfo.Points.Num() - 1.0f) / Duration; const FVector Tangent = SplineInfo.EvalDerivative(Time * TimeMultiplier, FVector::ZeroVector).GetSafeNormal(); return ComponentToWorld.TransformVectorNoScale(Tangent); }
FVector USplineComponent::GetWorldLocationAtTime(float Time, bool bUseConstantVelocity) const { if (Duration == 0.0f) { return FVector::ZeroVector; } if (bUseConstantVelocity) { return GetWorldLocationAtDistanceAlongSpline(Time / Duration * GetSplineLength()); } const float TimeMultiplier = (SplineInfo.Points.Num() - 1.0f) / Duration; const FVector Location = SplineInfo.Eval(Time * TimeMultiplier, FVector::ZeroVector); return ComponentToWorld.TransformPosition(Location); }
FVector USplineComponent::GetScaleAtTime(float Time, bool bUseConstantVelocity) const { if (Duration == 0.0f) { return FVector(1.0f); } if (bUseConstantVelocity) { return GetScaleAtDistanceAlongSpline(Time / Duration * GetSplineLength()); } else { const int32 NumPoints = SplineInfo.Points.Num(); const int32 NumSegments = bClosedLoop ? NumPoints : NumPoints - 1; const float TimeMultiplier = NumSegments / Duration; return GetScaleAtSplineInputKey(Time * TimeMultiplier); } }
FTransform USplineComponent::GetTransformAtTime(float Time, ESplineCoordinateSpace::Type CoordinateSpace, bool bUseConstantVelocity, bool bUseScale) const { if (Duration == 0.0f) { return FTransform::Identity; } if (bUseConstantVelocity) { return GetTransformAtDistanceAlongSpline(Time / Duration * GetSplineLength(), CoordinateSpace, bUseScale); } else { const int32 NumPoints = SplineInfo.Points.Num(); const int32 NumSegments = bClosedLoop ? NumPoints : NumPoints - 1; const float TimeMultiplier = NumSegments / Duration; return GetTransformAtSplineInputKey(Time * TimeMultiplier, CoordinateSpace, bUseScale); } }
FVector USplineComponent::GetRightVectorAtTime(float Time, ESplineCoordinateSpace::Type CoordinateSpace, bool bUseConstantVelocity) const { if (Duration == 0.0f) { return FVector::ZeroVector; } if (bUseConstantVelocity) { return GetRightVectorAtDistanceAlongSpline(Time / Duration * GetSplineLength(), CoordinateSpace); } else { const int32 NumPoints = SplineInfo.Points.Num(); const int32 NumSegments = bClosedLoop ? NumPoints : NumPoints - 1; const float TimeMultiplier = NumSegments / Duration; return GetRightVectorAtSplineInputKey(Time * TimeMultiplier, CoordinateSpace); } }