Jump to content

SplineGraph in C#


photo

Recommended Posts

Hey there I have a problem. I want to create a spline via C# so I thought it is a good idea to transfer the sample Spline (C++) into C# but my Spline wont render and I have no idea why because it should show a spline (with the Visualizer). Because when I assign the Script to a NodeDummy or so nothing happens does someone have an idea why?

Code:

using System;
using System.Collections;
using System.Collections.Generic;
using Unigine;

[Component(PropertyGuid = "295cde640e861673976ae9364c0e4f1d868385d8")]
public class TestSpline : Component
{
	SplineGraph spline;
	private void Init()
	{
		Unigine.Console.Run("show_messages 1");

		//create spline garph
		spline = new SplineGraph();

		//generate spline
		CreateSpline(spline);

	}
	
	private void Update()
	{
		// write here code to be called before updating each render frame

		RenderSpline(spline);
	}

	private void CreateSpline(SplineGraph splineGraph)
	{
		splineGraph.AddPoint(Rand(-10.0f, 10.0f));
		splineGraph.AddPoint(Rand(-10.0f, 10.0f));
		splineGraph.AddPoint(Rand(-10.0f, 10.0f));
		splineGraph.AddPoint(Rand(-10.0f, 10.0f));

		splineGraph.AddSegment(0, Rand(-10.0f, 10.0f), new vec3(0.0f, 0.0f, 1.0f), 1, Rand(-10.0f, 10.0f), new vec3(0.0f, 0.0f, 1.0f));
		splineGraph.AddSegment(1, Rand(-10.0f, 10.0f), new vec3(0.0f, 0.0f, 1.0f), 2, Rand(-10.0f, 10.0f), new vec3(0.0f, 0.0f, 1.0f));
		splineGraph.AddSegment(2, Rand(-10.0f, 10.0f), new vec3(0.0f, 0.0f, 1.0f), 3, Rand(-10.0f, 10.0f), new vec3(0.0f, 0.0f, 1.0f));
		splineGraph.AddSegment(3, Rand(-10.0f, 10.0f), new vec3(0.0f, 0.0f, 1.0f), 0, Rand(-10.0f, 10.0f), new vec3(0.0f, 0.0f, 1.0f));
	}

	public void RenderSpline(SplineGraph splineGraph)
	{
		int num_segments = 50;
		for (int i = 0; i < splineGraph.NumSegments; i++)
		{
			vec3 startpoint = new vec3(splineGraph.GetSegmentStartPoint(i));
			vec3 starttangent = new vec3(splineGraph.GetSegmentStartTangent(i));
			vec3 endpoint = new vec3(splineGraph.GetSegmentEndPoint(i));
			vec3 endtangent = new vec3(splineGraph.GetSegmentEndTangent(i));

			Visualizer.RenderVector(startpoint, startpoint + starttangent, new vec4(1.0f, 0.0f, 0.0f, 0.3f), 0.05f);
			Visualizer.RenderVector(endpoint, endpoint + endtangent, new vec4(1.0f, 0.0f, 0.0f, 0.3f), 0.05f);

			for (int j = 0; j < num_segments; j++)
			{
				vec3 p0 = new vec3(splineGraph.CalcSegmentPoint(i, (float)j / num_segments));
				vec3 p1 = new vec3(splineGraph.CalcSegmentPoint(i, (float)j + 1 / num_segments));

				Visualizer.RenderLine3D(p0, p1, new vec4(1.0f, 1.0f, 1.0f, 1.0f));
			}
		}
	}

	public vec3 Rand(float min, float max)
	{
		Random rand = new Random();
		vec3 ret = new vec3();
		ret.x = (float)rand.Next((int)min, (int)max);
		ret.y = (float)rand.Next((int)min, (int)max);
		ret.z = (float)rand.NextDouble(); //returns a number btwn 0.0 and 1.0
		return ret;
	}

