Simple mesh editing with egret Pro
At present, only the movement and deletion of the position of the point is realized (deletion still has problems), and the movement and deletion of the surface (the point is not deleted when the surface is deleted)... the remaining TODO... write it down
first
Project address: gitee address
Operation method:
use egretPro to open and then enter the editCube scene ,
click on the preview
and then check the Debug above, enter the Debug mode (currently used) to modify the model when it is running, and no data is stored.
The green dots represent the vertices of the model, and moving after selection can change the position of the vertices of the model. Then the purple line represents the connection between the points on the mesh. The surface is not easy to select, you can click the Editor on the left to expand the hierarchy. The surface
that starts with triangleEntity_ is the surface that can be selected. After selecting it, you can move it to modify the position of the moving surface.
After selecting a point, click delete under EditPoint on the right to delete the point
In the same way, you can also delete the surface.
The current deletion is to regenerate a mesh after deletion, and then redraw the points, lines and surfaces. ///todo. . . Only modify the original mesh
The method
EditCubeController is used to edit the mesh, hang this script on the object to be edited in the scene.
Then in EditCubeController
Then register the EditCubeSystem system in the onstart of EditCubeController. This system is used to collect changes in vertex positions, delete them, etc.
Application.instance.systemManager.registerSystem(EditCubeSystem);
Add the EditCubeController class to the getMatchers of the EditCubeSystem, and then judge in onEntityAdded. When the EditCubeController script is collected, execute the object with this script to create editable vertices and faces according to the mesh createVerticesEntities().
Get the target mesh and record the information. At present, the information recorded is actually useful for the position of the vertices point and the connection sequence of the 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();
Then clone the mesh, and replace meshFilter.mesh with the cloned one, otherwise it will be modified to the used mesh (for example, the cube in the engine used, and all the cubes will be changed once the point is moved)
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;
This sentence is to refresh the display of the mesh
meshFilter.mesh.needUpdate(MeshNeedUpdate.All);
Then record the point information. I am currently recording all the points with the same position together, and then finally generate a vertex I want. The information of each vertex corresponds to a MyVertInfo, the location where MyVertInfo stores points, and the starting position each time when point indices are used. Then use each MyVertInfo to generate a cube entity, and hang an EditPoint on the cube.
In onEntityAdded in EditCubeSystem, if Selected is collected, Selected is the selected object. If the object has an EditPoint component, change the edit mode to Vertex.
if (entity.getComponent(EditPoint)) {
this.editType = EditType.Vertex;
}
......
In onFrame (that is, update of the system), if the edit mode is vertex, the position of the updatePoints judgment point of EditPoint is different from that of the previous frame, and the model is refreshed if it is different.
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 Modify the value corresponding to the vertices of the model, and then refresh the model.
delete point.
A vertex may correspond to many connection points.
First delete all the points and indexes corresponding to the position.
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);
}
}
}
Then because the number of points has changed, for all other points larger than the deleted point, I feel that the index should be moved forward to delete the number of points smaller than him.
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;
}
. . . Finally, all the previous models are deleted, and the model and editable points are generated according to the new data, reGrawMesh(). . . TODO. . . Only modify the changed