为什么不通过的FileReader文件给Loader.load()用于three.js情景吗?不通过、情景、文件、FileReader

2023-09-08 10:51:51 作者:、安于现状

我试图用的FileReader通过一个客户端ASCII文件给loader.load(),但它看起来像该文件永远不会有。该文件会出现在3D场景中,如果我使用 loader.load(服务器路径test_file.stl')而不是 loader.load(文件对象)

我包括警报()函数来显示文件的ASCII文本,并且告诉我,JavaScript是抓取和处理文件,没有浏览器的安全屏障,但显然我没有正确地将文件传递到 loader.load()

 <!DOCTYPE HTML>
< HTML>
< HEAD>
<风格>
    体        {
            背景颜色:#fea47c;
                }

    DIV {
            位置:亲属;
            左:200像素;
            顶部:0px;
            背景颜色:#eeeeee;
            边界:1px的纯黑色;
            宽度:550px;
            高度:550px;
                }

    帆布      {
            宽度:550px;
            高度:550px;
                }
< /风格>
< /头>

<身体GT;

&所述;脚本的src =htt​​ps://raw.github.com/mrdoob/three.js/master/build/three.min.js>&所述; /脚本>
&LT;脚本src="https://raw.github.com/mrdoob/three.js/master/examples/js/loaders/STLLoader.js"></script>
&LT;脚本src="https://raw.github.com/mrdoob/three.js/master/examples/js/controls/TrackballControls.js"></script>

&LT;输入类型=文件ID =pickfile&GT;&LT; /输入&GT;

&LT;脚本&GT;

   的document.getElementById('pickfile')的addEventListener('改变',READFILE,假的)。

    功能READFILE(EVT)
                {
    变种的FileObject = evt.target.files [0];
    VAR读卡器=新的FileReader();
    reader.onload =函数(){警报(this.result)}; //验证ASCII文件内容被抓住了
    reader.readAsText(文件对象)
                }

        VAR集装箱,摄像,场景,渲染器,控制;

        在里面();
        动画();

        功能的init(){

            容器= document.createElement方法('格');
            document.body.appendChild(容器);

            VAR WIDTH = container.clientWidth;
            VAR HEIGHT = container.clientHeight;

            摄像头=新THREE.PerspectiveCamera(35,宽度/高度,.1,10000);

            camera.position.set(0,0,600);

            现场=新THREE.Scene();

            控制=新THREE.TrackballControls(摄像头,容器);
            controls.addEventListener('变',渲染);

            // 目的

            VAR装载机=新THREE.STLLoader();
            loader.addEventListener('负荷',函数(事件){

                VAR几何= event.content;

                VAR材料=新THREE.MeshLambertMaterial({环境:0xff5533,颜色:0xff5533});

                变种网状=新THREE.Mesh(几何形状,材料);

                scene.add(目);

            });

            loader.load(文件对象);

            //灯

            scene.add(新THREE.AmbientLight(0x222222));

            VAR平行光=新THREE.DirectionalLight(0XFFFFFF,1);
            directionalLight.position = camera.position;
            scene.add(平行光);

            //渲染器

            渲染器=新THREE.WebGLRenderer({反锯齿:真});
            renderer.setSize(宽度,高度);
            container.appendChild(renderer.domElement);

            window.addEventListener('调整',onWindowResize,假);


        }

        功能addLight(X,Y​​,Z,颜色,强度){

            VAR平行光=新THREE.DirectionalLight(颜色,强度);
            directionalLight.position.set(X,Y​​,Z)
            scene.add(平行光);

        }

       功能onWindowResize(){

            camera.aspect =宽/高;
            camera.updateProjectionMatrix();

            renderer.setSize(宽度,高度);
        }

        功能动画(){

            requestAnimationFrame(动画);
            controls.update();
            渲染();

        }

       功能渲染(){

           camera.lookAt(scene.position);
           renderer.render(场景,摄像头);

       }

&LT; / SCRIPT&GT;

&LT; /身体GT;
&LT; / HTML&GT;
 

解决方案

好吧,我又试了一次今天上午,我认为这个问题是我试图查看加载的结果从坏的拍摄角度或东西...反正,这里的基础上 https://raw.github.com为例/mrdoob/three.js/master/examples/webgl_loader_stl.html

的重要组成部分:

就像我上面提到的,loader.load没有任何过载,将采取实际的内容的文件的(和它有点愚蠢的认为它会)。它只会采取的位置的该文件......你需要的东西,从文件的内容创建模型。这将是 loader.parse

例如,下面的处理增加了您的模型,场景,其中场景在范围 READFILE

 函数READFILE(EVT)
{
    变种的FileObject = evt.target.files [0];
    VAR读卡器=新的FileReader();
    reader.onload =功能()
    {
        VAR装载机=新THREE.STLLoader();
        //alert(this.result)
        VAR几何= loader.parse(this.result);
        VAR材料=新THREE.MeshPhongMaterial(
        {
            环境:0xff5533,
            颜色:0xff5533,
            镜面:0x111111,
            光泽:200
        });
        变种网状=新THREE.Mesh(几何形状,材料);
        mesh.castShadow = TRUE;
        mesh.receiveShadow = TRUE;
        scene.add(目);
    };
    reader.readAsText(文件对象)
}
 
如何简单快速地合并 bootloader 和 APP 文件

全例如:

我把这个地方在网络上,但因为它使用从github上举办一些剧本,等这可能不是最好的主意。

 &LT;!DOCTYPE HTML&GT;
&LT; HTML&GT;
    &LT; HEAD&GT;
        &LT;风格&GT;
            体 {
                字体家庭:等宽;
                背景颜色:#000000;
                保证金:0px;
                溢出:隐藏;
            }
            #信息 {
                颜色:#FFF;
                位置:绝对的;
                顶:10px的;
                宽度:100%;
                文本对齐:中心;
                的z-index:100;
                显示:块;
            }
            #pickfile {
                颜色:#FFF;
                位置:绝对的;
                顶部:40PX;
                宽度:100%;
                文本对齐:中心;
                的z-index:100;
                显示:块;
            }
            一个 {
                颜色:天蓝
            }
        &LT; /风格&GT;
    &LT; /头&GT;

    &LT;身体GT;
        &所述;脚本的src =htt​​ps://raw.github.com/mrdoob/three.js/master/build/three.min.js&GT;&所述; /脚本&GT;
        &LT;脚本src="https://raw.github.com/mrdoob/three.js/master/examples/js/loaders/STLLoader.js"></script>
        &LT;脚本src="https://raw.github.com/mrdoob/three.js/master/examples/js/controls/TrackballControls.js"></script>
        &所述;脚本的src =htt​​ps://raw.github.com/mrdoob/three.js/master/examples/js/Detector.js&GT;&所述; /脚本&GT;
        &所述;脚本的src =htt​​ps://raw.github.com/mrdoob/three.js/master/examples/js/libs/stats.min.js&GT;&所述; /脚本&GT;
        &LT;输入类型=文件ID =pickfile&GT;&LT; /输入&GT;
        &LT;脚本&GT;
            的document.getElementById('pickfile')的addEventListener('改变',READFILE,假的)。

            功能READFILE(EVT)
            {
                变种的FileObject = evt.target.files [0];
                VAR读卡器=新的FileReader();
                reader.onload =功能()
                {
                    VAR装载机=新THREE.STLLoader();
                    //alert(this.result)
                    VAR几何= loader.parse(this.result);
                    VAR材料=新THREE.MeshPhongMaterial(
                    {
                        环境:0xff5533,
                        颜色:0xff5533,
                        镜面:0x111111,
                        光泽:200
                    });
                    变种网状=新THREE.Mesh(几何形状,材料);
                    mesh.castShadow = TRUE;
                    mesh.receiveShadow = TRUE;
                    scene.add(目);
                };
                reader.readAsText(文件对象)
            }
            如果Detector.addGetWebGLMessage()(Detector.webgl!);
            VAR容器,统计;
            VAR摄像头,场景,渲染器,对象;
            在里面();
            动画();

            功能的init()
            {
                容器= document.createElement方法('格');
                document.body.appendChild(容器);
                摄像头=新THREE.PerspectiveCamera(35,window.innerWidth / window.innerHeight,1,15);
                camera.position.set(3,0.5%,3);
                现场=新THREE.Scene();
                scene.fog =新THREE.Fog(0XFFFFFF,2,15);
                scene.fog.color.setHSV(0.06,0.2,0.45);
                // 格
                变种大小= 20,
                    步骤= 0.25;
                VAR几何=新THREE.Geometry();
                VAR材料=新THREE.LineBasicMaterial(
                {
                    颜色:0x000000处
                });
                对于(VAR I = -size; I&LT; =大小; I + =步)
                {
                    geometry.vertices.push(新THREE.Vector3(-size,-0.04,I));
                    geometry.vertices.push(新THREE.Vector3(大小,-0.04,I));
                    geometry.vertices.push(新THREE.Vector3(ⅰ,-0.04,-size));
                    geometry.vertices.push(新THREE.Vector3(ⅰ,-0.04,大小));
                }
                VAR线=新THREE.Line(几何形状,材料,THREE.LinePieces);
                line.position.y = -0.46;
                scene.add(线);
                // 地面
                VAR飞机=新THREE.Mesh(新THREE.PlaneGeometry(40,40),新THREE.MeshPhongMaterial(
                {
                    环境:0x999999,
                    颜色:0x999999,
                    镜面:0x101010
                }));
                plane.rotation.x = -Math.PI / 2;
                plane.position.y = -0.5;
                scene.add(平面);
                plane.receiveShadow = TRUE;
                // 目的
                //灯
                scene.add(新THREE.AmbientLight(值0x777777));
                addShadowedLight(1,1,1,0XFFFFFF,1.35);
                addShadowedLight(0.5,1,-1,0xffaa00,1);
                //渲染器
                渲染器=新THREE.WebGLRenderer(
                {
                    反锯齿:真正的,
                    clearColor:0x111111,
                    clearAlpha:1,
                    阿尔法:假的
                });
                renderer.setSize(window.innerWidth,window.innerHeight);
                renderer.setClearColor(scene.fog.color,1);
                renderer.gammaInput = TRUE;
                renderer.gammaOutput = TRUE;
                renderer.physicallyBasedShading = TRUE;
                renderer.shadowMapEnabled = TRUE;
                renderer.shadowMapCullFrontFaces = FALSE;
                container.appendChild(renderer.domElement);
                //统计
                统计数据=新的统计();
                stats.domElement.style.position ='绝对';
                stats.domElement.style.top =0px​​;
                container.appendChild(stats.domElement);
                //
                window.addEventListener('调整',onWindowResize,假);
            }

            功能addShadowedLight(X,Y​​,Z,颜色,强度)
            {
                VAR平行光=新THREE.DirectionalLight(颜色,强度);
                directionalLight.position.set(X,Y​​,Z)
                scene.add(平行光);
                directionalLight.castShadow = TRUE;
                //directionalLight.shadowCameraVisible = TRUE;
                变种D = 1;
                directionalLight.shadowCameraLeft = -d;
                directionalLight.shadowCameraRight = D;
                directionalLight.shadowCameraTop = D;
                directionalLight.shadowCameraBottom = -d;
                directionalLight.shadowCameraNear = 1;
                directionalLight.shadowCameraFar = 4;
                directionalLight.shadowMapWidth = 2048;
                directionalLight.shadowMapHeight = 2048;
                directionalLight.shadowBias = -0.005;
                directionalLight.shadowDarkness = 0.15;
            }

            功能onWindowResize()
            {
                camera.aspect = window.innerWidth / window.innerHeight;
                camera.updateProjectionMatrix();
                renderer.setSize(window.innerWidth,window.innerHeight);
            }
            //
            功能动画()
            {
                requestAnimationFrame(动画);
                渲染();
                stats.update();
            }

            功能渲染()
            {
                VAR定时器= Date.now()* 0.0005;
                camera.position.x = Math.cos(定时器)* 5;
                camera.position.z = Math.sin(定时器)* 5;
                camera.lookAt(scene.position);
                renderer.render(场景,摄像头);
            }
        &LT; / SCRIPT&GT;
    &LT; /身体GT;
