2016-09-07 64 views
1

我在這裏要做的是當用戶點擊對象模型的特定部分時,該部分的線框被暴露以顯示哪個部分正在發生變化。用戶可以從調色板中選取相同部分的顏色。在顏色選擇上,我希望模型的這一部分改變顏色。這裏child.material.color.set(selectedColor)由於某種原因不起作用。我錯過了什麼嗎?請原諒冗長的代碼庫。更改點擊對象模型的顏色 ​​- Three.js

<!DOCTYPE html> 
<html lang="en"> 
<head> 
    <meta charset="UTF-8"> 
    <title>Tacchhi.com Demo</title> 
    <link rel="stylesheet" href="css/main.css"> 
</head> 
<body> 

    <div class="palette"> 
     <span></span> 
     <span></span> 
     <span></span> 
    </div> 

    <script src="https://code.jquery.com/jquery-2.2.4.min.js"></script> 
    <script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/1.19.0/TweenMax.min.js"></script> 
    <script src="js/Three-r80.js"></script> 
    <script src="js/OrbitControls.js"></script> 
    <script src="js/OBJLoader.js"></script> 
    <script src="js/MTLLoader.js"></script> 
    <script src="js/Projector.js"></script> 
    <script> 
     //GLOBAL VARIABLES 
     var renderCanvas, scene, camera, renderer, cameraControl, objModel, raycaster, vector, clickInfo, marker, modelHasLoaded; 

     //VIEWPORT DIMENSIONS 
     var viewportWidth = window.innerWidth; 
     var viewportHeight = window.innerHeight; 

     function init(){ 
      //SCENE 
      window.scene = new THREE.Scene(); 

      //CAMERA 
      camera = new THREE.PerspectiveCamera(75, viewportWidth/viewportHeight, 1, 1000); 
      camera.position.set(0, 20, 160); 
      camera.lookAt(scene.position); 

      //RENDERER 
      renderer = new THREE.WebGLRenderer(); 
      renderer.setSize(viewportWidth, viewportHeight); 
      renderer.setClearColor('#ccc'); 

      //LIGHTING 
      var ambientLight = new THREE.AmbientLight('#000'); 
      scene.add(ambientLight); 
      var pointLight = new THREE.PointLight('#fff', 1, 2000); 
      pointLight.position.set(-window.innerWidth, 0, 0); 
      var pointLight2 = new THREE.PointLight('#fff', 1, 2000); 
      pointLight2.position.set(window.innerWidth, 0, 0); 
      var pointLight3 = new THREE.PointLight('#fff', 1, 2000); 
      pointLight3.position.set(0, viewportHeight/2, -100); 
      var pointLight4 = new THREE.PointLight('#fff', 1, 2000); 
      pointLight4.position.set(0, 0, 100); 
      scene.add(pointLight); 
      scene.add(pointLight2); 
      scene.add(pointLight3); 
      scene.add(pointLight4); 

      //OBJECT MODEL WITHOUT MATERIALS 
      var objLoader = new THREE.OBJLoader(); 
      objLoader.setPath('obj/') 
      objLoader.load('deadpool.obj', function(object){ 
       objModel = object; 
       objModel.position.set(0, -90, 0); 
       objModel.rotation.y = 300; 
       objModel.name = 'ObjectModel3D'; 
       modelHasLoaded = true; 
       scene.add(objModel); 
      }); 

      //ORBIT CONTROLS 
      cameraControl = new THREE.OrbitControls(camera); 

      //RENDER AFTER OBJECT HAS LOADED 
      function renderCheck(){ 
       if(modelHasLoaded){ 
        render(); 
        clearInterval(renderCheckInterval); 

        //set mouse cursor for drag/dragend 
        renderCanvas = document.getElementsByTagName("canvas")[0]; 
        renderCanvas.style.cursor = "url('images/grab-icon.png'), auto"; 
        renderCanvas.addEventListener('mousedown', function(){ 
         renderCanvas.style.cursor = "url('images/grabbing-icon.png'), auto"; 
        }, false); 
        renderCanvas.addEventListener('mouseup', function(){ 
         renderCanvas.style.cursor = "url('images/grab-icon.png'), auto"; 
        }, false); 
       } else {  
        console.log('model not loaded'); 
       } 
      } 
      var renderCheckInterval = setInterval(renderCheck, 500); 

      //RAYCASTING 
      raycaster = new THREE.Raycaster(); 
      vector = new THREE.Vector3(); 
      clickInfo = { 
       x: 0, 
       y: 0, 
       userHasClicked: false 
      }; 
      window.addEventListener('click', function(event){ 
       clickInfo.userHasClicked = true; 
       clickInfo.x = event.clientX; 
       clickInfo.y = event.clientY; 
      }, false); 

      //MARKER FOR RAYCASTING 
      marker = new THREE.Mesh(new THREE.SphereGeometry(1), new THREE.MeshBasicMaterial({color: 'red'})); 

      //APPEND CANVAS 
      document.body.appendChild(renderer.domElement); 
     } 

     function render(){ 
      //check for user clicks 
      if(clickInfo.userHasClicked){ 
       clickInfo.userHasClicked = false; 
       var x = (clickInfo.x/innerWidth) * 2 - 1; 
       var y = -(clickInfo.y/innerHeight) * 2 + 1; 
       vector.set(x, y, 0.5); 
       vector.unproject(camera); 
       raycaster.set(camera.position, vector.sub(camera.position).normalize()); 
       var intersects = raycaster.intersectObjects(scene.children, true); 
       if(intersects.length){ 
        var target = intersects[0]; 

        //place marker on click location 
        marker.position.set(target.point.x, target.point.y, target.point.z); 
        scene.add(marker); 
        applyWireframe(); 

        //display color palette 
        TweenLite.to($('.palette'), 0.75, {left: '0', ease: Power4.easeOut}); 
       } else { 
        removeWireframe(); 

        //hide color palette 
        TweenLite.to($('.palette'), 0.75, {left: '-100px', ease: Power4.easeOut}); 
       } 
      } 
      requestAnimationFrame(render); 
      cameraControl.update(); 
      renderer.render(scene, camera); 
     } 

     //APPLY WIREFRAME FOR THE SELECTED PART 
     function applyWireframe(){ 
      var wireframeObject = scene.getObjectByName('ObjectModel3D', true); 
      wireframeObject.traverse(function(child){ 
       if(child instanceof THREE.Mesh){ 
        child.material.wireframe = true; 
        child.material.linewidth = 1; 
        child.material.color.set('#333'); 
       } 
      }); 
     } 

     //REMOVE WIREFRAME FOR THE SELECTED PART 
     function removeWireframe(){ 
      scene.remove(marker); 
      var wireframeObject = scene.getObjectByName('ObjectModel3D', true); 
      wireframeObject.traverse(function(child){ 
       if(child instanceof THREE.Mesh){ 
        child.material.wireframe = false; 
        child.material.color.set('#fff'); 
       } 
      }); 
     } 

     //SET COLOR OF OBJECT MODEL 
     $('.palette span').click(function(){ 
      $color = new THREE.Color($(this).css('backgroundColor')); 
      var selectedColor = '#' + $color.getHexString(); 
      var item = scene.getObjectByName('ObjectModel3D', true); 
      item.traverse(function(child){ 
       if(child instanceof THREE.Mesh){ 
        child.material.color.set(selectedColor); 
        console.log('material color set to - ' + selectedColor); 
       } 
      }); 
     }); 

     window.onload = init; 
    </script> 
