Can I load 3dmodels from local?

I’ve loaded a model using loadModel(), but it requires a path from the website. And because I can’t upload a file larger than 5M,I wonder if there is a way to load a model just from local (maybe createFileInput)?
Thank you in advance.QQ截图20210921174528

1 Like

It’s a little tricky but it is definitely possible:

let input;
let m;

function setup() {
  createCanvas(windowWidth, windowHeight, WEBGL)
  input = createFileInput(handleFile);
  input.position(10, 10);
}

function draw() {
  background(255);
  orbitControl(2, 1, 0.05);
  if (m) {
    background(0);
    // This will depend on your model (I'm using the standard teapot example)
    scale(1, -1, 1);
    translate(0, 10, 0);
    model(m);
  }
}

function handleFile(file) {
  loadStrings(
    file.data,
    lines => {
      // See: https://developer.mozilla.org/en-US/docs/Web/API/Blob
      let blob = new Blob([lines.join('\n')], { type: 'text/plain' });
      
      loadModel(
        // This creates a temporary URL that can be used to fetch
        // the data in the Blob.
        // It is necessary to add the "#ext=.obj" to the end because
        // loadModel() uses the file extension to determine what
        // kind of model to load (which is a horrible design, but I digress).
        URL.createObjectURL(blob) + "#ext=.obj",
        true,
        loaded => {
          m = loaded;
        }
      );
    }
  );
}
1 Like

Wow! I tried your code and it worked! Thank you so much for the timely reply, I really appreciate it.

1 Like

emm, there’s stil one thing that bothers me. When I use my custom shader, and load a model, it just disappear. it seems I need a way to reload shader. Could you please take a look on that?Thank you.

let input;
let m,m0,currentmodel;
function preload(){
  m0=loadModel('teapot.obj',true);
  debugger
  mandel=loadShader('shader.vert','shader.frag');
}
function setup() {
  
  createCanvas(windowWidth, windowHeight, WEBGL)
  input = createFileInput(handleFile);
  input.position(10, 10);
  noStroke();
}

function draw() {
  background(255);
  orbitControl(2, 1, 0.05);
  if (m) {
    currentmodel=m;}
  else{
    currentmodel=m0;
  }
    background(155);
    // This will depend on your model (I'm using the standard teapot example)
    scale(1, -1, 1);
    //translate(0, 10, 0);
  //mandel.setUniform(aPosition);
  mandel.setUniform('cmatrix',this._renderer._curCamera.cameraMatrix.mat4);
  mandel.setUniform('pmatrix',this._renderer._curCamera.projMatrix.mat4);
    shader(mandel);
    model(currentmodel);

}

function handleFile(file) {
  loadStrings(
    file.data,
    lines => {
      // See: https://developer.mozilla.org/en-US/docs/Web/API/Blob
      let blob = new Blob([lines.join('\n')], { type: 'text/plain' });
      
      m=loadModel(
        // This creates a temporary URL that can be used to fetch
        // the data in the Blob.
        // It is necessary to add the "#ext=.obj" to the end because
        // loadModel() uses the file extension to determine what
        // kind of model to load (which is a horrible design, but I digress).
        URL.createObjectURL(blob) + "#ext=.obj",
        true
      );
    }
  );
}
https://editor.p5js.org/yangshuzhan/sketches/0rO0eylNg

This is definitely weird. There’s no obvious reason why this wouldn’t work. I’ve verified that it doesn’t happen with the default shader, but I don’t see any reason why your shader would cause a problem. I’ve also verified that it’s not specific to my file input model loader code (the same issue occurs if you load a new model from a URL). Seems like a bug in p5.js as far as I can tell. Here’s my test sketch: p5.js Web Editor

1 Like

Note that it’s functional if you use two seperate shaders for the two objects. I guess it’s because when I change the model, the shader and it’s attributes doesn’t change accordingly? I’m overwhelmed.

Ok, I figured it out: Calling loadModel while a custom shader is in use breaks the existing shader. · Issue #5455 · processing/p5.js · GitHub

This is a rather egregious p5.js bug. Basically loadModel calls outside of preload() are causing setup() to get re-run, which causes your preloaded shader to become invalid (because it is associated with a completely different WebGL context) :man_facepalming:. Hopefully the p5.js maintainers will address this quickly because I would consider this a high priority bug. I might try to submit a PR for it.

1 Like

Well done! This bug bothered me for weeks. Love you so much. :innocent: