Analysis of the reasons why the collision detection based on Three.js uses Vector.applyMatrix4()


Preface

I recently studied the 3D design on the webpage a little bit, which used the collision detection mechanism. Since I came into contact with this knowledge point for the first time, I can only program for Baidu. During the search process, I found that all the codes and methods are almost the same, all using rays. The detection mechanism, after reading other people's code, I found that the reason for using the Vector.applyMatrix4() function was incomprehensible. After a round of Baidu and Google to no avail, I manually programmed to explore the principle of its use.


1. What is Three.js?

Three.js is a plug-and-play WebGL framework. It is friendly to use in front-end 3D production and has simple development documents: Three.js Chinese tutorial , easy to develop, and very fast to get started. Here is a simple snowflake made by the author Special effects can be dragged and changed perspectives, the code cloud has been uploaded, link: Snow special effects . Okay, back on track, the following explains the matrix conversion in the collision mechanism.


Two, use reason analysis

1. Interpretation of collision detection mechanism

The collision detection mechanism here has been mentioned in the above chapter, which is the ray detection mechanism. Since the code on the Internet is relatively one-sided and the comments are general, the blogger will briefly describe it here. code show as below:

var geo1 = new THREE.BoxGeometry(80, 80, 80)
  var material = new THREE.MeshLambertMaterial({
    
    
    color: 0xeff444
  })
  var geo2 = new THREE.BoxGeometry(80, 80, 80)
  var mesh1 = new THREE.Mesh(geo1, material)
  var mesh2 = new THREE.Mesh(geo2, material)
  mesh2.position.x = 200

First generate two cubes, mesh1 and mesh2, and the second one is at the position 200 to the right of the first one to provide an initial position for collision detection.
Definition of ray function:

Raycaster( origin, direction, near, far ) {
    
     }
 
origin — 射线的起点向量。
direction — 射线的方向向量,应该归一化。
near — 所有返回的结果应该比 near 远。Near不能为负,默认值为0。
far — 所有返回的结果应该比 far 近。Far 不能小于 near,默认值为无穷大。

Collision detection process:

    var originPoint = mesh1.position.clone();
    for (var vertexIndex = 0; vertexIndex < mesh1.geometry.vertices.length; vertexIndex++) {
    
    
      // 顶点原始坐标
      var localVertex = mesh1.geometry.vertices[vertexIndex].clone();
      // 顶点经过变换后的坐标
      var globalVertex = localVertex.applyMatrix4(mesh1.matrix);
      // 获得由中心指向顶点的向量
      var directionVector = globalVertex.sub(mesh1.position);
      // 将方向向量初始化,并发射光线
      var ray = new THREE.Raycaster(originPoint, directionVector.clone().normalize());
      // 检测射线与多个物体的相交情况
      // 如果为true,它还检查所有后代。否则只检查该对象本身。缺省值为false
      var collisionResults = ray.intersectObjects([mesh2], true);
      // 如果返回结果不为空,且交点与射线起点的距离小于物体中心至顶点的距离,则发生了碰撞
      if (collisionResults.length > 0 && collisionResults[0].distance < directionVector.length()) {
    
    
        crash = true;   // crash 是一个标记变量
        alert("发生了碰撞")
      }
    }

The code here comes from Baidu search. Briefly, originPoint is the position of the center of the object and the vertex position is localVertex. The purpose of this code is to detect whether the distance from the center to the vertex is greater than the distance from the center to other objects. , A collision occurred. var collisionResults = ray.intersectObjects([mesh2], true)The function verifies whether there is a collision, where the input parameter must be an array, and the return value is the same as the content of the input array, and the order is from near to far. Next, lead to the problem to be analyzed in this article.

2. Analysis of the reasons for using Vector.applyMatrix4()

Because the bloggers are so ignorant and shallow, I always feel that I don’t need this Vector.applyMatrix4() function in my imagination. Tears, the code is here to guide the novices, and also to remind myself), I think the vertex coordinates and center coordinates are enough to get this pointing vector, so the blogger manually edited two cubes and set the keyboard for one cube to operate Displacement, and print the values ​​of localVertex and globalVertex during the movement to analyze the reason for use.

Insert picture description here
Insert picture description here
It can be seen that the localVertex.applyMatrix4(mesh1.matrix)coordinates of the vertices before and after the initial stage have not changed. Can this function be considered useless? Of course not. If you operate it here, you can observe:

Insert picture description here

The original coordinates are still unchanged, but the transformed coordinates change with the movement. The vector formed by this coordinate and the center coordinate is meaningful, so we can know that mesh1.geometry.verticesthe vertex value is the fixed value during initialization. Will change with the displacement, so the use of Vector.applyMatrix4() is naturally necessary.
You can see that the collision detection mechanism is successful after using this function.

Insert picture description here

This leads to a question, ray.intersectObjects([mesh2], true)whether the detection function of the intersection mechanism is to detect the initial vertex value of another object or the vertex value after Vector.applyMatrix4()? Readers can check it by themselves. The method is to move another object, and the object that emits the ray detection does not move, to see if the collision can be detected after the collision. The result is no, indicating that the function can only detect whether it collides with a stationary object, but cannot detect whether it collides with a moving object.


to sum up

It's 10.24 soon, I wish you all a happy holiday! ! !

Guess you like

Origin blog.csdn.net/jiljdlawjdlada/article/details/109203364