Giter VIP home page Giter VIP logo

splinemesh's People

Contributors

anomalousunderdog avatar basdp avatar fornan-ii avatar julzso23 avatar methusalah avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

splinemesh's Issues

[Question] change set of points and update spline after all are updated

HI,
I have 4 splines with 10 points each which I'm changing in 400Hz.
for each update I'm changing (in Spline.cs):

        public void UpdateNode(int i, Vector3 newPosition)
        {
            if (i < nodes.Count)
            {
                nodes[i].Position = newPosition;
            }
        }

the problem is that after each change rasie event:

       /// <summary>
        /// Node position
        /// </summary>
        public Vector3 Position {
            get { return position; }
            set {
                if (position.Equals(value)) return;
                position.x = value.x;
                position.y = value.y;
                position.z = value.z;
                 Changed?.Invoke(this, EventArgs.Empty);

            }
        }

which cause performance issuses.

is ther ea way to update alll spline points in a batch and only after that recreate/update the presentation/spline itself?

it will reduce redrawing by 10...

[bug] Use "for" instead of "foreach" in SplineMeshTiling

Hi
In the SplineMeshTilling, I see the follow script:

foreach (var go in generated.transform
.Cast()
.Select(child => child.gameObject).Except(used)) {
UOUtility.Destroy(go);
}

But some times, one or more child did not destroy. After that, I store the "Select" result to an Array and use "for" instead of "foreach". The problem is solved.

                                               Thanks.

Bases for extrusions

The extrusion needs to be enclosed by base faces. The editor should provide a way to control the UV offset, rotation and scale on these faces.

SendMessage cannot be called during Awake, CheckConsistency, or OnValidate

This error happens when loading the Showcase in the editor. There are about 20 of them , like this:

SendMessage cannot be called during Awake, CheckConsistency, or OnValidate
UnityEngine.GameObject:.ctor(String, Type[])
SplineMesh.UOUtility:Create(String, GameObject, Type[]) (at Assets/SplineMesh/Scripts/Utils/UOUtility.cs:9)
SplineMesh.ExampleGrowingRoot:Init() (at Assets/SplineMesh/Scripts/Example/ExampleGrowingRoot.cs:81)
SplineMesh.ExampleGrowingRoot:OnValidate() (at Assets/SplineMesh/Scripts/Example/ExampleGrowingRoot.cs:49)
UnityEngine.GUIUtility:ProcessEvent(Int32, IntPtr, Boolean&)

You can find info about this problem here: https://forum.unity.com/threads/sendmessage-cannot-be-called-during-awake-checkconsistency-or-onvalidate-can-we-suppress.537265/ and here: https://forum.unity.com/threads/sendmessage-cannot-be-called-during-awake-checkconsistency-or-onvalidate.428580/.

Basically this problem happens if you call the Unity API to set stuff before the system is stable. There is a partial description here: https://docs.unity3d.com/2019.1/Documentation/ScriptReference/GameObject-tag.html, but it applies to lots of other stuff.

It's new, since some time in 2019, there is a bug report, Unity have responded and it's probably not going away any time soon. The ideal fix is: don't set stuff in Awake() or OnValidate(). I'm running 2020.1.1 and I don't have any old versions available to check.

SplineMeshTiling direction bug

Hi
I am using SplineMeshTiling.
There are two nodes on Spline. The fields of Element 0 are: Position(0,0,0), Direction(0,0,0). The flelds of Element 1 are: Position(0,-10,0), Direction(0,-10,0).
And then i add Mesh and Material to SplineMeshTiling. You can see something wrong on the Element 0.
If you set Direction of Element 0 to (0,-1,0). The Mesh rendering is correct.
Thanks.

Scene Gizmo and handle improvement

Is there any plan to improve the Spline Gizmo display and handle in the scene view.
Currently there is some small annoying thing when working with the spline in scene view

  1. When the spline game object are not selected the spline gizmo are not visible. Having a toggle to always show spline when unselected would be great.
  2. For some reason, sometimes the spline handle and nodes are hard to select.

this is just an idea, would it be possible to adapt the technique used by Sebastien Lague to deal with the scene view handling and display? https://github.com/SebLague/Path-Creator

having the best of two world would be awesome

Implement different curves/line types

As commented by philc_uk on the asset store.

