본문 바로가기
카테고리 없음

바빌론JS - 장면에서 모델 불러오기

지난 시간에는 장면을 생성하고 이를 뷰어에서 불러오는 방법을 살펴보았습니다.

https://itadventure.tistory.com/683

 

바빌론JS - 장면 만들고 뷰어로 불러오기

지난 게시글에 바빌론JS를 이용하여 재미난걸 만들어보았었는데요.https://itadventure.tistory.com/680 바빌론js - 3차원 웹!평소 취미 활동대로 이것 저것 다양한 코드의 바다를 순항하던 중 아주 흥미로

itadventure.tistory.com

하지만 플레이 그라운드에는 장면 파일을 업로드하는 기능이 없습니다.
그래서 이번에는 플레이 그라운드에서 제공하는 기본 장면 컨텐츠를 가지고 놀아보는 시간을 가져 보겠습니다.


집 2채 장면 ( both houses scene ) 소개

바빌론JS에는 초보자를 위한 연습용 장면을 제공하는데요.
파일명이 both_houses_scene.babylon 입니다.
한글 이름은 제가 붙여 보았습니다 :)

그리고 URL은 https://assets.babylonjs.com/meshes/both_houses_scene.babylon 입니다.

해당 장면은 이렇게 생겼는데요.

각각 이름이 붙여져 있습니다.
집 2채는 detached_house, semi_house 이며,
땅바닥은 ground 라는 이름이 붙여져 있습니다.

이 물체들은 각각 분리되어 있으며 모델(Model) 또는 오브젝트(Object: 물체)라 부릅니다.


모델 1개 불러오기

이제 3개의 모델 중 1개만 불러오겠습니다.
플레이 그라운드 페이지 접속해서 ( https://playground.babylonjs.com/

아래 기본 코드를 복붙, 실행하면 

const createScene =  () => {
    // 장면 생성
    const scene = new BABYLON.Scene(engine);

    // 카메라 생성
    const camera = new BABYLON.ArcRotateCamera(
        "camera", 
        -Math.PI / 2, // 가로 방향 회전
        Math.PI / 2.5,  // 위아래 방향 회전
        4,  // 거리
        new BABYLON.Vector3(0, 0, 0),  // 카메라의 좌표
        scene // 연결할 장면
    );

    // HTML 페이지 canvas 에 카메라 연결
    camera.attachControl(canvas, true);
    
    // 빛, 사물, 특수효과를 배치
    // 코드 추가 영역...

    return scene;
}

기본 빈 화면이 나올 겁니다.

여기에 빛을 추가하고 앞의 장면 파일에서 semi_house 모델을 불러오는 코드를 추가하겠습니다.
코드 영역에 추가 후 실행해 주세요.

// 빛 주가
const light = new BABYLON.HemisphericLight(
    "light", 
    new BABYLON.Vector3(0, 1, 0)
);

// 장면에서 semi_house 가져오기
BABYLON.SceneLoader.ImportMeshAsync(
    "semi_house", 
    "https://assets.babylonjs.com/meshes/", 
    "both_houses_scene.babylon"
);

그러면 장면 중에서 semi_house 모델만 불러와 집 1채만 화면에 보일텐데요.

화면이 잘려보이는건 카메라(camera)가 집에 너무 가까와서입니다.
카메라를 뒤로 당겨보죠. 카메라 생성 코드의 아래 부분을 찾아,

4,  // 거리

숫자를 6으로 수정 후 실행하면, 집이 모두 보일 겁니다.

이와 같이 장면 파일에서 1개의 모델을 불러오는 코드는 이렇게 사용할 수 있습니다.

// 장면에서 semi_house 가져오기
BABYLON.SceneLoader.ImportMeshAsync(
    "semi_house", // semi_house 모델만 불러오기
    "https://assets.babylonjs.com/meshes/", 
    "both_houses_scene.babylon"
);

모델 2개 이상 불러오기

그렇다면 장면에서 2개 이상의 모델을 불러올 수도 있을까요?
장면에서 2개 이상의 모델을 불러오려면 대괄호로 이름을 묶어야 합니다.
아래와 같이 말이지요.

[ "semi_house", "detached_house" ]

앞의 코드에서 "semi_house" 라는 부분을 위 코드로 수정하면 끝이지요.

// 장면에서 semi_house 가져오기
BABYLON.SceneLoader.ImportMeshAsync(
    [ "semi_house", "detached_house" ],
    "https://assets.babylonjs.com/meshes/", 
    "both_houses_scene.babylon"
);

참고로 대괄호 대신 "" 를 사용하면 장면의 모든 모델을 불러옵니다.


3차원 좌표 이해

장면에서 불러온 모델은 각각 3차원 좌표라는게 있습니다.
기본적으로 가로 방향이 X좌표, 세로 방향이 Y좌표이며,

앞에서부터 멀리 떨어진 거리라는 개념이 있어 Z좌표가 추가됩니다.

이렇게 3개의 죄표를 3차원 벡터라고 하는데요.
자바스크립트에서 Vector3 로 표현합니다.


인스펙터로 위치 조정하기

변화를 관찰하기 위해, 먼저 모든 모델을 불러오도록 코드를 수정해 실행해 주세요.

// 장면에서 semi_house 가져오기
BABYLON.SceneLoader.ImportMeshAsync(
    "",
    "https://assets.babylonjs.com/meshes/", 
    "both_houses_scene.babylon"
);

그리고 화면을 약간 돌려 비스듬한 각도에서 바라보도록 돌려줍니다. ( 마우스로 드래그 )

코드를 통해 좌표를 수정할 수도 있지만, 직관적인 이해를 위해 Inspector(인스펙터) 도구를 사용하겠습니다.
인스펙터 아이콘을 선택하시면

인스펙터 창이 등장합니다.

Node 항목을 펼쳐 semi_house 모델을 선택하면,
아랫 부분에 속성이 나열될텐데요.

스크롤바를 쭉 내리다 보면 TRANSFORMS 라는 항목이 있는데 그 중 Position 이 바로 3차원 좌표입니다.

Position 항목을 우측 + 기호를 눌러 펼쳐 보면 X, Y, Z 값 입력 상자가 나올텐데요.

이 값을 수정하여 3차원 좌표값을 조정할 수 있습니다.
X 값을 1.0 에서 1.5로 수정해볼까요?
그러자 집이 오른쪽으로 갑자기 이동하는걸 보실 겁니다.

이번에는 집의 높이값을 올려 하늘로 띄워 봅시다.
Y 값 입력 상자를 한번 클릭하면 우측에 위아래 화살표( ▲▼ )가 보일텐데요.
위쪽 화살표를 마우스로 누르고 있으면,
Y좌표가 바뀌면서 집이 서서히 하늘로 옿라가는 것을 보실 수 있습니다.

집이 하늘로 올라가는지 아닌지 확실히 모르시겠다구요?
그러면 마우스로 화면을 돌려서 확인해보시면 됩니다.
중력의 법칙을 무시하고 공중에 떠 있는 집을 보실수 있을 겁니다 :)

