使用 egret Pro 进行简单的mesh编辑

使用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也被改了)

扫描二维码关注公众号,回复: 15130170 查看本文章
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。。。只修改更改的

猜你喜欢

转载自blog.csdn.net/weixin_38926960/article/details/115673756