Three.js - 推开然后在“鼠标移动”上恢复元素位置

     2023-02-27     277

关键词:

【中文标题】Three.js - 推开然后在“鼠标移动”上恢复元素位置【英文标题】:Three.js - Push away and then restore elements position on "mouse move" 【发布时间】:2016-06-29 13:35:24 【问题描述】:

大家好,我正在Three.js 开发一个项目,用户可以在其中hover 镶嵌面,并且每个网格在与不可见的球体相交时都应该被推开,当它在外面时回到原来的位置从它的区域。我使用this 和this example 作为参考,但我被卡住了,因为我不知道如何使它在Three.js 中工作。

在我的代码中,我可以hover 网格的每个面,使其变为红色并在鼠标消失后恢复其原始颜色。但我不能对这个职位做类似的事情。这是我认为问题所在的代码部分:

if (intersects.length > 0) 

    // if the closest object intersected is not the currently stored intersection object
    if (intersects[0].object != INTERSECTED) 

        // Restore previous intersection objects (if they exist) to their original color
        if (INTERSECTED) 
            INTERSECTED.face.color.setHex(INTERSECTED.currentHex);
        

        // Intersected elements
        INTERSECTED = intersects[0];
        var intGeometry = INTERSECTED.object.geometry;
        var intFace     = INTERSECTED.face;

        // Difference between intersected faces and geometry
        INTERSECTED.currentHex = intFace.color.getHex();
        intFace.color.setHex(0xc0392b);
        intGeometry.colorsNeedUpdate = true;

        // Identify the vertices of each face
        var intVertices = intGeometry.vertices;
        var v1 = intVertices[intFace.a],
            v2 = intVertices[intFace.a],
            v3 = intVertices[intFace.a];

        // Calculate the centroid of the selected face
        var intPosition = new THREE.Vector3();
        intPosition.x = (v1.x + v2.x + v3.x) / 3;
        intPosition.y = (v1.y + v2.y + v3.y) / 3;
        intPosition.z = (v1.z + v2.z + v3.z) / 3;
        console.log(intPosition);
    


通过console.log() 我可以看到人脸及其位置都被正确识别,但是球体没有正确跟踪鼠标,我需要位置方面的帮助。这是带有完整代码的JSFiddle

【问题讨论】:

要让球体跟随鼠标,您需要将屏幕坐标转换为threejs的世界位置。 Check this link 。并更新fiddle here,更改代码从第 375 行开始。 谢谢你!这是another question问题的一部分,我问过,如果你愿意,你可以在那里发布答案并获得奖励。 【参考方案1】:

您遇到的问题是您尝试使用ray.intersectObjectstargetList不是 THREE.Mesh 实例。 因此,当您尝试访问 intersectedFace.acc 时会抛出错误

【讨论】:

我已经编辑了这个问题,也许你可以再试试看。谢谢!【参考方案2】:

您没有将某些东西分配回您的几何体。大意:

intVertices[intFace.a].copy( intPosition );
intVertices[intFace.b].copy( intPosition );
intVertices[intFace.c].copy( intPosition );

intGeometry.verticesNeedUpdate = true;
intGeometry.normalsNeedUpdate = true;

【讨论】:

帅哥!但是我应该如何存储和重置位置?因为现在hover 上的每个区块都消失了。 我猜你需要另一个数组/缓冲区来保存你的顶点的state 这是一种可能性,我认为实现这一点的方法是每当与鼠标的距离低于球体半径时,将tessellated face 的质心推出。然后当它出来时,将它送回原来的位置。你怎么看? 为什么使用质心(这是额外的计算)而不是顶点本身?【参考方案3】:

这是一个关于这个主题的小测试: https://jsfiddle.net/77xvepp7/

它还不能正常工作,我将相机移动了一点,以便可以看到这个想法。

基本思想是从曲面中选择一个顶点作为“基点”,它可以是曲面的中心,就像您在示例中所做的那样,并保持该点作为参考点以移动所有其他点三角形的数量相同。如果不保存原始值,那么下一轮可能会有无效值,三角形会随机移动。

然后你计算鼠标到“基点”的距离,遍历所有顶点并将它们移动到基点的方向一些量。如果距离大于某个定义的量,则从顶点恢复原始值。

