如何解决在 AFrame 中随时随地操作顶点?
我有一架定制飞机:
JS:
AFRAME.registerGeometry('example',{
schema: {
vertices: {
default: ['-10 10 0','-10 -10 0','10 -10 0','10 -10 0'],}
},init: function (data) {
var geometry = new THREE.Geometry();
geometry.vertices = data.vertices.map(function (vertex) {
var points = vertex.split(' ').map(function(x){return parseInt(x);});
return new THREE.Vector3(points[0],points[1],points[2]);
});
geometry.computeBoundingBox();
geometry.faces.push(new THREE.Face3(0,1,2));
geometry.faces.push(new THREE.Face3(0,2,3));
geometry.mergeVertices();
geometry.computeFacenormals();
geometry.computeVertexnormals();
this.geometry = geometry;
}
});
HTML:
<a-entity id="myPlane" geometry="primitive: example; vertices: 1 1 -3,3 1 -3,2 2 -3,1 2 -3"></a-entity>
现在如何操作动画循环中的顶点位置?
先说第一点:
geometry.vertices[0]
我知道我可以通过以下方式访问网格:
document.getElementById("myPlane").object3D;
并改变它的位置,例如:
document.getElementById("myPlane").object3D.position.set(1,0)
但是平面网格的几何体上没有顶点:
document.getElementById("plane").object3D.children[0]
如何操作几何体的顶点?
编辑:
我发现你可以像这样更新顶点的位置:
document.getElementById("myPlane").object3D.children[0].geometry.attributes.position.array[0] = 20;
document.getElementById("myPlane").object3D.children[0].geometry.attributes.position.needsUpdate = true;
想在 tick() 函数中进行整个操作,因为我真正想要的是用一条线连接两个对象。
现在平面的顶点看起来像这样:
Float32Array(18) [-0,-3,-3]
因为飞机有 4 个点,我预计会有 4*3 = 12 个元素,但我们这里有 18 个元素。 xyz 旁边还有什么?
解决方法
顶点可用作对象几何的属性:
// mesh
const mesh = element.getObject3D("mesh");
// "vertices"
const vertices = mesh.geometry.attributes.position.array;
您可以简单地更改任何您想要的内容,并使用以下命令确认更新:
mesh.geometry.attributes.position.needsUpdate = true;
索引和非索引几何之间的差异带来了巨大的复杂性。简而言之:
- 非索引 几何体包含网格中任何三角形的所有顶点。一个平面包含两个三角形,因此有 2 个三角形 * 3 个顶点 * 3 个坐标 = 18 个条目。在这个例子中可以说明这一点,我操作了一个顶点,但只有一个三角形受到影响:
<script src="https://aframe.io/releases/1.0.0/aframe.min.js"></script>
<script>
AFRAME.registerComponent("foo",{
init: function() {
this.el.addEventListener("loaded",e => {
const mesh = this.el.getObject3D("mesh");
this.positionAttr = mesh.geometry.attributes.position;
})
},tick: function(time) {
// manipulate "Y" of the third vertex
let offset = 0.25 * Math.sin(time * 0.001);
this.positionAttr.array[2 * 3 + 1] = 0.5 + offset;
this.positionAttr.needsUpdate = true;
}
})
</script>
<a-scene>
<a-plane position="0 1.5 -2" wireframe="true" material="color: blue" foo></a-plane>
</a-scene>
- indexed 几何不喜欢将相同的顶点重复两次,因此它存储唯一的顶点,并提供引用任何存储顶点的“索引”。现在操纵顶点看起来完全不同:
<script src="https://aframe.io/releases/1.2.0/aframe.min.js"></script>
<script>
AFRAME.registerComponent("foo",tick: function(time) {
let offset = 0.25 * Math.sin(time * 0.001);
this.positionAttr.array[4] = 0.5 + offset;
this.positionAttr.needsUpdate = true;
}
})
</script>
<a-scene>
<a-plane position="0 1.5 -2" wireframe="true" material="color: blue" foo></a-plane>
</a-scene>
代码看起来相同,但 a-frame 版本不同 - 更改几何图形时应该得到相同的结果 (geometry.toNonIndexed())
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。