stride icon indicating copy to clipboard operation
stride copied to clipboard

[WIP] Base spline support

Open Aggror opened this issue 3 years ago • 14 comments

PR Details

This PR contains basic support for creating splines and visualizing those splines.

  • 3 new components: SplineComponent, SplineNodeComponent and SplineTraverserCompoentn
  • Visualisation is supported in the editor by viewing
  • Curves
  • Boundingboxes
  • Nodes
  • Other spline components are in the works as well, but purposely left out to focus on getting the core for Splines better in shape. That is also the reason there is no documentation written yet.
  • SplineMeshComponent
  • SplineDecoratorComponent

Motivation and Context

Splines are useful for camera paths, or any other object that requires bezier curve for movement, generating geometry and for distributing geometry (see prototype video). This first PR should cover the creation and editing of the spline.

Description

(outdate, should make a new one) For a full overview see this video which is specifically recorded for this PR: https://youtu.be/auLS9RObIXY Demo project: https://github.com/Aggror/SplineTools/tree/Spline-PR-1-demo

A spline entity exists out of SplineNodes (also entities) which are its children. These can be created entirely by code if so desired. To make them slightly more user friendly, these objects are utilised in components so that an editor user can view them inside the editor.

Some details

  • A spline exists out out nodes. 1 node that connects to another is called a (cubic bezier) curve
  • An (unscaled) entity contains the SplineComponent
  • The (unscaled) children of this entity should contain the SplineNodeComponent
  • The SplineComponent holds a reference to the children SplineNodeComponents
  • There need to be at least 2 SplineNodeComponents (only 1 per entity allowed) before a spline is calculated
  • The SplineComponent holds an internal SplineRenderer which generates spline visualisation geometry when the spline is updated. Previously generated meshes are discarded upon updating spline.

Spline traverser An entity with a reference to the spline, can traverse the spline. A basic Spline traverser component has been added that support moving forward and backwards along the spline. No rotations and physics support yet.

Types of changes

  • [ ] Docs change / refactoring / dependency upgrade
  • [ ] Bug fix (non-breaking change which fixes an issue)
  • [x] New feature (non-breaking change which adds functionality)
  • [ ] Breaking change (fix or feature that would cause existing functionality to change)

Checklist

  • [] My change requires a change to the documentation.
  • [ ] I have added tests to cover my changes.
  • [ ] All new and existing tests passed.

Aggror avatar Jan 19 '22 16:01 Aggror

Is this still being worked on?

markusstephanides avatar Jul 16 '22 18:07 markusstephanides

Is this still being worked on?

I had to put it in the fridge in order to complete the tutorials project. Since then I havent had the time yet to work further on this.

Aggror avatar Jul 17 '22 22:07 Aggror

Little update on this: I started my attempts at finishing this again.

  • Decided to re-add the Spline Traverser component, since that is 1 of the common use cases to have a spline. The decorator and mesh generator are still absent though.
  • A spline traverser can move forwards or backwards along the spline
    • no rotation support
    • Physical based movement not yet supported

Some open bugs:

  • opening a scene for the first time, doesn't render the spline trail. Updating the spline or 1 of its nodes or any of the settings, updates the spline.
  • duplicating a spline or creating a new spline, breaks older splines in the scene. Even upon reloading the scene. Only the latest spline component added works for some reason.

ezgif-3-a0d010f14d

Stride Fork: https://github.com/Aggror/Stride/tree/SplinePR Test project: https://github.com/Aggror/SplineTools/tree/Spline-PR-1-demo

Aggror avatar Jul 23 '22 19:07 Aggror

Alright another step closer to completion. SplineTraverserComponent references a SplineTraverser object. Traverser transform processor now deals with multiple traversers properly IN the editor. Running the game is not working yet.

Aggror avatar Jul 25 '22 20:07 Aggror

Did some more testing with test project.

  • I have tested the spline. spline nodes and spline traverser in the editor in a lot of ways:
    • Removing entities or removing spline node components of existing splines.
    • Removing spline nodes from the Spline component reference
    • Doing al of this while there are 2 spline traverser going forward and backwards on the spline

Some open bugs:

  • Something I still can't lay my finger on: opening a scene for the first time, doesn't render the spline trail. I can see that the spline is calculated and that the spline renderer is there. It just doesn't update the scene view.
    • Updating the spline position or any of the splinecomponent/splinenodecomponent settings does update the spline.

Aggror avatar Aug 04 '22 09:08 Aggror

I think I have done enough debugging for now. I want to take the plunge and remove the draft from this PR.

  • Removed the Spline traverser in-editor movement. It just doesn't have a nice feel to it. For now this component is runtime only.
  • Re-added the render option in the spline renderer to show spline node spheres.
  • Demo project has been updated: https://github.com/Aggror/SplineTools/tree/Spline-PR-1-demo