您可能会尝试使用顶点着色器来做到这一点,但问题是当鼠标在表面上时,每个顶点都会朝相反的方向移动,并且鼠标下方的三角形会缩放以填充空隙。选择一个点作为“基点”可以解决这个问题。

  // Modify the geometry
  var geometry = backgroundMesh.geometry;
    for ( var i = 0, il = geometry.faces.length; i < il; i ++ ) 

        var face = geometry.faces[ i ];

        if ( face instanceof THREE.Face3 ) 

            var a = geometry.vertices[face.a];
            var b = geometry.vertices[face.b];
            var c = geometry.vertices[face.c];
            var vList = [a,b,c];

            // The trick is to save the original face positions
            if(!a.origXSet) 
               a.origX = a.x;
               a.origY = a.y;
               a.origZ = a.z;
               a.origXSet = true;
            

            var vect = a;
            var dx = (vect.origX - pos.x), 
                dy = (vect.origY - pos.y), 
                dz = (vect.origZ - pos.z);

            // distance to the mouse
            var dist = Math.sqrt( dx*dx + dy*dy);

            // magic constant, react if distance smaller than 4
            if(dist < 4) 
              vList.forEach(function(v) 
              if(!v.origXSet) 
                   v.origX = v.x;
                   v.origY = v.y;
                   v.origZ = v.z;
                   v.origXSet = true;
               
               var len = Math.sqrt(dx*dx + dy*dy + dz*dz);
               if(len==0) return;
               var ndx = dx / len,
                   ndy = dy / len,
                   ndz = dz / len;
               v.x = v.origX + ndx * 2; // move 2 pixels
               v.y = v.origY + ndy * 2; 
               v.z = v.origZ + ndz * 2;
      );

       else 
          // otherwise, reset coordinates
          vList.forEach(function(v) 
            if(v.origXSet) 
             v.x = v.origX;
             v.y = v.origY;   
             v.z = v.origZ;
             
           );
      

       geometry.verticesNeedUpdate = true;
       geometry.normalsNeedUpdate = true;    

    
 

主要问题是:鼠标指针在世界坐标中的位置计算不正确。现在我没有精力考虑如何纠正这个问题,但决定发布这个答案,以便您可以继续。

【讨论】:

Three.js - 对象跟随鼠标位置

】Three.js-对象跟随鼠标位置【英文标题】:Three.js-Objectfollowsmouseposition【发布时间】:2016-07-0205:26:31【问题描述】:我正在Three.js中创建一个球体,它必须在鼠标移动时跟随鼠标,如thisexample中所示。处理鼠标移动的函数如下:fun... 查看详情

如何通过鼠标移动事件获取相机位置并在three.js中转换为屏幕坐标? [关闭]

】如何通过鼠标移动事件获取相机位置并在three.js中转换为屏幕坐标?[关闭]【英文标题】:Howtogetcamerapositionwithmousemoveeventandtransformintoscreencoordinatesinthree.js?[closed]【发布时间】:2016-05-0918:19:23【问题描述】:实际上我不知道这是... 查看详情

threejs导入模型(不确定尺寸)后如何确定相机位置及物体缩放比例

...定各种定位?1、打开threeJS软件,任意创建一个模型。2、然后选择模型并单击“选择并均匀缩放”按钮。3、将光标移动到X轴上,则X轴变为黄色,且光标的形状发生变化。4、按住回鼠标左键拖动光标,则模型随着光标的移动发... 查看详情

如何在three.js 上覆盖HTML 文本/按钮?

】如何在three.js上覆盖HTML文本/按钮?【英文标题】:HowtooverlayHTMLtext/buttonsonthree.js?【发布时间】:2018-04-2802:39:17【问题描述】:好的,这里对three.js很陌生,但我正在努力实现Google所拥有的https://beinternetawesome.withgoogle.com/interland... 查看详情

three.js游戏开发入门

...一方法是选择像Unity或Unreal这样的游戏引擎,学习语言,然后打包游戏并将其部署到你选择的平台上。试图通过浏览器向用户提供游戏的想法似乎是一项不可能完成的任务。幸运的是,由于浏览器技术的进步和硬件加速在所有流... 查看详情

cssdiv怎么做出来鼠标移动上就显示其内容?

