바닥 문제는 해결했고, 이제 cut 기능을 만들어보자
cut을 하기 위해서는 먼저 vertex를 model에서 삭제하는 기능을 만들어야한다
삭제 기능이 정말 어려운데 찬찬히 생각해보자
vertex 고정 기능 코드 분리
일단 이제 scene을 분리하고 진행하려고 한다
고정 vertex를 제거해서 cloth 모델이 나뒹구는데
이부분은 scene을 분리해서 simulation scene과 cut scene으로 기능을 분리하려고 한다
private init() {
// Set top of cloth to have a mass of 0 to hold still
// in order to get hanging from clothesline visual
{
// Variables to store top row
let minX = Number.MAX_VALUE;
let maxX = -Number.MAX_VALUE;
let maxY = -Number.MAX_VALUE;
for (let i = 0; i < this.numParticles; i++) {
minX = Math.min(minX, this.positions[3 * i]);
maxX = Math.max(maxX, this.positions[3 * i]);
maxY = Math.max(maxY, this.positions[3 * i + 1]);
}
// Thickness of the edge to zero out(?)
const eps = 0.000001;
return
for (let i = 0; i < this.numParticles; i++) {
const x = this.positions[3 * i];
const y = this.positions[3 * i + 1];
if (y > maxY - eps && (x < minX + eps || x > maxX - eps))
// if (y > maxY - eps)
this.invMass[i] = 0.0;
}
}
}
현재 이렇게 return으로 vertex 고정 코드를 막아버렸는데
그냥 init 함수 parameter로 단순하게 처리하자
private init(vertexFix :boolean) {
...
if(vertexFix === false) return
for (let i = 0; i < this.numParticles; i++) {
const x = this.positions[3 * i];
const y = this.positions[3 * i + 1];
if (y > maxY - eps && (x < minX + eps || x > maxX - eps))
// if (y > maxY - eps)
this.invMass[i] = 0.0;
}
이렇게 bool 변수로 처리해놓고 scene마다 true/false로 분리한다
raycast vertex debug
raycast를 이용해서 vertex focusing을 바꿀 수 있도록 기능을 넣자.
일단 state로 raycast mode를 넣어놓으면 좋을 것 같다.
export enum Mode{
NONE, RAYCAST
}
export let stateStop:boolean = false
export let curMode:Mode = Mode.NONE
export function stopState(){ stateStop = !stateStop }
export function changeMode(mode: Mode){ curMode = mode }
enum 타입의 사용은 C계열의 언어와 유사하다.
gui 버튼을 눌러서 mode를 변경할 수 있도록 gui를 만들자
일단 처음에 생성할 때 template에 있던 gui debug 목록이 거슬리니까 이름을 바꾸려고 한다.
한 번에 바꾸려면 vscode의 "F2"로 변경하면
다른 스크립트에서도 한 번에 잘 변형해준다
열거형 enum 사용하기
gui에서 mode를 변경하는 함수를 만들자
export enum Mode{
NONE, RAYCAST
}
분명 사용하는 enum type은 2가지가 있는데
이렇게 인덱스도 같이 떠서 enum type object의 로그를 찍어보니
실제로 이렇게 담겨있다. 필터링해야한다
export function changeMode(){
const modeChangeFolder = gui.addFolder('change mode')
const modeEnumTypes = Object.keys(state.Mode).filter(key => isNaN(Number(key)))
modeChangeFolder.add({}, 'mode', modeEnumTypes)
}
이렇게 그냥 숫자가 안나오게 필터링해서 처리했다
export function changeMode(){
const modeChangeFolder = gui.addFolder('change mode')
const modeEnumTypes = Object.keys(state.Mode).filter(key => isNaN(Number(key)))
modeChangeFolder.add({mode: state.curMode}, 'mode', modeEnumTypes).onChange((val: state.Mode)=>{
state.changeMode(val)
})
}
gui에서 change Mode를 변경하면 state manager에서 모드를 전역으로 변경할 수 있도록 했다.
이제 보니 state manager라고 하면 이름이 애매한 것 같기도 한다
이 코드대로 실행하면 enum이 처음에 인덱스가 뜨는데
export function changeMode(){
const modeChangeFolder = gui.addFolder('change mode')
const modeEnumTypes = Object.keys(mode.Mode).filter(key => isNaN(Number(key)))
modeChangeFolder.add({mode: mode.Mode[mode.curMode]}, 'mode', modeEnumTypes).onChange((val: mode.Mode)=>{
mode.changeMode(val)
})
}
이렇게 처음 값을 Mode enum의 값으로 고쳐주면 된다.