	public void  MoveMesh(SplineGraph splineGraph)
	{
		float time = Unigine.Engine.TotalTime;

		//float t = time - Math.Floor((double)(time / spline.NumSegments)) * spline.NumSegments;
		float t = (float)(time - Math.Floor(time / splineGraph.NumSegments) * splineGraph.NumSegments);
		int segment_id = (int)t;
		t -= (float) segment_id;

		vec3 p = new vec3(splineGraph.CalcSegmentPoint(segment_id, t));
		vec3 direction = new vec3(splineGraph.CalcSegmentTangent(segment_id, t));
		vec3 up = new vec3(splineGraph.CalcSegmentUpVector(segment_id, t));

		//mesh is not implemented still yet

		//mesh.setWorldPosition(p);
		//mesh.setWorldDirection(direction, up);
	}
}

 

Edited by paul.masan
Link to comment

Oh thanks a lot now I see the Spline still messed up but this is my code so for now there is no problem from your side thanks a lot :) Now it only renders the spline when I start the game/engine (compile) is there a way to change this?grafik.thumb.png.0715ed05f1400fbd0facc02318bda4a8.png

 

Edited by paul.masan
Link to comment

Hmm they are kind of hard... so i have implemented the node which moves along the spline but there is still some trouble with them.

  1. Every time I try to render a curved spline it looks like the picture above
  2. The Node moves a little bit messy along the spline and sometimes disappear

EDIT: I had my music played in background of the video so i had to take it down

So here is my code it have no compile errors...

using System;
using System.Collections;
using System.Collections.Generic;
using Unigine;

[Component(PropertyGuid = "ff2e4bd90c324364769a37731e9696367534181d")]
public class RopewayTest : Component
{
	private SplineGraph spline;

	[Parameter(Title = "SplineMoveObject")]
	public Node carrier;


	private void Init()
	{
		Unigine.Console.Run("show_messages 1");
		//Unigine.Console.Run("show_visualizer 1");

		Visualizer.Enabled = true;
		//create spline garph
		spline = new SplineGraph();

		//generate spline
		CreateSpline(spline);

		//SmoothSpline(spline);
		SmoothSpline(spline);
	}

	private void Update()
	{
		// write here code to be called before updating each render frame

		RenderSpline(spline);
		MoveMesh(spline);
	}

	private void CreateSpline(SplineGraph splineGraph)
	{
		//just create a simple triangle
		splineGraph.AddPoint(new vec3(0f, 0f, 0f));
		splineGraph.AddPoint(new vec3(0f, 10f, 0f));
		splineGraph.AddPoint(new vec3(10f, 10f, 0f));

		splineGraph.AddSegment(0, splineGraph.GetPoint(0), splineGraph.GetPoint(1), 1, splineGraph.GetPoint(1), splineGraph.GetPoint(0));
		splineGraph.AddSegment(1, splineGraph.GetPoint(1), splineGraph.GetPoint(2), 2, splineGraph.GetPoint(2), splineGraph.GetPoint(1));
		splineGraph.AddSegment(2, splineGraph.GetPoint(2), splineGraph.GetPoint(0), 0, splineGraph.GetPoint(0), splineGraph.GetPoint(2));
		
	}

	private void SmoothSpline(SplineGraph splineGraph)
	{
		for (int i = 0; i < splineGraph.NumSegments - 1; i++)
		{
			vec3 t0 = splineGraph.GetSegmentEndTangent(i);
			vec3 t1 = splineGraph.GetSegmentStartTangent(i + 1);

			vec3 sum = t0 + t1;

			t0 = t0.Normalize() * 2.0f - sum * t0.Length * 0.5f;
			t1 = t1.Normalize() * 2.0f - sum * t1.Length * 0.5f;

			splineGraph.SetSegmentEndTangent(i, t0);
			splineGraph.SetSegmentStartTangent(i + 1, t1);
		}
	}

