javascript - 有没有办法从three.js中的函数参数获取位置(xyz)?
问题描述
我试图根据 three.js 文档中的布料示例构建一个标志,但在定义标志的约束时遇到了麻烦。
示例链接:
https
://threejs.org/examples/#webgl_animation_cloth 示例
源代码:https ://github.com/mrdoob/three.js/blob/master/examples/webgl_animation_cloth.html
因为代码有大约 300 行,所以我已经尽我最大的努力注释每个代码块。
在我的解释中, function SatisfyConstraints
在两点之间进行减法以获得微分向量。然后它计算长度并从中得出修正。
代码末尾的“模拟”函数 SatisfyConstraints
用于调节旗帜的飘扬方式。
var container, renderer, scene, camera, controls;
var near, far;
var params = {
enableWind: true,
showBall: false
}
var DAMPING = 0.03;
var MASS = 0.15;
var DRAG = 1 - DAMPING;
var DistanceUntilRest = 25;
var GRAVITY = 981 * 1.4;
var gravityVector = new THREE.Vector3( 0, - GRAVITY, 0 ).multiplyScalar( MASS ); // F = mg
var ForceVector = new THREE.Vector3();
var windForce = new THREE.Vector3( 0, 0, 0 );
var TIMESTEP = 18 / 1000;
var TIMESTEP_SQ = TIMESTEP * TIMESTEP;
var xSegs = 10, ySegs = 10;
var clothFunction = planeEquation( DistanceUntilRest * xSegs, DistanceUntilRest * ySegs );
var cloth = new Cloth(xSegs, ySegs);
function planeEquation (width, height) {
return function (a, b, target) {
var x = (a - 0.5) * width;
var y = (b + 0.5) * height;
var z = 0; // idk why z has to be 0
target.set( x, y, z);
}
}
function Particles (x, y, z, mass) {
this.position = new THREE.Vector3();
this.previous = new THREE.Vector3();
this.original = new THREE.Vector3();
this.acceleration = new THREE.Vector3( 0 , 0 , 0);
this.mass = mass;
this.invMass = 1 / mass;
this.FVector = new THREE.Vector3();
this.tmp = new THREE.Vector3();
// initializing clothFunction so planeEquation can set the target
clothFunction(x, y, this.position);
clothFunction(x, y, this.previous);
clothFunction(x, y, this.original);
}
// converting force into acceleration
Particles.prototype.addForce = function (force) {
this.acceleration.add( this.FVector.add(force).multiplyScalar(this.invMass) )
};
// after each time sequence the new position adds itself by the amount of drag and acceleration
Particles.prototype.integrate = function (timeSequence) {
var newPos = this.tmp.subVectors(this.position, this.previous);
newPos.multiplyScalar(DRAG).add(this.position);
newPos.add( this.acceleration.multiplyScalar( timeSequence ) );
// passes tmp down to this.previous then assumes this.position as the new position
this.tmp = this.previous;
this.previous = this.position;
this.position = newPos;
// resetting acceleration
this.acceleration.set(0, 0, 0);
};
var diff = new THREE.Vector3();
function SatisfyConstraints (point, next_point, distance) {
diff.subVectors(next_point.position, point.position);
var currentDist = diff.length();
if (currentDist === 0) return;
var correction = diff.multiplyScalar(1 - distance / currentDist);
var correctionHalf = correction.multiplyScalar(0.5);
point.position.add( correctionHalf );
next_point.position.sub( correctionHalf );
}
function Cloth(width, height) {
this.width = width || 10;
this.height = height || 10;
var particles = [], constraints = [];
var i, j, u, v;
for (i = 0; i <= height; i++ ) {
for (j = 0; j <= width; j++) {
particles.push( new Particles( i / width, j / height, 0, MASS) )
}
}
// Providing structure for cloth - similar to drawing
for (i = 0; i <= height; i++ ) {
for (j = 0; j <= width; j++) {
constraints.push([
particles[index(i, j)],
particles[index(i, j + 1)],
DistanceUntilRest
]);
constraints.push([
particles[index(i, j)],
particles[index(i + 1, j)],
DistanceUntilRest
])
}
}
for ( u = width, v = 0; v < height; v ++ ) {
constraints.push( [
particles[ index( u, v ) ],
particles[ index( u, v + 1 ) ],
DistanceUntilRest
] );
}
for ( v = height, u = 0; u < width ; u ++ ) {
constraints.push( [
particles[ index( u, v ) ],
particles[ index( u + 1, v ) ],
DistanceUntilRest
] );
}
this.particles = particles;
this.constraints = constraints;
function index( u, v ) {
return u + v * ( width + 1 );
}
this.index = index;
}
function simulate( time ) {
if ( ! lastTime ) {
lastTime = time;
return;
}
var i, j, il, particles, particle, constraints, constraint;
// Aerodynamics forces
if ( params.enableWind ) {
var indx;
var normal = new THREE.Vector3();
var indices = clothGeometry.index;
var normals = clothGeometry.attributes.normal;
particles = cloth.particles;
for ( i = 0, il = indices.count; i < il; i += 3 ) {
for ( j = 0; j < 3; j ++ ) {
indx = indices.getX( i + j );
normal.fromBufferAttribute( normals, indx );
tmpForce.copy( normal ).normalize().multiplyScalar( normal.dot( windForce ) );
particles[ indx ].addForce( tmpForce );
}
}
}
for ( particles = cloth.particles, i = 0, il = particles.length; i < il; i ++ ) {
particle = particles[ i ];
particle.addForce( gravityVector );
particle.integrate( TIMESTEP_SQ );
}
// Start Constraints
constraints = cloth.constraints;
il = constraints.length;
for ( i = 0; i < il; i ++ ) {
constraint = constraints[ i ];
SatisfyConstraints( constraint[ 0 ], constraint[ 1 ], constraint[ 2 ] );
}
var pos;
// Ball Constraints
ballPosition.z = - Math.sin( Date.now() / 600 ) * 90; //+ 40;
ballPosition.x = Math.cos( Date.now() / 400 ) * 70;
if ( params.showBall ) {
sphere.visible = true;
for ( particles = cloth.particles, i = 0, il = particles.length; i < il; i ++ ) {
particle = particles[ i ];
pos = particle.position;
diff.subVectors( pos, ballPosition );
if ( diff.length() < ballSize ) {
// collided
diff.normalize().multiplyScalar( ballSize );
pos.copy( ballPosition ).add( diff );
}
}
} else {
sphere.visible = false;
}
// Floor Constraints
for ( particles = cloth.particles, i = 0, il = particles.length; i < il; i ++ ) {
particle = particles[ i ];
pos = particle.position;
if ( pos.y < - 250 ) {
pos.y = - 250;
}
}
}
我还尝试position.copy(point), position.copy(next_point)
在 SatisfyConstraints 中使用来复制坐标并将传递的参数粘贴到新变量中,但它不起作用。
function SatisfyConstraints (point, next_point, distance) {
var pointPos, next_pointPos;
pointPos.position.copy(point);
next_pointPos.position.copy(next_point);
diff.subVectors(pointPos, next_pointPos);
...
}
我希望SatisfyConstraints
能像往常一样工作,但我收到了如下错误消息:
未捕获的类型错误:在动画 (simulation3D.html:419)
的模拟 (simulation3D.html:212)处
无法读取
SatisfyConstraints (simulation3D.html:102) 处未定义的属性“位置”
解决方案
使用chrome开发工具调试)
function SatisfyConstraints (point, next_point, distance) {
var pointPos, next_pointPos;
pointPos.position.copy(point); // <-using of undefined (not-initialized) pointPos
next_pointPos.position.copy(next_point);
diff.subVectors(pointPos, next_pointPos);
...
我猜 pointPos 应该是 THREE.Vector3 类的一个实例。
推荐阅读
- javascript - d3 它不显示任何图形
- html - 对齐表格行
- r - 有没有办法使用ggiraph和onclick在R闪亮的模态窗口中显示过滤的数据表?
- c - 当替换的大小与原始文件相同时,修改文件是否安全
- vim - vim:根据正在编辑的文件名设置标签文件名
- sql-server - 在 Order by 子句中使用三列
- swift - 为什么绑定在 Playgrounds 中的 View 和 ViewModel 之间不起作用?
- azure - 无法从 Azure Cloud Shell 访问 Kubernetes 仪表板
- swift - 搜索栏未显示在视图控制器中
- python - 创建与数据一起运行的 zope 实例的另一个精确副本