For this there will need to be a Curve interface or base class and probably separated direction indicators on the nodes.

In the editor interface you should be able to select the node curve types:

  • corner point (no curve)
  • cusp point (separate directions)
  • smooth point (CubicBezierCurve )

Dynamic Mesh Knots

I need to create a "Basic Pipe" slpine where each node of the spline is dynamic and constantly updating position and rotation information. The current example doesn't allow you to modify those parameters? Any suggestions on how to make these changes?

Spline is not creating.

Whenever I go to GameObject>3D Object>Spline no Spline object is created and when i imported the package it used to create Spline but in sometime it becomes non editable. I re-imported but it doesn't work.

[Question] Add band around points

Hi,
Great project.
I was wondering if there is a way to mark the points on the spline curve (maybe with width).
some thing like:
image

I try to create something like tihs:
image

[Question] Extend spline past the end points

Hi,
I managed to create catheter like spline.
Is there a way to extend the curve/spline past the endppoints by a distance (say 1 millimeter) without artificially adding 2 points and hide them?

image

Modifying the position of a SplineNode only seems to change one control point

As mentioned in my other issue report, I'm working on a game with a player running wire between devices, using SplineMesh. Right now I have it set to change its end node's Position to the transform.position of the player. This almost works, but on inspection during play, I see that only one of the control points for that final node is moving, the other is stuck in place. This causes radical curvature changes as I move the player around.

There's a very good chance that I'm missing something here, and there might be a better way to do this. Is this intentional behavior? Or is there a better way to move the control point at runtime?

Rename examples

Rename scripts from the not obsolete form of exemple to example.

Alternatively the example scripts could be renamed to general components which could directly be used. ExempleSower would then be renamed to SplineSower in line with the SplineExtrusion script (example). This way it wouldn't be weird to use "example" components on your objects.

A instance of prefab in scene can not auto Serialize

Hi
I create empty GameObject on Inspector, And then add Spline.
I drag it to Project window to create a prefab.
Select the GameObject in Inspector, then Set Selected Node Position to (5,5,0) and save Scene. If you open other Scene and Back to this Scene, you can see the Position is not (5,5,0) but the value of Prefab(5,0,0). If you modify the position use Script ,the effict like this.
If you Uppack Complete the GameObject and modify the Position, it can Serialize. After you open oterh Scene and Back to this Scene, you can see the position is (5,5,0). Or if you modify in Scene window use the Axis, it can Serialize too.
Thanks.

MeshBender.cs floating point precision problem with Repeat mode

Hi,
I've encounter some problem these days when I adjust the scale X in repeat mode.

When using curve spcce, If I adjust the (scale X) that
(size of mesh) x (scale X ) x (repetitionCount) ≒ spline.Length
Some meshes would fail with following error message.
Error message like

"Mesh.uv is out of bounds. The supplied array needs to be the same size as the Mesh.vertices array."
"Failed setting triangles. Some indices are referencing out of bounds vertices. IndexCount: X, VertexCount: Y"

It seems that the number of vertices does not match to (source.Mesh.vertices.Count() x repetitionCount)

After some test, I found that the problem is caused by floating point precision problem
The value "distOnSpline" of "distance" will be slight greater than slpine.Length (about 10^06).
And it will cause different problem in non-curve space and curve space setting.

In Non-curve space:

} else {
	float distOnSpline = intervalStart + distance;
	//if (true) { //spline.isLoop) {
		while (distOnSpline > spline.Length) {
			distOnSpline -= spline.Length;
		}
	//} else if (distOnSpline > spline.Length) {
	//    continue;
	//}
	sample = spline.GetSampleAtDistance(distOnSpline);
}

This will make the end of the mesh incorrectly links to the begin of the mesh.

In Curve space:

if (!useSpline) {
	if (distance > curve.Length) 
		continue;
	sample = curve.GetSampleAtDistance(distance);
}

And it will make these vertices skips when adding them into 'bentVertices' after iterations.

bentVertices.Add(sample.GetBent(vert));

I think that's how the vertices number do not meet uv and triangle numbers.

Here's my workaround now, but I think there's some better way.

