Rainingcloud Posted April 21, 2020 Share Posted April 21, 2020 (edited) 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 April 21, 2020 by paul.masan Link to comment
morbid Posted April 21, 2020 Share Posted April 21, 2020 Hi, We'll check it this week. By the way, are you sure visualizer is enabled? By default, it's turned off. Try in console: show_visualizer 1 Thanks! How to submit a good bug report --- FTP server for test scenes and user uploads: ftp://files.unigine.com user: upload password: 6xYkd6vLYWjpW6SN Link to comment
Rainingcloud Posted April 21, 2020 Author Share Posted April 21, 2020 (edited) 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? Edited April 21, 2020 by paul.masan Link to comment
morbid Posted April 22, 2020 Share Posted April 22, 2020 No, you wouldn't see it in the editor since the Spline is created in runtime. How to submit a good bug report --- FTP server for test scenes and user uploads: ftp://files.unigine.com user: upload password: 6xYkd6vLYWjpW6SN Link to comment
Rainingcloud Posted April 22, 2020 Author Share Posted April 22, 2020 (edited) 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. Every time I try to render a curved spline it looks like the picture above 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 April 22, 2020 by Rainingcloud Link to comment
karpych11 Posted April 22, 2020 Share Posted April 22, 2020 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 1 Link to comment
Rainingcloud Posted April 22, 2020 Author Share Posted April 22, 2020 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
christian.wolf2 Posted April 22, 2020 Share Posted April 22, 2020 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
Rainingcloud Posted April 29, 2020 Author Share Posted April 29, 2020 (edited) 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 April 30, 2020 by Rainingcloud First Bugfix Link to comment
christian.wolf2 Posted April 30, 2020 Share Posted April 30, 2020 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
Rainingcloud Posted April 30, 2020 Author Share Posted April 30, 2020 (edited) 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 April 30, 2020 by Rainingcloud Noticed Problem Link to comment
christian.wolf2 Posted April 30, 2020 Share Posted April 30, 2020 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
Rainingcloud Posted April 30, 2020 Author Share Posted April 30, 2020 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
christian.wolf2 Posted April 30, 2020 Share Posted April 30, 2020 (edited) 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 April 30, 2020 by christian.wolf2 Link to comment
Rainingcloud Posted April 30, 2020 Author Share Posted April 30, 2020 Ok but this is the only way that I know to create a straight splinesegment... Link to comment
christian.wolf2 Posted April 30, 2020 Share Posted April 30, 2020 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
Rainingcloud Posted April 30, 2020 Author Share Posted April 30, 2020 (edited) 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 April 30, 2020 by Rainingcloud Link to comment
Rainingcloud Posted May 1, 2020 Author Share Posted May 1, 2020 (edited) 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. 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 May 2, 2020 by Rainingcloud Compressed spline Error Link to comment
christian.wolf2 Posted May 2, 2020 Share Posted May 2, 2020 (edited) 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 May 2, 2020 by christian.wolf2 Link to comment
Rainingcloud Posted May 2, 2020 Author Share Posted May 2, 2020 (edited) 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 May 2, 2020 by Rainingcloud Solution Idea Link to comment
Rainingcloud Posted May 4, 2020 Author Share Posted May 4, 2020 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
Rainingcloud Posted May 14, 2020 Author Share Posted May 14, 2020 So my Spline is now available on GitHub :) So if anyone is interested in it here is the Link: https://github.com/Raining-Cloud/Unigine-Spline regards Rainingcloud aka. Paulchen 2 Link to comment
Recommended Posts