Download

(39) Rama's Extra Blueprint Nodes for You as a Plugin, No C++ Required!

Rama, you are an unstoppable coding machine! Thank you for continuing to kick such ***! Cheers!

J^2

Hee hee! You’re welcome!

I look forward to any pics you choose to share of the pics you generate using my new node!

Rama

Hey Rama!
I never posted in this thread before, even though I have used your plugin quite a lot! (shame on me…) So let me first take a minute to thank you for all the awesome work you have done! not only some of these nodes are useful (or even essential!) but the plugin as a whole serves as a great base plugin and C++ example.

In fact, you inspired me to make a plugin that I was planing to release with all the custom nodes I have been using in my projects over the last year but apparently I’m way too lazy to finish it :stuck_out_tongue:

I call it the “Math Plugin” :p, it includes various nodes starting from simple (missing) nodes like negate int/float, to more advanced intersection checks (to be used as collision check alternatives etc.)

3347099af001a575814d73a9d38845c3ad7ceef1.jpeg
a06214a8e79329601efa5108641912805f7b6083.jpeg

Let me know if you find any of these interesting… It would be kinda cool to have some of these added to your plugin if you think they are useful :slight_smile:

Hi there TK-Master!

Rest of community is invited to chime in as to which of your nodes they would like, I personally think that the Is Point in Box, that receives the extent and center of box, would be great! (FBox not exposed to BP yet as far as I know)

Line to Line Intersection
Line Inside Sphere (is this an intersection or whole line has to be inside sphere?)
Closest Points between Two Line Segements
Project Point onto Line
Closest Point on Sphere to Line
Closest Point on Line Segment

Set Vector Length
Increment Float
Increment Integer
IsEven
IsPowerOf2
IsMultipleOf
RoundToNearestMultiple
GridSnap

Would all be great!

I think a lot of people will love the Geometry functions and Grid Snap feature!

And the various math functions will be very helpful !

Thanks!

Rama

Been stalking the forums since day 1, but I must say now TK-Master, these would be IMMENSELY helpful. Like, helpful enough to get the ball rolling for something nice.

Also Rama, you’re a saint. :slight_smile:

If you build it, they will come.

Round to nearest multiple would be nice. I round down to the blocks location, so if you click 187, it rounds to 100. In my game, I spawn a grid of blocks, and they are 100 wide each. You can click on em and it removes them. I have to do: block location = blockWidth / 100 -> floor * 100

Hee hee!


Nice to hear from you Jamendxman3!

[FONT=Comic Sans MS]Welcome to the forums Fayle!

:slight_smile:

One of my absolute favorite sayings / movies!

:slight_smile:

Rama

Alright then :wink: I’m just going to drop the header and cpp files here, then it’s up to Rama (and the community) to decide which nodes are added :stuck_out_tongue:

I also added a bonus function to convert velocity to another speed unit, this can be used for car speedometers etc.

.h file


//By TK-Master

#pragma once

#include "Runtime/UMG/Public/UMG.h"
#include "MathFunctionLibrary.generated.h"

/* Speed Units Enum. */
UENUM()
enum ESpeedUnit
{
	/* Centimeter / second (cm/s). This is default unreal velocity unit. */
	CentimeterPerSecond,

	/* Foot / second (ft/s). */
	FootPerSecond,

	/* Meter / second (m/s). */
	MeterPerSecond,

	/* Meter / minute (m/min). */
	MeterPerMinute,

	/* Kilometer / second (km/s). */
	KilometerPerSecond,

	/* Kilometer / minute (km/min). */
	KilometerPerMinute,

	/*Kilometer / hour (km/h). */
	KilometerPerHour,

	/* Mile / hour (mph). */
	MilePerHour,

	/* Knot (kn). Nautical mile per hour. */
	Knot,

	/* Mach (speed of sound) (M) at standard atm. */
	Mach,

	/* Speed of light. */
	SpeedOfLight,

	/* Yard / second. */
	YardPerSecond
};


UCLASS()
class MATHPLUGIN_API UMathFunctionLibrary : public UBlueprintFunctionLibrary
{
	GENERATED_UCLASS_BODY()

public:

	//Reverses the sign (- or +) of a float.
	UFUNCTION(BlueprintPure, Category = "Math|Float")
	static float NegateFloat(float A);

	//Reverses the sign (- or +) of an integer.
	UFUNCTION(BlueprintPure, Category = "Math|Integer")
	static int32 NegateInt(int32 A);

	//Reverses the sign (- or +) of a Vector2D.
	UFUNCTION(BlueprintPure, Category = "Math|Vector2D")
	static FVector2D NegateVector2D(FVector2D A);

	//Changes the size (length) of a Vector to the given size (normalized vector * size).
	UFUNCTION(BlueprintPure, Category = "Math|Vector")
	static FVector SetVectorLength(FVector A, float size);

	//Converts radians to degrees.
	UFUNCTION(BlueprintPure, Category = "Math|Vector")
	static FVector VectorRadiansToDegrees(FVector RadVector);

