2017-04-26 4 views
0

"disk.png"를 사용하여 만든 텍스처를 제외하고 MouseOver 이벤트를 구현하여 응용 프로그램에서 여러 객체의 색상을 변경할 수있었습니다. 결과 창의 빨간색 점). 나는 반대를 할 수 있고 텍스처의 색만 바꿀 수 있기를 원합니다. 그런 일을하기 위해 내 코드의 어떤 부분을 변경해야합니까?Three.js에서 MouseOver의 텍스처 색상 변경

var renderer, scene, camera; 
 
var control; 
 
var stats; 
 
var cameraControl; 
 
//var radius = 7.7; 
 
var radius = 15; 
 
var group = new THREE.Object3D(); 
 
    
 
var raycaster = new THREE.Raycaster(); 
 
var mouse = new THREE.Vector3(), INTERSECTED; 
 
    
 
// Initialize the scene, camera and objects. 
 
function init() { 
 
    
 
    // To display anything, you need 3 things: (1) Scene, (2) Camera, (3) Renderer 
 
    scene = new THREE.Scene(); 
 
    camera = new THREE.PerspectiveCamera(45, window.innerWidth/window.innerHeight, 0.1, 1000); 
 
    renderer = new THREE.WebGLRenderer(); 
 
    renderer.setClearColor(0x000000, 1.0); 
 
    renderer.setSize(window.innerWidth, window.innerHeight); 
 
    renderer.shadowMapEnabled = true; 
 
    
 
    // Mars needs (1) geometry, (2) material, (3) mesh 
 
    var sphereGeometry = new THREE.SphereGeometry(15, 60, 60); 
 
    var sphereMaterial = createMarsMaterial(); 
 
    var marsMesh = new THREE.Mesh(sphereGeometry, sphereMaterial); 
 
    marsMesh.name = 'mars'; 
 
    scene.add(marsMesh); 
 
    
 
    // position and point the camera to the center of the scene 
 
    camera.position.x = 25; 
 
    camera.position.y = 26; 
 
    camera.position.z = 30; 
 
    camera.lookAt(scene.position); 
 
    
 
    // add controls 
 
    cameraControl = new THREE.OrbitControls(camera); 
 
    
 
    // setup the control object for the control gui 
 
    control = new function() { 
 
    this.rotationSpeed = 0.000; 
 
    }; 
 
    
 
    // add extras 
 
    addControlGui(control); 
 
    addStatsObject(); 
 
    
 
    // add the output of the renderer to the html element 
 
    document.body.appendChild(renderer.domElement); 
 
    
 
    // add a star field 
 
    var starsGeometry = new THREE.Geometry(); 
 

 
    for (var i = 0; i < 10000; i ++) { 
 

 
    var star = new THREE.Vector3(); 
 
    star.x = THREE.Math.randFloatSpread(2000); 
 
    star.y = THREE.Math.randFloatSpread(2000); 
 
    star.z = THREE.Math.randFloatSpread(2000); 
 

 
    starsGeometry.vertices.push(star) 
 

 
    } 
 

 
    var starsMaterial = new THREE.PointsMaterial({ color: 0xF9F9CF }) 
 

 
    var starField = new THREE.Points(starsGeometry, starsMaterial); 
 

 
    scene.add(starField); 
 

 
    // start animating 
 
    render(); 
 
    
 
} 
 
    
 
function createMarsMaterial() { 
 
    
 
    // 4096 is the maximum width for maps 
 
    var marsTexture = THREE.ImageUtils; 
 
    marsTexture.crossOrigin = ""; 
 
    
 
    marsTexture = THREE.ImageUtils.loadTexture("https://tatornator12.github.io/classes/final-project/Using_Three_-_D3/mars.jpg"); 
 
    var marsMaterial = new THREE.MeshBasicMaterial(); 
 
    marsMaterial.map = marsTexture; 
 
    return marsMaterial; 
 
} 
 
    
 
function addControlGui(controlObject) { 
 
    
 
    var gui = new dat.GUI(); 
 
    gui.add(controlObject, 'rotationSpeed', -0.01, 0.01); 
 
} 
 
    
 
