Search Unity

SplineMesh, the plugin to create curved content

Discussion in 'Assets and Asset Store' started by methusalah999, Dec 14, 2017.

  1. IkeaGuy

    IkeaGuy

    Joined:
    Jul 22, 2020
    Posts:
    2
    Hello! Just installed the asset and it seems really great!
    But I have a few questions:
    Is it possible to select multiple nodes at once? Its really annoying to have to move each node by itself.
    And can you make it so that the spline gizmos doesn't disappear when you deselect a spline. To not constantly have to reselect the spline when you accidentally click somewhere else would be nice. ;)

    And my last question is if it's possible to place different meshes along different parts of the spline.

    Other than that this asset seems great! :D
     
  2. methusalah999

    methusalah999

    Joined:
    May 22, 2017
    Posts:
    643
    It is not possible to select multiple nodes at a time, but it seems usefull and should not be a big deal to implement.

    It is not possible to draw the spline gizmos if the game object is not selected, and it seems like a bad practice. Maybe we could add a slider to change the handles' size to avoid miss clicks instead?

    Placing different meshes along the spline is definitly possible with SplineMesh. There is a built in script in the asset called ExampleTrack that does just that (it's not featured in the showcase scene, though). It allows to place different meshes on each curve, but you can also place different meshes wherever you need with your own script. Just duplkicate ExampleTrack and change it to your taste.

    I'm sorry to say that I don't work actively on this asset anymore, and I only try and provide support. That said, the asset is open-source and I study carefully any contributions and pull request on github. So don't hesitate to push your code if you implement something usefull!

    Have fun bending things !

    ExampleTrack in action:
    track.jpg
     
  3. plippuner

    plippuner

    Joined:
    May 16, 2018
    Posts:
    6
    Hey methusalah999

    Thanks for your answer. We figured out, how to use GetProjectionSample for our use case!

    Code (CSharp):
    1. // Get Player Position relative to spline origin (using transform.InverseTransformPoint()
    2. CurveSample sample = spline.GetProjectionSample(transform.InverseTransformPoint(player.position));
    3. // Sync pointer (for example a simple sphere or the player itslef) to the nearest point on spline
    4. pointer.position = transform.TransformPoint(sample.location);
    The strange behaviour of the sphere was due to us using world position logic instead of a converted local to world position logic.

    Thank you very much!
     
    methusalah999 likes this.
  4. IkeaGuy

    IkeaGuy

    Joined:
    Jul 22, 2020
    Posts:
    2
    Thank you for the quick reply!
    I just wan't to say that I still find this to be a really good asset, and an amazing asset considering that it's free!
     
    methusalah999 likes this.
  5. angrypenguin

    angrypenguin

    Joined:
    Dec 29, 2011
    Posts:
    15,620
    Hi @methusalah999, I'm trying out SplineMesh for something and it's mostly groovy. I'm integrating it into an existing custom workflow. Pre-defined paths need some geometry made along them.

    I've added a Spline and a SplineMeshTiling to the relevant prefab, and another script uses AddNode to populate the node list, set positions and control points and so on, and that's all working great.

    What I haven't figured out is how to get the mesh to re-generate in the Editor as we make changes to stuff. Right now I change the path data, then navigate to the SplineMeshTiling component and change any variable to make it update. I want to kick off an update in code. I tried calling SplineMeshTiling.CreateMeshes() after making changes, but the mesh just stays how it was. As far as I can tell the Spline itself will be updated from its internal message passing.

    What am I missing?

    Thanks for the library, by the way!

    Edit: Ok, it's not even updating when I update the Spline by directly moving its own handles. It seems to only ever update when I re-select the SplineMeshTiling component and change something there.

    Edit 2: I've found a workaround, which is to find the MeshBender and call Compute() on it. My guess is that isDirty isn't getting set reliably.

    For what it's worth, where you've got stuff like...
    Code (csharp):
    1. if (!updateInPlayMode && Application.isPlaying)
    2. {
    3.     return;
    4. }
    ... it'd be a good idea to also put "enabled = false;", as that'll stop Update() getting called on that component in the future. You could probably even just do that in Start() or Awake().

    When using event based stuff as you are, my general model is to set "enabled = true;" whenever I respond to an event that might require changes, and "enabled = false;" when I've finished updating to account for them.
     
    Last edited: Sep 21, 2020
  6. angrypenguin

    angrypenguin

    Joined:
    Dec 29, 2011
    Posts:
    15,620
    Here's a slightly updated copy of SplineMesh for anyone who'd like it. This one remembers what tool you last used, and turns it back on when the Editor is disabled (ie: another object is selected) to make working in the Scene view a little nicer.

    Edit: Must have missed something, though, as it doesn't seem especially reliable.
     

    Attached Files:

    Last edited: Sep 21, 2020
  7. methusalah999

    methusalah999

    Joined:
    May 22, 2017
    Posts:
    643
    As you noticed, SplineMesh relies on the listener pattern to update the bent content. Whenever you change the list of node, or a property of a node, an event is raised and the relevent part only is updated. You don't have to call any update or recompute method.

    This occurs both during edit mode and play mode, but if you use SplineMeshTiling, you have to check "update in play mode". This option is only used to prevent the generated content to be re-created when the game start, to preserve baked lighting.

    If the content is not updating correctly, it may be due to the static batching (Unity merging the meshes together before the game strats for optimization purposes). Please try to deactivate it in project settings -> player -> other. static batching effect can be observed in any of the generated bent element, in the MeshFilter component, your mesh is no more "generated mesh" but something created by Unity.
     
  8. Sawrig

    Sawrig

    Joined:
    May 28, 2020
    Posts:
    2
    Howdy!

    Newbie here, just looking for help. I've imported Spline Mesh and I'm getting these errors. Any ideas?
    Really appreciate any help you could offer. Excited to use this like mad for a ball rolling mechanic.

    Can't believe you're offering this out of the good of your heart too. Damn!

    Thanks
    upload_2020-9-23_12-24-48.png
     
  9. Sawrig

    Sawrig

    Joined:
    May 28, 2020
    Posts:
    2
    Probably should Note I'm using Unity 2019.4.1f1 if that helps in anyway!
     
  10. methusalah999

    methusalah999

    Joined:
    May 22, 2017
    Posts:
    643
    That's the first time I hear about that. My best guess is that the LINQ package is not installed correctly in you Visual Studio, or maybe very outdated. Both scenario are very unlikely, though, as LINQ is installed by default in most VS configurations.

    Can you try opening Visual Studio Installer, check that you have the Unity integration installed and update things. Also maybe go with a fresh Unity install?

    Please tell me if that does not solve the issue.
     
  11. Kamil1988

    Kamil1988

    Joined:
    Sep 20, 2020
    Posts:
    1
    Hello everyone,
    I am about to make a puzzle game with transparent pipes and a waterjet.
    The pipes can be rotated and have splines on them. I want to let a very long cylinder with a watershader follow the splines.
    It's not a problem with just one spline, but how can I connect multiple splines with each other using script?

    My first Idea was to add a collider at the beginning and end of each spline and change the spline in the followerscript of the waterjet to the next spline it touches. The problem is that the origin of the waterjet has to be in shape of all splines/pipes even if its changing to another spline.

    Therefore I would like to have a spline created via script.
    I would like to add a collider on the end of my first spline and colliders on each start of the splines on my pipe gameobjects. On my first spline should be a script with a method to generate or lets say to extand my first spline.
    Somethink like:

    Code (CSharp):
    1. void Spline firstSpline;
    2.  
    3. void OnTriggerEnter(Collider other)
    4. {
    5. //add nodes from other to the end of firstSpline
    6. //set the collider position to the new end and let it collide with the next spline to repeat OnTriggerEnter (untill there is no further spline)
    7. }
    I digged into the example scenes and this forum and found some code lines that could help. But my scripting skills are limited and i dont know how to use that code. Is there a documentation about all the methodes, properties and parameters for this asset?
    I would also be very grateful if someone could help me out with a few lines of code to get the node information from other and add them to firstSpline.
     
  12. methusalah999

    methusalah999

    Joined:
    May 22, 2017
    Posts:
    643
    when your water go forward into the spline, you are using the spline time or distance one way or another. So, you can detect when you arrive at the spline end, because time become greater than 1, or distance becomes greater that spline length.

    Therefore, colliders seem useless, as well as adding nodes to the spline. Just expand your water until you reach the end of the spline "n", and then start expanding the water mesh on the spline "n+1".

    Now in SplineMesh, there is no native way to connect splines with each other. You will have to add some script to save this linking information. Here is some pseudo-code.
    Code (CSharp):
    1. watterDistance += watterSpeed * Time.DeltaTime;
    2. ExpandWatter(watterDistance);
    3. if (watterDistance >= spline.Length){
    4.     // watter has reached the end of the spline
    5.     var nextSpline = GetComponent<SplineLink>().next;
    6.    
    7.     var watterOffset = watterDistance - splineLength;
    8.     nextSpline.startWatterCirculation(watterOffset);
    9. }
    Don't hesitate to ask more detailled questions.
     
  13. knas01

    knas01

    Joined:
    Feb 24, 2018
    Posts:
    236
    Hi, I'm trying to tile and bend a mesh to create cables but I have some issues making it look good. I have several meshes in the same fbx so their pivot is a bit off. I don't know if this is the problem but you can see how it's deformed. Changing the individual values for the points is very hard since they don't update in realtime and changing the smoothness doesn't help much either. It's very finicky to make it look good. Any suggestions?
     

    Attached Files:

  14. methusalah999

    methusalah999

    Joined:
    May 22, 2017
    Posts:
    643
    You can solve this issue by changing the transform of the mesh in splinemeshtiling component. The translation, rotation and scale are applied to the original mesh before it is prepared for bending.
     
  15. knas01

    knas01

    Joined:
    Feb 24, 2018
    Posts:
    236
    Ah, that's how it works. Now it's fine. Thanks.
     
    methusalah999 likes this.
  16. Spectra_7

    Spectra_7

    Joined:
    Oct 17, 2017
    Posts:
    33
    Hello. First of all great asset!

    Sorry if this question is already answered, but how do I update the mesh deform in runtime by moving its nodes?
    I just want to click and drag the nodes when playing the game.

    Whenever in play mode I select a node and move it around, the mesh doesn't get updated and stays there. I have also set Update In Play Mode to true.
     
  17. methusalah999

    methusalah999

    Joined:
    May 22, 2017
    Posts:
    643
    It should work out of the box, but Unity is batching your meshes before play and then SplineMesh can't change it. To see if batching is the problem, you can go into project settings => player => other and uncheck static batching.
     
    Spectra_7 likes this.
  18. Spectra_7

    Spectra_7

    Joined:
    Oct 17, 2017
    Posts:
    33
    Yup, disabling Static Batching solved the problem. Thanks a lot.
     
    methusalah999 likes this.
  19. gewl

    gewl

    Joined:
    May 19, 2016
    Posts:
    95
    I have not changed anything in SplineMesh code. I have tried with a fresh install of the latest version. When the samples array is not null, it logs as an array filled with CurveSamples; otherwise, it logs as null.
     
  20. kosirmilan

    kosirmilan

    Joined:
    Oct 6, 2020
    Posts:
    1
    Congrats! This looks amazing! Can't wait to work with this. Is it maybe possible to use it in VR also?
     
  21. methusalah999

    methusalah999

    Joined:
    May 22, 2017
    Posts:
    643
    SplineMesh is compatible with all Unity versions, all platforms, all render pipelines, everything ^^
     
  22. methusalah999

    methusalah999

    Joined:
    May 22, 2017
    Posts:
    643
    I'm sorry I can't reproduce your bug. Do you get the issue in the showcase scene? and on every spline?

    If so I don't know how to reproduce and help.
     
  23. knas01

    knas01

    Joined:
    Feb 24, 2018
    Posts:
    236
    Hi, I'm using the mesh tiling script with mesh smoothing and I'm wondering how many of those you can use performance vice? Do these scripts cost anything if they are not changed during play?
     
  24. methusalah999

    methusalah999

    Joined:
    May 22, 2017
    Posts:
    643
    The cost will mostly depend on the number of vertices in the mesh, and no, only the individual meshes that must be re-bent will cost something during playtime.
     
  25. knas01

    knas01

    Joined:
    Feb 24, 2018
    Posts:
    236
    methusalah999 likes this.
  26. AndrewCzarnietzki

    AndrewCzarnietzki

    Joined:
    Jul 23, 2013
    Posts:
    189
    Very nice quality splines! I really want to use this tool :D

    The only problem is I can't seem to click on the handles? I can't rotate or duplicate anything. This is in 2020.1.8f1. Fairly vanilla version of Unity, so not sure what's missing. Any assistance?

    Thanks!
     
  27. AndrewCzarnietzki

    AndrewCzarnietzki

    Joined:
    Jul 23, 2013
    Posts:
    189
    I'm using URP. I tried turning off AA as I know there's been some select-in-viewport issues there. I have the same issue if game view is present or not. The splines seem to update fine when I use the lateral transformation, but I can't rotate or click on handles, insert or add other nodes, etc.

    This includes a brand new spline or trying to modify the example assets.

    While I have a spline selected, I can no longer use the rotation or scale gizmos--which is fine, but I'm not seeing any other way to rotate a node other than to use its red handles.
     
  28. methusalah999

    methusalah999

    Joined:
    May 22, 2017
    Posts:
    643
    You are right to say that you can't move or rotate the nodes when a spline object is selected. The standard gizmos are hidden and the spline can only be moved by the dedicated SplineMesh gizmos.

    Do you actually see the spline gizmo itself and the node handles (white curved line with white squares along it)? In a normal situation, you can click on the white squares to select a node, then the square is replaced by a translation gizmo and the red direction handle appear for this node.

    I don't know of any issue with SplineMesh using 2020, though I haven't tested your specific version. Can you please ensure that you have only one inspector window open? to be sure, can you change your Unity layout to the default one?
     
  29. AndrewCzarnietzki

    AndrewCzarnietzki

    Joined:
    Jul 23, 2013
    Posts:
    189
    Hmm, looks like this might be a case of "have you tried turning it off and on again?". I can now click on the handles and move them to rotate nodes as I'd expect--which makes this tool usable :)

    Not sure why I had to restart Unity to get it to work, but I've seen Unity do weirder things...

    Alt still doesn't work (it enters a camera mode?), but I'm not sure that's a feature I particularly want either. Pardon the false alarm and thanks for the quick response and excellent tool!
     
    methusalah999 likes this.
  30. plippuner

    plippuner

    Joined:
    May 16, 2018
    Posts:
    6
    I had the same Issue like AndrewCzarnietzki, and the solution was to reset Unity to the standard layout. Afterwards all handles were visible again.
     
  31. methusalah999

    methusalah999

    Joined:
    May 22, 2017
    Posts:
    643
    Thanks for the info, something must be wrong in the SplineEditor, I will try to look into it. If you can identify what was causing the issue in your previous layout, I'm interested to know it!
     
    Last edited: Oct 21, 2020
  32. plippuner

    plippuner

    Joined:
    May 16, 2018
    Posts:
    6
    Also, Alt doesn't work for me neither. Maybe it has something to do with different Keyboard-Layouts or Keyboard-Types? I for example use a Swiss Keyboard Layout.

    On another note: I'm trying to update 2 SplineMeshTiling Splines at the same time in Play Mode. If I have only one Spline GameObject active, it works just fine, but if I have both active simultaneaously, it stops working. The gizmos draw at the right place, but the mesh stops updating. Is this a known issue or limitation?

    Cheers
     
  33. methusalah999

    methusalah999

    Joined:
    May 22, 2017
    Posts:
    643
    Please try to deactivate de static batching in player settings.
     
  34. julesradu

    julesradu

    Joined:
    Nov 9, 2017
    Posts:
    6
    Hi, I am trying this in Unity 2019.4 but I can't see any way of editing the splines. Here's how it looks after I create a new Spline object - there are no handles to manipulate; when I select any of the demo splines, I don't have any handles there either. I restarted Unity; all the default Gizmos seem enabled; static batching makes no difference. What's wrong ? Thanks.

    upload_2020-10-22_11-55-24.png
     
  35. methusalah999

    methusalah999

    Joined:
    May 22, 2017
    Posts:
    643
    Does it work on the examples? Can you try and get the camera far too see if the spline is elsewhere? Can you please try to use the default layout (it seems to be the case already)

    Thanks
     
  36. julesradu

    julesradu

    Joined:
    Nov 9, 2017
    Posts:
    6
    Thank you it's fixed !! The problem was the layout - I switched to default layout and it was fixed.
    It would be good to know what specifically was the problem.
    I think the Gizmos were disabled in my layout but not sure.
     
    methusalah999 likes this.
  37. GrandahlD

    GrandahlD

    Joined:
    Jul 26, 2012
    Posts:
    3
    I'm so glad I found this package, I'll definitely be picking up the paid asset. I'd like to run an issue by you before I go too much further:

    At some point during runtime in my infinite-runner I need to translate all the splines in my scene back towards the origin so we don't get too far away and cause floating point issues. It looks like spline nodes are in World Space, so simply translating the spline gameobject backwards doesn't do much.

    Would you recommend I
    A) Manually translate each node,
    B) Convert the Spline code into localspace coordinates or
    C) Something else entirely :)

    I appreciate any suggestions or advice you have for me!
     
  38. methusalah999

    methusalah999

    Joined:
    May 22, 2017
    Posts:
    643
    It is possible to change the transform of the spline object. All the generated content will be translated with it as normal and nodes won't update. But you will eventually have some floating point errors if you translate it too far away.

    Translating nodes is the good solution in most situations. The only issue with this is that it will cause all nodes to update the curved content at once and that may lead to a lag. Beware, you may feel like it is not a issue at soem stage, but things could get worse when you add more detailled mesh or more props to bend.

    If/when the lag becomes noticeable, the solution is too avoid too much content to be updated during a single frame. A common way is to move the nodes one after the other using a coroutine or multiple frames, or you can maybe implement a solution where the nodes are being moved backward on a regular basis, one at a time, for example when the player reach the begining of the next curve.

    Hope it helps, have fun bending things !
     
  39. a_galloway

    a_galloway

    Joined:
    Apr 22, 2018
    Posts:
    4
    I was wondering if there was specific settings to use for Baked indirect lighting in HDRP? It seems even if I generate lightmap UVs for the meshes that are with the spline, they have issues baking. Would I need to separate the mesh from the spline and make it into it's own prefab to bake it?

    Example of the issue: https://drive.google.com/file/d/1J9pn12uq5LYTTqL6JVZT0awMhn49wSV_/view?usp=sharing

    Thank you for your time.
     
  40. methusalah999

    methusalah999

    Joined:
    May 22, 2017
    Posts:
    643
    UV should be ok as is. If your meshes have very different scale due to ellongated curves, you may have some variation in the baked light precision, but it would most likely be unnoticeable.

    Note that I've accepted a ^pull request some while ago on the subject, and that I haven't tested it much. if you are in a repeat fill mode you can try and revert that code change to see if it solves your issue. It is located in MeshBender.cs, line 235 or so. Just comment the foreach and uncomment the original lines.
    upload_2020-10-24_22-51-37.png
     
  41. a_galloway

    a_galloway

    Joined:
    Apr 22, 2018
    Posts:
    4
    Hi, sorry for the late reply, I couldn't find that code on that line in that script on the most recent version. This is what I have: https://gyazo.com/dbeac1feae20a970146029c4d017d395

    To give more context, it looks like the lightmaps are being baked but just repeating the same along the spline mesh, I'm on repeat fill mode also.
     
  42. methusalah999

    methusalah999

    Joined:
    May 22, 2017
    Posts:
    643
    Ok it seems that this modification has never make it to the asset store and I only have it on my computer. If you have the patience, could you please test it for me and tell me if it works on your side? The idea is to simply replace the all for loop that you have pasted in your screenshot, at line 228, by this one:
    Code (CSharp):
    1.             float uvStep = 1.0f / repetitionCount;
    2.             for (int i = 0; i < repetitionCount; i++) {
    3.                 foreach (var index in source.Triangles) {
    4.                     triangles.Add(index + source.Vertices.Count * i);
    5.                 }
    6.                 uv.AddRange(source.Mesh.uv);
    7.  
    8.                 //uv2.AddRange(source.Mesh.uv2);
    9.                 //uv3.AddRange(source.Mesh.uv3);
    10.                 foreach (var _uv in source.Mesh.uv) {
    11.                     // scaling uv2 and uv3 for baked and realtime lightmaps
    12.                     var scaledU = _uv.x * uvStep + i * uvStep;
    13.                     uv2.Add(new Vector2(scaledU, _uv.y));
    14.                     uv3.Add(new Vector2(scaledU, _uv.y));
    15.                 }
    16.                 uv4.AddRange(source.Mesh.uv4);
    17. #if UNITY_2018_2_OR_NEWER
    18.                 uv5.AddRange(source.Mesh.uv5);
    19.                 uv6.AddRange(source.Mesh.uv6);
    20.                 uv7.AddRange(source.Mesh.uv7);
    21.                 uv8.AddRange(source.Mesh.uv8);
    22. #endif
    23.             }
    Long story short, this will offset the UV of each repeated mesh so they use different parts of the light map.

    As I said, I've not tested it much. I have not had any issue with this method but it may cause the lighting information to overlap with other objects in the scene.

    If that does not work, you can try to use the method
    Unwrapping.GenerateSecondaryUVSet(result);
    instead at the end of the method, after the last line
    MeshUtility.Update(...);


    I'm interested in any feedback!
     
  43. a_galloway

    a_galloway

    Joined:
    Apr 22, 2018
    Posts:
    4
    Hi, that first piece of code did the trick!, lightmaps seem to be baking as they should. Thanks so much for the quick support and fix!
     
    methusalah999 likes this.
  44. zagreekie

    zagreekie

    Joined:
    Nov 20, 2017
    Posts:
    29
    I was wondering is there any convenient way to mix LODs into the splines? for example, I wanted to use splines to make quite a few wires and tubes, in the environment for a side on colony builder style game. however, I fear when the player zooms out more the polycount will get a bit ridiculous.
     
  45. methusalah999

    methusalah999

    Joined:
    May 22, 2017
    Posts:
    643
    You can bend multiple meshes on a single spline, by adding multiple time a bending script like the SplineMeshTiling one.

    Then it is maybe possible to update a LODGroup by settings the generated mesh renderer into the correct LOD. I've never made that through script, though.

    You can also simply activate or deactivate the different versions of your bending scripts, depending on the camera altitude or distance, and have them activate or deactivate their generated objects accordingly.
     
  46. zagreekie

    zagreekie

    Joined:
    Nov 20, 2017
    Posts:
    29
    Good idea, thanks!

    your asset is truly awesome thank you for making it. here is a heart made of splines for you. upload_2020-11-4_12-5-39.png

    p.s. Is there a way I could bake this into a solid mesh to rig/animate it? I saw that you do support real-time modification of the splines so I could just animate some scale changes. however at least in your demo that seemed fairly processor expensive(I think?).

    p.s.s. also if I could somehow combine the meshes I could generate far cheaper colliders for it.
     
    Last edited: Nov 4, 2020
    methusalah999 likes this.
  47. methusalah999

    methusalah999

    Joined:
    May 22, 2017
    Posts:
    643
    Bending meshes is doable in realtime and the cost depends almost only on the vertex count. SplineMesh is fast, but you will have to test it to be sure it fits into your CPU budget.

    SplineMesh does not allow to save a mesh as an asset, but it is pretty straitforward in the Unity Editor :
    Code (CSharp):
    1. foreach(generated mesh)
    2. {
    3.     AssetDatabase.CreateAsset(generated mesh, path in assets);
    4.     AssetDatabase.SaveAssets();
    5. }
    Combine meshes is also not a big deal. You just have to create a new mesh with a concactenation of the vertices, normals, uvs1, 2, 3... You also have to concatenate indices but you will have to offset them first, so they indicate the new position of the vertices in the array. It is maybe possible to use sub-meshes for a simpler solution.

    A word about the collider though, it is often better to place primitive colliders along the spline, than to compute a mesh collider from the bent mesh. Ten thousands of sphere colliders may still be way faster than a mesh collider.
     
  48. zagreekie

    zagreekie

    Joined:
    Nov 20, 2017
    Posts:
    29
    Awesome thank you!

    last question, I was looking into animating splines but noticed that node location/scale is not visible to the unity animator. is there a reason for that? or just no one needed to animate them up until now.
     
  49. methusalah999

    methusalah999

    Joined:
    May 22, 2017
    Posts:
    643
    location/rotation/scale are not using a Transform component because they are part of a property system that is observed by SplineMesh. This systeme ensure that SplineMesh will always update when something changes, and only the very thing that has changed.

    To animate, you will have to add a dummy gameobjects for each spline node, with a simple script updating the node's location/rotation/scale each frame, according to the dummy's Transform (in lateUpdate, after the animation occurs). You can then animate these gameobjects as normal.
     
    zagreekie likes this.
  50. zagreekie

    zagreekie

    Joined:
    Nov 20, 2017
    Posts:
    29
    thanks so much for all the help :)
     
    methusalah999 likes this.