	//Converts degrees to radians.
	UFUNCTION(BlueprintPure, Category = "Math|Vector")
	static FVector VectorDegreesToRadians(FVector DegVector);

	/**
	* Rounds an integer to the lower multiple of the given number.
	* If Skip Self is set to True it will skip to the previous multiple if the integer rounds to itself.
	* @param Multiple - The multiple number to round to.
	* @param skipSelf - Skip to the previous multiple if the integer rounds to itself.
	*/
	UFUNCTION(BlueprintPure, Category = "Math|Integer")
	static int32 RoundToLowerMultiple(int32 A, int32 Multiple = 32, bool skipSelf = false);

	/**
	* Rounds an integer to the upper multiple of the given number.
	* If Skip Self is set to True it will skip to the next multiple if the integer rounds to itself.
	* @param Multiple - The multiple number to round to.
	* @param skipSelf - Skip to the next multiple if the integer rounds to itself.
	*/
	UFUNCTION(BlueprintPure, Category = "Math|Integer")
	static int32 RoundToUpperMultiple(int32 A, int32 Multiple = 32, bool skipSelf = false);

	/** Rounds an integer to the nearest multiple of the given number. */
	UFUNCTION(BlueprintPure, Category = "Math|Integer")
	static int32 RoundToNearestMultiple(int32 A, int32 Multiple = 32);

	/** Returns true if the integer is a power of two number. */
	UFUNCTION(BlueprintPure, meta = (CompactNodeTitle = "PwrOf2"), Category = "Math|Integer")
	static bool isPowerOfTwo(int32 x);

	/** Returns true if the integer is a multiple of the given number. */
	UFUNCTION(BlueprintPure, Category = "Math|Integer")
	static bool isMultipleOf(int32 A, int32 Multiple);

	/** Returns true if the number is even (false if it's odd). */
	UFUNCTION(BlueprintPure, meta = (CompactNodeTitle = "isEven"), Category = "Math|Float")
	static bool isEvenNumber(float A);

	/**
	* Find closest point on a Sphere to a Line.
	* When line intersects Sphere, then closest point to LineOrigin is returned.
	* @param SphereOrigin		Origin of Sphere
	* @param SphereRadius		Radius of Sphere
	* @param LineOrigin		Origin of line
	* @param LineDir			Direction of line.
	* @return Closest point on sphere to given line.
	*/
	UFUNCTION(BlueprintPure, Category = "Math|Vector")
	static FVector ClosestPointOnSphereToLine(FVector SphereOrigin, float SphereRadius, FVector LineOrigin, FVector LineDir);

	/** Find the point on line segment from LineStart to LineEnd which is closest to Point. */
	UFUNCTION(BlueprintPure, Category = "Math|Vector")
	static FVector ClosestPointOnLineSeqment(FVector Point, FVector LineStart, FVector LineEnd);

	/** Returns true if the given Point vector is within a box (defined by BoxOrigin and BoxExtent). */
	UFUNCTION(BlueprintPure, Category = "Math|Vector|Intersection")
	static bool isPointInsideBox(FVector Point, FVector BoxOrigin, FVector BoxExtent);

	/** Determines whether a line intersects a sphere. */
	UFUNCTION(BlueprintPure, Category = "Math|Vector|Intersection")
	static bool isLineInsideSphere(FVector LineStart, FVector LineDir, float LineLength, FVector SphereOrigin, float SphereRadius);

	/**
	* Swept-Box vs Box test.
	* Sweps a box defined by Extend from Start to End points and returns whether it hit a box or not plus the hit location and hit normal if successful.
	*/
	UFUNCTION(BlueprintPure, Category = "Math|Vector|Intersection")
	static bool LineExtentBoxIntersection(FBox inBox, FVector Start, FVector End, FVector Extent, FVector& HitLocation, FVector& HitNormal, float& HitTime);

	/**
	* Get the shortest distance between a point and a plane.
	* The output is signed so it holds information as to which side of the plane normal the point is.
	*/
	UFUNCTION(BlueprintPure, Category = "Math|Vector")
	static float SignedDistancePlanePoint(FVector planeNormal, FVector planePoint, FVector point);

	/**
	* Returns a vector point which is a projection from a point to a line (defined by the vector couple LineOrigin, LineDirection).
	* The line is infinite (in both directions).
	*/
	UFUNCTION(BlueprintPure, Category = "Math|Vector")
	static FVector ProjectPointOnLine(FVector LineOrigin, FVector LineDirection, FVector Point);

	/**
	* Performs a sphere vs box intersection test.
	* @param SphereOrigin the center of the sphere being tested against the box.
	* @param SphereRadius the size of the sphere being tested.
	* @param BoxOrigin the box origin being tested against.
	* @param BoxExtent the box extend (width, depth, height).
	* @return Whether the sphere/box intersect or not.
	*/
	UFUNCTION(BlueprintPure, Category = "Math|Vector|Intersection")
	static bool SphereBoxIntersection(FVector SphereOrigin, float SphereRadius, FVector BoxOrigin, FVector BoxExtent);

