개발/three.js / / 2023. 1. 20. 04:12

[Capstone Project] three.js geometry docs code 분석하기

반응형
※ 해당 글은 capstone 종합설계 프로젝트를 하면서 적었던 일지를 돌아보며 작성한 것입니다.

개발일지 2022.10.01

Three.js Geometry Browser

 

Three.js Geometry Browser

 

threejs.org

위 코드에서 필요한 부분만을 잘라내서 cylinder만 빼오는 방법을 연구중이다.

 

hash tag

const selectedGeometry = window.location.hash.substring( 1 );

보아하니 URL의 geometry 태그가 있는 것은 window.location.hash.substring을 이용해서 보여줄 geometry가 무엇인지를 선택하여 보여주는 것인 모양이다.

고로 cylinder만을 렌더링하려는 나에게는 필요없는 기능이다.

chooseFromHash

function chooseFromHash( mesh ) {

    const selectedGeometry = window.location.hash.substring( 1 ) || 'TorusGeometry';

    if ( guis[ selectedGeometry ] !== undefined ) {

        guis[ selectedGeometry ]( mesh );

    }

    if ( selectedGeometry === 'TextGeometry' ) {

        return { fixed: true };

    }

    //No configuration options
    return {};

}

이 커스텀 함수는 hash로 받은 geometry 이름의 종류에 따라서 렌더링 할 geometry를 결정한다.

함수를 보면 값이 없을 경우 TorusGeometry로 되어있었기 때문에 기본적으로 도넛 모양이 나왔던 것이다.

chooseFromHash 함수로 전달되는 mesh는 전체 코드에서는 object3D group을 매개변수로 전달한다. 이 Group()이 내 생각에는 유니티에서 빈 오브젝트 안에 다른 여러 오브젝트를 넣는 느낌인 것 같다.

 

const guis = {
    CylinderGeometry: function ( mesh ) {

        const data = {
            radiusTop: 5,
            radiusBottom: 5,
            height: 10,
            radialSegments: 8,
            heightSegments: 1,
            openEnded: false,
            thetaStart: 0,
            thetaLength: twoPi
        };

        function generateGeometry() {

            updateGroupGeometry( mesh,
                new CylinderGeometry(
                    data.radiusTop,
                    data.radiusBottom,
                    data.height,
                    data.radialSegments,
                    data.heightSegments,
                    data.openEnded,
                    data.thetaStart,
                    data.thetaLength
                )
            );

            return new CylinderGeometry(
                data.radiusTop,
                data.radiusBottom,
                data.height,
                data.radialSegments,
                data.heightSegments,
                data.openEnded,
                data.thetaStart,
                data.thetaLength
            );
        }

        const folder = gui.addFolder( 'THREE.CylinderGeometry' );

        folder.add( data, 'radiusTop', 0, 30 ).onChange( generateGeometry );
        folder.add( data, 'radiusBottom', 0, 30 ).onChange( generateGeometry );
        folder.add( data, 'height', 1, 50 ).onChange( generateGeometry );
        folder.add( data, 'radialSegments', 3, 64 ).step( 1 ).onChange( generateGeometry );
        folder.add( data, 'heightSegments', 1, 64 ).step( 1 ).onChange( generateGeometry );
        folder.add( data, 'openEnded' ).onChange( generateGeometry );
        folder.add( data, 'thetaStart', 0, twoPi ).onChange( generateGeometry );
        folder.add( data, 'thetaLength', 0, twoPi ).onChange( generateGeometry );


        return generateGeometry();
    }
};

쓸데없는 코드들은 없애고, CylinderGeometry에 대한 코드만 수정하여 위와 같이 만들었다.

 

여기서 updateGroupGeometry를 보자.

function updateGroupGeometry( mesh, geometry ) {

    mesh.children[ 0 ].geometry.dispose();
    mesh.children[ 1 ].geometry.dispose();

    mesh.children[ 0 ].geometry = new WireframeGeometry( geometry );
    mesh.children[ 1 ].geometry = geometry;

    // these do not update nicely together if shared
}

매개변수로 전달된 mesh에는 plane mateirial와 line material 로 만든 mesh가 각각 들어있다.

 

코드를 보면 children 0,1번에 접근하여 처리하는 것을 볼 수 있는데, 0번은 wireframe mesh, 1번은 geometry이다. dispose로 0,1 번 geometry를 모두 폐기 시켜주고 수정된 geometry로 update한다.

log를 찍어보니 wireframe geometry는 attribute에 position밖에 없고, cylinder geometry의 attribute에는 normal, position, uv가 모두 있다. writeframe의 경우는 면도 텍스처도 없으므로 normal와 uv가 없는 모양이다.

 

기본적인 geometry들의 경우 길이나 segment, 면적 등을 손쉽게 조정할 수 있으나, 직접 vertex를 지정한 custom geometry를 만들었을 때는 방법을 찾아보아야할 것이다.

 

2022.10.01 직접 vertex를 지정한 모델 만들기

docs의 cylinder geometry의 동작방식을 간단하게 보았으니, 이번에는 직접 vertex를 지정하여 모델을 만들고, 조작해보자.

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