2016-09-07 4 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

그냥 무리 :

는 올바른 16 진수 selectedColor인가?

는 하드 코드는 를 사용하여 다른 색상은 모든 개체가 착색지고 확인하기 위해, setHex 대신을 설정합니다.

전화 requestAnimationFrame (render);을 클릭하면 색상 변경 후 모든 변경 사항이 반영됩니다. 그렇지 않으면 장면이 새로 고침 될 때까지 약간의 시간이 걸릴 수 있습니다.

편집 : 여기

은 아마도이 고통스러운 솔루션입니다 ... 빨간 약을 제공하지만 그래픽의 세계에서 어쨌든 가장 좋은 방법입니다 ... 당신이 공유해야 재료. 즉, 모든 종류의 필요한 재료를 미리 만들고 모든 응용 프로그램에서 동일한 정의 된 재료를 다시 사용하는 것입니다. 이렇게하면 재료를 만들거나 삭제할 때 응용 프로그램 메모리 또는 오버 헤드가 절약됩니다. 그런 다음 ObjectMaterial과 SelectedObjectMaterial과 같은 두 가지 자료를 작성하십시오. 오브젝트가 선택 될 때마다 Material을 SelectedObjectMaterial으로 변경하고 더 이상 선택하지 않는 즉시 ObjectMaterial을 다시 할당하십시오.

공유 방법론은 메쉬 및 지오메트리에도 적용되므로 더 최적의 애플리케이션, 더 나은 성능 및 명확한 코드를 의미합니다.

+0

selectedColor가 정확합니다. ** setHex() ** 대신 ** set() **이 작동하지 않습니다. 유일한 일은 장면에서 와이어 프레임을 제거하는 것입니다. 객체 모델의 첫 번째 색상은 계속 유지됩니다. –

+0

하드 코딩 된 색상으로 작동합니까? – juagicre

+0

하드 코딩 된 색상으로 작업하지 않습니다. –