You can also download a debug .exe here: https://drive.google.com/file/d/1CnvEKHf0ti3OCcTTS8cLpctZ5CzchEXu/view?usp=sharing

Aggror avatar Sep 02 '22 16:09 Aggror

The traverser has issues with suttery rotation and getting stuck at low frame rates:

stutter.webm

I understand that might be related to your comment over on the speed property:

The speed at which the traverser moves over the spline. Use a negative value, to go in to the opposite direction Note: Using a high value, can cause jitters. With a higher speed value, it is recommended to reduced the amount of spline points or segments

Could you elaborate on what the issue is exactly ? Perhaps I could find a solution for you

Eideren avatar Sep 05 '22 23:09 Eideren

Could you elaborate on what the issue is exactly ? Perhaps I could find a solution for you

With a high speed/velocity, a traverser can overshoot its target. If the traverser is not within a threshold range of the target position, the traverser continues with its current velocity. I am not sure if a low FPS causes the same issue. The check for the next node is just a simple distance check.

var distance = Vector3.Distance(entity.Transform.WorldMatrix.TranslationVector, targetBezierPoint.Position);

  if (distance < thresholdDistance)
  {
      SetNextTarget();

In most scenarios, this code works fine, but with high amount of nodes or a high velocity, another check needs to be performed: If the added velocity overshoots the target position. Thus far I didn't find it worth it since it is a matter of tweaking the velocity.

Aggror avatar Sep 07 '22 18:09 Aggror

Did not manage to get the jitter to go away when the game window is not selected or when fps is low. I also have some improvements for the spline renderer although that can also be a part of a different PR when spline meshes are fully supported. I am also interested in whether my code is architecturally sound (does that make sense?).

Aggror avatar Oct 05 '22 13:10 Aggror

On your question on being architecturally sound - you've placed most of your update logic in the models rather than having them just be containers and placing logic in the component processors. I think for a feature of this scale it's not a bad idea, but would ensure there's decent logical separation between what is user facing and what is internal state, which would be normally placed in a class in the processor (such that ComponentData[component] can point towards that internal data).

manio143 avatar Oct 05 '22 23:10 manio143

Hey, I took some time tonight to review parts of your PR. Good work overall! I mostly looked at general stuff and did not dive into actual computation logic you have there.

Two general things to look at:

* Make sure all new files have the copyright notice and that it includes .NET Foundation

* Sort usings to ensure easier checking of referenced namespaces.

I hope I could provide some valuable comments. There's quite a few, but let's make sure they're not discouraging :D I do code review every week and may have a somewhat dry style of delivery.

Thanks @manio143 for the thorough review. It is good that you don't hold back on comments, otherwise I won't learn anything and we end with bad code. Will get back to improving things soon.

Aggror avatar Oct 06 '22 19:10 Aggror

On your question on being architecturally sound - you've placed most of your update logic in the models rather than having them just be containers and placing logic in the component processors. I think for a feature of this scale it's not a bad idea, but would ensure there's decent logical separation between what is user facing and what is internal state, which would be normally placed in a class in the processor (such that ComponentData[component] can point towards that internal data).

I had feedback from several users, that not all of them want to use use components (which are now tied to processors). They just want to be able to do something simple like:

var spline = new Spline();
spline.PointA = pointA;
spline.PointB = pointB;
spline.UpdateSpline();

The UpdateSpline could be move to the SplineProcessor, but that would require the user to make a SplineProcessor. Is that a better design principle?

var spline = new Spline();
spline.PointA = pointA;
spline.PointB = pointB;

var splineProccesor = new SplineProccesor ();
splineProccesor.UpdateSpline(spline);

Aggror avatar Sep 17 '23 10:09 Aggror

I had feedback from several users, that not all of them want to use use components (which are now tied to processors).

I think we need to understand the different parts of how splines would be used. So for example you can isolate maths parts completely from anything engine related and allow the user to work with those object even if they're not using Stride systems. Then for things which interact with other parts of Stride you would put those in a component-processor style. The component can just hold a spline object and expose it's public properties inline in the editor.

manio143 avatar Sep 17 '23 12:09 manio143

I had feedback from several users, that not all of them want to use use components (which are now tied to processors).

I think we need to understand the different parts of how splines would be used. So for example you can isolate maths parts completely from anything engine related and allow the user to work with those object even if they're not using Stride systems. Then for things which interact with other parts of Stride you would put those in a component-processor style. The component can just hold a spline object and expose it's public properties inline in the editor.

Thanks for replying. So that would bring me to a spline builder/service/generator. Spline and SplineNode will contain nothing but data, but the service contains the logic to tie these 2 together.

Aggror avatar Sep 17 '23 12:09 Aggror