	/**
	* Find closest points between 2 line segments.
	* @param	(Line1Start, Line1End)	defines the first line segment.
	* @param	(Line2Start, Line2End)	defines the second line segment.
	* @param	LinePoint1		Closest point on segment 1 to segment 2.
	* @param	LinePoint2		Closest point on segment 2 to segment 1.
	*/
	UFUNCTION(BlueprintPure, Category = "Math|Vector|Intersection")
	static void ClosestPointsOfLineSegments(FVector Line1Start, FVector Line1End, FVector Line2Start, FVector Line2End, FVector& LinePoint1, FVector& LinePoint2);

	/**
	* Calculate the intersection point of two infinitely long lines. Returns true if lines intersect, otherwise false.
	* Note that in 3d, two lines do not intersect most of the time.
	* So if the two lines are not in the same plane, use Closest Points On Two Lines instead.
	* @param IntersectionPoint The intersection point of the lines. Returns zero if the lines do not intersect or the operation fails.
	* @param LinePoint1 Line point of the first line.
	* @param LineDir1 Line direction (normal) of the first line. Should be a normalized vector.
	* @param LinePoint2 Line point of the second line.
	* @param LineDir2 Line direction (normal) of the second line. Should be a normalized vector.
	* @return true if lines intersect, otherwise false.
	*/
	UFUNCTION(BlueprintPure, Category = "Math|Vector|Intersection")
	static bool LineToLineIntersection(FVector& IntersectionPoint, FVector LinePoint1, FVector LineDir1, FVector LinePoint2, FVector LineDir2);

	/*
	* Calculate the closest points between two infinitely long lines.
	* If lines are intersecting (not parallel) it will return false! Use Line To Line Intersection instead.
	* @param closestPointLine1 The closest point of line1 to line2. Returns zero if the lines intersect.
	* @param closestPointLine2 The closest point of line2 to line1. Returns zero if the lines intersect.
	* @param linePoint1 Line point of the first line.
	* @param lineVec1 Line direction (normal) of the first line. Should be a normalized vector.
	* @param linePoint2 Line point of the second line.
	* @param lineVec2 Line direction (normal) of the second line. Should be a normalized vector.
	* @return true if lines are parallel, false otherwise.
	*/
	UFUNCTION(BlueprintPure, Category = "Math|Vector")
	static bool ClosestPointsOnTwoLines(FVector& closestPointLine1, FVector& closestPointLine2, FVector linePoint1, FVector lineVec1, FVector linePoint2, FVector lineVec2);

	/*
	* Returns 0 if point is on the line segment.
	* Returns 1 if point is not on the line segment and it is on the side of linePoint1.
	* Returns 2 if point is not on the line segment and it is on the side of linePoint2.
	*/
	UFUNCTION(BlueprintPure, Category = "Math|Vector")
	static int32 PointOnWhichSideOfLineSegment(FVector linePoint1, FVector linePoint2, FVector point);

	/*
	* Returns true if the two line segments are intersecting and not parallel.
	* If you need the intersection point, use Closest Points On Two Lines.
	*/
	UFUNCTION(BlueprintPure, Category = "Math|Vector|Intersection")
	static bool AreLineSegmentsCrossing(FVector pointA1, FVector pointA2, FVector pointB1, FVector pointB2);

	/*Returns true if vector point is inside a rectangle defined by the rectA/rectC/rectB/rectD corner points.*/
	UFUNCTION(BlueprintPure, Category = "Math|Vector|Intersection")
	static bool isPointInsideRectangle(FVector point, FVector rectA, FVector rectC, FVector rectB, FVector rectD);

	/*Snaps vector to nearest grid multiple.*/
	UFUNCTION(BlueprintPure, Category = "Math|Vector")
	static FVector GridSnap(FVector A, float Grid);

	/*Calculates the distance between two vectors.*/
	UFUNCTION(BlueprintPure, Category = "Math|Vector")
	static float VectorDistance(FVector VectorA, FVector VectorB);

	/*What is P% of number A?*/
	UFUNCTION(BlueprintPure, Category = "Math|Float")
	static float CalculatePercentageOfNumber(float P, float A);

	/*A is what percent of B?*/
	UFUNCTION(BlueprintPure, Category = "Math|Float")
	static float CalculatePercentageRatio(float A, float B);

	/*A is P% of what?*/
	UFUNCTION(BlueprintPure, Category = "Math|Float")
	static float CalculateNumberFromPercentage(float A, float P);

	/*Converts UMG layout offsets to another anchor.*/
	UFUNCTION(BlueprintPure, Category = "Math|Anchor", meta = (HidePin = "WorldContextObject", DefaultToSelf = "WorldContextObject"))
	static void ConvertAnchorToAnchor(UObject* WorldContextObject, FAnchors CurrentAnchor, FMargin Offsets, FAnchors TargetAnchor, FMargin& ConvertedOffsets);

