2013-08-20 35 views
11

Tôi đang cố gắng trao đổi kết cấu hình ảnh khi chạy trên một tệp ..jj được tải ba.js. Dưới đây là đoạn code trực tiếp từ ví dụ three.js với sửa đổi chút ít:Thay đổi kết cấu của tệp .obj được tải trong ba.js tại thời gian chạy

 var container, stats; 
     var camera, scene, renderer; 
     var mouseX = 0, mouseY = 0; 
     var windowHalfX = window.innerWidth/2; 
     var windowHalfY = window.innerHeight/2; 


     init(); 
     animate(); 


     function init() { 

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

      camera = new THREE.PerspectiveCamera(45, window.innerWidth/window.innerHeight, 1, 2000); 
      camera.position.z = 100; 

      //scene 
      scene = new THREE.Scene(); 

      var ambient = new THREE.AmbientLight(0x101030); 
      scene.add(ambient); 

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

      //manager 
      var manager = new THREE.LoadingManager(); 
      manager.onProgress = function (item, loaded, total) { 

       console.log(item, loaded, total); 

      }; 

      //model 
      var loader = new THREE.OBJLoader(manager); 
      loader.load('obj/female02/female02.obj', function (object) { 
       object.traverse(function (child) { 

        if (child instanceof THREE.Mesh) { 
         //create a global var to reference later when changing textures 
         myMesh = child; 
         //apply texture 
         myMesh.material.map = THREE.ImageUtils.loadTexture('textures/ash_uvgrid01.jpg'); 
         myMesh.material.needsUpdate = true; 
        } 

       }); 


       object.position.y = - 80; 
       scene.add(object); 

      }); 

      //render 
      renderer = new THREE.WebGLRenderer(); 
      renderer.setSize(window.innerWidth, window.innerHeight); 
      container.appendChild(renderer.domElement); 

      document.addEventListener('mousemove', onDocumentMouseMove, false); 
      window.addEventListener('resize', onWindowResize, false); 

     } 

     function newTexture() { 
      myMesh.material.map = THREE.ImageUtils.loadTexture('textures/land_ocean_ice_cloud_2048.jpg'); 
      myMesh.material.needsUpdate = true; 
     } 

     function onWindowResize() { 

      windowHalfX = window.innerWidth/2; 
      windowHalfY = window.innerHeight/2; 

      camera.aspect = window.innerWidth/window.innerHeight; 
      camera.updateProjectionMatrix(); 

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

     } 

     function onDocumentMouseMove(event) { 

      mouseX = (event.clientX - windowHalfX)/2; 
      mouseY = (event.clientY - windowHalfY)/2; 

     } 

     //animate 
     function animate() { 

      requestAnimationFrame(animate); 
      render(); 

     } 

     function render() { 

      camera.position.x += (mouseX - camera.position.x) * .05; 
      camera.position.y += (- mouseY - camera.position.y) * .05; 

      camera.lookAt(scene.position); 

      renderer.render(scene, camera); 

     } 