...个功能。1、新建html文档,在body标签中添加一个div标签,然后在div标签中添加p标签,为p标签添加内容:2、为了方便演示,给div标签设置宽高和背景颜色,然后给p标签设置“display”属性,属性值为“none”,这样p标签中的文字... 查看详情

本机上使用three.js载入纹理

怎样载入纹理//首先,创建一个纹理varmapUrl="../images/molumen_small_funny_angry_monster.jpg";varmap=THREE.ImageUtils.loadTexture(mapUrl);//然后,创建phong材质来显示光影效果,把纹理传给该材质varmaterial=newTHREE.MeshPhongMaterial({map:map}) 查看详情

如何在轴 three.js 上旋转 3D 对象?

】如何在轴three.js上旋转3D对象?【英文标题】:Howtorotatea3Dobjectonaxisthree.js?【发布时间】:2012-06-1902:49:11【问题描述】:我对three.js中的旋转有很大的问题我想在我的一个游戏中旋转我的3D立方体。//initgeometry=newTHREE.CubeGeometrygrid,... 查看详情

Three.js - 在自定义几何图形上平滑着色 Lambert 材质的问题

...着色Lambert材质的网格。使用循环,我创建了顶点数组,然后是面,然后我调用了geometr 查看详情

在 Three.js 中为加载的 glb 模型分配纹理

...可以通过遍历加载的模型找到网格。我想创建一些文本,然后将该文本显示为模型上的纹理。但是当 查看详情

在 three.js 中的球体上使用纹理

】在three.js中的球体上使用纹理【英文标题】:Usingtexturesonspheresinthree.js【发布时间】:2013-06-2221:30:10【问题描述】:我能够使用javascript和three.js库创建一个球体。但是我有一个图像我想覆盖在球体的顶部,每当我这样做时,球... 查看详情

鼠标移动上的CSS js重绘而不消失

...:59:22【问题描述】:我通过鼠标位置在窗口上用CSS画圆。然后我慢慢移动光标,很好地重绘,但如果我更快地移动光标,我可以看到圆圈是如何消失的。我怎样才能在不消失的情况下顺利重绘?我在下面尝试的代码:.circleposition... 查看详情

在移动设备上支持 Canvas 和 WebGL (three.js)?

】在移动设备上支持Canvas和WebGL(three.js)?【英文标题】:SupportofCanvasandWebGL(three.js)onmobledevices?【发布时间】:2012-01-0821:33:12【问题描述】:有一个很棒的3D应用程序框架,名为three.js。据我了解,它有几个渲染子系统:基于Canvas... 查看详情

在 Three.js 着色器上启用扩展

】在Three.js着色器上启用扩展【英文标题】:EnablinganextensiononaThree.jsshader【发布时间】:2012-06-1918:20:42【问题描述】:如何?到目前为止我的代码:获得扩展:vardomElement=document.createElement(\'canvas\');vargl=domElement.getContext(\'webgl\')||do... 查看详情

如何在 THREE.JS 上创建自定义网格?

】如何在THREE.JS上创建自定义网格?【英文标题】:HowtocreateacustommeshonTHREE.JS?【发布时间】:2012-03-0409:31:44【问题描述】:我已经问过这个问题并得到了答案:vargeom=newTHREE.Geometry();varv1=newTHREE.Vector3(0,0,0);varv2=newTHREE.Vector3(0,500,0);v... 查看详情

three.js探索:目录

...型的加载2、多模型组合成一个大模型3、设备模型的选中鼠标移动上去后的选中效果。4、设备模型选中后的弹窗:嵌入视频、html页面、rtmp流点击选中后的效果。5、设备模型报警。6、设备模型的运动驱动:设备部件的运... 查看详情

在 three.js 中移动相机、lookAt 和旋转

...是[0,0,0]。圆圈看起来好像从上方看(如预期的那样)。然后我将相机移动到[30,0 查看详情

如何通过拖动鼠标 QT 检查按钮?鼠标移动事件

...hButton_i)i=1,2,3,4,5。我想要做的是拖动鼠标(按下按钮),然后在“是”上拖动选中按钮的setText,否则在“否”上。我尝试了以下代码,但结果是:当我按下鼠标按钮然 查看详情