function addStatsObject() { 
 
    stats = new Stats(); 
 
    stats.setMode(0); 
 
    stats.domElement.style.position = 'absolute'; 
 
    stats.domElement.style.left = '0px'; 
 
    stats.domElement.style.top = '0px'; 
 
    document.body.appendChild(stats.domElement); 
 
} 
 
    
 
function render() { 
 
    stats.update(); 
 
    cameraControl.update(); 
 
    scene.getObjectByName('mars').rotation.y += control.rotationSpeed; 
 
    
 
    renderer.render(scene, camera); 
 
    requestAnimationFrame(render); 
 
} 
 
    
 
function handleResize() { 
 
    camera.aspect = window.innerWidth/window.innerHeight; 
 
    camera.updateProjectionMatrix(); 
 
    renderer.setSize(window.innerWidth, window.innerHeight); 
 
} 
 
    
 
window.onload = init; 
 
window.addEventListener('resize', handleResize, false); 
 
window.addEventListener('mousemove', onMouseMove, false); 
 

 
    
 
    
 
var Landing_Sites = "https://tatornator12.github.io/classes/final-project/Mars_LandingSites2.json"; 
 

 
d3.queue() 
 
    .defer(d3.json, Landing_Sites) 
 
    .await(ready); 
 

 
function ready(error, json) { 
 
    if (error) throw error; 
 

 
    scene.add(graticule = wireframe(graticule10(), new THREE.LineBasicMaterial({color: 0xaaaaaa}))); 
 
    
 
    json.features.forEach(function(d) { group.add(createDot(d)) }); 
 
    scene.add(group); 
 
    d3.timer(function(t) { 
 
    //group.rotation.y = Math.sin(t/11000) * Math.PI/3 - Math.PI/2; 
 
    // group.rotation.y = t/10000; 
 
    renderer.render(scene, camera); 
 
    }); 
 

 
} 
 

 
// Converts a point [longitude, latitude] in degrees to a THREE.Vector3. 
 
function vertex(point) { 
 
    var lambda = point[0] * Math.PI/180, 
 
     phi = point[1] * Math.PI/180, 
 
     cosPhi = Math.cos(phi); 
 
    return new THREE.Vector3(
 
    radius * cosPhi * Math.cos(lambda), 
 
    radius * cosPhi * Math.sin(lambda), 
 
    radius * Math.sin(phi) 
 
); 
 
} 
 

 
function createDot(feature) { 
 
    
 
    var landingSitesGeometry = new THREE.Geometry(); 
 
    var position = vertex(feature.geometry.coordinates); 
 
    landingSitesGeometry.vertices.push(position); 
 
    var landingSitesMaterial = new THREE.PointsMaterial({ size: 1.5, color: 0xff0000, map: THREE.ImageUtils.loadTexture("https://raw.githubusercontent.com/mrdoob/three.js/master/examples/textures/sprites/disc.png"), transparent: true }); 
 
var dot = new THREE.Points(landingSitesGeometry, landingSitesMaterial); 
 
    dot.position.set(position.x, position.y, position.z); 
 
    return dot; 
 
} 
 

 
// Converts a GeoJSON MultiLineString in spherical coordinates to a THREE.LineSegments. 
 
function wireframe(multilinestring, material) { 
 
    var geometry = new THREE.Geometry; 
 
    multilinestring.coordinates.forEach(function(line) { 
 
    d3.pairs(line.map(vertex), function(a, b) { 
 
     geometry.vertices.push(a, b); 
 
    }); 
 
    }); 
 
    return new THREE.LineSegments(geometry, material); 
 
} 
 

 
// See https://github.com/d3/d3-geo/issues/95 
 
function graticule10() { 
 
    var epsilon = 1e-6, 
 
     x1 = 180, x0 = -x1, y1 = 80, y0 = -y1, dx = 10, dy = 10, 
 
     X1 = 180, X0 = -X1, Y1 = 90, Y0 = -Y1, DX = 90, DY = 360, 
 
     x = graticuleX(y0, y1, 2.5), y = graticuleY(x0, x1, 2.5), 
 
     X = graticuleX(Y0, Y1, 2.5), Y = graticuleY(X0, X1, 2.5); 
 

 
    function graticuleX(y0, y1, dy) { 
 
    var y = d3.range(y0, y1 - epsilon, dy).concat(y1); 
 
    return function(x) { return y.map(function(y) { return [x, y]; }); }; 
 
    } 
 

 
    function graticuleY(x0, x1, dx) { 
 
    var x = d3.range(x0, x1 - epsilon, dx).concat(x1); 
 
    return function(y) { return x.map(function(x) { return [x, y]; }); }; 
 
    } 
 

 
    return { 
 
    type: "MultiLineString", 
 
    coordinates: d3.range(Math.ceil(X0/DX) * DX, X1, DX).map(X) 
 
     .concat(d3.range(Math.ceil(Y0/DY) * DY, Y1, DY).map(Y)) 
 
     .concat(d3.range(Math.ceil(x0/dx) * dx, x1, dx).filter(function(x) { return Math.abs(x % DX) > epsilon; }).map(x)) 
 
     .concat(d3.range(Math.ceil(y0/dy) * dy, y1 + epsilon, dy).filter(function(y) { return Math.abs(y % DY) > epsilon; }).map(y)) 
 
    }; 
 
} 
 
    
 
    function onMouseMove(event) { 
 

 
\t // calculate mouse position in normalized device coordinates 
 
\t // (-1 to +1) for both components 
 
    
 
    event.preventDefault(); 
 

 
\t mouse.x = (event.clientX/window.innerWidth) * 2 - 1; 
 
\t mouse.y = - (event.clientY/window.innerHeight) * 2 + 1; 
 

 
    // update the picking ray with the camera and mouse position 
 
\t raycaster.setFromCamera(mouse, camera); 
 
    
 
    
 
    // calculate objects intersecting the picking ray 
 
\t var intersects = raycaster.intersectObjects(scene.children); 
 

 
    // if there is one (or more) intersections 
 
    if (intersects.length > 0) 
 
    { 
 
    // if the closest object intersected is not the currently stored intersection object 
 
    if (intersects[ 0 ].object != INTERSECTED) 
 
    { 
 
     // restore previous intersection object (if it exists) to its original color 
 
     if (INTERSECTED) 
 
      INTERSECTED.material.color.setHex(INTERSECTED.currentHex); 
 
     // store reference to closest object as current intersection object 
 
     INTERSECTED = intersects[ 0 ].object; 
 
     // store color of closest object (for later restoration) 
 
     INTERSECTED.currentHex = INTERSECTED.material.color.getHex(); 
 
     // set a new color for closest object 
 
     INTERSECTED.material.color.setHex(0x00ff00); 
 
    } 
 
    } 
 
    else // there are no intersections 
 
    { 
 
    // restore previous intersection object (if it exists) to its original color 
 
    if (INTERSECTED) 
 
     INTERSECTED.material.color.setHex(INTERSECTED.currentHex); 
 
    // remove previous intersection object reference 
 
    //  by setting current intersection object to "nothing" 
 
    INTERSECTED = null; 
 
} 
 
    
 
}
body { 
 
    /* set margin to 0 and overflow to hidden, to go fullscreen */ 
 
    margin: 0; 
 
    overflow: hidden; 
 
}
<script src="https://d3js.org/d3.v4.min.js"></script> 
 
<script src="https://d3js.org/topojson.v2.min.js"></script> 
 
<script src="https://tatornator12.github.io/classes/final-project/Using_Three_-_D3/three.js"></script> 
 
<script src="https://tatornator12.github.io/classes/final-project/Using_Three_-_D3/OrbitControls.js"></script> 
 
<script src="https://tatornator12.github.io/classes/final-project/Using_Three_-_D3/dat.gui.min.js"></script> 
 
<script src="https://tatornator12.github.io/classes/final-project/Using_Three_-_D3/stats.min.js"></script>

+0

뭔가 코드 문제가 될 것으로 보인다. 이미지 텍스처를 제거하더라도 작동하지 않습니다. 중단 점을 찍으면 레이 캐스트가 교차점을 감지하지 못한다는 것을 알 수 있습니다. 이상한 ... – Nate

+0

수정 방법에 대한 의견이 있으십니까? 텍스처를 만드는 코드에서 뭔가 잘못되었다는 것을 의미합니까? 또는 교차로와? – Lprox5

+0

알고 싶습니다. 어제 그걸 가지고 놀았고 그 문제를 일으키는 원인을 알 수 없었습니다. 내 실망한 시간에 다시 한번 살펴 보겠습니다. – Nate