	/*Converts linear velocity vector to a more useful speed unit.*/
	UFUNCTION(BlueprintPure, Category = "Math|Vector")
	static float ConvertLinearVelocity(FVector Velocity, TEnumAsByte<enum ESpeedUnit> SpeedUnit);

	//Other misc. functions.

	/* Returns true if ColorA is equal to ColorB (A == B)*/
	UFUNCTION(BlueprintPure, meta = (FriendlyName = "Equal (Linear Color)", CompactNodeTitle = "==", Keywords = "== equal"), Category = "Math|Color")
	static bool EqualEqual_LinearColorLinearColor(FLinearColor ColorA, FLinearColor ColorB);

	/*Get the value for given console variable name.*/
	UFUNCTION(BlueprintPure, Category = "Development")
	static float GetConsoleVariableFloat(FString VariableName);

	/*Get the value for given console variable name.*/
	UFUNCTION(BlueprintPure, Category = "Development")
	static int32 GetConsoleVariableInt(FString VariableName);

	//------------------------------------------------------------
	//Physics functions! (why aren't these exposed by Epic yet?!)

	/**
	* Get the current world velocity of a point on a physics-enabled component.
	* @param Point - Point in world space.
	* @param DrawDebugInfo - Draw debug point & string.
	* @param BoneName - If a SkeletalMeshComponent, name of body to get velocity of. 'None' indicates root body.
	* @return The velocity of the point in world space.
	*/
	UFUNCTION(BlueprintCallable, Category = "Physics")
	static FVector GetVelocityAtPoint(UPrimitiveComponent* Target, FVector Point, FName BoneName = NAME_None, bool DrawDebugInfo = false);

	/*
	* Set the physx center of mass offset.
	* Note: this offsets the physx-calculated center of mass (it is not an offset from the pivot point).
	*/
	UFUNCTION(BlueprintCallable, Category = "Physics")
	static void SetCenterOfMassOffset(UPrimitiveComponent* Target, FVector Offset, FName BoneName = NAME_None);

};


.cpp file


//By TK-Master

#include "MathPluginPrivatePCH.h"
#include "StaticMeshResources.h"
#include "PhysXIncludes.h"
#include "PhysicsPublic.h"

UMathFunctionLibrary::UMathFunctionLibrary(const class FObjectInitializer& PCIP)
	: Super(PCIP)
{
}

float UMathFunctionLibrary::NegateFloat(float A)
{
	return -A;
}

int32 UMathFunctionLibrary::NegateInt(int32 A)
{
	return -A;
}

FVector2D UMathFunctionLibrary::NegateVector2D(FVector2D A)
{
	return -A;
}

FVector UMathFunctionLibrary::SetVectorLength(FVector A, float size)
{
	return A.GetSafeNormal() * size;
}

FVector UMathFunctionLibrary::VectorRadiansToDegrees(FVector RadVector)
{
	return FVector::RadiansToDegrees(RadVector);
}

FVector UMathFunctionLibrary::VectorDegreesToRadians(FVector DegVector)
{
	return FVector::DegreesToRadians(DegVector);
}

int32 UMathFunctionLibrary::RoundToLowerMultiple(int32 A, int32 Multiple, bool skipSelf)
{
	int32 result = (A / Multiple) * Multiple;
	if (skipSelf && result == A && result != 0)
	{
		return ((A-1) / Multiple) * Multiple;
	}
	return result;
}

int32 UMathFunctionLibrary::RoundToUpperMultiple(int32 A, int32 Multiple, bool skipSelf)
{
	if (skipSelf || FMath::Fmod(A, Multiple) != 0)
	{
		A = ((A + Multiple) / Multiple) * Multiple;
	}
	return A;
}

int32 UMathFunctionLibrary::RoundToNearestMultiple(int32 A, int32 Multiple)
{
	return ((A + Multiple / 2) / Multiple) * Multiple;
}

bool UMathFunctionLibrary::isPowerOfTwo(int32 x)
{
	//return x && ((x&-x) == x);
	return FMath::IsPowerOfTwo(x);
}

bool UMathFunctionLibrary::isMultipleOf(int32 A, int32 Multiple)
{
	return FMath::Fmod(A, Multiple) == 0;
}

bool UMathFunctionLibrary::isEvenNumber(float A)
{
	return FMath::Fmod(A, 2) == 0;
}

FVector UMathFunctionLibrary::ClosestPointOnSphereToLine(FVector SphereOrigin, float SphereRadius, FVector LineOrigin, FVector LineDir)
{
	static FVector OutClosestPoint;
	FMath::SphereDistToLine(SphereOrigin, SphereRadius, LineOrigin, LineDir.GetSafeNormal(), OutClosestPoint);
	return OutClosestPoint;
}

FVector UMathFunctionLibrary::ClosestPointOnLineSeqment(FVector Point, FVector LineStart, FVector LineEnd)
{
	return FMath::ClosestPointOnLine(LineStart, LineEnd, Point);
}