	public void RenderSpline(SplineGraph splineGraph)
	{
		int numPoints = splineGraph.NumPoints;
		int numSegments = splineGraph.NumSegments;
		for (int i = 0; i < numPoints; i++)
		{
			Visualizer.RenderPoint3D(splineGraph.GetPoint(i), 0.1f, new vec4(1.0f, 1.0f, 1.0f, 1.0f));
		}
		for (int i = 1; i < numSegments; i++)
		{
			Visualizer.RenderLine3D(splineGraph.GetPoint(i - 1), splineGraph.GetPoint(i), new vec4(1.0f, 0.0f, 0.0f, 1.0f));
		}
		
		Visualizer.RenderLine3D(splineGraph.GetPoint(numPoints-1), splineGraph.GetPoint(0), new vec4(1.0f, 0.0f, 0.0f, 1.0f)); // for the last line

	}

	public vec3 Rand(float min, float max)
	{
		Random rand = new Random();
		vec3 ret = new vec3();
		ret.x = (float)rand.Next((int)min, (int)max);
		ret.y = (float)rand.Next((int)min, (int)max);
		ret.z = (float)rand.NextDouble(); //returns a number btwn 0.0 and 1.0
		return ret;
	}

	public void MoveMesh(SplineGraph splineGraph)
	{
		float time = Game.Time;

		float t = time - (float)Math.Floor(time / splineGraph.NumSegments) * splineGraph.NumSegments;
		int segment_id = (int)t;
		t -= (int)segment_id;

		vec3 p = new vec3(splineGraph.CalcSegmentPoint(segment_id, t));
		vec3 direction = splineGraph.CalcSegmentTangent(segment_id, t);
		vec3 up = splineGraph.CalcSegmentUpVector(segment_id, t);

		node.WorldPosition = p;
		node.SetWorldDirection(direction, up);
	}

}

 

Edited by Rainingcloud
Link to comment

Hi,

I found some errors when creating spline segments and rendering them. Tangent and upward directions at points were set incorrectly. And when rendering, you need to use several intermediate points to render the curves. This is all fixed in the component. Also added comments.

RopewayTest.cs

  • Like 1
Link to comment

Oh thanks a lot I tried this render method in the past but it looked like the Picture I posted above... I dont know why but i have my old code so I will have look so i know what ive done wrong.
Thanks a lot!

 

Link to comment

Maybe worth an addition to move objects in the splinegraph. Actually calculating t over all segments is not the way you go. You have to calculate t for each SplineSegment which is between 0 and 1. If your t-value exceed this limit move to the neighbour segment and "reset" t. The reason why your mesh disappears is you calculate tangent and position for values larger or smaller the limit.

Second thing: if you exceed the limits (either 1 or 0), you need to check for your next segment if t have to increase or decrease. Basically, if the mesh on the spline move from startPoint to endPoint, add iFPS to your t-value, if other way around substract iFPS.

 

Link to comment

Ok I worked a bit on the project but now I have a weird problem again...
So this is the Function:
 

	private void UpdateCarriers(float iFps)
	{
		foreach (RWCarrier carrier in myCarriers) // go through every carrier for now only one is in the list
		{

			float newSplinePos = carrier.actSplinePos + myControl.ropeWaySpeed * iFps; //the way the carrier moved between the two frames
			int segmentID = carrier.actSplineSegment; //just to not call is everytime 

			if (newSplinePos > leftRopeSpline.me.GetLength(carrier.actSplineSegment)) //if the limit of the spline eceeded go to the next one
			{
				carrier.actSplinePos = newSplinePos - leftRopeSpline.me.GetLength(segmentID); //assign new pos
				carrier.actSplineSegment++;
				segmentID++;
				if(leftRopeSpline.me.NumSegments <= segmentID) //just for now because the spline goes for testing only one way
				{
					carrier.actSplinePos = 0;
					carrier.actSplineSegment = 0;
					segmentID = 0;
				}
			}
			else
			{
				carrier.actSplinePos = newSplinePos; //assign the new pos
			}
			float t = 0.01f * (100 * carrier.actSplinePos / leftRopeSpline.me.GetLength(segmentID)); //get t from the SplineGraph.Length

			Log.Message(t.ToString() + " t\n");
			Log.Message(carrier.actSplineSegment.ToString() + "segment\n");
			Log.Message(carrier.actSplinePos.ToString() + "pos\n");

			vec3 pos = new vec3(leftRopeSpline.me.CalcSegmentPoint(segmentID, t)); //get the new pos of the carrier
			vec3 direction = leftRopeSpline.me.CalcSegmentTangent(segmentID, t); 
			vec3 up = leftRopeSpline.me.CalcSegmentUpVector(segmentID, t);

			//carrier.carrier.Position = pos; ERROR
           		 carrier.carrier.WorldPosition = pos; //Works now!
			
		}
	}