&LT; / HTML&GT;
 

I'm trying to use FileReader to pass a client side ASCII file to loader.load() but it looks like the file never gets there. The file does appear in the 3D scene if I use loader.load('server path to test_file.stl') instead of loader.load(fileObject).

I included an alert() function to display the file's ASCII text and that tells me the JavaScript is grabbing and processing the file and there is no Chrome security barrier but apparently I'm not properly passing the file to loader.load().

<!DOCTYPE html>
<html>
<head>
<style>
    body        {
            background-color:#fea47c;
                }

    div         { 
            position:relative;
            left:200px;           
            top:0px;
            background-color: #eeeeee;
            border:1px solid black;             
            width:550px;
            height:550px;
                }

    canvas      {
            width:550px;
            height:550px;
                }
</style>
</head>

<body>

<script src="https://raw.github.com/mrdoob/three.js/master/build/three.min.js"></script>
<script src="https://raw.github.com/mrdoob/three.js/master/examples/js/loaders/STLLoader.js"></script>      
<script src="https://raw.github.com/mrdoob/three.js/master/examples/js/controls/TrackballControls.js"></script> 

<input type="file" id="pickfile"></input>

<script> 

   document.getElementById('pickfile').addEventListener('change', readFile, false);

    function readFile (evt) 
                {
    var fileObject = evt.target.files[0];    
    var reader = new FileReader();
    reader.onload = function() {alert(this.result)};    // verifies ASCII file contents were grabbed
    reader.readAsText(fileObject)
                }

        var container, camera, scene, renderer, controls;

        init();
        animate();

        function init() {

            container = document.createElement( 'div' );
            document.body.appendChild( container );

            var width = container.clientWidth;
            var height = container.clientHeight;

            camera = new THREE.PerspectiveCamera( 35, width / height, .1 , 10000);

            camera.position.set( 0, 0, 600);

            scene = new THREE.Scene();

            controls = new THREE.TrackballControls( camera , container); 
            controls.addEventListener( 'change', render );

            // object

            var loader = new THREE.STLLoader();
            loader.addEventListener( 'load', function ( event ) {

                var geometry = event.content;

                var material = new THREE.MeshLambertMaterial( { ambient: 0xff5533, color: 0xff5533 } );

                var mesh = new THREE.Mesh( geometry, material );

                scene.add( mesh );

            } );

            loader.load(fileObject);

            // lights

            scene.add( new THREE.AmbientLight( 0x222222 ) );

            var directionalLight = new THREE.DirectionalLight( 0xffffff, 1 );
            directionalLight.position = camera.position;
            scene.add( directionalLight );

            // renderer

            renderer = new THREE.WebGLRenderer( { antialias: true } );
            renderer.setSize( width , height );
            container.appendChild( renderer.domElement );

            window.addEventListener( 'resize', onWindowResize, false );


        }

        function addLight( x, y, z, color, intensity ) {

            var directionalLight = new THREE.DirectionalLight( color, intensity );
            directionalLight.position.set( x, y, z )
            scene.add( directionalLight );

        }

       function onWindowResize() {   

            camera.aspect = width / height;
            camera.updateProjectionMatrix();

            renderer.setSize( width, height );
        }

        function animate() {

            requestAnimationFrame( animate );
            controls.update();
            render();

        }

       function render() {

           camera.lookAt( scene.position );
           renderer.render( scene, camera );

       }