if (!useSpline)
{
	if (distance > curve.Length)
	{ 
		distance = curve.Length;
	}
	sample = curve.GetSampleAtDistance(distance);
} else {
	float distOnSpline = intervalStart + distance;
	if (distOnSpline > spline.Length + 0.0001f)
	{
		while (distOnSpline > spline.Length)
		{
			distOnSpline -= spline.Length;
		}
	}
	else if (distOnSpline > spline.Length)
		distOnSpline = spline.Length;
	sample = spline.GetSampleAtDistance(distOnSpline);        
}
sampleCache[distance] = sample;

I just brutally add some offset (0.0001f) to avoid floating point precision.
It works for me but there should be some better solutions.

Thanks.

SplineNode should have the property LocalDirection

When I hear "direction" when used to describe a vector, I anticipate an absolute vector pointing in the direction provided by its elements. So with SplineNode.Direction, I failed to realize that it requires a world coordinate.

Rather than changing this entirely and breaking previous code, adding an additional property for the same field, LocalDirection, which subtracts the position of the SplineNode and gives the direction in local space, could be handy. We would still only have one direction field, but two ways of accessing and changing it based on the context.

Snap sower to terrain surface

As commented by philc_uk on the asset store. This could be implemented in the sower or as a separate script.

The code from the comment:

.. 
public bool SnapToSurface = true; 
.. 

Line 110: 
    go.transform.position += binormal;
    if (SnapToSurface) 
    {
        RaycastHit hit = new RaycastHit();
        Physics.Raycast (new Ray (go.transform.position, Vector3.down), out hit);
        if (hit.collider != null) 
        {
            go.transform.position = hit.point;
        }
    }

Manage generated objects of each components without conflict

the generated object life cycle is not perfect. It relies on root instance ID which is a fragile pattern.

We should be able to provide better life cycle management by enforcing unique instance of a generator and by placing each generator on separate children of the spline root object

ExtrusionSegment will never set isDirty to false

The ExtrusionSegment behaviour does set isDirty to true, but doesn't set it to false after computing the vertices. This leads to it computing the segment on every frame, resulting in high CPU usage, and low framerates.

What is the exact purpose of SplineNode.direction?

Hi Benoit, thank you for your great library. I'm wondering if you can explain the purpose of SplineNode.direction in detail. What I'd like to achieve is to avoid "sharp" edges as you can see from the image attached and have the curves point from one SplineNode to the next.

image

[Question] SplineMeshTiling misses deleting some segments.

SplineMeshTiling misses deleting some segments.

Hi,

I 've using this amazing script for weeks and it helps me a lot.
Then found that some segment will not be deleted when switching curve space to non-curve space.

I think it come from the following scripts.

SplineMeshTiling.cs

	// we destroy the unused objects. This is classic pooling to recycle game objects.
	foreach (var go in generated.transform
		.Cast<Transform>()
		.Select(child => child.gameObject).Except(used)) {
		UOUtility.Destroy(go);
	}

Casue the children changes after the during the 'foreach' iteration.
One segment needed to be destroyed will be skiped in every two iteration.

Using backward iteration from the original IEnumerable list.
Or simply add ".ToList()" ,
making it a saved list may solve this problem.

SplineMeshTiling.cs

	// we destroy the unused objects. This is classic pooling to recycle game objects.
	foreach (var go in generated.transform
		.Cast<Transform>()
		.Select(child => child.gameObject).Except(used).ToList()) {
		UOUtility.Destroy(go);
	}

Thanks.

SplineExtruder should allow for removal of collider

I'm currently working on a project where a player can drag a wire between a voltage source and a potential sink for it, using Spline Mesh. It works great so far, except that in initial trials, the SplineExtruder I was using also added a mesh collider to the generated mesh, which I had to comment out in the code to turn off.

I'm hesitant to submit a fix until I fully understand how to use Spline Mesh, but this seems like it would be a great thing to make optional! Maybe with a boolean check box? I really don't need to worry about collisions with it.

Can't rotate any of the nodes...

I can't seem to rotate any of the nodes in the Scene view. Also it's not possible to set the rotation / position values in the Inspector. Unity 2017.3.1
Thanks!

Undo/Redo

While undo/redo is implemented in most editing scenario, the spline is not updated.

This feature must be activated for all node edition, loop/unloop and extrusion shape modification, and should allow content update.

Spline mesh not scriptable?

Hey,

