본문 바로가기
자바스크립트와 캔버스

바빌론JS - 미니자동차

어릴적 장난감 자동차를 붕붕 소리내어 가지고 놀아보신 적이 있나요?
적어도 필자의 어릴적 기억으로는 큰 장난감 자동차를 가진 친구를 어느정도 부러워 했던것 같습니다.

추억을 회상하며 가상 공간에서 만들어보는 장난감 자동차의 세계로 떠나볼까요? :)
이 게시글은 공식 튜토리얼을 소화하여 크레이의 입맛에 맞게 재구성하였습니다.

지난 게시글에서는 마을을 저장하고 불러오는 부분을 진행했었는데요.
이번 시간에는 그 연속이긴 하나 당장은 마을을 불러오지는 않을 겁니다.

https://itadventure.tistory.com/690

 

바빌론JS - 마을 저장 & 열기

지난 시간에는 멋진 마을을 꾸며 보았습니다.https://itadventure.tistory.com/689 바빌론JS - 마을 꾸미기지난 게시글에는 집을 만들고 표면을 꾸며보았지요.https://itadventure.tistory.com/688 바빌론 JS - 집의

itadventure.tistory.com


소스 기본형

비주얼 스튜디오를 시작하고 아래 기본 소스형으로 index.html 과 main.js 를 준비해주세요.

index.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>My Babylon.js App</title>

    <style>
        html, body {
            overflow: hidden;
            width: 100%;
            height: 100%;
            margin: 0;
            padding: 0;
        }

        #renderCanvas {
            width: 100%;
            height: 100%;
            touch-action: none;
        }
    </style>

</head>
<body>

    <canvas id="renderCanvas"></canvas>

    <script src="https://cdn.babylonjs.com/babylon.js"></script>
    <script src="https://cdn.babylonjs.com/loaders/babylonjs.loaders.min.js"></script>
    <script src="https://code.jquery.com/pep/0.4.3/pep.js"></script>
    <script src="https://cdn.babylonjs.com/gui/babylon.gui.min.js"></script>
    <script src="https://assets.babylonjs.com/generated/Assets.js"></script>
    <script src="https://preview.babylonjs.com/serializers/babylonjs.serializers.js"></script>
    <script src="https://cdn.babylonjs.com/earcut.min.js"></script>

    <script src="./main.js"></script>
</body>
</html>

main.js

const canvas = document.getElementById("renderCanvas");
const engine = new BABYLON.Engine(canvas,true);

var createScene = function () {
    var scene = new BABYLON.Scene(engine);
    var camera = new BABYLON.ArcRotateCamera(
        "camera", 
        BABYLON.Tools.ToRadians(90), 
        BABYLON.Tools.ToRadians(65), 
        2,  // 카메라 거리
        BABYLON.Vector3.Zero(), 
        scene
    );
    
    camera.wheelDeltaPercentage = 0.01; // 마우스휠 속도
    camera.minZ = 0;    // 근거리 커팅 X

    // 카메라 캔버스 연결
    camera.attachControl(canvas, true);

    // 빛
    var light = new BABYLON.HemisphericLight(
        "light", 
        new BABYLON.Vector3(0, 1, 0), 
        scene
    );
    // 빛강도
    light.intensity = 1.5;

    // 시작
    
    // 씬 리턴
    return scene;
};

// 함수화 코드

const scene = createScene();

engine.runRenderLoop(function () {
    scene.render();
});

window.addEventListener("resize", function () {
    engine.resize();
});

불필요한 부분을 일부 걷어내고 크레이 입맛에 맞게 조정했는데요.
특히 이번 예제는 '돌출'이라는 기능을 위해 아래 코드가 추가되었습니다.

<script src="https://cdn.babylonjs.com/earcut.min.js"></script>

미니자동차 몸통

이제 자동차 몸통을 만들텐데요.
바빌론JS는 배열을 이용하여 외곽선 좌표 목록을 담은 다음에,

두께를 부여하는 BABYLON.MeshBuilder.ExtrudePolygon() 함수를 적용하면 물체를 돌출할 수 있습니다.

외곽선은 아래 순서로 좌표를 구성할텐데요.

일일히 좌표를 계산하는 건 골치아프니 설명은 생략할 겁니다 :)
// 시작 이라 적힌 부분 아래부터 코드를 넣어주시는데요,
아래 코드를 사용하면 outline 에 외곽선 좌표 구성이 배열로 입력되는데요.

// 외곽선 벡터를 생성
const outline = []

