2016-09-07 33 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);色を変更した後は、行ったすべての変更が反映されます。そうしないと、シーンが更新されるまでに時間がかかることがあります。

EDIT:

ここでそれは赤い丸薬を付属しています... ...多分これは痛みを伴う解決策ですが、グラフィックスの世界では、とにかくベストプラクティスであるあなたは、材料を共有する必要があり。つまり、すべての種類の必要なマテリアルを事前に作成し、アプリケーション全体を通して全く同じ定義済みのマテリアルを再利用することを意味します。これにより、材料の作成 - 削除時にアプリケーションのメモリやオーバーヘッドが節約されます。次に、ObjectMaterialとSelectedObjectMaterialの2つのマテリアルを作成します。オブジェクトが選択されるたびに、その材料をSelectedObjectMaterialに変更します。これが選択されなくなると直ちに、ObjectMaterialを再度割り当てます。

共有方法は、メッシュやジオメトリにも適用されるため、より最適なアプリケーション、優れたパフォーマンス、より明確なコードを保存できます。

+0

selectedColorが正しくありません。 ** setHex()の代わりにset()**が動作しません。起こっているのは、シーンからのワイヤフレームの削除だけです。オブジェクトモデルの最初の色はまだ存続します。 –

+0

ハードコーディングされた色で動作しますか? – juagicre

+0

ハードコーディングされた色では動作しません。 –

関連する問題