Z좌표도 조정해볼까요?
Z좌표값을 음수 -1.5를 입력해보세요.
그러면 집이 카메라쪽으로 가까워져 원근감 때문에 크게 보입니다.
반대로 양수를 입력하면 카메라에서 멀어져 작게 보이게 될 겁니다.

지금 입력한 설정값들은 모두 임시 정보인데요.
왜냐하면 왼쪽에 있는 코드를 실행하면 다시 원래 좌표로 돌아가 버리기 때문입니다.
그래서 지금 좌표를 어딘가 메모를 해두어야 코드에 사용할 수 있습니다.
이런 식으로 말이지요. (1.5, 0.7, -1.5)


자바스크립트 코드로 위치 조정하기

자. 이제 다시 플레이( ▷ ) 버튼을 누르면 집이 원래 좌표로 돌아가는 것을 확인할 수 있습니다.

어떻게 하면 자바 스크립트로 집의 위치를 조정할 수 있을까요?
한가지 제약 조건이 있습니다. 집 모덜을 불러오는데 시간이 소요되기 때문에
집을 불러오는 코드 후 바로 위치를 조정하는 코드를 사용해서는 안됩니다.

그러므로 아래 코드는 실행되지 않습니다.

// 장면에서 semi_house 가져오기
BABYLON.SceneLoader.ImportMeshAsync(
    "",
    "https://assets.babylonjs.com/meshes/", 
    "both_houses_scene.babylon"
);

// 여기서 집의 위치를 조정한다고? No!
const semi_house = scene.getMeshByName("semi_house");
semi_house.position.y = 2;

그러면 어떻게 해야 할까요?
자바스크립트에는 프로미스(Promise) 라는 기술이 있는데요.
코드 실행이 끝나기를 기다렸다가 끝나면 이어서 다음 액션을 실행하는 기술을 말합니다.
그리고 프로미스 유형의 함수를 만드는 방법이 있는데요. 여기서 원리를 설명드리긴 복잡하니 ImportMeshAsync 함수는 그냥 프로미스형 함수다~ 라고만 알아두시면 되겠습니다.프로미스형 함수로 위치를 조정하는 코드를 실행하려면 아래와 같이 코드를 작성해 주시면 됩니다.

// 장면에서 semi_house 가져오기
BABYLON.SceneLoader.ImportMeshAsync(
    "",
    "https://assets.babylonjs.com/meshes/", 
    "both_houses_scene.babylon"
).then((result) => {
    // 여기에서 좌표 위치를 조정
});

그리고 semi_house 모델의 3차원 좌표를 (1.5, 0.7, -1.5) 로 조정하기 위해 코드를 아래와 같이 수정해주면 됩니다.

// 장면에서 semi_house 가져오기
BABYLON.SceneLoader.ImportMeshAsync(
    "",
    "https://assets.babylonjs.com/meshes/", 
    "both_houses_scene.babylon"
).then((result) => {
    const semi_house = scene.getMeshByName("semi_house");
    semi_house.position = new BABYLON.Vector3(1.5, 0.7, -1.5 );
});

이와 같이 장면에 여러 모델을 넣어놓고, 사용할 모델을 필요시 불러와 지지고 볶으면서 사용할 수 있습니다.
재미있는 경험이 되셨나요?
관심 있는 분께 도움이 되셨는지 모르겠군요.
오늘도 방문해주신 분들께 감사드립니다:)


다음 게시글 : https://itadventure.tistory.com/685

 

바빌론JS - 웹개발 기본형

지난 게시글 장면 처리편에 이어서 오늘은 웹 개발 기본형에 대해 다뤄보겠습니다.https://itadventure.tistory.com/684 바빌론JS - 장면에서 모델 불러오기지난 시간에는 장면을 생성하고 이를 뷰어에서

itadventure.tistory.com