bool UMathFunctionLibrary::isPointInsideBox(FVector Point, FVector BoxOrigin, FVector BoxExtent)
{
	FBox Box = FBox::BuildAABB(BoxOrigin, BoxExtent);
	return FMath::PointBoxIntersection(Point, Box);
}

bool UMathFunctionLibrary::SphereBoxIntersection(FVector SphereOrigin, float SphereRadius, FVector BoxOrigin, FVector BoxExtent)
{
	FBox Box = FBox::BuildAABB(BoxOrigin, BoxExtent);
	return FMath::SphereAABBIntersection(SphereOrigin, FMath::Square(SphereRadius), Box);
}

bool UMathFunctionLibrary::isLineInsideSphere(FVector LineStart, FVector LineDir, float LineLength, FVector SphereOrigin, float SphereRadius)
{
	return FMath::LineSphereIntersection(LineStart, LineDir, LineLength, SphereOrigin, SphereRadius);
}

bool UMathFunctionLibrary::LineExtentBoxIntersection(FBox inBox, FVector Start, FVector End, FVector Extent, FVector& HitLocation, FVector& HitNormal, float& HitTime)
{
	return FMath::LineExtentBoxIntersection(inBox, Start, End, Extent, HitLocation, HitNormal, HitTime);
}

float UMathFunctionLibrary::SignedDistancePlanePoint(FVector planeNormal, FVector planePoint, FVector point)
{
	return FVector::DotProduct(planeNormal, (point - planePoint));
}

FVector UMathFunctionLibrary::ProjectPointOnLine(FVector LineOrigin, FVector LineDirection, FVector Point)
{
	//FVector linePointToPoint = point - linePoint;
	//float t = FVector::DotProduct(linePointToPoint, lineDir);
	//return linePoint + lineDir * t;

	//FVector closestPoint;
	//OutDistance = FMath::PointDistToLine(point, lineDir, linePoint, closestPoint);
	//return closestPoint;

	FVector SafeDir = LineDirection.GetSafeNormal();
	return LineOrigin + (SafeDir * ((Point - LineOrigin) | SafeDir));
}

void UMathFunctionLibrary::ClosestPointsOfLineSegments(FVector Line1Start, FVector Line1End, FVector Line2Start, FVector Line2End, FVector& LinePoint1, FVector& LinePoint2)
{
	FMath::SegmentDistToSegmentSafe(Line1Start, Line1End, Line2Start, Line2End, LinePoint1, LinePoint2);
}

bool UMathFunctionLibrary::LineToLineIntersection(FVector& IntersectionPoint, FVector LinePoint1, FVector LineDir1, FVector LinePoint2, FVector LineDir2)
{
	//Are lines coplanar?
	if (!FVector::Coplanar(LinePoint1, LineDir1, LinePoint2, LineDir2, DELTA))
	{
		return false;
	}

	FVector LineDir3 = LinePoint2 - LinePoint1;
	FVector CrossDir1And2 = FVector::CrossProduct(LineDir1, LineDir2);
	FVector CrossDir3And2 = FVector::CrossProduct(LineDir3, LineDir2);

	float s = FVector::DotProduct(CrossDir3And2, CrossDir1And2) / CrossDir1And2.SizeSquared();

	if (s > 1.0f || s < 0.0f)
	{
		return false;
	}
	else
	{
		IntersectionPoint = LinePoint1 + (LineDir1 * s);
		return true;
	}
}

bool UMathFunctionLibrary::ClosestPointsOnTwoLines(FVector& closestPointLine1, FVector& closestPointLine2, FVector linePoint1, FVector lineVec1, FVector linePoint2, FVector lineVec2)
{
	float a = FVector::DotProduct(lineVec1, lineVec1);
	float b = FVector::DotProduct(lineVec1, lineVec2);
	float e = FVector::DotProduct(lineVec2, lineVec2);

	float d = a*e - b*b;

	//lines are not parallel
	if (d != 0.0f)
	{
		FVector r = linePoint1 - linePoint2;
		float c = FVector::DotProduct(lineVec1, r);
		float f = FVector::DotProduct(lineVec2, r);

		float s = (b*f - c*e) / d;
		float t = (a*f - c*b) / d;

		closestPointLine1 = linePoint1 + lineVec1 * s;
		closestPointLine2 = linePoint2 + lineVec2 * t;

		return true;
	}
	else
	{
		return false;
	}
}

int32 UMathFunctionLibrary::PointOnWhichSideOfLineSegment(FVector linePoint1, FVector linePoint2, FVector point)
{
	FVector lineVec = linePoint2 - linePoint1;
	FVector pointVec = point - linePoint1;

	float dot = FVector::DotProduct(pointVec, lineVec);

	//point is on side of linePoint2, compared to linePoint1
	if (dot > 0)
	{
		//point is on the line segment
		if (pointVec.Size() <= lineVec.Size())
		{
			return 0;
		}

		//point is not on the line segment and it is on the side of linePoint2
		else
		{
			return 2;
		}
	}

	//Point is not on side of linePoint2, compared to linePoint1.
	//Point is not on the line segment and it is on the side of linePoint1.
	else
	{
		return 1;
	}
}

