three.js 中的防撞墙
Collision walls in three.js
我正在 three.js 创建游戏。我是这个领域的新手,但我已经阅读了很多碰撞文档。
我使用光线投射在立方体中包含的船和立方体中包含的岛屿之间进行碰撞。我试过这样解决问题。
collision2 = false;
var originPoint = MovingCube.position.clone();
clearText();
for (var vertexIndex = 0; vertexIndex < MovingCube.geometry.vertices.length; vertexIndex++)
{
var localVertex = MovingCube.geometry.vertices[vertexIndex].clone();
var globalVertex = localVertex.applyMatrix4( MovingCube.matrix );
var directionVector = globalVertex.sub( MovingCube.position );
var ray = new THREE.Raycaster( originPoint, directionVector.clone().normalize() );
var collisionResults = ray.intersectObjects( collidableMeshList );
if ( collisionResults.length > 0 && collisionResults[0].distance < directionVector.length() ) {
appendText(" Hit "),
collision2 = true;
}
}
if ( keyboard.pressed("W") ){
obj.translateZ( moveDistance ),
if (collision2==true){
obj.translateZ( -moveDistance*4 ),
}
}
if ( keyboard.pressed("S") ){
obj.translateZ( - moveDistance ),;
if (collision2==true){
obj.translateZ( moveDistance*4 ),
}
}
if ( keyboard.pressed("A") ){
obj.rotateOnAxis( new THREE.Vector3(0,1,0), rotateAngle),
if (collision2==true){
obj.rotateOnAxis( new THREE.Vector3(0,1,0), -rotateAngle*3),
}
}
if ( keyboard.pressed("D") ){
obj.rotateOnAxis( new THREE.Vector3(0,1,0), -rotateAngle),
if (collision2==true){
obj.rotateOnAxis( new THREE.Vector3(0,1,0), rotateAngle*3),
}
}
乘以 3 "moveDistance" 和 "rotateAngle" 以免我的船在碰撞过程中被 raycat 发射的射线撞毁。它经常有效,但有时船会卡住或进入岛屿。我考虑过当船与基于立方体的面的岛相撞时将船移动几个像素。示例:船在正 X 轴上与立方体的面发生碰撞,从立方体位置减去像素以使船移开。但我不知道该怎么做,这对我来说是一个很好的解决方案。我该如何解决与墙壁碰撞的问题?
(我现在不想使用任何物理引擎)
感谢那些愿意帮助我的人!
编辑:
我想指出立方体(岛)的哪一侧与船相撞。如果面朝向 X 轴(正向),则将船向后移动 40 像素 (obj.position = + 40),这适用于每个面。所以你永远不能让船进入立方体。我在看这个我认为可能有用的例子,但我还不知道如何解决它。
https://stemkoski.github.io/Three.js/Mouse-Click.html
这是我的包含船的立方体。
var mats2 = [];
var cubeGeometry = new THREE.CubeGeometry(25,135,121,10,10,10);
for (var i = 0; i < 6; i ++) {
mats2.push(new THREE.MeshBasicMaterial( { color: 0xff0000, wireframe:true } ));
}
MovingCube = new THREE.Mesh( cubeGeometry, mats2 );
scene.add( MovingCube );
collidableMeshList0.push(MovingCube);
有无数种方法可以用光线投射来解决这个问题。但我做过的最有效的工作之一是制作一个简单的点质量系统,将 3 个点质量排列成三角形,与 3 个弹簧连接并进行简单的 verlet 样式模拟以将它们保持在三角形配置中。然后您通过获取该三角形的向量来重建对象矩阵,并构成一个正交基础并将其插入您的 three.js目的。然后每帧,你对你的点质量施加一个重力,如果它们低于你的海平面,则应用一个与点在海平面以下的深度成比例的任意浮力。然后对于每个点质量,您从点的中心向下投射光线,并调整点质量位置以保持与高度图的地面高度的距离。
这是我很久以前制作的类似产品的原型:
http://vectorslave.com/webgl/zbox.html(ASWD + 方向键控制直升机)
我想我找到了一个很好的解决方案。
每次发生碰撞时,都可以知道受影响的面孔。使用.face.normal。例如:如果碰撞面是面向 -x 轴的面,您将拥有:x: -1, y: 0, z: 0。如果碰撞面是面向 + x 轴的面,您将拥有:x: +1, y: 0, z: 0。其他轴同理。所以我通过以下方式解决了。现在船不再卡在墙上了!
var originPoint = MovingCube.position.clone();
clearText();
for (var vertexIndex = 0; vertexIndex < MovingCube.geometry.vertices.length; vertexIndex++)
{
var localVertex = MovingCube.geometry.vertices[vertexIndex].clone();
var globalVertex = localVertex.applyMatrix4( MovingCube.matrix );
var directionVector = globalVertex.sub( MovingCube.position );
var ray = new THREE.Raycaster( originPoint, directionVector.clone().normalize() );
collisionResults1 = ray.intersectObjects( collidableMeshList );
if ( collisionResults1.length > 0 && collisionResults1[0].distance < directionVector.length() ) {
appendText(" Hit "),
faccia = collisionResults1[0].face.normal;
if (faccia.x <=-0.9 ){
obj.position.x = originPoint.x -30,
}
if (faccia.x >=0.9 ){
obj.position.x = originPoint.x +30,
}
if (faccia.z <=-0.9 ){,
obj.position.z = originPoint.z -30,
}
if (faccia.z >=0.9 ){
obj.position.z = originPoint.z +30,
}
我正在 three.js 创建游戏。我是这个领域的新手,但我已经阅读了很多碰撞文档。 我使用光线投射在立方体中包含的船和立方体中包含的岛屿之间进行碰撞。我试过这样解决问题。
collision2 = false;
var originPoint = MovingCube.position.clone();
clearText();
for (var vertexIndex = 0; vertexIndex < MovingCube.geometry.vertices.length; vertexIndex++)
{
var localVertex = MovingCube.geometry.vertices[vertexIndex].clone();
var globalVertex = localVertex.applyMatrix4( MovingCube.matrix );
var directionVector = globalVertex.sub( MovingCube.position );
var ray = new THREE.Raycaster( originPoint, directionVector.clone().normalize() );
var collisionResults = ray.intersectObjects( collidableMeshList );
if ( collisionResults.length > 0 && collisionResults[0].distance < directionVector.length() ) {
appendText(" Hit "),
collision2 = true;
}
}
if ( keyboard.pressed("W") ){
obj.translateZ( moveDistance ),
if (collision2==true){
obj.translateZ( -moveDistance*4 ),
}
}
if ( keyboard.pressed("S") ){
obj.translateZ( - moveDistance ),;
if (collision2==true){
obj.translateZ( moveDistance*4 ),
}
}
if ( keyboard.pressed("A") ){
obj.rotateOnAxis( new THREE.Vector3(0,1,0), rotateAngle),
if (collision2==true){
obj.rotateOnAxis( new THREE.Vector3(0,1,0), -rotateAngle*3),
}
}
if ( keyboard.pressed("D") ){
obj.rotateOnAxis( new THREE.Vector3(0,1,0), -rotateAngle),
if (collision2==true){
obj.rotateOnAxis( new THREE.Vector3(0,1,0), rotateAngle*3),
}
}
乘以 3 "moveDistance" 和 "rotateAngle" 以免我的船在碰撞过程中被 raycat 发射的射线撞毁。它经常有效,但有时船会卡住或进入岛屿。我考虑过当船与基于立方体的面的岛相撞时将船移动几个像素。示例:船在正 X 轴上与立方体的面发生碰撞,从立方体位置减去像素以使船移开。但我不知道该怎么做,这对我来说是一个很好的解决方案。我该如何解决与墙壁碰撞的问题? (我现在不想使用任何物理引擎) 感谢那些愿意帮助我的人!
编辑:
我想指出立方体(岛)的哪一侧与船相撞。如果面朝向 X 轴(正向),则将船向后移动 40 像素 (obj.position = + 40),这适用于每个面。所以你永远不能让船进入立方体。我在看这个我认为可能有用的例子,但我还不知道如何解决它。
https://stemkoski.github.io/Three.js/Mouse-Click.html
这是我的包含船的立方体。
var mats2 = [];
var cubeGeometry = new THREE.CubeGeometry(25,135,121,10,10,10);
for (var i = 0; i < 6; i ++) {
mats2.push(new THREE.MeshBasicMaterial( { color: 0xff0000, wireframe:true } ));
}
MovingCube = new THREE.Mesh( cubeGeometry, mats2 );
scene.add( MovingCube );
collidableMeshList0.push(MovingCube);
有无数种方法可以用光线投射来解决这个问题。但我做过的最有效的工作之一是制作一个简单的点质量系统,将 3 个点质量排列成三角形,与 3 个弹簧连接并进行简单的 verlet 样式模拟以将它们保持在三角形配置中。然后您通过获取该三角形的向量来重建对象矩阵,并构成一个正交基础并将其插入您的 three.js目的。然后每帧,你对你的点质量施加一个重力,如果它们低于你的海平面,则应用一个与点在海平面以下的深度成比例的任意浮力。然后对于每个点质量,您从点的中心向下投射光线,并调整点质量位置以保持与高度图的地面高度的距离。
这是我很久以前制作的类似产品的原型: http://vectorslave.com/webgl/zbox.html(ASWD + 方向键控制直升机)
我想我找到了一个很好的解决方案。
每次发生碰撞时,都可以知道受影响的面孔。使用.face.normal。例如:如果碰撞面是面向 -x 轴的面,您将拥有:x: -1, y: 0, z: 0。如果碰撞面是面向 + x 轴的面,您将拥有:x: +1, y: 0, z: 0。其他轴同理。所以我通过以下方式解决了。现在船不再卡在墙上了!
var originPoint = MovingCube.position.clone();
clearText();
for (var vertexIndex = 0; vertexIndex < MovingCube.geometry.vertices.length; vertexIndex++)
{
var localVertex = MovingCube.geometry.vertices[vertexIndex].clone();
var globalVertex = localVertex.applyMatrix4( MovingCube.matrix );
var directionVector = globalVertex.sub( MovingCube.position );
var ray = new THREE.Raycaster( originPoint, directionVector.clone().normalize() );
collisionResults1 = ray.intersectObjects( collidableMeshList );
if ( collisionResults1.length > 0 && collisionResults1[0].distance < directionVector.length() ) {
appendText(" Hit "),
faccia = collisionResults1[0].face.normal;
if (faccia.x <=-0.9 ){
obj.position.x = originPoint.x -30,
}
if (faccia.x >=0.9 ){
obj.position.x = originPoint.x +30,
}
if (faccia.z <=-0.9 ){,
obj.position.z = originPoint.z -30,
}
if (faccia.z >=0.9 ){
obj.position.z = originPoint.z +30,
}