【问题标题】:Replace 3d model (json)替换 3d 模型 (json)
【发布时间】:2018-09-24 14:14:03
【问题描述】:

我在网上找到了一个示例,在此示例中显示了一个放置在停车场上的 3D 模型(摩天轮),并以 Google 街景全景图为背景。

现在我想用另一个 3d 对象(小行星)替换摩天轮,我将其下载为 3DS 和 OBJ。文件。我通过 Blender 将 3DS 文件转换为 JSON,但是当我替换文件时,它只显示一个空白屏幕。

我该怎么做?这是我的代码:

<!DOCTYPE html>
<html lang="en">
    <head>
        <title>Street View Overlay - EINA</title>
        <meta charset="utf-8">
        <meta name="viewport" content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0">
        <style>
            body {
                margin: 0px;
                overflow: hidden;
            }
            p {
                font-family:sans-serif;
                font-size:11px;
                font-weight:bold;
                color:#111111;
            }
        </style>
    </head>
    <body>              
        <div id="streetviewpano" style="position: absolute; top:0; bottom:0; left:0; right:0; z-index: 0">  
        </div>
        <div id="container" style="position: absolute; top:0; bottom:100px; left: 0; right: 0; z-index: 100;">
        </div>
        <script type="text/javascript" src="https://maps.google.com/maps/api/js?sensor=false"></script>

        <script src="lib/jquery-2.0.3.js"></script>
        <script src="lib/jquery.mousewheel.js"></script>
        <script src="lib/three.min.js"></script>
        <script src="lib/Detector.js"></script>
        <script src="src/streetviewoverlay.js"></script>

        <script>
        var METERS2DEGREES = 0.0000125; 
        var objectPosition = [48.804828,2.1203071];
        function hackMapProjection(lat, lon, originLat, originLon) {
            var lonCorrection = 1.5;
            var rMajor = 6378137.0;

            function lonToX(lon) {
                return rMajor * (lon * Math.PI / 180);
            }

            function latToY(lat) {
                if (lat === 0) {
                    return 0;
                } else {
                    return rMajor * Math.log(Math.tan(Math.PI / 4 + (lat * Math.PI / 180) / 2));
                }
            }

            var x = lonToX(lon - originLon) / lonCorrection;
            var y = latToY(lat - originLat);
            return {'x': x, 'y': y};
        }

        function latLon2ThreeMeters(lat, lon) {
            var xy = hackMapProjection(lat, lon, objectPosition[0], objectPosition[1]);
            return {'x': xy.x, 'y': 0, 'z': -xy.y};
        }

        var jsonLoader = new THREE.JSONLoader();
        jsonLoader.load( "model3d/wheel.js", loadWheel );

        function loadWheel(geometry, materials) {
            var mesh;
            mesh = new THREE.Mesh(geometry, new THREE.MeshFaceMaterial(materials));

            meshPos =  latLon2ThreeMeters(objectPosition[0], objectPosition[1]);                         

            mesh.geometry.computeBoundingBox();
            var xsize = mesh.geometry.boundingBox.max.x - mesh.geometry.boundingBox.min.x;
            var ysize = mesh.geometry.boundingBox.max.y - mesh.geometry.boundingBox.min.y;
            var zsize = mesh.geometry.boundingBox.max.z - mesh.geometry.boundingBox.min.z;
            var desiredXSize = 10; 
            var desiredYSize = 10; 
            var desiredZSize = 10; 

            mesh.scale.x = desiredXSize / xsize;
            mesh.scale.y = desiredYSize / ysize;
            mesh.scale.z = desiredZSize / zsize;

            mesh.position.x = meshPos.x;
            mesh.position.y = meshPos.y - 2; // the parking lot is sligthly under the street level
            mesh.position.z = meshPos.z;

            mesh.rotation.y = Math.PI/2;

            mesh.castShadow = true;

            var streetViewOverlay = StreetViewOverlay();
            streetViewOverlay.load({streetView: true, objects3D: true, webGL:true}, mesh,48.8049084,2.120357);           
        }

        </script>
    </body>
</html>

【问题讨论】:

    标签: javascript three.js blender google-street-view


    【解决方案1】:

    所以事情就是这样..您可以转换为three.json格式,这很好,但是您的转换工具的版本必须与您正在使用的三个版本相匹配..您还希望接近最新的three.js版本..

    但一个大问题是,three.json 格式在版本之间仍然有些变化,所以我过去曾遇到过以前导出的模型过时的情况。

    如果我们是你 .. 我会使用 OBJLoader 并直接加载您的 OBJ,或者使用 GLTF 或 Collada 等格式以及它们各自的加载器。这些格式不太可能老化。特别是 GTLF 看起来正朝着得到广泛支持的方向发展,并且具有许多不错的功能,使其对实时 3d 非常有效。

    r.e.您的具体问题:首先我会问您是否在加载模型时在控制台中看到任何错误。其次,我会在加载程序内的行上放置一个调试断点,并直观地检查场景及其 .children,

    或使用 scene.traverse((elem)=>{console.log(elem.type,elem);}); 将其记录在代码中;

    如果这没有显示至少一个“网格”,则意味着您的转换可能有问题。如果确实显示,则可能意味着网格太小而无法看到,太大而无法看到,或者可能是材料是意外透明或许多其他可能性。此时,您可以查看 mesh.geometry 并确保其中包含顶点和元素...

    这一切都失败了:

    如果您尝试使用 OBJLoader 或其他加载器,但仍然无法正常工作。请与我们联系。 :)

    【讨论】:

    • 感谢您的回答@manthrax。我用 OBJLoader 替换了 JSONloader。所以现在我的代码是: var loader = new THREE.OBJLoader(); loader.load("model3d/wheel.obj", loadWheel); function loadWheel(geometry, materials) { 但我仍然得到一个空白页和控制台中的错误:TypeError: THREE.OBJLoader is not a constructor
    • 对不起,我忘了提.. OBJLoader.js 是一个单独的脚本,您必须在三个.js 之后加载。它位于此处:github.com/mrdoob/three.js/tree/dev/examples/js/loaders
    • 实际上我在某处找到了脚本并将其包含在内。所以现在我有 但它仍然不起作用。
    • 看看你能不能把你的代码放在codesandbox里,我们可以看看:codesandbox.io/s/6xp2my39z
    • 谢谢 Manthrax 我设法通过朋友找到了解决方案。他使用 python 进行了转换 - convert_obj_three.py of three.js。我现在唯一缺少的是纹理(用于 3d 对象)。
    猜你喜欢
    • 2011-12-04
    • 1970-01-01
    • 2013-07-20
    • 1970-01-01
    • 2012-08-12
    • 2012-11-17
    • 1970-01-01
    • 2015-11-13
    • 2011-05-16
    相关资源
    最近更新 更多