개발 · 컴퓨터공학/three.js / / 2024. 7. 22. 09:00

Threejs Cloth Tailor 개발일지 - threejs hierarchy window gui (유니티 하이어라키 같은 기능) 구현하기, object3d traverse, lil-gui hierarchy, threejs editor

728x90
반응형

 

threejs hierarchy gui 구현하기 

unity hierarchy window

기껏 mesh를 분리하였는데 사용자 입장에서 object가 분리된건지 geometry가 따로 노는건지 알 턱이 없다.

나도 그래서 hierarchy 기능을 빠르게 추가하고자 한다.

 

구현 방법에 대해서 알아보자.

hierarchy 기능의 경우 많은 곳에서 구현되어있을 것 같다.

 

좀 찾아보니 방법이 보편적으로 있는게 아니라 구현 방법마다 다른 것 같다.

그중 object.traverse를 사용하는 방법도 제안된다.

https://threejs.org/docs/#api/en/core/Object3D.traverse

 

three.js docs

 

threejs.org

 

Object3D traverse

traverse. 이름만 들어도 object 계층을 탐색하는 느낌이다.

매개변수로 function을 넣는데, object3d를 첫 번째 변수로 가진 함수?

역시 공식문서의 설명은 부실하다. 좀 더 찾아보자. 

 

질의 응답을 보다보면 callback 으로 들어간 function은 object의 all of children마다 호출된다고 한다.

즉 호출되는 함수에서 children object를 매개변수로 받아 계층 내 모든 object들을 순회하며 특정 기능을 실행시키는 것이다.

 

이를 hierarchy로 적용한다고 생각하면, gui에 하위 element로 추가하는 함수를 모든 children object마다 실행시키는 것이다.

그럼 각 object가 어떤 object 밑에 있는지는 각 parent children를 통해 끼워 넣는 건가. 

이건 실제로 구현한 코드를 보는게 좋을 것 같다.

 

lil gui (dat gui) 이용하기

lil gui(dat gui)를 이용해서 hierarchy를 한 번 구현 테스트해보자.

 

import * as THREE from 'three';
import * as dat from 'lil-gui';

class HierarchyUI {
    private gui: dat.GUI;

    constructor() {
        this.gui = new dat.GUI({ title: 'Hierarchy' });
    }

    public buildHierarchy(object: THREE.Object3D): void {
        this.gui.destroy();  // 기존 GUI를 제거
        this.gui = new dat.GUI({ title: 'Hierarchy' });  // 새로운 GUI 생성
        this.addFolder(object, this.gui);
    }

    private addFolder(object: THREE.Object3D, parentGui: dat.GUI): void {
        const folder = parentGui.addFolder(object.name || object.type);

        object.children.forEach(child => {
            this.addFolder(child, folder);
        });

        folder.open();  // 모든 폴더를 기본적으로 열어 둠
    }
}

export default HierarchyUI;

hierarchy class를 만들어서 넣어보자.

 

scene에 있는 object들이 뜬다. 하지만 계층적으로 나오는지는 확인하기 어렵다.

임의의 children object를 넣어보자. 

 

 

class HierarchyUI {
    private gui: dat.GUI;

    constructor() {
        this.gui = new dat.GUI({ title: 'Hierarchy' });
        this.setPosition()
    }

    public buildHierarchy(object: THREE.Object3D): void {
        this.gui.destroy();  // 기존 GUI를 제거
        this.gui = new dat.GUI({ title: 'Hierarchy' });  // 새로운 GUI 생성
        this.setPosition()
        this.addFolder(object, this.gui);
    }

    private setPosition(): void {
        const guiDomElement = this.gui.domElement;
        guiDomElement.style.position = 'absolute';
        guiDomElement.style.top = '0';
        guiDomElement.style.left = '0';
        guiDomElement.style.zIndex = '100';  // GUI가 다른 요소 위에 표시되도록 z-index 설정
    }

    private addFolder(object: THREE.Object3D, parentGui: dat.GUI): void {
        const folder = parentGui.addFolder(object.name || object.type);

        object.children.forEach(child => {
            this.addFolder(child, folder);
        });

        folder.open();  // 모든 폴더를 기본적으로 열어 둠
    }
}

set position을 통해 hierarchy는 좌측 상단에 두자.

 

  const testbox1 = new Mesh(new BoxGeometry(1), new MeshBasicMaterial({color: 'red'}))
  const testbox2 = new Mesh(new BoxGeometry(1), new MeshBasicMaterial({color: 'red'}))
  const testbox3 = new Mesh(new BoxGeometry(1), new MeshBasicMaterial({color: 'red'}))
  testbox1.children.push(testbox2)
  testbox2.children.push(testbox3)
  scene.add(testbox1)

test mesh들이 children으로 들어간 게 잘 표현된다.

한 번 mesh separate가 바로 hierarchy 에 반영되는지 보자 

 

mesh separate hierarchy

mesh separate를 실행하니 hierarchy에 cloth0, cloth1 로 나우어지는 것을 확인할 수 있다.

 

threejs editor 

https://github.com/mrdoob/three.js/tree/master/editor

 

three.js/editor at master · mrdoob/three.js

JavaScript 3D Library. Contribute to mrdoob/three.js development by creating an account on GitHub.

github.com

mugen87 이라는 개발자분이 개발한 threejs 기반 editor이다.

오픈소스로 되어있어서 참고하기 너무 좋고.

 

특히 이 mugen87이라는 분이 threejs를 사랑하셔서 forum에서 자주 활동하신다. 

 

현재 lil-gui로 구현을 해놓았지만, clicked mesh의 경우 hierarchy에서표시해주면 좋겠어서 

일단 threejs editor에서 hierarchy를 어떻게 구현하였는지 보면 좋을 것 같다.

728x90
반응형
  • 네이버 블로그 공유
  • 네이버 밴드 공유
  • 페이스북 공유
  • 카카오스토리 공유