bool UMathFunctionLibrary::AreLineSegmentsCrossing(FVector pointA1, FVector pointA2, FVector pointB1, FVector pointB2)
{
	FVector closestPointA;
	FVector closestPointB;
	int32 sideA;
	int32 sideB;

	FVector lineVecA = pointA2 - pointA1;
	FVector lineVecB = pointB2 - pointB1;

	bool valid = ClosestPointsOnTwoLines(closestPointA, closestPointB, pointA1, lineVecA.GetSafeNormal(), pointB1, lineVecB.GetSafeNormal());

	//lines are not parallel
	if (valid)
	{
		sideA = PointOnWhichSideOfLineSegment(pointA1, pointA2, closestPointA);
		sideB = PointOnWhichSideOfLineSegment(pointB1, pointB2, closestPointB);

		if ((sideA == 0) && (sideB == 0))
		{
			return true;
		}
		else
		{
			return false;
		}
	}

	//lines are parallel
	else
	{
		return false;
	}
}

bool UMathFunctionLibrary::isPointInsideRectangle(FVector point, FVector rectA, FVector rectC, FVector rectB, FVector rectD)
{
	FVector vector;
	FVector linePoint;

	//get the center of the rectangle
	vector = rectC - rectA;
	float size = -(vector.Size() / 2.0f);

	vector = vector.GetSafeNormal() * (vector.Size() + size);
	FVector middle = rectA + vector;

	FVector xVector = rectB - rectA;
	float width = xVector.Size() / 2.0f;

	FVector yVector = rectD - rectA;
	float height = yVector.Size() / 2.0f;

	linePoint = ProjectPointOnLine(middle, xVector.GetSafeNormal(), point);
	vector = linePoint - point;
	float yDistance = vector.Size();

	linePoint = ProjectPointOnLine(middle, yVector.GetSafeNormal(), point);
	vector = linePoint - point;
	float xDistance = vector.Size();

	if ((xDistance <= width) && (yDistance <= height))
	{
		return true;
	}
	else
	{
		return false;
	}
}

FVector UMathFunctionLibrary::GridSnap(FVector A, float Grid)
{
	return A.GridSnap(Grid);
}

float UMathFunctionLibrary::VectorDistance(FVector VectorA, FVector VectorB)
{
	return (VectorA - VectorB).Size();
}

float UMathFunctionLibrary::CalculatePercentageOfNumber(float P, float A)
{
	return (P / 100) * A;
}

float UMathFunctionLibrary::CalculatePercentageRatio(float A, float B)
{
	return A * 100 / B;
}

float UMathFunctionLibrary::CalculateNumberFromPercentage(float A, float P)
{
	return A / (P / 100);
}

void UMathFunctionLibrary::ConvertAnchorToAnchor(UObject* WorldContextObject, FAnchors CurrentAnchor, FMargin Offsets, FAnchors TargetAnchor, FMargin& ConvertedOffsets)
{
	if (CurrentAnchor.Minimum == TargetAnchor.Minimum && CurrentAnchor.Maximum == TargetAnchor.Maximum)
	{
		ConvertedOffsets = Offsets;
		return;
	}

	FVector2D View = FVector2D(1, 1);
	UWorld* World = GEngine->GetWorldFromContextObject(WorldContextObject);
	if (World && World->IsGameWorld())
	{
		if (UGameViewportClient* ViewportClient = World->GetGameViewport())
		{
			ViewportClient->GetViewportSize(View);
		}
	}

	FMargin ZeroAnchorOffsets = Offsets;
	//Convert to 0,0 anchor first.
	if (CurrentAnchor.Minimum != FVector2D(0, 0) || CurrentAnchor.Maximum != FVector2D(0, 0))
	{
		ZeroAnchorOffsets.Left = View.X * CurrentAnchor.Minimum.X + Offsets.Left;
		ZeroAnchorOffsets.Top = View.Y * CurrentAnchor.Minimum.Y + Offsets.Top;

		if (CurrentAnchor.Minimum.X != CurrentAnchor.Maximum.X)
		{
			ZeroAnchorOffsets.Right = View.X * CurrentAnchor.Maximum.X - (Offsets.Right + Offsets.Left);
		}
		if (CurrentAnchor.Minimum.Y != CurrentAnchor.Maximum.Y)
		{
			ZeroAnchorOffsets.Bottom = View.Y * CurrentAnchor.Maximum.Y - (Offsets.Bottom + Offsets.Top);
		}

		if (TargetAnchor.Minimum == FVector2D(0, 0) && TargetAnchor.Maximum == FVector2D(0, 0))
		{
			ConvertedOffsets = ZeroAnchorOffsets;
			return;
		}
	}

	//Convert 0,0 anchor offsets to target anchor offsets.
	ConvertedOffsets.Left = (-View.X) * TargetAnchor.Minimum.X + ZeroAnchorOffsets.Left;
	ConvertedOffsets.Top = (-View.Y) * TargetAnchor.Minimum.Y + ZeroAnchorOffsets.Top;

	ConvertedOffsets.Right = TargetAnchor.Minimum.X != TargetAnchor.Maximum.X ? View.X * TargetAnchor.Maximum.X - (ZeroAnchorOffsets.Left + ZeroAnchorOffsets.Right) : ZeroAnchorOffsets.Right;
	ConvertedOffsets.Bottom = TargetAnchor.Minimum.Y != TargetAnchor.Maximum.Y ? View.Y * TargetAnchor.Maximum.Y - (ZeroAnchorOffsets.Top + ZeroAnchorOffsets.Bottom) : ZeroAnchorOffsets.Bottom;
}

