Javascript Verlet 3D断球
我试图用它来制作一个柔软的球体 我基本上创建一个网格,并通过弹簧连接每个顶点。我正在使用three.js渲染球体。我相信一切都正常工作,但我不确定如何获得预期的结果。如果连接太弱,我的球就会塌陷;如果连接太硬,我的球就会爆炸。有些事情似乎不对劲。问题发生在物体坠落并撞到地面的瞬间。我将发布代码的主要部分,但是我不确定我的方法是否有效,是否可以用来产生我想要的结果Javascript Verlet 3D断球,javascript,three.js,game-physics,verlet-integration,Javascript,Three.js,Game Physics,Verlet Integration,我试图用它来制作一个柔软的球体 我基本上创建一个网格,并通过弹簧连接每个顶点。我正在使用three.js渲染球体。我相信一切都正常工作,但我不确定如何获得预期的结果。如果连接太弱,我的球就会塌陷;如果连接太硬,我的球就会爆炸。有些事情似乎不对劲。问题发生在物体坠落并撞到地面的瞬间。我将发布代码的主要部分,但是我不确定我的方法是否有效,是否可以用来产生我想要的结果 function verletStick3D(p1, p2, distance, rigid){ this.type =
function verletStick3D(p1, p2, distance, rigid){
this.type = "stick";
this.p1 = p1;
this.p2 = p2;
this.distance = distance;
this.rigid = rigid;
this.update = function(){
var dx = this.p1.x - this.p2.x;
var dy = this.p1.y - this.p2.y;
var dz = this.p1.z - this.p2.z;
var distance = Math.sqrt(dx * dx + dy * dy + dz * dz);
var difference = this.distance - distance;
var percent = difference / distance / 2;
var offsetX = dx * percent * this.rigid;
var offsetY = dy * percent * this.rigid;
var offsetZ = dz * percent * this.rigid;
this.p1.x += offsetX;
this.p1.y += offsetY;
this.p1.z += offsetZ;
this.p2.x -= offsetX;
this.p2.y -= offsetY;
this.p2.z -= offsetZ;
}
}
function verletPoint3D(x, y,z, maxX, maxZ, bounce = 0.9, friction =
1.0, gravity = {x:0, y:-0.03, z:0}){
y = y + 10;
this.type = "point";
this.x=x;
this.y=y;
this.z=z;
this.xOld=x;
this.yOld=y;
this.zOld=z;
this.bounce = bounce;
this.friction = friction;
this.gravity = gravity;
this.update = function(){
var vx = (this.x - this.xOld) * this.friction;
var vy = (this.y - this.yOld) * this.friction;
var vz = (this.z - this.zOld) * this.friction;
this.xOld = this.x;
this.yOld = this.y;
this.zOld = this.z;
this.x += vx;
this.y += vy;
this.z += vz;
this.y += this.gravity.y;
this.x += this.gravity.x;
this.z += this.gravity.z;
}
this.setGravity = function(gravity){
this.gravity = gravity;
}
this.constrain = function(){
var vx = (this.x - this.xOld) ;
var vy = (this.y - this.yOld) ;
if(this.x > this.maxX){
this.x = width;
this.xOld = this.x + vx * this.bounce;
}
if(this.x < this.minX){
this.x ;
this.xOld = this.x + vx * this.bounce;
}
if(this.z > this.maxZ ){
this.z = height ;
this.zOld = this.z + vz * this.bounce;
}
if(this.z < this.minZ){
this.z = 0;
this.zOld = this.z + vz * this.bounce;
}
if(this.y < 0){
this.y = 0;
this.yOld = this.y + vy * this.bounce;
}
}
}
function verletFromMesh(vertices, faces, maxX, maxY){
var points = [];
for(var i = 0; i < vertices.length; i++){
var p = new verletPoint3D(vertices[i].x, vertices[i].y, vertices[i].z, maxX, maxY, 0.9, 0.9);
points.push(p);
}
var springs = []
/*
for(var i = 0; i < faces.length; i++){
var face = faces[i];
var p1 = face.a;
var p2 = face.b;
var p3 = face.c;
springs.push(new verletStick( p1,p2, distance3D(p1, p2), 1.0) )
springs.push(new verletStick( p2,p3, distance3D(p2, p3), 1.0) )
springs.push(new verletStick( p3,p1, distance3D(p3, p1), 1.0) )
}*/
for(var i = 0; i < points.length; i++){
var p1 = points[i];
for(var j= i+1; j < points.length; j++){
var p2 = points[j];
if(p1.x == p2.x && p1.y == p2.y && p1.z == p2.z)
continue;
var dist = distance3D(p1, p2)
springs.push(new verletStick3D( p1,p2, dist, 1.0) )
}
}
return new verletObj(points, springs);
}
功能verletStick3D(p1、p2、距离、刚性){
this.type=“stick”;
这是1.p1=p1;
这是p2=p2;
这个距离=距离;
这个。刚性=刚性;
this.update=函数(){
var dx=this.p1.x-this.p2.x;
var dy=this.p1.y-this.p2.y;
var dz=this.p1.z-this.p2.z;
变量距离=数学sqrt(dx*dx+dy*dy+dz*dz);
var差=此距离-距离;
var百分比=差异/距离/2;
var offsetX=dx*百分比*此为刚性;
var offsetY=dy*百分比*this.刚性;
var offsetZ=dz*百分比*此为刚性;
这是1.p1.x+=抵销x;
这个.p1.y+=offsetY;
这个.p1.z+=offsetZ;
这.p2.x-=抵销x;
this.p2.y-=offsetY;
这.p2.z-=偏移量z;
}
}
函数verletPoint3D(x,y,z,maxX,maxZ,bounce=0.9,摩擦力=
1.0,重力={x:0,y:-0.03,z:0}){
y=y+10;
this.type=“点”;
这个.x=x;
这个。y=y;
这个。z=z;
这个.xOld=x;
这个。yOld=y;
这个.zOld=z;
这个.弹跳=弹跳;
摩擦=摩擦;
重力=重力;
this.update=函数(){
var vx=(this.x-this.xOld)*this.摩擦力;
var vy=(this.y-this.yOld)*this.摩擦力;
var vz=(this.z-this.zOld)*this.摩擦力;
this.xOld=this.x;
this.yOld=this.y;
this.zOld=this.z;
这个.x+=vx;
这个.y+=vy;
这个.z+=vz;
这个.y+=这个.gravity.y;
这个.x+=这个.gravity.x;
这个.z+=这个.gravity.z;
}
this.setGravity=函数(重力){
重力=重力;
}
this.constraint=函数(){
var vx=(this.x-this.xOld);
var vy=(this.y-this.yOld);
if(this.x>this.maxX){
x=宽度;
this.xOld=this.x+vx*this.bounce;
}
if(this.xthis.maxZ){
这个。z=高度;
this.zOld=this.z+vz*this.bounce;
}
if(this.z
嗯,很难准确地看出您的错误所在,但在我看来,您的弹簧可能无法反转运动。这将导致爆炸/坍塌,具体取决于它们的强度。我强烈建议尝试显式地限制它们对球体的影响,希望这能帮助您进一步调试这个问题
你的数学工作方式,特别是当设置偏移量dx*percent*this.刚性时代码>使这些动态力看起来是静态的,因此发挥的作用太大
附言:你查过这个了吗?这是关于摩擦的,但我认为答案在这里是可以引用的:
在运动物体上引入一个小的,恒定的加速度
指向与运动相反的方向。确保它不能
实际上,把运动倒过来;如果您在集成中检测到这一点
第一步,把速度设为零
希望这能让你找到正确的方向。嘿,洛弗斯,谢谢你的回复。有一些问题,但其中之一是“varvz=(this.z-this.zOld);”以及代码其他部分中的一些其他内容。我真的需要想出一个更好的方法来处理这些点之间的联系。不过我让它工作了。