4

I'm creating a simple WebGL project and need a way to load in models. I decided to use OBJ format so I need a way to load it in. The file is (going to be) stored on the server and my question is: how does one in JS load in a text file and scan it line by line, token by token (like with streams in C++)? I'm new to JS, hence my question. The easier way, the better.

UPDATE: I used your solution, broofa, but I'm not sure if I did it right. I load the data from a file in forEach loop you wrote but outside of it (i.e. after all your code) the object I've been filling data with is "undefined". What am I doing wrong? Here's the code:

var materialFilename;

function loadOBJModel(filename)
{
    // ...

    var req = new XMLHttpRequest();
    req.open('GET', filename);
    req.responseType = 'text';
    req.onreadystatechange = function()
    {
        if (req.readyState == 4)
        {
            var lines = req.responseText.split(/\n/g);
            lines.forEach(function(line)
            {
                readLine(line);
            });
        }
    }
    req.send();

    alert(materialFilename);

    // ...
}

function readLine(line)
{
    // ...

    else if (tokens[0] == "mtllib")
    {
        materialFilename = tokens[1];
    }

    // ...
}
6
  • It may or may not be an option, but you could let mrdoob.github.com/three.js do some of the heavy lifting for you. It has multiple loader options to take advantage of. Commented Nov 26, 2012 at 23:37
  • @mookamafoob I've tried that already but the lack of actual documentation rendered it unusable for me. Commented Nov 26, 2012 at 23:40
  • @broofa Of course, added now. Commented Nov 27, 2012 at 21:03
  • The problem is onreadystatechange is an asynchronous callback - it doesn't get called until after the current event loop completes (i.e. after you've tried to alert the value of materialFilename. Move your alert to the end of the onreadystatechange function and you should be good to go. P.S. you've inspired me to ask a minor question on SO etiquette :) - meta.stackexchange.com/questions/156897/… Commented Nov 27, 2012 at 21:13
  • @broofa I knew it was async but thought it might work anyway since I put alert right after materialFilename = tokens[1]; and it always got executed (with correct value) before the alert in loadOBJModel function. Anyway, alert was just for debugging causes and I need the loadOBJModel function to return data loaded from the file, how do I do that? Commented Nov 27, 2012 at 21:40

2 Answers 2

3

You can use XMLHttpRequest to fetch the file, assuming it's coming from the same domain as your main web page. If not, and you have control over the server hosting your file, you can enable CORS without too much trouble. E.g.

To scan line-by-line, you can use split(). E.g. Something like this ...

var req = new XMLHttpRequest();
req.open('GET', '/your/url/goes/here');
req.onreadystatechange = function() {
  if (req.readyState == 4) {
    if (req.status == 200) {
      var lines = req.responseText.split(/\n/g);
      lines.forEach(function(line, i) {
        // 'line' is a line of your file, 'i' is the line number (starting at 0)
      });
    } else {
      // (something went wrong with the request)
    }
  }
}

req.send();
Sign up to request clarification or add additional context in comments.

5 Comments

'Not sure why @Brad's answer was downvoted. XHR/CORS is probably what you want and, as he notes, you're pretty much on your own for parsing at the token level, if that's what you want. If you google around you can probably find utilities for generating JS parsers AST definitions, but that's out of scope here.
I've tried this solution, I added "console.log(req.responseText);" but my browser (firefox) shows me: only "ill-formed" (I'm not sure of the translation, I have polish-languaged brwoser) in the developer toolbar.
@NPS: was missing a closing '}' on the else block. Fixed code - please try again.
Nope, it was a minor typo, I didn't even bother to mention that. Of course, I fixed that before running the code. Your code started working for me after removing "if (req.status == 200)" (it gets some other code afair and yet it works). And the warning I mentioned disappeared after adding: "req.responseType = 'text';". Thx for help anyway.
I added an update to my question, I would be grateful if you could answer that.
0

If you can't simply load the data with XHR or CORS, you could always use the JSON-P method by wrapping it with a JavaScript function and dynamically attaching the script tag to your page.

You would have a server-side script that would accept a callback parameter, and return something like callback1234(/* file data here */);.

Once you have the data, parsing should be trivial, but you will have to write your own parsing functions. Nothing exists for that out of the box.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.