float UMathFunctionLibrary::ConvertLinearVelocity(FVector Velocity, TEnumAsByte<enum ESpeedUnit> SpeedUnit)
{
	if (Velocity.IsZero()) return 0.f;

	float unit = 0;
	switch (SpeedUnit)
	{
		case CentimeterPerSecond:
			unit = 1;
			break;
		case FootPerSecond:
			unit = 0.03280839895013;
			break;
		case MeterPerSecond:
			unit = 0.01;
			break;
		case MeterPerMinute:
			unit = 0.6;
			break;
		case KilometerPerSecond:
			unit = 0.00001;
		case KilometerPerMinute:
			unit = 0.0006;
			break;
		case KilometerPerHour:
			unit = 0.036;
			break;
		case MilePerHour:
			unit = 0.02236936292054;
			break;
		case Knot:
			unit = 0.01943844492441;
			break;
		case Mach:
			unit = 0.00002915451895044;
			break;
		case SpeedOfLight:
			unit = 3.335640951982E-11;
			break;
		case YardPerSecond:
			unit = 0.01093613298338;
			break;
		default:
			break;
	};

	return Velocity.Size() * unit;
}

bool UMathFunctionLibrary::EqualEqual_LinearColorLinearColor(FLinearColor ColorA, FLinearColor ColorB)
{
	return ColorA == ColorB;
}

float UMathFunctionLibrary::GetConsoleVariableFloat(FString VariableName)
{
	static const auto CVar = IConsoleManager::Get().FindTConsoleVariableDataFloat(*VariableName);

	if (CVar != 0)
	{
		//return CVar->GetValueOnGameThread();
		return CVar->GetValueOnAnyThread();
	}
	return 0.f;
}

int32 UMathFunctionLibrary::GetConsoleVariableInt(FString VariableName)
{
	static const auto CVar = IConsoleManager::Get().FindTConsoleVariableDataInt(*VariableName);

	if (CVar != 0)
	{
		return CVar->GetValueOnGameThread();
	}
	return 0;
}


FVector UMathFunctionLibrary::GetVelocityAtPoint(UPrimitiveComponent* Target, FVector Point, FName BoneName, bool DrawDebugInfo)
{
	/** //Math version of this function
	FTransform Transform = Target->GetComponentTransform();
	FVector LocalLinearVelocity = Transform.InverseTransformVectorNoScale(Target->GetPhysicsLinearVelocity());
	FVector LocalAngularVelocity = Transform.InverseTransformVectorNoScale(Target->GetPhysicsAngularVelocity());
	FVector ResultPointVelocity = LocalLinearVelocity + FVector::CrossProduct(FVector::DegreesToRadians(LocalAngularVelocity), Transform.InverseTransformVectorNoScale(Point - Target->GetCenterOfMass()));
	*/

	if (!Target) return FVector::ZeroVector;

	//You can actually get it from the physx body instance instead.
	FBodyInstance* BI = Target->GetBodyInstance(BoneName);
	if (BI && BI->IsValidBodyInstance())
	{
		FVector PointVelocity = BI->GetUnrealWorldVelocityAtPoint(Point);

		UWorld* TheWorld = Target->GetWorld();
		if (DrawDebugInfo && TheWorld)
		{
			DrawDebugPoint(TheWorld, Point, 10, FColor(FLinearColor(1.0f, 0.8f, 0.0f, 1.0f)), false, -1.0f);
			DrawDebugString(TheWorld, Point, FString::SanitizeFloat(PointVelocity.Size()), NULL, FColor::White, 0.0f);
		}

		return PointVelocity;
	}
	return FVector::ZeroVector;
}

void UMathFunctionLibrary::SetCenterOfMassOffset(UPrimitiveComponent* Target, FVector Offset, FName BoneName)
{
	if (!Target) return;

	FBodyInstance* BI = Target->GetBodyInstance(BoneName);
	if (BI && BI->IsValidBodyInstance())
	{
		BI->COMNudge = Offset;
		BI->UpdateMassProperties();
	}
}


Hey,Rama!You really did a wonderful job!
How can i make a plugin?
I wrote a function library and i want to make it a plugin.Can you help me?

