无法似乎将我的obj添加到场景中:THREE.Object3D.add:对象不是THREE.Object3D

时间:2019-01-21 19:59:03

标签: javascript html three.js objloader

我刚开始使用 three.js 。我曾经使用JSON文件作为3D模型,但是当我从Blender导出3D文件时,实际的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模型似乎已加载,但我认为无法将其添加到场景中

1 个答案:

答案 0 :(得分:0)

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

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

从objloader2文档设置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;似乎还有另一个问题,缺少正确的声明,可能导致场景无法正确渲染。