Not signed in (Sign In)

Discussion Tag Cloud

Categories

Vanilla 1.1.9 is a product of Lussumo. More Information: Documentation, Community Support.

    • CommentAuthorole
    • CommentTimeOct 17th 2014 edited
     
    I have seen some people using invisible (wireframe) trains in order to orient objects to a track.

    For example when you want to create custom crossties. One method would be to create an invisible track with lots of trains and lots of cars on them and then have a script that detects the nearest train of a scene object and use the bogie matrix to orient the scene object.

    Forget about that technique. Here is something better, that does not require invisible trains. It does not even require an additional invisible track.

    All you need to do is to use the Simulator.findNearestCoasterTrack method that returns a TrackPos instance. This is a way overlooked feature. It was in there since the first release of NL2 and that technique can be used for all kinds of effects and custom rides such as water flumes that work completely without any invisible cars. Here is an Example:


    import nlvm.math3d.*;
    import com.nolimitscoaster.*;

    public class OrientToRail extends Script
    {
    public bool onInit()
    {
    SceneObject sco = sim.getSceneObjectForEntityId(getParentEntityId());
    if (sco == null)
    {
    System.err.println("Not a scene object");
    return false;
    }

    Vector3f pos = new Vector3f(0,0,0);
    sco.getTranslation(pos);
    TrackPos trackPos = sim.findNearestCoasterTrack(pos, 10);
    if (trackPos == null)
    {
    System.err.println("No track found within range");
    return false;
    }

    Matrix4x4f m = trackPos.getCenterRailsMatrix();
    sco.setMatrix(m);

    // return false to indicate that the script can stop now. There is nothing more to do.
    return false;
    }
    }


    Attach that script to a scene object and then put the scene object close to a track. See the magic happen then in play mode.

    The only downside of this technique is that it will by quite slow if you have lots of crosstie scene objects, the engine will start one script for each instance. If you have hundreds of crossties, you might want to optimize things. E.g. put multiple crossties in one SCO and then change the script so that it will orient multiple elements instead of the whole scene object. The TrackPos class has a method to offset the position along the track. By offsetting the position along the track, you can follow the track similiar to what the bogie will do when it runs on the track.
    • CommentAuthorsolomon123
    • CommentTimeOct 17th 2014
     
    Finaly!!!
    Vekoma track here I come.;-)
  1.  
    Fantastic. Crossties coming to coast raider, finally =)

    edit:
    • CommentAuthorAlbo85
    • CommentTimeOct 17th 2014
     
    Can't wait to try this method!
    @secretimbecile wow your screenshot looks amazing! It's gonna be another epic ride!!!
  2.  
    THANK. YOU. SO MUCH.

    Could I please use this in a tutorial?

    Also, is there any way to duplicate sco objects inside a script?
    • CommentAuthorole
    • CommentTimeOct 18th 2014 edited
     
    Sure you can use this in a tutorial.

    I did a small change. The onInit method now returns with false. There is no onNextFrame method required because there is nothing more to do than to orient the object, so the onInit method can return false. Returning false will quit this script. When having lots of crossties, this can speed things up dramatically while running the simulation.

    By returning false, the drawback of lots of running scripts will be prevented. Loading time will still be very slow though.

    No, there is no way to duplicate sco objects. There is a solution If you want to auto-assign objects following a track. You need to create a pool of sco instances inside the editor and you need to give them names with increasing numbers. E.g. "crosstie0", "crosstie1"... A script can then access the sco objects using sim.getSceneObject(name). Be sure to add this script to a coaster instead of a scene object.
    •  
      CommentAuthorPhyter
    • CommentTimeOct 18th 2014 edited
     
    Here's a version that uses a single .3DS file containing as many tie objects as you need. The tie objects in the .3DS file are referenced by index so they don't need to be named anything special.


    import nlvm.math3d.*;
    import com.nolimitscoaster.*;

    public class OrientToRail extends Script
    {
    public bool onInit()
    {
    SceneObject sco = sim.getSceneObjectForEntityId(getParentEntityId());
    if (sco == null)
    {
    System.err.println("Not a scene object");
    return false;
    }

    int count = sco.getElementCount();
    SceneObjectElement[] elem = new SceneObjectElement[count];

    for(int i=0; i<count; i++)
    {
    elem[i] = sco.getElementAt(i);
    }

    Vector3f pos = new Vector3f(0,0,0);
    sco.getTranslation(pos);
    TrackPos trackPos = sim.findNearestCoasterTrack(pos, 10);
    if (trackPos == null)
    {
    System.err.println("No track found within range");
    return false;
    }

    Matrix4x4f scom = sco.getMatrix();
    scom.invert();

    for(int i=0; i<count; i++)
    {
    float offset = i*2.0f; // change this value to adjust the distance between ties.

    Matrix4x4f m = trackPos.getTrackPosOnCenterRailsWithOffset(offset).getCenterRailsMatrix();
    m.multLeft(scom);

    elem[i].setMatrix(m);
    }

    // return false to indicate that the script can stop now. There is nothing more to do.
    return false;
    }
    }
  3.  
    I tried it and this happened:
    • CommentAuthorole
    • CommentTimeOct 24th 2014
     
    Cool, seems like it is working.
  4.  
    Its meant to follow the course of that coaster waaaaay down there
    • CommentAuthorole
    • CommentTimeOct 24th 2014
     
    Ah okay. Do you use Phyters or my script? I cannot help much unless you provide more info about what exactly you were doing and planned to do. Seems like you either have a typo in the script or th elements in the 3ds are linked or are not at the origin or something.
  5.  
    Phyters, I haven't touched the script and the crosstie model is in sketchup around the origin, and unlinked.
    •  
      CommentAuthorPhyter
    • CommentTimeOct 24th 2014
     
    I'm at a complete loss as to why that would happen. Even if it were some coordinate transform issue you would at least expect the ties to follow in the shape of the shuttle track. But it's painting an entirely different path. What you're showing me there defies all logic. Must be black magic.

    If you can post or email the file so I can see I'll be happy to riddle out what evil magic is interfering with the natural order of the universe.
    • CommentAuthorDojynn
    • CommentTimeOct 24th 2014
     
    So here is a question i am wondering about. I am thinking, maybe, it could be possible to use this concept to build a custom spline track. What are your thoughts?
  6.  
    download to park: http://www.mediafire.com/download/l3maruharx6izrl/Railtest.nl2pkg
    • CommentAuthorole
    • CommentTimeOct 25th 2014 edited
     
    I have looked into the park. The problem is inside the 3ds file. The objects are organized in some kind of linked hierarchy. The script does not work when the objects are linked to other nodes. All elements must be root objects, otherwise the script above will not work correctly. I saw that all crosstie objects that are leafs are called Mesh01, Mesh02... Here is an easy fix for your specific 3ds...


    import nlvm.math3d.*;
    import com.nolimitscoaster.*;

    public class OrientToRail extends Script
    {
    public bool onInit()
    {
    SceneObject sco = sim.getSceneObjectForEntityId(getParentEntityId());
    if (sco == null)
    {
    System.err.println("Not a scene object");
    return false;
    }

    Vector3f pos = new Vector3f(0,0,0);
    sco.getTranslation(pos);
    TrackPos trackPos = sim.findNearestCoasterTrack(pos, 10);
    if (trackPos == null)
    {
    System.err.println("No track found within range");
    return false;
    }

    Matrix4x4f scom = sco.getMatrix();
    scom.invert();

    int count = sco.getElementCount();

    float offset = 0;
    for(int i=0; i<count; i++)
    {
    SceneObjectElement elem = sco.getElementAt(i);

    if (elem.getName().startsWith("Mesh"))
    {
    Matrix4x4f m = trackPos.getTrackPosOnCenterRailsWithOffset(offset).getCenterRailsMatrix();
    m.multLeft(scom);
    elem.setMatrix(m);

    // change this value to adjust the distance between ties.
    offset += 2;
    }
    }

    // return false to indicate that the script can stop now. There is nothing more to do.
    return false;
    }
    }
  7.  
    Thanks! Works a charm!
  8.  
    Hello there. I was trying out TCM's custom crossties and I found out the script for an easy fix for it hasn't get attached to the track. But instead it got under the track. The script's working though, but it wasn't positioning it right. Here's the picture

  9.  
    I'm having issues too.

    even if the crosstie is half of a millimeter off from being exactly aligned with the track, this happens:

    • CommentAuthorTOGO Fan
    • CommentTimeNov 14th 2014
     
    Is that a weird Chinese knockoff coaster style like this coaster?

    http://rcdb.com/11077.htm?p=43041
    • CommentAuthorTheBeatles
    • CommentTimeNov 14th 2014
     
    @Togo, looks more like the Big One.
    • CommentAuthorTOGO Fan
    • CommentTimeNov 14th 2014
     
    Or is it a Morgan coaster style? I'm guessing above all it is a Chinese knockoff coaster being built by TheCodeMaster.
    • CommentAuthorJAKool
    • CommentTimeNov 14th 2014
     
    omfg TOGO it's an Arrow Hyper.
    • CommentAuthorTOGO Fan
    • CommentTimeNov 14th 2014
     
    It looks more like Morgan.
  10.  
    either way, I still need help, is there any way to solve this?
  11.  
    Same thing. Is there a way to position the crossties on the script above?
    • CommentAuthorole
    • CommentTimeNov 14th 2014
     
    Will it work if you replace sco.getMatrix with sco.getAbsoluteMatrix?
  12.  
    Yes, the problem still persists, do I have to place the ties in a specific place/ orientation?
    • CommentAuthorole
    • CommentTimeNov 14th 2014
     
    Not sure why this happens. Might be an issue with pivot off center or something. You need to have the ties placed so that the center is exactly between both rails.
  13.  
    Could be any number of errors, it looks firstly like your 3ds might have an offset origin; the matrix provided will ( i'm assuming ) be relative to the origin on the 3ds. Changing your 3ds in the modelling program of your choice relative to it's origin should fix the issue. Either that, or you could perform some lovely ( hint : not ) vector calculus / linear algebra on your matrix to align it.