JK강재신 / Unity · XR
← 프로젝트 목록

쓰리디아이 / 2016

경운기 시뮬레이션 SW 개발

현실의 조작 장비와 가상 교통 환경 결합

MR마커 정합차량·보행자 FSM
프로젝트 연도 / 기록 당시 상태2016
개발팀 · 리소스 인력 제외3인 · 팀원
사용 기술Unity3D · VR · AR

PROJECT IN ACTION

실행 화면과 시연

경운기 시뮬레이션 SW 개발 프로젝트 화면

이 영상은 본 과제 참여 이후 참여 기업이 변경되어, 본인이 작업한 결과물과 일부 다릅니다. 원문 설명을 유지했습니다.

경운기 시뮬레이션 SW 개발 · 시연 1 프로젝트 이미지
YouTube / PROJECT VIDEO

경운기 시뮬레이션 SW 개발 · 시연 1

직접 열기 ↗

OVERVIEW

프로젝트와 나의 역할

크로마키 MR 정합과 신호 체계에 따른 차량·보행자 FSM을 개발했습니다.

  • 크로마키 기술을 이용한 MR 기능 개발
  • 신호 시스템을 이용한 차량, 보행자 FSM 개발

ENGINEERING NOTES

기능별 구현과 문제 해결

담당 기능의 배경부터 구현 방식과 선택한 범위까지 정리했습니다.

01

실제 조작 장비와 가상 경운기의 정합

배경과 과제

HMD 전면 외부 카메라의 크로마키 영상과 가상 경운기의 위치가 맞아야 했습니다.

내가 구현한 방식

경운기에 부착한 마커로 카메라의 상대 위치를 파악하고, 카메라 부착 위치의 오프셋을 반영해 MR 화면을 정합했습니다.

선택의 이유와 범위

실제 장비와 가상 객체 사이의 위치 기준을 맞추는 작업을 담당했습니다.

2026 / RECONSTRUCTED EXAMPLE

공통 기준으로 자세 좌표 옮기기

센서 기준의 관절 자세를 로컬 좌표로 바꾼 뒤 아바타 기준으로 옮깁니다.

  1. 센서 관절
  2. 기준 Pose 역변환
  3. 아바타 기준 적용
  4. 출력 Pose

설명용 개념도 · 실제 제품 화면이나 전체 시스템 설계도가 아닙니다.

사용 방법과 적용 범위

보정된 sensorRoot, sensorJoint, avatarRoot Pose를 Retarget에 전달합니다.

축·단위·스케일은 미리 일치해야 합니다. 장비 캘리브레이션이나 스켈레톤 리깅 전체를 구현하지 않습니다.

예제 코드 펼치기포트폴리오용 재구성 코드 · 실제 업무 소스 아님
// 2026 portfolio reconstruction. Not original production source or a sensor SDK adapter.
using System;
using UnityEngine;
namespace PortfolioExamples
{
    public static class PoseAlignment
    {
        // Sensor and avatar roots must both be calibrated. Scaling is intentionally unsupported.
        public static Pose Retarget(Pose sensorRoot, Pose sensorJoint, Pose avatarRoot)
        {
            Vector3 localPosition = Quaternion.Inverse(sensorRoot.rotation) * (sensorJoint.position - sensorRoot.position);
            Quaternion localRotation = Quaternion.Inverse(sensorRoot.rotation) * sensorJoint.rotation;
            return new Pose(avatarRoot.position + avatarRoot.rotation * localPosition,
                avatarRoot.rotation * localRotation);
        }
        public static Pose AlignHead(Vector3 markerWorld, Quaternion hmdRotation, Quaternion rotationOffset)
            => new Pose(markerWorld, rotationOffset * hmdRotation);
    }
}
02

정체된 보행자가 다시 경로를 따르게 하기

배경과 과제

신호에 따라 움직이는 보행자들이 서로 충돌해 제자리에서 멈추면 교통 흐름이 막혔습니다.

내가 구현한 방식

이동해야 하는 상태에서 일정 시간 위치 변화가 없으면 보행자를 측면으로 이동시켜 경로 추종을 재개하도록 했습니다.

선택의 이유와 범위

이동 명령이 있는 상태와 실제 위치 변화를 함께 확인했습니다. 당시 프로젝트의 Path 기반 FSM에 적용한 정체 복구 방식입니다.

2026 / RECONSTRUCTED EXAMPLE

경로 이동 중 정체 상태 감지

이동해야 하지만 위치 변화가 없는 시간을 누적해 복구 필요 여부를 반환합니다.

  1. 이동 명령
  2. 위치 변화 확인
  3. 정체 시간 누적
  4. 복구 요청

설명용 개념도 · 실제 제품 화면이나 전체 시스템 설계도가 아닙니다.

사용 방법과 적용 범위

매 프레임 Tick을 호출하고 true일 때 주변 공간을 검사한 뒤 복구 동작을 수행합니다.

안전한 위치 탐색이나 실제 이동은 호출자가 담당합니다. 벽을 통과시키는 코드는 없습니다.

예제 코드 펼치기포트폴리오용 재구성 코드 · 실제 업무 소스 아님
// 2026 portfolio reconstruction. Not original production source.
using System;
using UnityEngine;
namespace PortfolioExamples
{
    public sealed class PathRecovery
    {
        Vector3 last; bool initialized; float idle;
        public bool Tick(Vector3 position, bool shouldMove, float deltaTime, float timeout, float epsilon)
        {
            if (deltaTime < 0 || timeout <= 0 || epsilon < 0) throw new ArgumentOutOfRangeException();
            if (!initialized) { last = position; initialized = true; return false; }
            if (!shouldMove || (position-last).sqrMagnitude > epsilon*epsilon) { idle = 0; last = position; return false; }
            idle += deltaTime;
            if (idle < timeout) return false;
            idle = 0; return true; // Caller must validate collision-free lateral space before moving.
        }
        public void Reset() { initialized=false; idle=0; }
    }
}

MORE SCREENS

추가 실행 화면

CODE & VALIDATION

코드와 검증 범위

기존 코드 발췌와 2026년 포트폴리오용 재구성 코드를 구분해 제공합니다. 재구성 코드는 실제 제품 소스가 아니며, 일반 원리를 설명하기 위해 새로 작성했습니다.

Unity 6000.0.23f1 컴파일 및 Editor 검증 56개 통과. 실제 장비 연동과 제품 통합은 검증 범위에 포함하지 않습니다.

예제별 사용법과 검증 내용 ↗
다른 프로젝트 살펴보기 ↗