0

我是使用three.js的新手。我曾经使用 JSON 文件作为我的 3D 模型,但是当我从 Blender 导出它时,实际的 3D 文件有一些问题,所以我切换到 obj。实际模型现在很好,但我不知道如何从JSON切换到obj。这是我所能得到的,但我不断收到错误:THREE.Object3D.add:对象不是 THREE.Object3D 的实例。

var scene = new THREE.Scene();
var camera = new THREE.PerspectiveCamera(
  60,
  window.innerWidth / window.innerHeight,
  10,
  1000
);

camera.position.z = 100;
camera.position.y = 10;

var renderer = new THREE.WebGLRenderer({
  alpha: true
});
var manager = new THREE.LoadingManager(loadModel);

manager.onProgress = function(item, loaded, total) {
  console.log(item, loaded, total);
};

var wrapper = new THREE.Object3D();
var textureloader = new THREE.TextureLoader();

renderer.setSize(window.innerWidth, window.innerHeight);

var light = new THREE.DirectionalLight(0xffffff, 1.0);

light.position.set(100, 100, 100);
scene.add(light);
var light2 = new THREE.DirectionalLight(0xffffff, 1.0);

light2.position.set(-100, 100, -100);
scene.add(light2);

function onError() {}

function onProgress(xhr) {
  if (xhr.lengthComputable) {
    var percentComplete = (xhr.loaded / xhr.total) * 100;
    console.log("model " + Math.round(percentComplete, 2) + "% downloaded");
  }
}
var head;
var loader = new THREE.OBJLoader2(manager);

loader.load(
  "http://trhidouan309.barzalou.com/site_web/js/profil.obj",
  function(obj) {
    head = obj;
  },
  onProgress,
  onError
);

function loadModel() {
  setTimeout(function() {
    wrapper.add(head);
    scene.add(wrapper);
  }, 10);
}

material.opacity = 0.6;

var hiddenPlane = new THREE.Mesh(planeGeometry, material);

hiddenPlane.position.set(0, 0, 50);
scene.add(hiddenPlane);

var mouse = new THREE.Vector2(0, 0);
var point = new THREE.Vector3(0, 0, 0);
var raycaster = new THREE.Raycaster();

camera.lookAt(scene.position);
window.addEventListener("mousemove", onMouseMove, false);
window.addEventListener("resize", onWindowResize, false);

function onMouseMove(event) {
  event.preventDefault();
  mouse.x = (event.clientX / window.innerWidth) * 2 - 1;
  mouse.y = -(event.clientY / window.innerHeight) * 2 + 1;
  raycaster.setFromCamera(mouse, camera);
  var intersects = raycaster.intersectObject(hiddenPlane);
  if (intersects.length > 0) {
    point = intersects[0].point;
  }
}

function onWindowResize() {
  camera.aspect = window.innerWidth / window.innerHeight;
  camera.updateProjectionMatrix();
  renderer.setSize(window.innerWidth, window.innerHeight);
}

function animate() {
  requestAnimationFrame(animate);
  render();
}

function render() {
  wrapper.lookAt(point);
  renderer.render(scene, camera);
}

window.onload = function() {
  document.getElementById("scene3d").appendChild(renderer.domElement);
};

animate();
<script src="js/LoaderSupport.js"></script>
<script src="js/OBJLoader2.js"></script>
<script src="js/index.js"></script>

3D 模型似乎已加载,但我认为无法将其添加到场景中

4

1 回答 1

0

您在调用加载 obj 文件并呈现它的时间时遇到问题。您正在通过加载管理器调用 loadModel,其中包含对名为 head 的对象的调用,然后由 loader.load() 函数对其进行初始化。此外,您正在异步调用 loader.load() ,这将导致进一步的计时问题。

解决此问题的一种方法是通过传递文档OBJLoader2 ThreeJS (见下文)中提到的正确参数来同步调用 loader.load() 并将对loader.load 的调用移动到加载管理器之前,以便它在加载之前加载名为 head 的对象被使用。

从 objloader2 doc 将 useAsync 设置为 false 会导致加载器同步加载:

.load ( url : String, onLoad : Function, onProgress : Function, onError : Function, onMeshAlter : Function, useAsync : boolean ) : null

这种方式可确保在加载 .obj 文件之前不使用 obj 对象。

请参阅下面的代码片段:

 var scene = new THREE.Scene();
    var camera = new THREE.PerspectiveCamera(60, window.innerWidth / window.innerHeight, 10, 1000);
    camera.position.z = 100;
    camera.position.y = 10;
    var renderer = new THREE.WebGLRenderer({
        alpha: true
    });

    //Moved loader.load and passed correct sync args
    var head;
    var loader = new THREE.OBJLoader2(manager);
    loader.load('http://trhidouan309.barzalou.com/site_web/js/profil.obj', function (obj) {
        head = obj;
    }, onProgress, onError, null, false);

    var manager = new THREE.LoadingManager(loadModel);
    manager.onProgress = function (item, loaded, total) {
        console.log(item, loaded, total);
    };
    var wrapper = new THREE.Object3D;
    var textureloader = new THREE.TextureLoader();
    renderer.setSize(window.innerWidth, window.innerHeight);
    var light = new THREE.DirectionalLight(0xffffff, 1.0);
    light.position.set(100, 100, 100);
    scene.add(light);
    var light2 = new THREE.DirectionalLight(0xffffff, 1.0);
    light2.position.set(-100, 100, -100);
    scene.add(light2);

    function onError() {}

    function onProgress(xhr) {
        if (xhr.lengthComputable) {
            var percentComplete = xhr.loaded / xhr.total * 100;
            console.log('model ' + Math.round(percentComplete, 2) + '% downloaded');
        }
    }

    function loadModel() {
        setTimeout(function () {
            wrapper.add(head);
            scene.add(wrapper);
        }, 10);
    }
    material.opacity = 0.6;
    var hiddenPlane = new THREE.Mesh(planeGeometry, material);
    hiddenPlane.position.set(0, 0, 50);
    scene.add(hiddenPlane);
    var mouse = new THREE.Vector2(0, 0);
    var point = new THREE.Vector3(0, 0, 0);
    var raycaster = new THREE.Raycaster();
    camera.lookAt(scene.position);
    window.addEventListener('mousemove', onMouseMove, false);
    window.addEventListener('resize', onWindowResize, false);

    function onMouseMove(event) {
        event.preventDefault();
        mouse.x = (event.clientX / window.innerWidth) * 2 - 1;
        mouse.y = -(event.clientY / window.innerHeight) * 2 + 1;
        raycaster.setFromCamera(mouse, camera);
        var intersects = raycaster.intersectObject(hiddenPlane);
        if (intersects.length > 0) {
            point = intersects[0].point;
        }
    };

    function onWindowResize() {
        camera.aspect = window.innerWidth / window.innerHeight;
        camera.updateProjectionMatrix();
        renderer.setSize(window.innerWidth, window.innerHeight);
    }

    function animate() {
        requestAnimationFrame(animate);
        render();
    }

    function render() {
        wrapper.lookAt(point);
        renderer.render(scene, camera);
    }
    window.onload = function () {
        document.getElementById("scene3d").appendChild(renderer.domElement);
    }

    animate();

PS:似乎还有另一个问题是material.opacity = 0.6;缺少正确的声明,这可能会导致场景无法正确渲染。

于 2019-01-21T21:03:01.087 回答