Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Guide to custom placing stuff on spline
#13
While CurvyGenerator is no doubt optimized, I'm starting to think I'd either need to use the job system on multiple meshes at once on parallel, or use a compute shader.

Would you possibly have ideas on how I can prepare the spline data for something like that?

I already got my own custom curving working but its rather brute force and slow. I'm thinking this is in part why you rasterize the spline and also generate spots. 
I assume rasterizing the spline just pre-caches points in a way thats easy for generation, and generating spots pre-allocates the locations (or transform positions) to spawn stuff.


My idea is either

A) lock the spline angles to only support specific angles (like 10) then build a cache dictionary for each mesh of all possible rotation types and grab from there (instead of generating new ones every frame
B) use jobs to deform the meshes in parallel
C) use a compute shader 

//Generator
private void GenerateInstances()
{
    var depth = _depth = wallCurvePrefab.SourceBounds.size.z;
    var splineDistance = _splineDistance = curvySpline.TFToDistance(1f);
    var placeableDistance = _placeableDistance = Mathf.Max(splineDistance - depth, 0f);
    var totalPlaceableWalls = _placeableWalls = Mathf.CeilToInt(placeableDistance / depth);
    var emptySpace = placeableDistance - totalPlaceableWalls;
    var padding = _padding = emptySpace / 2f;
    var paddingOffset = padding / 2f;

    var depthModifiedScale = 1f + padding;
   
    var distanceOnSpline = 1f;

    for (var i = 0; i < totalPlaceableWalls; i++)
    {
        var wall = GetWallFromPool();

        if (i == 0 || i == totalPlaceableWalls - 1)
        {
            var scale = wall.CachedTransform.localScale;
            scale.
z = depthModifiedScale;
            wall.
transform.localScale = scale;
        }
        else
        {
            wall.
transform.localScale = Vector3.one;
        }

        if (i == 0)
        {
            distanceOnSpline += paddingOffset;
        }
        else
        {
            distanceOnSpline += (depth * wall.
ScaleZ + depth * _wallCurveInstances[i - 1].ScaleZ) / 2f;
        }

        var tf = curvySpline.DistanceToTF(distanceOnSpline);
        curvySpline.InterpolateAndGetTangentFast(tf, out var position, out var tangent, Space.World);

        wall.transform.SetPositionAndRotation(position, Quaternion.LookRotation(tangent));
        if (curveMeshes) wall.CurveMesh(curvySpline, tangent, distanceOnSpline, dontCreateNewMeshIfPossible);
    }
}


//CurveDeformation
[Button]
public void CurveMesh(CurvySpline curvySpline, Vector3 mir, float distanceOnSpline,
    bool dontCreateNewMeshIfPossible)
{
    if (!IsSetup) return;

    ResetMesh();

    var copiedVertices = new Vector3[_originalVertices.Length];
    // var mesh =sourceMesh;
    var bounds = SourceBounds;
    var depth = bounds.size.z * ScaleZ;
    var halfDepth = depth / 2f;

    var startingTangent = Vector3.zero;
    _isCurved = false;
    for (var i = 0; i < _originalVertices.Length; i++)
    {
        var vertex = _originalVertices[i];
        var zDistance = GetVertexZDistance(vertex);
        var startTf = curvySpline.DistanceToTF(distanceOnSpline - halfDepth);
        var endTf = curvySpline.DistanceToTF(distanceOnSpline + halfDepth);
        _startPosition = curvySpline.InterpolateFast(startTf, Space.World);
        _endPosition = curvySpline.InterpolateFast(endTf, Space.World);
        var tf = curvySpline.DistanceToTF(distanceOnSpline + depth * (zDistance - 0.5f));
        curvySpline.
InterpolateAndGetTangentFast(tf, out var position, out var tangent, Space.World);
        if (i == 0)
        {
            startingTangent = tangent;
        }

        _isCurved = startingTangent != tangent;

        var normal = -Vector3.Cross(tangent, Vector3.up).normalized;
        var newVertexPosition = normal * vertex.x + position + vertex.y * Vector3.up;
        newVertexPosition =
transform.InverseTransformPoint(newVertexPosition);
        copiedVertices[i] = newVertexPosition;
    }

    if (dontCreateNewMeshIfPossible)
    {
        if (!_isCurved) return;

    }

    meshFilter.sharedMesh = CloneMesh(sourceMesh);
    var mesh = meshFilter.sharedMesh;
    mesh.
vertices = copiedVertices;
    mesh.
RecalculateBounds();
    mesh.
RecalculateNormals();
}

private float GetVertexZDistance(Vector3 vertex)
{
    var bounds = sourceMesh.bounds;
    return (vertex.z - bounds.min.z) / bounds.size.z;
}
Reply


Messages In This Thread
RE: Guide to custom placing stuff on spline - by Lupos - 11-23-2023, 02:41 AM

Possibly Related Threads…
Thread Author Replies Views Last Post
  How to get length starting from one spline to connected nth spline Dragon-3623 1 1 05-14-2024, 04:52 PM
Last Post: _Aka_
  Curvy Line Renderer for UI Spline? gekido 3 6 04-04-2024, 12:56 PM
Last Post: _Aka_
  Get position of all control points for a spline gekido 1 6 03-28-2024, 10:08 PM
Last Post: _Aka_
Bug Changing spline connection in inspector causes splines to revert to defaults lacota 3 6 03-18-2024, 07:55 PM
Last Post: _Aka_

Forum Jump: