【问题标题】:Mirrored Raycaster on WebGl Globe (sphere)WebGl Globe(球体)上的镜像 Raycaster
【发布时间】:2020-05-01 00:34:28
【问题描述】:

对于我的论文项目,我使用 DataArts WebGL Globe 来开发一个网页,该网页将在触摸显示器上的展览中使用。作为显示器触摸,我需要使地球可点击以选择单个国家并打开弹出窗口并突出显示所选国家。我正在使用 RayCaster 来查找触摸/点击的坐标,但是通过我的方法,我获得了镜像选择(从字面上看,如果我点击一个点,点击将定位在地球的相反大小)。问题似乎只在 x 轴上,但我认为我犯了更多错误。整个代码和整个项目上传到http://www.pietroforino.com/globe/,raycaster代码位于第660行的onMouseDown函数中。这里是代码

var raycaster  = new THREE.Raycaster();
var mouse = new THREE.Vector3();

[...]

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

raycaster.setFromCamera( mouse, camera );

var intersects = raycaster.intersectObjects( scene.children );

for ( var i = 0; i < intersects.length; i++ ) {
data = intersects[i];
var d = data.point.clone().normalize();
var u = Math.round(4096 * (1 - (0.5 + Math.atan2(d.z, d.x) / (2 * Math.PI))));
var v = Math.round(2048 * (0.5 - Math.asin(d.y) / (Math.PI)));
var p = mapContext.getImageData(u,v,1,10).data;
countryCode = p[0];

for( var prop in countryColorMap ) {
    if( countryColorMap.hasOwnProperty( prop ) ) {
         if( countryColorMap[ prop ] === countryCode )
             console.log(prop, countryCode);
  }
} // end for loop

lookupContext.clearRect(0,0,256,1);

for (var j = 0; j < 228; j++)
{
  if (j == 0)
    lookupContext.fillStyle = "rgba(0,0,0,1.0)"
  else if (j == countryCode)
    lookupContext.fillStyle = "rgba(240,48,104,0.6)"
  else
    lookupContext.fillStyle = "rgba(0,0,0,1.0)"

  lookupContext.fillRect( j, 0, 1, 1 );
 }

 lookupTexture.needsUpdate = true;
}

我需要这个实现,请帮我解决这个问题。

编辑 1.0

非常感谢您的回答,我已将 var 从 i 更改为 j,但没有任何改变。我也试过删除

for ( var i = 0; i < intersects.length; i++ ) {

这是没用的,但又没有任何改变。现在可能是什么?

附言新版while代码上线了

【问题讨论】:

    标签: three.js raycasting webgl-globe


    【解决方案1】:

    您的代码中存在错误。外部for 循环变量i 在内部for 循环中被修改。也就是说这里的循环变量:

    for ( var i = 0; i < intersects.length; i++ )
    

    改变
    for (var i = 0; i < 228; i++)
    

    这打破了第一个循环。只需在第二个循环中将i 替换为j 即可解决此问题。

    顺便说一句:我不确定你为什么要遍历 intersects。我想只选择离相机最近的交叉点的第一个条目就足够了。

    【讨论】:

    • 非常感谢您的回答,我已将 var 从 i 更改为 j,但没有任何改变。我也尝试删除“for (var i = 0; i
    • 你确定计算uv的代码是正确的吗?我指的是您用来确定国家代码的坐标。你有这个计算的参考吗?
    • 是的,我将这个项目 stemkoski.github.io/Three.js/Country-Select-Highlight.html 用作参考,并对 76 版的three.js 进行了一些修改
    • 它可能不起作用,因为原始应用程序以不同方式计算 raycasterray 属性。尝试修改来自Projector.pickingRay() 的代码,看看是否有帮助。顺便说一句:如果您通过TextureLoader 加载纹理,则无需将Texture.needsUpdate 设置为true。加载程序正在为您执行此操作。这样,您可以解决浏览器控制台中的警告。
    • 再次感谢您,我曾尝试使用projector.pickingRay,但它与我的three.js [Error] THREE.Projector: .pickingRay() is now raycaster.setFromCamera(). [Error] TypeError: undefined is not an object (evaluating 'rayCaster.intersectObject') 版本以及当我尝试降级到参考中使用的版本(r62 ),一切都停止工作。我不知道如何解决这个问题,我找到的唯一参考是这个,但似乎我不能与我当前版本的 three.js 一起使用
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-04-08
    • 1970-01-01
    • 2017-03-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多