</script>

</body>
</html>

解决方案

Ok, I tried again this morning, and I think the problem was I was trying to view the loaded results from a bad camera angle or something... anyways, here's an example based on https://raw.github.com/mrdoob/three.js/master/examples/webgl_loader_stl.html

The essential part:

Like I mentioned above, loader.load does not have any overload that would take the actual contents of the file (and it's kinda silly to think it would). It will only take a location for the file... you needed something that creates your model from the file contents. That would be loader.parse.

For example, the following handler adds your model to a scene where scene is in scope of readFile:

function readFile(evt)
{
    var fileObject = evt.target.files[0];
    var reader = new FileReader();
    reader.onload = function ()
    {
        var loader = new THREE.STLLoader();
        //alert(this.result)
        var geometry = loader.parse(this.result);
        var material = new THREE.MeshPhongMaterial(
        {
            ambient: 0xff5533,
            color: 0xff5533,
            specular: 0x111111,
            shininess: 200
        });
        var mesh = new THREE.Mesh(geometry, material);
        mesh.castShadow = true;
        mesh.receiveShadow = true;
        scene.add(mesh);
    };
    reader.readAsText(fileObject)
}

Whole example:

I'd put this somewhere on the net but as it uses github to host some of the scripts, etc. that's probably not the best idea.

<!DOCTYPE html>
<html>
    <head>
        <style>
            body {
                font-family: Monospace;
                background-color: #000000;
                margin: 0px;
                overflow: hidden;
            }
            #info {
                color: #fff;
                position: absolute;
                top: 10px;
                width: 100%;
                text-align: center;
                z-index: 100;
                display:block;
            }
            #pickfile {
                color: #fff;
                position: absolute;
                top: 40px;
                width: 100%;
                text-align: center;
                z-index: 100;
                display:block;
            }
            a {
                color: skyblue
            }
        </style>
    </head>

    <body>
        <script src="https://raw.github.com/mrdoob/three.js/master/build/three.min.js"></script>
        <script src="https://raw.github.com/mrdoob/three.js/master/examples/js/loaders/STLLoader.js"></script>
        <script src="https://raw.github.com/mrdoob/three.js/master/examples/js/controls/TrackballControls.js"></script>
        <script src="https://raw.github.com/mrdoob/three.js/master/examples/js/Detector.js"></script>
        <script src="https://raw.github.com/mrdoob/three.js/master/examples/js/libs/stats.min.js"></script>
        <input type="file" id="pickfile"></input>
        <script>
            document.getElementById('pickfile').addEventListener('change', readFile, false);

            function readFile(evt)
            {
                var fileObject = evt.target.files[0];
                var reader = new FileReader();
                reader.onload = function ()
                {
                    var loader = new THREE.STLLoader();
                    //alert(this.result)
                    var geometry = loader.parse(this.result);
                    var material = new THREE.MeshPhongMaterial(
                    {
                        ambient: 0xff5533,
                        color: 0xff5533,
                        specular: 0x111111,
                        shininess: 200
                    });
                    var mesh = new THREE.Mesh(geometry, material);
                    mesh.castShadow = true;
                    mesh.receiveShadow = true;
                    scene.add(mesh);
                }; 
                reader.readAsText(fileObject)
            }
            if (!Detector.webgl) Detector.addGetWebGLMessage();
            var container, stats;
            var camera, scene, renderer, objects;
            init();
            animate();

            function init()
            {
                container = document.createElement('div');
                document.body.appendChild(container);
                camera = new THREE.PerspectiveCamera(35, window.innerWidth / window.innerHeight, 1, 15);
                camera.position.set(3, 0.5, 3);
                scene = new THREE.Scene();
                scene.fog = new THREE.Fog(0xffffff, 2, 15);
                scene.fog.color.setHSV(0.06, 0.2, 0.45);
                // Grid
                var size = 20,
                    step = 0.25;
                var geometry = new THREE.Geometry();
                var material = new THREE.LineBasicMaterial(
                {
                    color: 0x000000
                });
                for (var i = -size; i <= size; i += step)
                {
                    geometry.vertices.push(new THREE.Vector3(-size, -0.04, i));
                    geometry.vertices.push(new THREE.Vector3(size, -0.04, i));
                    geometry.vertices.push(new THREE.Vector3(i, -0.04, -size));
                    geometry.vertices.push(new THREE.Vector3(i, -0.04, size));
                }
                var line = new THREE.Line(geometry, material, THREE.LinePieces);
                line.position.y = -0.46;
                scene.add(line);
                // Ground
                var plane = new THREE.Mesh(new THREE.PlaneGeometry(40, 40), new THREE.MeshPhongMaterial(
                {
                    ambient: 0x999999,
                    color: 0x999999,
                    specular: 0x101010
                }));
                plane.rotation.x = -Math.PI / 2;
                plane.position.y = -0.5;
                scene.add(plane);
                plane.receiveShadow = true;
                // Object
                // Lights
                scene.add(new THREE.AmbientLight(0x777777));
                addShadowedLight(1, 1, 1, 0xffffff, 1.35);
                addShadowedLight(0.5, 1, -1, 0xffaa00, 1);
                // renderer
                renderer = new THREE.WebGLRenderer(
                {
                    antialias: true,
                    clearColor: 0x111111,
                    clearAlpha: 1,
                    alpha: false
                });
                renderer.setSize(window.innerWidth, window.innerHeight);
                renderer.setClearColor(scene.fog.color, 1);
                renderer.gammaInput = true;
                renderer.gammaOutput = true;
                renderer.physicallyBasedShading = true;
                renderer.shadowMapEnabled = true;
                renderer.shadowMapCullFrontFaces = false;
                container.appendChild(renderer.domElement);
                // stats
                stats = new Stats();
                stats.domElement.style.position = 'absolute';
                stats.domElement.style.top = '0px';
                container.appendChild(stats.domElement);
                //
                window.addEventListener('resize', onWindowResize, false);
            }

            function addShadowedLight(x, y, z, color, intensity)
            {
                var directionalLight = new THREE.DirectionalLight(color, intensity);
                directionalLight.position.set(x, y, z)
                scene.add(directionalLight);
                directionalLight.castShadow = true;
                //directionalLight.shadowCameraVisible = true;
                var d = 1;
                directionalLight.shadowCameraLeft = -d;
                directionalLight.shadowCameraRight = d;
                directionalLight.shadowCameraTop = d;
                directionalLight.shadowCameraBottom = -d;
                directionalLight.shadowCameraNear = 1;
                directionalLight.shadowCameraFar = 4;
                directionalLight.shadowMapWidth = 2048;
                directionalLight.shadowMapHeight = 2048;
                directionalLight.shadowBias = -0.005;
                directionalLight.shadowDarkness = 0.15;
            }

            function onWindowResize()
            {
                camera.aspect = window.innerWidth / window.innerHeight;
                camera.updateProjectionMatrix();
                renderer.setSize(window.innerWidth, window.innerHeight);
            }
            //
            function animate()
            {
                requestAnimationFrame(animate);
                render();
                stats.update();
            }

            function render()
            {
                var timer = Date.now() * 0.0005;
                camera.position.x = Math.cos(timer) * 5;
                camera.position.z = Math.sin(timer) * 5;
                camera.lookAt(scene.position);
                renderer.render(scene, camera);
            }
        </script>
    </body>
</html>