// 1) 차 바닥
outline.push(new BABYLON.Vector3(-0.3, 0, -0.1));
outline.push(new BABYLON.Vector3(0.2, 0, -0.1));

// 2) 차 앞쪽. 곡선 표현을 위해 삼각함수 사용
for (let i = 0; i < 20; i++) {
    outline.push(new BABYLON.Vector3(
        0.2 * Math.cos(i * Math.PI / 40), 
        0, 
        0.2 * Math.sin(i * Math.PI / 40) - 0.1)
    );
}

// 3) 지붕
outline.push(new BABYLON.Vector3(0, 0, 0.1));
// 4) 차 뒤
outline.push(new BABYLON.Vector3(-0.3, 0, 0.1));

이어서 아래 코드를 추가하면 외곽선이 돌출되어 모델이 완성됩니다.

// 돌출
const car = BABYLON.MeshBuilder.ExtrudePolygon(
    "car", 
    {
        shape: outline,
        depth: 0.2
    }
);


코드 함수화

이제 이 차 몸통 코드를 함수화해 단순화시켜 봅시다.
// 함수화 코드 라 적힌 부분 아래 자동차 몸통 함수화 코드를 추가하고,

const buildCar = () => {
    // 외곽선 벡터를 생성
    const outline = []

    // 1) 차 바닥
    outline.push(new BABYLON.Vector3(-0.3, 0, -0.1));
    outline.push(new BABYLON.Vector3(0.2, 0, -0.1));

    // 2) 차 앞쪽. 곡선 표현을 위해 삼각함수 사용
    for (let i = 0; i < 20; i++) {
        outline.push(new BABYLON.Vector3(
            0.2 * Math.cos(i * Math.PI / 40), 
            0, 
            0.2 * Math.sin(i * Math.PI / 40) - 0.1)
        );
    }

    // 3) 지붕
    outline.push(new BABYLON.Vector3(0, 0, 0.1));
    // 4) 차 뒤
    outline.push(new BABYLON.Vector3(-0.3, 0, 0.1));

    // 돌출
    const car = BABYLON.MeshBuilder.ExtrudePolygon(
        "car", 
        {
            shape: outline,
            depth: 0.2
        }
    );

    return car;
}

// 시작 부분 아래 코드를 변경해 주세요.

const car = buildCar();

보기 쉽게 바뀌었지요 ? :)


타이어

타이어는 간단히 실린더(원통)를 사용할 겁니다.
오른쪽 뒷바퀴를 하나 만들고

나머지 바퀴 3개는 복제할텐데요.

자동차 함수화 코드의 car 반환코드 윗 부분에

    return car;
}

오른쪽 뒷바퀴 실린더(원통)를 생성하는 코드를 추가하고 ( 공식 투토리얼과 다름 )

const wheelRB = BABYLON.MeshBuilder.CreateCylinder(
    "wheelRB", 
    {diameter: 0.125, height: 0.05}
)

자동차 몸통을 실린더의 부모로 지정하는 코드를 추가합니다.
이렇게 하면 자동차 몸통이 이동, 회전하면 바퀴도 함께 이동, 회전합니다.

wheelRB.parent = car;

그리고 바퀴의 위치를 조정하는 코드를 추가하면 되는데요.

wheelRB.position.z = -0.1;
wheelRB.position.x = -0.2;
wheelRB.position.y = 0.035;

이렇게 됩니다.

나머지 3개의 바퀴는 이 바퀴를 복사하면 되는데요.
여기서는 clone 을 사용할 겁니다.

wheelRF = wheelRB.clone("wheelRF");
wheelRF.position.x = 0.1;

wheelLB = wheelRB.clone("wheelLB");
wheelLB.position.y = -0.2 - 0.035;

wheelLF = wheelRF.clone("wheelLF");
wheelLF.position.y = -0.2 - 0.035;

그러면 이렇게 되지요.

이제 이 미니자동차에 메트리얼을 적용하여 집처럼 꾸며 볼 겁니다 :)


마무~리

외곽선을 돌출하여 자동차 외형을 구성하는 부분을 다뤄보았는데요.
찾으시는 분에게 도움이 되셨을지 모르겠습니다:)
오늘도 방문하신 모든 분들께 감사드립니다.


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

 

바빌론JS - 때깔나는 미니자동차

지난 시간에는 미니자동차 외형을 구성하는 모델을 만들었는데요.https://itadventure.tistory.com/691 바빌론JS - 미니자동차어릴적 장난감 자동차를 붕붕 소리내어 가지고 놀아보신 적이 있나요?적어도

itadventure.tistory.com