使用egret Pro进行简单的mesh编辑
目前只实现了 点的位置的移动和删除(删除还有问题),以及面的移动和删除(删除面的时候没删除点)…剩下的TODO…
就先记下
项目地址 :gitee地址
运行方式:
使用egretPro 打开 然后进入editCube场景
点击预览
然后勾选上方的 Debug,进入Debug模式(目前用的)运行的时候才执行修改模型,也没有储存数据。
绿色的点代表了模型的顶点,选中后移动可以改变模型顶点的位置。然后紫色的线代表了mesh上点的连线。面不太好选中,可以点击左边的Editor,展开层级
以triangleEntity_开头的就是可以选中的面,选中之后移动可以修改移动面的位置。
选中点后,点击右侧EditPoint下的delete,可以删除这个点
同理,也可以删除面
目前删除都是删了之后重新再生成一个mesh,再重新画一遍点,线面。///todo。。。 只修改原来的mesh
方法
EditCubeController是用来编辑mesh的方法,在场景里给要编辑物体挂上这个脚本。
然后在 EditCubeController
然后在EditCubeController的onstart里注册EditCubeSystem系统,这个系统是用来收集顶点位置的改变,以及删除等等的
Application.instance.systemManager.registerSystem(EditCubeSystem);
在EditCubeSystem的getMatchers里加上EditCubeController这个类,然后在onEntityAdded那判断,当收集到EditCubeController这个脚本的时候,执行给带这个脚本的物体根据mesh来创建可编辑的顶点和面createVerticesEntities()。
获取目标mesh 并记录信息。目前其实记录的信息就vertices 点的位置和 indices 连线顺序有用。
this.vertices = targetMesh.getAttribute("POSITION").slice();
this.normal = targetMesh.getAttribute("NORMAL").slice();
this.uv = targetMesh.getAttribute("TEXCOORD_0").slice();
this.indices = targetMesh.getIndices().slice();
然后将mesh克隆,并把meshFilter.mesh替换成克隆后的不然会修改到使用的mesh(比如用的引擎的里cube,一移动点所有cube也被改了)
saveMesh.setAttribute(AttributeSemantics.POSITION, this.vertices.slice());
saveMesh.setAttribute(AttributeSemantics.NORMAL, this.normal.slice());
saveMesh.setAttribute(AttributeSemantics.TEXCOORD_0, this.uv.slice()); saveMesh.setIndices(this.indices.slice());
meshFilter.mesh = saveMesh;
这句是刷新mesh的显示
meshFilter.mesh.needUpdate(MeshNeedUpdate.All);
然后记录点的信息。我目前是把所有位置一样的点记录在一起,然后最后生成一个我要的顶点。每个顶点的信息对应一个MyVertInfo,MyVertInfo存点的位置,和点indices用到的时候每次的起始位置。再用每个MyVertInfo对应生成一个cube实体,cube上挂一个EditPoint。
EditCubeSystem里onEntityAdded里,如果收集到Selected,Selected的是选中的物体。如果该物体上有EditPoint组件,把编辑模式改为顶点。
if (entity.getComponent(EditPoint)) {
this.editType = EditType.Vertex;
}
......
在onFrame里(就是system的update),如果编辑模式是顶点,执行EditPoint 的 updatePoints判断点的位置跟上一帧一不一样,不一样的话刷新模型。
public updatePoints() {
const entity = this.entity as GameEntity;
let isChange: boolean = false;
if (!entity.transform.localPosition.equal(this.lastPosition)) {
this.lastPosition.set(
entity.transform.localPosition.x,
entity.transform.localPosition.y,
entity.transform.localPosition.z);
isChange = true;
}
if (isChange === false) {
return false; // 若未发生变化则不更新
}
this.changeModelVertices();
return true;
}
changeModelVertices 修改模型的 vertices对应的值,然后刷新模型。
删除点。
一个顶点有可能对应好多个连线的点。
先把对应位置的点和索引全删了。
for (let i = vertsIndex.length - 1; i >= 0; i--) {
const vertIndex = vertsIndex[i];
vertices.splice(vertIndex * 3, 3);
normal.splice(vertIndex * 3, 3);
uv.splice(vertIndex * 2, 2);
for (let index = 0; index < indices.length; index += 3) {
if (indices[index] == vertIndex || indices[index + 1] == vertIndex || indices[index + 2] == vertIndex) {
indices.splice(index, 3);
}
}
}
然后因为点的数量改变了,所有比删掉的点大的其他点,我感觉是索引都应该往前移动删掉的比他小的点的个数。
for (let index = 0; index < indices.length; index++) {
let deleteTime = 0;
for (let i = 0; i < vertsIndex.length; i++) {
if (indices[index] > vertsIndex[i]) {
deleteTime++;
}
}
indices[index] -= deleteTime;
}
。。。最后把之前的模型全删了,根据新的数据生成模型和可编辑点,reGrawMesh()。。。TODO。。。只修改更改的