</body> 
</html> 

回答

1

只是一堆想法:

是selectedColor一個正確的十六進制?

硬編碼使用另一種顏色設置代替setHex的,只是要確定所有的對象越來越着色。

致電requestAnimationFrame(render);在顏色變化後,它會反映您可能已經完成的所有更改,否則可能需要一些時間才能刷新場景。

編輯:

這裏談到的紅色藥丸...也許這是一個痛苦的解決方案,但它是最好的做法反正在圖形世界...... 你應該分享材料。這意味着,預先創建所有需要的材料,並在整個應用程序中重複使用相同的定義材料。這可以在創建 - 刪除資料時節省應用程序內存或開銷。然後,創建兩個材質,例如:ObjectMaterial和SelectedObjectMaterial。無論何時您的對象被選中,只要它不再被選中,就將其材質更改爲SelectedObjectMaterial,並將其重新分配給ObjectMaterial。

共享方法也適用於網格和幾何體,這意味着更好的應用程序,更好的性能和更清晰的代碼。

+0

selectedColor是正確的。 ** set()**而不是** setHex()**也不工作。唯一發生的事情就是從場景中移除線框。對象模型的第一個顏色仍然存在。 –

+0

它可以使用硬編碼的顏色嗎? – juagicre

+0

不適用於硬編碼顏色。 –