the myControl.ropeWaySpeed is just an float in this case 10f
The carrier has this for movement:
 

	//for the spline movement

	public int actSplineSegment { get; set; }
	public float actSplinePos { get; set; }
	public float t { get; set; }

So the UpdateCarriers is called in the Update()
It all works, kind of...
Because the Carrier makes a short break while switch to the new segment, and also the carrier floats like the Spline but not along it.
Edit: I tried a lot and just found that the second Error was :

//Error
carrier.carrier.Position = pos; 
//works
carrier.carrier.WorldPosition = pos; 

So now the only problem is this stopping while switch to the new spline. You can see the problem in the video below.

If you have some questions/suggestion feel free to ask :)
(The Splines will be curved soon)

Edited by Rainingcloud
First Bugfix
Link to comment

Hi rainingcloud,

it seems you made some progress with your spline movement. So my few hints again: :)

Do not try to calculate your t-value from your carrier position (act.SplinePos). This leads to the problem you faced in your code when calculating t-value. For small values of actSplinePos your t-value will also be too small, for large values closer to your spline length your t value will also increase in very small steps.

So instead use something like:

currentTValue += Game::get()->getIFps() * movementRatioOnSpline;

The currentTValue needs to be stored in your carrier class, same as movementRatioOnSpline. Now calculate the actual position from the currentTValue. The movementRatioOnSpline needs to be calculated for each segment differently, because you need to move RELATIVELY to your spline. So when changing to another segment try this one:

movementRatioOnSpline = myControl.ropeWaySpeed / currentSplineSegment->getLength();

 

Best

Christian

 

Link to comment

Hi Christian,
Uhm I tried this but the problem is the same:

The Carrier makes a break while switching segments, also the problem with the T is that the speed of the carrier is not the same for each segment.

EDIT: The problem is now that the carrier moves slow at the start and the end of the splinesegment


Here is my Code:
 

private void UpdateCarriers()
	{
		foreach (RWCarrier carrier in myCarriers) // go through every carrier for now only one is in the list
		{
			int actSegment = carrier.actSplineSegment;

			carrier.movementOnSpline = myControl.ropeWaySpeed / leftRopeSpline.me.GetLength(actSegment);
			carrier.currentT += carrier.movementOnSpline * Game.IFps;

			if (carrier.currentT > 1)
			{
				carrier.currentT--;
				carrier.actSplineSegment++;
				actSegment++;
				if (leftRopeSpline.me.NumSegments <= actSegment) //just for now because the spline goes for testing only one way
				{
					carrier.actSplinePos = 0;
					carrier.actSplineSegment = 0;
					actSegment = 0;
				}

			}

			vec3 pos = new vec3(leftRopeSpline.me.CalcSegmentPoint(actSegment, carrier.currentT)); //get the new pos of the carrier
			vec3 direction = leftRopeSpline.me.CalcSegmentTangent(actSegment, carrier.currentT); 
			vec3 up = leftRopeSpline.me.CalcSegmentUpVector(actSegment, carrier.currentT);

			carrier.carrier.WorldPosition = pos; //assign the new pos
			
		}
	}

 

Edited by Rainingcloud
Noticed Problem
Link to comment

Actually using the carrier speed and divide it by the spline segment length should avoid slower/faster movement. While t is of cause not the same for each segment because it depends on the segment length. Think about a straight segment path. If one segment is doubled in length it travels faster on the spline than the short one.

