0

Three.WebGLRenderer: Uncaught TypeError: Object # has no method 'split'

aka TypeError: 'undefined' is not a function (evaluating 'url.split( '/' )')

I'm a newbie to Three.JS and WebGL, and I can't get my webpage to to render my 3D model. I have basic familiarity with Javascript, but not a master. Can someone please help me fix this error?

My renderer page is at: http://test.soundfit.me/render3D/View3DModel.html. I am getting a TypeError inside the three.js code.

Chrome's JavaScript Console reports:

THREE.WebGLRenderer 66                                     three.js:20270
Uncaught TypeError: Object #<Object> has no method 'split' three.js:10940
    THREE.Loader.extractUrlBase                            three.js:10940
    THREE.JSONLoader.load                                  three.js:11480
    (anonymous function)                                   View3DModel.html:18

Safari says:

[Error] TypeError: 'undefined' is not a function (evaluating 'url.split( '/' )')

My invoking code:

I believe this error is generated by this function in my rendering page, which invokes functions within three.js:

loader.load({model:"obj/mesh.js",callback:callbackModel});

How do I fix the problem?

Supporting Background:

THREE.Loader.extractUrlBase:##

extractUrlBase: function ( url ) {
    var parts = url.split( '/' );
    if ( parts.length === 1 ) return './';
    parts.pop();
    return parts.join( '/' ) + '/';
}

THREE.JSONLoader

THREE.JSONLoader = function ( showStatus ) {
    THREE.Loader.call( this, showStatus );
    this.withCredentials = false;
};

THREE.JSONLoader.prototype = Object.create( THREE.Loader.prototype );

THREE.JSONLoader.prototype.load = function ( url, callback, texturePath ) {
    var scope = this;
    // todo: unify load API to for easier SceneLoader use
    texturePath = texturePath && ( typeof texturePath === "string" ) ? texturePath : this.extractUrlBase( url );
    this.onLoadStart();
    this.loadAjaxJSON( this, url, callback, texturePath );
};

What I did:

My OBJ file, texture files and JS object are here: http://test.soundfit.me/render3D/obj/

I used convert_obj_three.py to create the obj/mesh.js javascript object.

The renderer webpage I am using is as described in the instructions for porting-3d-graphics-to-the-web-webgl-intro-part-2 article on opera.com.

In keeping with the comment by federicostrazzullo on that site, I modified the renderer by moved the animate() call from its initial position to after the createScene(…) function, to avoid the following other uncaught TypeError:

Uncaught TypeError: Cannot read property 'rotation' of undefined View3DModel.html:21
render  View3DModel.html:21
animate View3DModel.html:20
(anonymous function)

Debugger listing

The renderer code as displayed in the debugger follows:

1.  <html lang="en">
2.  <head>
3.  <title>SoundFit SugarCube 3D Model Viewer</title>
4.  <meta charset="utf-8">
5.  <meta name="viewport" content="width=device-width, user-scalable=no, 
    minimum-scale=1.0, maximum-scale=1.0">
6.  <style>
        body{
            background:#fff;
            padding:0;
            margin:0;
            overflow:hidden;
            font-family:'trebuchet ms','lucida grande','lucida sans unicode',arial,
                helvetica,sans-serif;
            text-align:center
        }
        canvas{
            pointer-events:none;
            z-index:10
        }
        p{
            font-size:small
        }
    </style>
7.  </head>
8.  <body>
9.  <div>
10. <h2>SoundFit 3D Model Viewer</h2>
11. <p>by Scott L. McGregor, SoundFit</p>
12. <p>adapted from the <a href="https://github.com/mrdoob/three.js">Three.js</a> 
    example webgl_objconvert_test.html</p>
13. </div>
14. <script src="three.js-master/build/three.js"></script>
15. <script src="three.js-master/examples/js/Detector.js"></script>
16. <script src="js/RequestAnimationFrame.js"></script>
17. <script>if(!Detector.webgl)Detector.addGetWebGLMessage();
    var SCREEN_WIDTH=window.innerWidth;
    var SCREEN_HEIGHT=window.innerHeight;
    var FLOOR=0;
    var container;
    var camera,scene;
    var webglRenderer;
    var zmesh,geometry;
    var mouseX=0,mouseY=0;
    var windowHalfX=window.innerWidth/2;
    var windowHalfY=window.innerHeight/2;
    document.addEventListener('mousemove',onDocumentMouseMove,false);
    init();
    function init() {
        container=document.createElement('div');
        document.body.appendChild(container);
        camera=new THREE.PerspectiveCamera(75,SCREEN_WIDTH/SCREEN_HEIGHT,1,100000);
        camera.position.z=75;
        scene=new THREE.Scene();
        var ambient=new THREE.AmbientLight(0xffffff);
        scene.add(ambient);
        var directionalLight=new THREE.DirectionalLight(0xffeedd);
        directionalLight.position.set(0,-70,100).normalize();
        scene.add(directionalLight);
    }