first of all thanks for the asset.
Bu my problem is, that im trying to change scale X of spline mesh tiling via script. Its changing in console, but I can't see the changes in play mode.

Is there something im doing wrong? Help will be much appreciated :)

splineMesh.scale.x += splineMesh.scale.x * Time.deltaTime;
splineMeshProblem

Here you can see, that the scale of x variable has been changed to 2 (was 0.1). But no changes in editor or play mode :/ When X is 2, the spline should have "grown", where number 2 is in picture, but it has stayed in place.

EDIT:
Also when I animate variable X, the value changes in animation, but the spline isn't updating.

error CS0066 in SplineNode.cs

Hi, thank you so much for the great tool and the open source initiative! Great tool.

Sadly, I wasn't able to make it work on Unity 2022.1.5f1 (haven't tested on other versions at the moment)

I get the following error

Assets\SplineMesh\Scripts\Bezier\SplineNode.cs(105,35): error CS0066: 'SplineNode.Changed': event must be of a delegate type

I tried the following patch but to no avail (I'm not very familiar with events and delegates in c#)

https://docs.microsoft.com/en-us/dotnet/csharp/misc/cs0066

public delegate EventHandler();
public event EventHandler Changed;

How to reproduce

  • Import the package SplineMesh using Package manager in Unity 2022.1.5f1
  • Open the show case scene
  • Script SplineNode.cs won't compile (CS0066)

A screenshot of the error if this could help :)
https://pasteboard.co/mN3L28uBbZRz.png

Many thanks!

public event EventHandler Changed;

up vector handle too short

Up vector handle is always 1 unit far from the node. This is unusable if the user work at a large or tiny scale.

The handle should be scaled according to the camera distance, and outside the translation gizmo so it can always be handled

Exact values from inspector

It is often impossible to enter nodes coordinates in the inspector to have precisely placed spline nodes.

Instance SplineMeshTiling to prevent copies overwriting each other

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using UnityEngine;
#if UNITY_EDITOR
using UnityEditor.Experimental.SceneManagement;
#endif

namespace SplineMesh {
///


/// Deform a mesh and place it along a spline, given various parameters.
///
/// This class intend to cover the most common situations of mesh bending. It can be used as-is in your project,
/// or can serve as a source of inspiration to write your own procedural generator.
///

[ExecuteInEditMode]
[SelectionBase]
[DisallowMultipleComponent]
public class SplineMeshTiling : MonoBehaviour {
string _instanceId = "";

    private GameObject generated;
    private Spline spline = null;
    private bool toUpdate = false;

    public bool initOnEnable = false;
    [Tooltip("Mesh to bend along the spline.")]
    public Mesh mesh;
    [Tooltip("Material to apply on the bent mesh.")]
    public Material material;
    [Tooltip("Physic material to apply on the bent mesh.")]
    public PhysicMaterial physicMaterial;
    [Tooltip("Translation to apply on the mesh before bending it.")]
    public Vector3 translation;
    [Tooltip("Rotation to apply on the mesh before bending it.")]
    public Vector3 rotation;
    [Tooltip("Scale to apply on the mesh before bending it.")]
    public Vector3 scale = Vector3.one;

    [Tooltip("If true, a mesh collider will be generated.")]
    public bool generateCollider = true;

    [Tooltip("If true, the mesh will be bent on play mode. If false, the bent mesh will be kept from the editor mode, allowing lighting baking.")]
    public bool updateInPlayMode;

    [Tooltip("If true, a mesh will be placed on each curve of the spline. If false, a single mesh will be placed for the whole spline.")]
    public bool curveSpace = false;

    [Tooltip("The mode to use to fill the choosen interval with the bent mesh.")]
    public MeshBender.FillingMode mode = MeshBender.FillingMode.StretchToInterval;

    private void OnEnable() {
        if (initOnEnable) {
            Init();
        }
    }