So here is my C++ code (you can try to adapt it to C#) that works without any issues:

 

bool SplineMovementNode::getNextSplineSegment()
{
	SplinePointPtr nextPoint;

	if (!invertedDirection)
		nextPoint = currentSplineSegment->getEndPoint();
	else
		nextPoint = currentSplineSegment->getStartPoint();

	if (nextPoint->getNumSegments() == 1)
		return false;

	//get all splineSegments
	Unigine::Vector<SplineSegmentPtr> splineSegments;
	nextPoint->getSplineSegments(splineSegments);

	if (splineSegments[0] == currentSplineSegment)
		currentSplineSegment = splineSegments[1];
	else
		currentSplineSegment = splineSegments[0];

	//calculate the new movement-ratio
	movementRatioOnSpline = speed / currentSplineSegment->getLength();

	return true;
}

void SplineMovementNode::init()
{
	invertedDirection = true;
	speed = 2.f;

	Vec3 initialPosition = currentSplineSegment->calcPoint(currentTValue);
	node->setWorldPosition(initialPosition);
	movementRatioOnSpline = speed / currentSplineSegment->getLength();
}

int SplineMovementNode::update()
{
	if (!invertedDirection)
	{
		currentTValue += Game::get()->getIFps() * movementRatioOnSpline;

		if (currentTValue >= 1.f)
		{
			if (!getNextSplineSegment())
			{
				//there is no next node, so destroy this one
				return 0;
			}

			currentTValue -= 1.f;
		}

	}
	else
	{
		currentTValue -= Game::get()->getIFps() * movementRatioOnSpline;

		if (currentTValue <= 0.f)
		{
			if (!getNextSplineSegment())
			{
				//there is no next node, so destroy this one
				return 0;
			}

			currentTValue += 1.f;
		}
	}


	//set the new position
	Vec3 position = currentSplineSegment->calcPoint(currentTValue);
	position.z += zCorrection;											//ignore that line for your code
	node->setWorldPosition(position + splineGraphPosition);
	node->setWorldDirection(currentSplineSegment->calcTangent(currentTValue), currentSplineSegment->calcUpVector(currentTValue));
	node->setTransform(node->getTransform() * Mat4(rotateX(-90.f)));
      
	return 1;
}

 

Maybe one point that might be a problem is your start/endTangent of your SplineSegment. Because if they are not the same length, there could be some issues. I solved it by making them uniform in length.

 

Best

Christian

 

 

Link to comment

Uhm for now the tangents are Vec3.ZERO because I dont want a curve for now
 

public void AddSplineSegment(vec3 nextPoint)
		{
			int actPoint = me.AddPoint(nextPoint); //adding a point and save the index
			if (actPoint > 0) me.AddSegment(actPoint - 1, vec3.ZERO, vec3.UP, actPoint, vec3.ZERO, vec3.UP); //create a segment between the last and the new point
		}

I have a look at your c++ code and try to figure out what i´ve done wrong

regards

Link to comment
2 hours ago, Rainingcloud said:

if (actPoint > 0) me.AddSegment(actPoint - 1, vec3.ZERO, vec3.UP, actPoint, vec3.ZERO, vec3.UP); //create a segment between the last and the new point

 

Than that is your issue. The tangent vector should be an real position in your world. Now your setting them at your spline start point and end point. I guess that is not what you want.

Edited by christian.wolf2
Link to comment

If you only want to achieve a straight spline segment you can use for your start tangent:

vec3 startTangent = vec3(endPoint - startPoint).normalize();

For your endPoint just use -startTangent.

 

Cheers

Link to comment

Sorry for the circumstances but yeah the problem was the vec3.ZERO but I can´t figure out how to create a straight SplineSegment.
@christian.wolf2I tried this solution in the past and now it doesen´t work

So if anyone has an Idea or knows how to make a straight spline, it would help me a lot
regards
 

Edited by Rainingcloud
Link to comment

So now I have straight spline but they keep stopping at the start and th end of long splinesegments:


Does someone knows why this happens ?

Edit:

I noticed the problem its because the Spline gets compressed, in the Picture below you can see that the Renderet Segments are getting shorter in the end.
grafik.thumb.png.6f08a6ea28f470047168ab66ceccc4bc.png

I tryed a lot but cant get rid of it.

I use this for creating a SplineSegment:
 

int actPoint = me.AddPoint(nextPoint); //adding a point and save the index

		if (actPoint > 0)
		{
			vec3 startTangent = new vec3(me.GetPoint(actPoint) - me.GetPoint(actPoint - 1)).Normalize();
			startTangent = startTangent + startTangent;
			int segmentIndex = me.AddSegment(actPoint - 1, startTangent, vec3.UP, actPoint, -startTangent, vec3.UP); //create a segment between the last and the new point
		}

I would really appriciate any suggestions :)