Yes Rama, that is also a question I had. If I make a bunch of macros for math nodes, could I turn those into a plugin? Do I need C++ knowledge?

Also, maybe you could make a tutorial on how to do this? Maybe just something simple like how to make a node in c++ that adds A & B. Hope you consider it, thanks!

I wrote up a plugin that is a template for BP libraries a while ago! Here’s the wiki link!

You can download that and use that to get started!

Rama’s Plugin Template

:slight_smile:

Yes you do need to use C++ :slight_smile: See my Link!

Rama’s Plugin Template

:slight_smile:

Rama

30+ New Math, Physics, and 3D Geometry Nodes!

Live as of May 1st, 2015

Dear Community,

I have the May Celebration node release for you today!

Community member TK-Master has gifted us with over 30 new BP nodes for Math, Physics, and 3D Geometry calculations!

I highlighted my personal favorite nodes in green!


**UMG Anchor Conversion**
Please note you can now convert UMG Anchor coordinates to other coordinate spaces!

Snap To 3D Grid
You can use the Snap Node to snap any 3D space Vector to a grid size of your choosing!

So you could use this node to to regulate the position of an in-game 3D positioning tool (like for RTS Games!) to a grid of your choosing, while still accounting for rolling hills of landscapes and big vertical differences!


**Convert Physics Linear Velocity**

Ever wonder how fast in **Km/hr** an in-game Unreal Engine physics ball was hurling through the air?

Ever want to know the **meters/second** speed of a falling physics-simulating box?

Or how about the **miles/hour** of your UE4 Physics Vehicle?

Well thanks to TK-Master's new node you can now easily convert the value that you get from GetPhysicsLinearVelocity of any physics-simulating body to a speed in the units of your choosing!

Here's is TK-Master's current list of available conversions!



```


/* Speed Units Enum. */
UENUM()
enum ESpeedUnit
{
	/* Centimeter / second (cm/s). This is default unreal velocity unit. */
	CentimeterPerSecond,

	/* Foot / second (ft/s). */
	FootPerSecond,

	/* Meter / second (m/s). */
	MeterPerSecond,

	/* Meter / minute (m/min). */
	MeterPerMinute,

	/* Kilometer / second (km/s). */
	KilometerPerSecond,

	/* Kilometer / minute (km/min). */
	KilometerPerMinute,

	/*Kilometer / hour (km/h). */
	KilometerPerHour,

	/* Mile / hour (mph). */
	MilePerHour,

	/* Knot (kn). Nautical mile per hour. */
	Knot,

	/* Mach (speed of sound) (M) at standard atm. */
	Mach,

	/* Speed of light. */
	SpeedOfLight,

	/* Yard / second. */
	YardPerSecond
};


```



BP Nodes for 3D Geometric Analysis!

Here are pics showing the complete list of the new 3D Geometry Nodes!

To see the full list, get the latest version of my plugin and type in “TK” and you will see all the 30+ new nodes available to you!

3347099af001a575814d73a9d38845c3ad7ceef1.jpeg


**Thank You!**

**Thank you TK-Master for your contribution!**

These nodes are going to be extremely useful for a lot of people !

Most Recent Plugin Download From UE4 Wiki

:slight_smile:

Rama

Oh man, this is a good one. Thanks so much for sharing this!

Veneration for holy Rama! :smiley:
Thanks bunches you two!

Rama, I tried using the VictoryAI plugin template, I placed it in my UE4 Project’s plugins folder, and it tells me that it can’t compile, and that I need to compile from source manually. I have the launcher version of the engine, not GitHub. What am I doing wrong? And how do I recompile plugin once I’ve made my stuff?

Hee hee! You’re welcome!

I’ve thoroughly both of your (very first two!) posts Fayle, great to hear form you!

Compiling Plugins

Hi there!

Yes you definitely need to compile my template yourself, because you also cannot add code to it unless you compile it yourself!

You need Visual Studio Express 2013 for Desktop.

Make sure to get the “Community” edition or the one that says “For Windows Desktop”

Install that, and then you can use VS to compile.

The only alternative to a C++ plugin would be to make a BP Library asset that you share with people.

Enjoy!

:slight_smile:

Rama

30+ New Nodes!
PS: I recently released 30+ new nodes for Math, 3D Geometric Analysis, and Physics!

Hello Rama, I am working on a temperature system, it basically is for games where you want the user to see the temperature where player is at, or anywhere for that matter. You will be able to add heat sources, cold sources, and the temperature will radiate in the game. It will be fully customize-able with room temperature, temperature source influence, temperature flicker, and lots more when I’m done. It is really all just a back-end thing that nobody sees, but if people want, they could have the player take damage if where they are is too hot, and other things. If this works out, I will also make a moisture system as well. I will be making a node to initialize temperatures, node to add temperature source, remove temp source, and all of that. Is this something that you’d like in the Victory Plugin? If so, how would I get that stuff to you if I made it using your plugin template?

I reinstalled my Visual Studio 2013, with the VS 2013 Ultimate for desktop, but how do I compile VictoryAI manually?