    public void Init() {
        if (_instanceId.Length < 1) {
            if (transform.childCount > 0 && transform.GetChild(0).name.Contains(GetType().Name)) {
                string name = transform.GetChild(0).name;
                _instanceId = name.Substring(0, name.IndexOf("_"));
            } else {
                _instanceId = UnityEngine.Random.Range(0, 999999999).ToString();
            }
        }
        // tip : if you name all generated content in the same way, you can easily find all of it
        // at once in the scene view, with a single search.
        string generatedName = _instanceId + "_genBy_" + GetType().Name;
        var generatedTranform = transform.Find(generatedName);
        generated = generatedTranform != null ? generatedTranform.gameObject : UOUtility.Create(generatedName, gameObject);

        spline = GetComponentInParent<Spline>();
        spline.NodeListChanged += (s, e) => toUpdate = true;

        toUpdate = true;
    }

    private void OnValidate() {
        if (spline == null) return;
        toUpdate = true;
    }

    private void Update() {
        // we can prevent the generated content to be updated during playmode to preserve baked data saved in the scene
        if (!updateInPlayMode && Application.isPlaying) return;

        if (toUpdate) {
            toUpdate = false;
            CreateMeshes();
        }
    }

    public void CreateMeshes() {

#if UNITY_EDITOR
// we don't update if we are in prefab mode
if (PrefabStageUtility.GetCurrentPrefabStage() != null) return;
#endif
var used = new List();

        if (curveSpace) {
            int i = 0;
            foreach (var curve in spline.curves) {
                var go = FindOrCreate(_instanceId + "segment " + i++ + " mesh");
                go.GetComponent<MeshBender>().SetInterval(curve);
                go.GetComponent<MeshCollider>().enabled = generateCollider;
                used.Add(go);
            }
        } else {
            var go = FindOrCreate(_instanceId + "segment 1 mesh");
            go.GetComponent<MeshBender>().SetInterval(spline, 0);
            go.GetComponent<MeshCollider>().enabled = generateCollider;
            used.Add(go);
        }

        // we destroy the unused objects. This is classic pooling to recycle game objects.
        foreach (var go in generated.transform
            .Cast<Transform>()
            .Select(child => child.gameObject).Except(used)) {
            UOUtility.Destroy(go);
        }
    }

    private GameObject FindOrCreate(string name) {
        var childTransform = generated.transform.Find(name);
        GameObject res;
        if (childTransform == null) {
            res = UOUtility.Create(name,
                generated,
                typeof(MeshFilter),
                typeof(MeshRenderer),
                typeof(MeshBender),
                typeof(MeshCollider));
            res.isStatic = !updateInPlayMode;
        } else {
            res = childTransform.gameObject;
        }
        res.GetComponent<MeshRenderer>().material = material;
        res.GetComponent<MeshCollider>().material = physicMaterial;
        MeshBender mb = res.GetComponent<MeshBender>();
        mb.Source = SourceMesh.Build(mesh)
            .Translate(translation)
            .Rotate(Quaternion.Euler(rotation))
            .Scale(scale);
        mb.Mode = mode;
        return res;
    }
}

}

Editor code preventing compilation to standalone player

the SplineEditor.cs and SplineExtrusionEditor.cs are editor related code that prevent compilation to standalone player.

I have added #if UNITY_EDITOR and #endif and it seems to works.
It may be good idea to add it to here also?

MeshBender would be able to work with an interval on the spline

Currently, MeshBender apply a mesh on a curve, regardless of the scale of the mesh. To create a railroad, for example, you have to insure each curve has exactly the same length, which is impossible to do and absurd.

MeshBender would allow to bend a mesh on a given spline interval instead of a curve. It would also allow to specify the number of time the mesh has to be placed, or the scale along spline.

can't edit node values in the inspector

when trying to input in or drag the individual node fields, the value seems to change for about 1 frame (visible only in the spline/extrusion shape, not in the actual field), before reverting back to default immediately. editing direction/position/up vector using the handles works as expected.

i dug around in the code a bit but could not find the cause. i put a debug line in one of the property setters and it looks like it's being called correctly when editing the value, but not when it reverts back to default, which might point to a problem with serialization?

using unity 2018.3.14f1 on windows 10 (x64), tried with both the asset store version and the code in this repository.

thank you!

Use a namespace!!

In the name of sweet baby Jesus will you PLEASE use a namespace for your code! This is especially important if you have such generic class names like "Tool", "Vertex", and "Spline". I value my sanity. Thanks!

Weird issue with gitignore in fork

Forked, cloned, opened in unity, now fork is polluted with tracked Library files, that for some reason get into git despite being blocked by gitignore, do you happen to know what causes it?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.