Điều duy nhất tôi nói thêm là chức năng newTexture và một tham chiếu đến lưới như myMesh. Đây là ví dụ ban đầu (http://threejs.org/examples/webgl_loader_obj.html). Hàm không ném bất kỳ lỗi nào nhưng tệp .obj không cập nhật. Tôi biết tôi chỉ còn thiếu một cái gì đó cơ bản ở đây ..

Cập nhật: mỗi câu trả lời tuyệt vời dưới đây, đây là mã đúng với một số bổ sung để trao đổi kết cấu thông qua một lĩnh vực đầu vào:

var container, stats; 
    var camera, scene, renderer; 
    var mouseX = 0, mouseY = 0; 
    var windowHalfX = window.innerWidth/2; 
    var windowHalfY = window.innerHeight/2; 
    var globalObject; 

    init(); 
    animate(); 

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

     camera = new THREE.PerspectiveCamera(45, window.innerWidth/window.innerHeight, 1, 2000); 
     camera.position.z = 100; 

     //scene 
     scene = new THREE.Scene(); 

     var ambient = new THREE.AmbientLight(0x101030); 
     scene.add(ambient); 

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

     //manager 
     var manager = new THREE.LoadingManager(); 
     manager.onProgress = function (item, loaded, total) { 
     console.log(item, loaded, total); 
     }; 

    //model 
    var loader = new THREE.OBJLoader(manager); 
    loader.load('obj/female02/female02.obj', function (object) { 
     //store global reference to .obj 
     globalObject = object; 

     object.traverse(function (child) { 
      if (child instanceof THREE.Mesh) { 
       child.material.map = THREE.ImageUtils.loadTexture('textures/grid.jpg'); 
       child.material.needsUpdate = true; 
      } 
     }); 

     object.position.y = - 80; 
     scene.add(object); 
    }); 

    //render 
    renderer = new THREE.WebGLRenderer(); 
    renderer.setSize(window.innerWidth, window.innerHeight); 
    container.appendChild(renderer.domElement); 

    document.addEventListener('mousemove', onDocumentMouseMove, false); 
    window.addEventListener('resize', onWindowResize, false); 
    } 

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

    function onDocumentMouseMove(event) { 
    mouseX = (event.clientX - windowHalfX)/2; 
    mouseY = (event.clientY - windowHalfY)/2; 
    } 

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

    function render() { 
    camera.position.x += (mouseX - camera.position.x) * .05; 
    camera.position.y += (- mouseY - camera.position.y) * .05; 
      camera.lookAt(scene.position); 
      renderer.render(scene, camera); 
    } 

    function newTexture() { 
    var newTexturePath = "textures/" + document.getElementById("texture").value + ""; 

    globalObject.traverse(function (child) { 
     if (child instanceof THREE.Mesh) { 
      //create a global var to reference later when changing textures 
      child; 
      //apply texture 
      child.material.map = THREE.ImageUtils.loadTexture(newTexturePath); 
      child.material.needsUpdate = true; 
     } 
    }); 
    } 
+0

Không cần thiết 'child.material.needsUpdate = true; 'trong trường hợp này. Nó được đặt cho bạn bởi 'loadTexture()'. Đặt 'needsUpdate' chính bạn có thể gây ra vấn đề nếu tải kết cấu không đồng bộ bị trì hoãn. – WestLangley

+0

Cảm ơn bạn đã cập nhật mã <3 –

Trả lời

9

Vấn đề ở đây là có nhiều mắt lưới con trong biến số object. Bằng cách chỉ có một biến toàn cầu myMesh, bạn chỉ đang lưu trữ lưới con cuối cùng. Do đó, khi bạn cố gắng cập nhật kết cấu bằng biến toàn cục này, chỉ một trong các mắt lưới được cập nhật kết cấu, có thể là một phần ẩn nhỏ không hiển thị rõ ràng.

Các giải pháp sẽ được một trong hai:

  • cửa hàng một biến toàn cầu myMeshes mảng và đẩy myMesh vào nó mỗi khi có một. Sau đó, trong hàm newTexture() của bạn, hãy lặp qua tất cả các mục trong mảng này và cập nhật bản đồ/tài liệu của chúng.
  • Hoặc lưu trữ biến số object (số trả về từ cuộc gọi lại của OBJLoader) vào một biến toàn cầu duy nhất. Sau đó, trong hàm newTexture() của bạn, hãy lặp qua tất cả các mắt lưới như cách thực hiện trong mã (sử dụng câu lệnh traverse()if) và cập nhật bản đồ/tài liệu của chúng.

Cuối cùng, gọi newTexture() ở đâu đó trong mã của bạn cũng sẽ giúp;)

+0

Nó hoạt động ngay bây giờ cảm ơn! Tôi đã sử dụng tùy chọn thứ hai. Và yeah, tôi đã gọi newTexture() trong giao diện điều khiển để không rõ ràng. Tôi đã đăng mã làm việc ở trên vì lợi ích của mọi người. –

Các vấn đề liên quan