답변

1

포인트의 경계 영역은 반경 0으로 초기화됩니다. 귀하의 마우스는 결코 그것을 치지 않습니다. 나는 바운딩 구를 수동으로 만들어야 만했다.

var renderer, scene, camera; 
 
var control; 
 
var stats; 
 
var cameraControl; 
 
//var radius = 7.7; 
 
var radius = 15; 
 
var group = new THREE.Object3D(); 
 
    
 
var raycaster = new THREE.Raycaster(); 
 
var mouse = new THREE.Vector3(), INTERSECTED; 
 
    
 
// Initialize the scene, camera and objects. 
 
function init() { 
 
    
 
    // To display anything, you need 3 things: (1) Scene, (2) Camera, (3) Renderer 
 
    scene = new THREE.Scene(); 
 
    camera = new THREE.PerspectiveCamera(45, window.innerWidth/window.innerHeight, 0.1, 1000); 
 
    renderer = new THREE.WebGLRenderer(); 
 
    renderer.setClearColor(0x000000, 1.0); 
 
    renderer.setSize(window.innerWidth, window.innerHeight); 
 
    renderer.shadowMapEnabled = true; 
 
    
 
    // Mars needs (1) geometry, (2) material, (3) mesh 
 
    var sphereGeometry = new THREE.SphereGeometry(15, 60, 60); 
 
    var sphereMaterial = createMarsMaterial(); 
 
    var marsMesh = new THREE.Mesh(sphereGeometry, sphereMaterial); 
 
    marsMesh.name = 'mars'; 
 
    scene.add(marsMesh); 
 
    
 
    // position and point the camera to the center of the scene 
 
    camera.position.x = 25; 
 
    camera.position.y = 26; 
 
    camera.position.z = 30; 
 
    camera.lookAt(scene.position); 
 
    
 
    // add controls 
 
    cameraControl = new THREE.OrbitControls(camera); 
 
    
 
    // setup the control object for the control gui 
 
    control = new function() { 
 
    this.rotationSpeed = 0.000; 
 
    }; 
 
    
 
    // add extras 
 
    addControlGui(control); 
 
    addStatsObject(); 
 
    
 
    // add the output of the renderer to the html element 
 
    document.body.appendChild(renderer.domElement); 
 
    
 
    // add a star field 
 
    var starsGeometry = new THREE.Geometry(); 
 

 
    for (var i = 0; i < 10000; i ++) { 
 

 
    var star = new THREE.Vector3(); 
 
    star.x = THREE.Math.randFloatSpread(2000); 
 
    star.y = THREE.Math.randFloatSpread(2000); 
 
    star.z = THREE.Math.randFloatSpread(2000); 
 

 
    starsGeometry.vertices.push(star) 
 

 
    } 
 

 
    var starsMaterial = new THREE.PointsMaterial({ color: 0xF9F9CF }) 
 

 
    var starField = new THREE.Points(starsGeometry, starsMaterial); 
 

 
    scene.add(starField); 
 

 
    // start animating 
 
    render(); 
 
    
 
} 
 
    
 
function createMarsMaterial() { 
 
    
 
    // 4096 is the maximum width for maps 
 
    var marsTexture = THREE.ImageUtils; 
 
    marsTexture.crossOrigin = ""; 
 
    
 
    marsTexture = THREE.ImageUtils.loadTexture("https://tatornator12.github.io/classes/final-project/Using_Three_-_D3/mars.jpg"); 
 
    var marsMaterial = new THREE.MeshBasicMaterial(); 
 
    marsMaterial.map = marsTexture; 
 
    return marsMaterial; 
 
} 
 
    
 
function addControlGui(controlObject) { 
 
    
 
    var gui = new dat.GUI(); 
 
    gui.add(controlObject, 'rotationSpeed', -0.01, 0.01); 
 
} 
 
    
 
function addStatsObject() { 
 
    stats = new Stats(); 
 
    stats.setMode(0); 
 
    stats.domElement.style.position = 'absolute'; 
 
    stats.domElement.style.left = '0px'; 
 
    stats.domElement.style.top = '0px'; 
 
    document.body.appendChild(stats.domElement); 
 
} 
 
    
 