regards
Rainingcloud

Edited by Rainingcloud
Compressed spline Error
Link to comment

Hi Rainingcloud,

 

okay, after some testing on my side I figured out, what caused the error.

I was wrong that you need only normalize the tangent vector, but also apply 1/3 to it (so divide by ten and multiply by 3). The reason is, that UNIGINE splines are cubic bezier splines with two control points (see in the documentation). Therefor, for a straight line, you have to set your tangent exactly one third before and one third after your start and endpoint.

 

vec3 startTangent = (vec3(endPoint - startPoint).normalize() / 10.f) * 3.f;

The rest stays the same. Sorry for the confusion.

 

Best

Christian

 

EDIT: By the way: If you only want to work with straight splines (that have no curves) you will be better using the direction vector and skip the spline graph completely. Calculating a position for an cubic spline is more costly than using standard movement approach.

Edited by christian.wolf2
Link to comment

Hi Christian,
I really appriciate your help.

I have no idea why but the Splines also wont work for me now i have no idea whats the problem but now they begin anoying me...
Maybe i'm just to dump to use them but they keep doing this stopping thing.
I thought about direction vectors but im the end I want the spline to be curved and straight like a real ropeway.

I just made a new project from scratch and tryed it again, still wont work. And do this stopping stuff.
I could switch to the version where i calc T via the segment length maybe it works but it would be a workaround...

I insert the hole code of my test project, maybe it helps... (If you want to use it you can just Create a net core project and assign the script to a simple cube)
 

Spoiler

using System;
using System.Collections;
using System.Collections.Generic;
using Unigine;

[Component(PropertyGuid = "ff2e4bd90c324364769a37731e9696367534181d")]
public class RopewayTest : Component
{
	private SplineGraph spline;

	[Parameter(Title = "SplineMoveObject")]
	public Node carrier;

	public float speed = 2;

	private int segmentIndex = 0;
	private float curT = 0;
	private float movemntRatioOnSpline = 0;


	private void Init()
	{
		Unigine.Console.Run("show_messages 1");
		//Unigine.Console.Run("show_visualizer 1");

		Visualizer.Enabled = true;
		//create spline garph
		spline = new SplineGraph();

		//generate spline
		CreateSpline(spline);

		//SmoothSpline(spline);
		//SmoothSpline(spline);

		movemntRatioOnSpline = speed / spline.GetLength(segmentIndex);
	}

	private void Update()
	{
		// write here code to be called before updating each render frame

		RenderSpline(spline);
		MoveMesh(spline);
	}

	public void MoveMesh(SplineGraph splineGraph)
	{
		curT += Game.IFps * movemntRatioOnSpline;
		if (curT > 1.0f)
		{
			curT -= 1.0f;
			segmentIndex++;
			if (segmentIndex > splineGraph.NumSegments)
			{
				segmentIndex = 0;
			}

		}


		vec3 pos = new vec3(splineGraph.CalcSegmentPoint(segmentIndex, curT));
		vec3 direction = splineGraph.CalcSegmentTangent(segmentIndex, curT);
		vec3 up = splineGraph.CalcSegmentUpVector(segmentIndex, curT);

		node.Position = pos;
		node.SetWorldDirection(direction, up);
	}

