我正在创建一个动画,该动画显示关于创建3D曲面的2D功能的旋转。我已经能够成功渲染表面,现在我正在尝试使用MorphTargets创建动画部分。在THREE.js中为自定义网格变形目标动画
不幸的是,虽然我已经成功地将所有的变形框架推送到了我的几何体中,但我无法使动画播放。我发现的所有动画示例都使用搅拌器导入模型,因此不是完全有用(许多也是过时的)。
我正在看变形马作为例子(http://threejs.org/examples/#webgl_morphtargets_horse),并试图尽可能复制代码,但我没有成功。
这里是我的代码初始化morphVerticeHolder,这是一个二维数组来保存每个动画帧
//First indices of multiarray corresponds to morph frame, second to the vertice
var morphVerticeHolder = [];
for(var i = 0; i < 20; i++) {
morphVerticeHolder[i] = [];
}
这里是我的代码推顶点沿轴的顶点。请注意,我同时推动我的变形顶点。 mI表示网格间隔。
for(var i = xstart; i <= xend; i+= mI) {
geo.vertices.push(new THREE.Vector3(i,0,0));
for(var j = 0; j < 20; j++) { //20 Frames of the morph animation
morphVerticeHolder[j].push(new THREE.Vector3(i,0,0));
}
}
该代码推动所有的顶点。我沿着x轴范围,而j沿着θ范围,填充网格的顶点。
//Push the vertices
var tmesh = 2*Math.PI/meshPoints; //Theta mesh interval
verticeCounter = 0;
for(var i = xstart; i <= xend; i+=mI) {
var rMain = solveEquation(i);
var rSecond = solveEquation(i+mI);
var counter = 0;
for(var j = 0; j < 2*Math.PI; j += tmesh) {
geo.vertices.push(new THREE.Vector3(i, rMain*Math.cos(j/1000),rMain*Math.sin(j/1000)));
for(var k = 0; k < 20; k++) {
morphVerticeHolder[k].push(new THREE.Vector3(i, rMain*Math.cos(j*(k+1)/20),rMain*Math.sin(j*(k+1)/20)));
}
}
}
除法1000是用于开始原始目出接近0,然后动画它旋转使用变形的顶点(其范围从所希望的值,以20/20的1/20的目的。
然后我推的面孔。你可以试着解释我的算法,但本质上我想通了,如何跟踪它的顶点是在哪里。
for(var i = 0; i < meshPoints; i++) {
var sI = meshPoints*(i+1);
var sI2 = meshPoints*(i+2);
for(var j = 0; j < meshPoints-1; j ++) {
if(i === 0) {
//First Point, Fill end
geo.faces.push(new THREE.Face3(sI+j, sI+j+1, 0));
geo.faces.push(new THREE.Face3(sI+j+1, sI+j, 0));
//Filll Body
geo.faces.push(new THREE.Face3(sI+j, sI+j+1, sI2+j));
geo.faces.push(new THREE.Face3(sI+j+1, sI+j, sI2+j));
geo.faces.push(new THREE.Face3(sI+j+1, sI2+j, sI2+j+1));
geo.faces.push(new THREE.Face3(sI2+j, sI+j+1, sI2+j+1));
} else if(i === meshPoints-1) {
//Last Point, Fill end
geo.faces.push(new THREE.Face3(sI+j, sI+j+1, meshPoints-1));
geo.faces.push(new THREE.Face3(sI+j+1, sI+j, meshPoints-1));
} else {
geo.faces.push(new THREE.Face3(sI+j, sI+j+1, sI2+j));
geo.faces.push(new THREE.Face3(sI+j+1, sI+j, sI2+j));
geo.faces.push(new THREE.Face3(sI+j+1, sI2+j, sI2+j+1));
geo.faces.push(new THREE.Face3(sI2+j, sI+j+1, sI2+j+1));
}
}
}
而这里的休息,初始化和这样的。
for(var k = 0; k < 20; k++) {
geo.morphTargets.push({ name: "target" + k, vertices: morphVerticeHolder[k]});
}
var uniforms = {
resolution: { type: "v2", value: new THREE.Vector2 },
zmax: { type: "f", value: maxz},
zmin: { type: "f", value: minz}
};
var mat = new THREE.ShaderMaterial({
uniforms: uniforms,
vertexShader: document.getElementById('cubeVertexShader').innerHTML,
fragmentShader: document.getElementById('cubeFragmentShader').innerHTML
});
functionObject = new THREE.Mesh(geo, mat);
this.scene.add(functionObject);
functionObject.name = 'current';
this.animation = new THREE.MorphAnimation(functionObject, 'Revolution');
this.animation.play();
this.setWithinRender(function() {
this.animation.update(.1);
});
this.setWitinRender将匿名函数放入THREE.js的渲染循环中(这是一个与THREE安装程序分开调用的函数。
正如我上面提到的,网格渲染,如果我在推动原始顶点时去掉了/ 1000,我会得到整个曲面。但是,如上所述设置的动画不起作用。有没有人对此有所了解?
谢谢!