function render() { 
 
    stats.update(); 
 
    cameraControl.update(); 
 
    scene.getObjectByName('mars').rotation.y += control.rotationSpeed; 
 
    
 
    renderer.render(scene, camera); 
 
    requestAnimationFrame(render); 
 
} 
 
    
 
function handleResize() { 
 
    camera.aspect = window.innerWidth/window.innerHeight; 
 
    camera.updateProjectionMatrix(); 
 
    renderer.setSize(window.innerWidth, window.innerHeight); 
 
} 
 
    
 
window.onload = init; 
 
window.addEventListener('resize', handleResize, false); 
 
window.addEventListener('mousemove', onMouseMove, false); 
 

 
    
 
    
 
var Landing_Sites = "https://tatornator12.github.io/classes/final-project/Mars_LandingSites2.json"; 
 

 
d3.queue() 
 
    .defer(d3.json, Landing_Sites) 
 
    .await(ready); 
 

 
function ready(error, json) { 
 
    if (error) throw error; 
 

 
    scene.add(graticule = wireframe(graticule10(), new THREE.LineBasicMaterial({color: 0xaaaaaa}))); 
 
    
 
    json.features.forEach(function(d) { group.add(createDot(d)) }); 
 
    scene.add(group); 
 
    d3.timer(function(t) { 
 
    //group.rotation.y = Math.sin(t/11000) * Math.PI/3 - Math.PI/2; 
 
    // group.rotation.y = t/10000; 
 
    renderer.render(scene, camera); 
 
    }); 
 
    console.clear(); 
 

 
} 
 

 
// Converts a point [longitude, latitude] in degrees to a THREE.Vector3. 
 
function vertex(point) { 
 
    var lambda = point[0] * Math.PI/180, 
 
     phi = point[1] * Math.PI/180, 
 
     cosPhi = Math.cos(phi); 
 
    return new THREE.Vector3(
 
    radius * cosPhi * Math.cos(lambda), 
 
    radius * cosPhi * Math.sin(lambda), 
 
    radius * Math.sin(phi) 
 
); 
 
} 
 

 
function createDot(feature) { 
 
    
 
    var landingSitesGeometry = new THREE.Geometry(); 
 
    var position = vertex(feature.geometry.coordinates); 
 
    landingSitesGeometry.vertices.push(position); 
 
    var landingSitesMaterial = new THREE.PointsMaterial({ size: 1.5, color: 0xff0000, map: THREE.ImageUtils.loadTexture("https://raw.githubusercontent.com/mrdoob/three.js/master/examples/textures/sprites/disc.png"), transparent: true }); 
 
var dot = new THREE.Points(landingSitesGeometry, landingSitesMaterial); 
 
    dot.position.set(position.x, position.y, position.z); 
 
    dot.geometry.boundingSphere = new THREE.Sphere(); 
 
    dot.geometry.boundingSphere.center.x = position.x; 
 
    dot.geometry.boundingSphere.center.y = position.y; 
 
    dot.geometry.boundingSphere.center.z = position.z; 
 
    dot.geometry.boundingSphere.radius = 1.5; 
 
    return dot; 
 
} 
 

 
// Converts a GeoJSON MultiLineString in spherical coordinates to a THREE.LineSegments. 
 
function wireframe(multilinestring, material) { 
 
    var geometry = new THREE.Geometry; 
 
    multilinestring.coordinates.forEach(function(line) { 
 
    d3.pairs(line.map(vertex), function(a, b) { 
 
     geometry.vertices.push(a, b); 
 
    }); 
 
    }); 
 
    return new THREE.LineSegments(geometry, material); 
 
} 
 

 
// See https://github.com/d3/d3-geo/issues/95 
 