18. webglRenderer=new THREE.WebGLRenderer();
    webglRenderer.setSize(SCREEN_WIDTH,SCREEN_HEIGHT);
    webglRenderer.domElement.style.position="relative";
    container.appendChild(webglRenderer.domElement);
    var loader=new THREE.JSONLoader(),
    callbackModel=function(geometry){
        createScene(geometry,90,FLOOR,-50,105)
    };
    loader.load({model:"obj/mesh.js",callback:callbackModel});
    function createScene(geometry,x,y,z,b){
        zmesh=new THREE.Mesh(geometry,new THREE.MeshFaceMaterial());
        zmesh.position.set(0,16,0);
        zmesh.scale.set(1,1,1);
        scene.add(zmesh);
    }
19. animate();
    function onDocumentMouseMove(event){
        mouseX=(event.clientX-windowHalfX);
        mouseY=(event.clientY-windowHalfY);
    }
20. function animate(){requestAnimationFrame(animate);
    render();}
21. function render(){
        zmesh.rotation.set(-mouseY/500+1,-mouseX/200,0);
        webglRenderer.render(scene,camera);
    }
    </script>
22. </body>
23. </html>
mcgregor94086
  • 1,467
  • 3
  • 11
  • 22
  • try `loader.load( "obj/mesh.js", callbackModel );` – WestLangley Mar 18 '14 at 19:54
  • I am now getting a different error: `THREE.WebGLRenderer 66 three.js.pagespeed.jm.IbfJvZyj1b.js:487 Uncaught TypeError: Cannot read property 'rotation' of undefined View3DModel.html:30 9 Uncaught TypeError: Cannot read property 'rotation' of undefined View3DModel.html:30 Uncaught TypeError: Cannot read property 'map' of undefined three.js.pagespeed.jm.IbfJvZyj1b.js:515 1345 Uncaught TypeError: Cannot read property 'attributes' of undefined ` – mcgregor94086 Mar 19 '14 at 01:13
  • @WestLangley : I am now getting a different error:Uncaught TypeError: Cannot read property 'rotation' of undefined. `THREE.WebGLRenderer 66 three.js.pagespeed.jm.IbfJvZyj1b.js:487` `Uncaught TypeError: Cannot read property 'rotation' of undefined View3DModel.html:30` `Uncaught TypeError: Cannot read property 'rotation' of undefined View3DModel.html:30` `Uncaught TypeError: Cannot read property 'map' of undefined three.js.pagespeed.jm.IbfJvZyj1b.js:515` `Uncaught TypeError: Cannot read property 'attributes' of undefined` – mcgregor94086 Mar 19 '14 at 01:19
  • You need to practice using the debugger. The loading has not competed yet, so `zmesh` is not defined. Loading is asynchronous. – WestLangley Mar 19 '14 at 01:33
  • @WestLangley: If the errors are because that the model has not completed loading, then the problem is that it NEVER completes loading. It is throwing an error every second, from inside the animate() function, and continues to do so forever. Can you tell me why it is still loading, while it is already in animate()? – mcgregor94086 Mar 19 '14 at 14:36
  • I can't debug your code for you, but your model is fine. Do this: ` var loader = new THREE.JSONLoader(); loader.load( "mesh.js", function ( geometry, materials ) { mesh = new THREE.Mesh( geometry, new THREE.MeshFaceMaterial( materials ) ); mesh.material.materials[ 0 ].side = THREE.DoubleSide; mesh.material.materials[ 1 ].side = THREE.DoubleSide; mesh.rotation.set( - Math.PI / 2, 0, 0 ); scene.add( mesh ); } ); ` – WestLangley Mar 19 '14 at 19:13
  • @WestLangley: When I do that zmesh in the render() function is undefined, so zmesh.rotation throws and error continuously each time it renders. But I moved your code to inside the createScene funtion and changed mesh to zmesh and I now am seeing texture mapped models! Thanks! – mcgregor94086 Mar 19 '14 at 20:37

1 Answers1

0

The zmesh geometry need to have rotation in it's data. The error say that it is not able to find the rotation for your mesh.

You can add rotation using How to rotate a 3D object on axis three.js? post

Community
  • 1
  • 1
viewport
  • 1
  • 3