	private void CreateSpline(SplineGraph splineGraph)
	{
		vec3 pos1 = new vec3(10, 10, 1);
		vec3 pos2 = new vec3(20, 10, 1);
		vec3 pos3 = new vec3(20, 20, 1);
		vec3 pos4 = new vec3(10, 20, 1);

		splineGraph.AddPoint(pos1);
		splineGraph.AddPoint(pos2);
		splineGraph.AddPoint(pos3);
		splineGraph.AddPoint(pos4);

		vec3 startTangent  = new vec3((pos2 -pos1).Normalize() / 10.0f) * 3.0f;
		splineGraph.AddSegment(0, startTangent, vec3.UP, 1, -startTangent, vec3.UP);

		startTangent = new vec3((pos2 - pos3).Normalize() / 10.0f) * 3.0f;
		splineGraph.AddSegment(1, startTangent, vec3.UP, 2, -startTangent, vec3.UP);

		startTangent = new vec3((pos3 - pos4).Normalize() / 10.0f) * 3.0f;
		splineGraph.AddSegment(2, startTangent, vec3.UP, 3, -startTangent, vec3.UP);

		startTangent = new vec3((pos4 - pos1).Normalize() / 10.0f) * 3.0f;
		splineGraph.AddSegment(3, startTangent, vec3.UP, 0, -startTangent, vec3.UP);
	}

	private void SmoothSpline(SplineGraph splineGraph)
	{
		for (int i = 0; i < splineGraph.NumSegments - 1; i++)
		{
			vec3 t0 = splineGraph.GetSegmentEndTangent(i);
			vec3 t1 = splineGraph.GetSegmentStartTangent(i + 1);

			vec3 sum = t0 + t1;

			t0 = t0.Normalize() * 2.0f - sum * t0.Length * 0.5f;
			t1 = t1.Normalize() * 2.0f - sum * t1.Length * 0.5f;

			splineGraph.SetSegmentEndTangent(i, t0);
			splineGraph.SetSegmentStartTangent(i + 1, t1);
		}
	}

	public void RenderSpline(SplineGraph splineGraph)
	{
		int numPoints = splineGraph.NumPoints;
		int numSegments = splineGraph.NumSegments;
		for (int i = 0; i < numPoints; i++)
		{
			Visualizer.RenderPoint3D(splineGraph.GetPoint(i), 0.1f, new vec4(1.0f, 1.0f, 1.0f, 1.0f));
		}

		// to render the spline, you need to take into account several intermediate points of the segments
		// for example, use 50 intermediate points for each segment
		// as a result, each segment will be rendered not as one straight line, but as a combination of 49 lines

		int segmentParts = 50;
		float inverseSegmentsParts = 1.0f / segmentParts;
		vec4 color = new vec4(1.0f, 0.0f, 0.0f, 1.0f);
		for (int i = 0; i < numPoints; i++)
			for (int j = 0; j < segmentParts-1; j++)
			{
				vec3 pos1 = splineGraph.CalcSegmentPoint(i, j * inverseSegmentsParts);
				vec3 pos2 = splineGraph.CalcSegmentPoint(i, (j + 1) * inverseSegmentsParts);
				Visualizer.RenderLine3D(pos1, pos2, color);
			}
	}

}

 

Edit: I have finally understood how the spline works the solution would be  an an algorithm which decompress the spline so that it always is the same size I will have a look at this.
Regards
Rainingcloud
 

Edited by Rainingcloud
Solution Idea
Link to comment

Ok i solved the problem pretty easy.
The solution is: Don't use the Unigine SplineGraph :)
So I wrote my own Spline which can have straight and curved segments. The curved ones are based on a 3 point bezier so its easy to use them too.
I am really thankful for all who helped me, huge shoutout to you.

Here is again a little video:

One last question, how can i set the topic to solved ?

best regards
Rainingcloud

Link to comment
  • 2 weeks later...
×
×
  • Create New...