function graticule10() { 
 
    var epsilon = 1e-6, 
 
     x1 = 180, x0 = -x1, y1 = 80, y0 = -y1, dx = 10, dy = 10, 
 
     X1 = 180, X0 = -X1, Y1 = 90, Y0 = -Y1, DX = 90, DY = 360, 
 
     x = graticuleX(y0, y1, 2.5), y = graticuleY(x0, x1, 2.5), 
 
     X = graticuleX(Y0, Y1, 2.5), Y = graticuleY(X0, X1, 2.5); 
 

 
    function graticuleX(y0, y1, dy) { 
 
    var y = d3.range(y0, y1 - epsilon, dy).concat(y1); 
 
    return function(x) { return y.map(function(y) { return [x, y]; }); }; 
 
    } 
 

 
    function graticuleY(x0, x1, dx) { 
 
    var x = d3.range(x0, x1 - epsilon, dx).concat(x1); 
 
    return function(y) { return x.map(function(x) { return [x, y]; }); }; 
 
    } 
 

 
    return { 
 
    type: "MultiLineString", 
 
    coordinates: d3.range(Math.ceil(X0/DX) * DX, X1, DX).map(X) 
 
     .concat(d3.range(Math.ceil(Y0/DY) * DY, Y1, DY).map(Y)) 
 
     .concat(d3.range(Math.ceil(x0/dx) * dx, x1, dx).filter(function(x) { return Math.abs(x % DX) > epsilon; }).map(x)) 
 
     .concat(d3.range(Math.ceil(y0/dy) * dy, y1 + epsilon, dy).filter(function(y) { return Math.abs(y % DY) > epsilon; }).map(y)) 
 
    }; 
 
} 
 
    
 
    function onMouseMove(event) { 
 

 
\t // calculate mouse position in normalized device coordinates 
 
\t // (-1 to +1) for both components 
 
    
 
    event.preventDefault(); 
 

 
\t mouse.x = (event.clientX/window.innerWidth) * 2 - 1; 
 
\t mouse.y = - (event.clientY/window.innerHeight) * 2 + 1; 
 

 
    // update the picking ray with the camera and mouse position 
 
\t raycaster.setFromCamera(mouse, camera); 
 
    
 
    
 
    // calculate objects intersecting the picking ray 
 
\t var intersects = raycaster.intersectObjects(scene.children[3].children); 
 

 
    // if there is one (or more) intersections 
 
    if (intersects.length > 0) 
 
    { 
 
    // if the closest object intersected is not the currently stored intersection object 
 
    if (intersects[ 0 ].object != INTERSECTED) 
 
    { 
 
     // restore previous intersection object (if it exists) to its original color 
 
     if (INTERSECTED) 
 
      INTERSECTED.material.color.setHex(INTERSECTED.currentHex); 
 
     // store reference to closest object as current intersection object 
 
     INTERSECTED = intersects[ 0 ].object; 
 
     // store color of closest object (for later restoration) 
 
     INTERSECTED.currentHex = INTERSECTED.material.color.getHex(); 
 
     // set a new color for closest object 
 
     INTERSECTED.material.color.setHex(0x00ff00); 
 
    } 
 
    } 
 
    else // there are no intersections 
 
    { 
 
    // restore previous intersection object (if it exists) to its original color 
 
    if (INTERSECTED) 
 
     INTERSECTED.material.color.setHex(INTERSECTED.currentHex); 
 
    // remove previous intersection object reference 
 
    //  by setting current intersection object to "nothing" 
 
    INTERSECTED = null; 
 
} 
 
    
 
}
body { 
 
    /* set margin to 0 and overflow to hidden, to go fullscreen */ 
 
    margin: 0; 
 
    overflow: hidden; 
 
}
<script src="https://d3js.org/d3.v4.min.js"></script> 
 
<script src="https://d3js.org/topojson.v2.min.js"></script> 
 
<script src="https://tatornator12.github.io/classes/final-project/Using_Three_-_D3/three.js"></script> 
 
<script src="https://tatornator12.github.io/classes/final-project/Using_Three_-_D3/OrbitControls.js"></script> 
 
<script src="https://tatornator12.github.io/classes/final-project/Using_Three_-_D3/dat.gui.min.js"></script> 
 
<script src="https://tatornator12.github.io/classes/final-project/Using_Three_-_D3/stats.min.js"></script>

+0

위대한! 그 동안 쉐이더없이 완벽하게 실행됩니다. 마우스 오버 이벤트를 인식하지 못하기 때문에 쉐이더없이 처리해야하는지 궁금합니다. 그럼에도 불구하고, 나는 정말로 당신의 시간에 감사 드리며 이것에 대해 도움을! – Lprox5

+0

@ Lprox5 여러분을 환영합니다! 쉐이더 =와 함께 행운을 빈다.) – Nate

관련 문제