현황 정리
현재 vertex 제거하고 물리 시뮬레이션에 반영하기까지 구현이 되었다
근데 생각해보면, 나중에 천을 연결할 때에는 결국에 vertex 간에 새로운 edge로써 연결해야한다
결국 vertex를 지우는 것보다는
edge를 만들고 edge를 지움으로써 cut / attach를 구현해야한다
그러면 edge의 경우에는 하나만 연결할 수는 없으니까 두 개 이상의 vertex를 접합에 사용해야한다
음.. 접합 좀 어려운 것 같다
정리하면 결국 edge 단위로 자르기 / 붙이기를 해야하니까
edge 자르기를 구현하고 mesh 붙이기 알고리즘을 좀 찾아보자
edge 표시 이벤트
일단 edge를 자르기 위해서 이벤트가 필요하다
마우스로 vertex에서 vertex까지 쭉 드래그를 했을 때, 지나온 vertex들 간의 edge들이 시각화되는 이벤트가 있으면 좋다
새로운 모드 remove edge에서는 mesh에서 클릭을 시작한 가장 가까운 vertex부터 클릭을 제거한 시점까지 지나온 vertex까지 edge를 연결해서 표시하는 이벤트와 함수가 필요하다
export function stackClickVertexIndex(scene: Scene, camera: Camera){
raycaster.setFromCamera(mouse, camera)
const intersects = raycaster.intersectObjects(scene.children)
if (intersects.length > 0) {
for(let i = 0; i < intersects.length; i++){
const intersect = intersects[i]
if(intersect.object === gizmoLine) continue
const vertexIndex: number = findClosestVertexIndex(intersect.point, intersect.object as Mesh)[0]
cuttingVertexIndexList.push(vertexIndex)
break
}
}
}
vertex index list를 stack하는 함수를 만들어서 마우스로 드래그하는 동안 지나온 vertex의 index들을 모은다
move 이벤트이다보니 중복해서 들어가는 걸 깜박했다
if(cuttingVertexIndexList.includes(vertexIndex) === false)
조건 체크를 해주고
function stackClickVertexIndex(scene: Scene, camera: Camera){
raycaster.setFromCamera(mouse, camera)
const intersects = raycaster.intersectObjects(scene.children)
const clickMesh: Mesh = getIntersectObject(scene, camera)!
if (intersects.length > 0) {
for(let i = 0; i < intersects.length; i++){
const intersect = intersects[i]
if(intersect.object === gizmoLine) continue
const vertexIndex: number = findClosestVertexIndex(intersect.point, intersect.object as Mesh)[0]
if(cuttingVertexIndexList.includes(vertexIndex) === false){
cuttingVertexIndexList.push(vertexIndex)
let vertexPosList: Vector3[] = []
for(let i=0; i<cuttingVertexIndexList.length; i++){
vertexPosList.push(new Vector3(
clickMesh.geometry.attributes.position.getX(cuttingVertexIndexList[i]),
clickMesh.geometry.attributes.position.getY(cuttingVertexIndexList[i]),
clickMesh.geometry.attributes.position.getZ(cuttingVertexIndexList[i])
).applyMatrix4(clickMesh.matrixWorld)
)
}
drawLineVertexIndexList(scene, vertexPosList)
}
break
}
}
}
가져온 인덱스 리스트를 통해 position을 가져와서 line을 그려주도록 함수를 짠다
주의할 것은 index로 vector를 가져왔을 때 좌표계를 world로 변경해주는 것
function drawLineVertexIndexList(scene: Scene, vecList: Vector3[]){
let material = new LineBasicMaterial({
color: '#5ea9ff',
linewidth: 10
})
console.log(vecList)
let geometry = new BufferGeometry().setFromPoints(vecList)
gizmoLine.geometry = geometry
gizmoLine.material = material
scene.add(gizmoLine)
}
그리고 list에 따라서 line을 그려주는데, 이게 mesh의 wireframe과 겹쳐서 잘 안보인다
겹치는 line material
같은 depth에 있어서 렌더링이 겹치는 경우 material 설정에서 depth 관련된 것이 있는 모양이다
아... 갑자기 생각난게 move시점에만 순간적으로 보였다가 했던게 겹치는 문제 보다도 이벤트 호출 시점 문제였던 것 같기도 하다.
실제로 천 material을 안보이게 테스트해보니 예상이 맞았다
window.addEventListener('mousemove', ()=>{
if(mode.curMode !== "RAYCAST") {scene.remove(gizmoLine)}
if(mode.curMode === "REMOVE_VERTEX"){
window.addEventListener('mousemove', viewInterFunc, false)
}
}, false)
이벤트 함수들을 찾아보다가 문제 원인으로 추정되는 부분을 발견했다
지금 그려주고 있는 gizmoLine을 RAYCAST가 아닐때 제거해주는 함수가 있었다
지워서 확인해보니 이 코드가 문제가 맞았다
if(mode.curMode !== "RAYCAST" && mode.curMode !== "REMOVE_EDGE") {scene.remove(gizmoLine)}
이렇게 REMOVE EDGE mode에 대한 조건도 추가해주니
line이 잘 보이게 되었다
이제 요 line에 해당되는 edge들을 분리하는 작업을 해보자
edge 분리하기
edge를 분리하기 위해서는 뭘 진행해야 할까
우선 edge하나를 이루는 vertex 들이 포함되었던 face들에
vertex가 두 개로 분리되었을 때 각각 어떤 매커니즘으로 face에 포함시켜야할지 구분하는 방법이 우선인 것 같다
mesh edge 자르기 방법 탐색
생각을 좀 해봤는데 간단히 나오지는 않는다
방법을 모색을 시간이 좀 필요할 것 같다