쓰리디아이 / 2023
특전교 낙하산 시뮬레이터
회전 장비에서도 자연스럽게 이어지는 트래킹

프로젝트 연도 / 상태2023 · 개발 중 이직
개발팀 · 리소스 인력 제외3인 · 팀장
사용 기술Unity3D · C# · VR · Winform
OVERVIEW
프로젝트와 나의 역할
장비 회전 방향에 따른 Kinect 데이터 선택과 자세 Merge/Fade, 개발 일정 관리를 담당했습니다.
- 회전하는 장비에 대한 키넥트 자세 Merge 기능 개발
- 프로젝트 고도화 작업 업무 분장 및 일정 관리
CHALLENGE
해결해야 했던 문제
장비 회전으로 여러 Kinect의 자세 데이터를 합치기 어려움
APPROACH
선택한 해결 방식
장비 회전 각도에 따라 훈련자를 잘 관측하는 센서를 선택해 자세가 어색해지는 구간을 줄였습니다.
RECONSTRUCTED EXAMPLE
포트폴리오용 재구현 코드
장비 회전 각도에 따른 센서 선택을 재현합니다. 전환 임계값과 보간은 이번 예제에 추가한 설계입니다.
당시 제품의 원본 소스가 아닌 새로 작성한 예제입니다. Unity 컴파일·실행 검증은 아직 하지 않았습니다.
코드 펼쳐보기
// Portfolio reconstruction, 2026. Not original production source.
// Models rotation-dependent sensor selection; no proprietary sensor SDK or data.
using System;
using UnityEngine;
public sealed class RotationSensorSelector : MonoBehaviour
{
[Serializable] public class Source
{
public Transform calibratedPose; // All poses must already share world coordinates.
public float bestFacingYaw;
public bool tracked = true; // Set by the sensor adapter, including stale-data handling.
}
[SerializeField] Transform rig;
[SerializeField] Transform output;
[SerializeField] Source[] sources;
[SerializeField, Min(0)] float switchMarginDegrees = 12;
[SerializeField, Min(0.001f)] float blendSeconds = 0.15f;
int selected = -1;
bool Valid(int i) => sources != null && i >= 0 && i < sources.Length && sources[i] != null
&& sources[i].tracked && sources[i].calibratedPose != null;
void LateUpdate()
{
if (rig == null || output == null || sources == null) return;
float yaw = rig.eulerAngles.y;
int best = -1; float bestError = float.PositiveInfinity;
for (int i = 0; i < sources.Length; i++)
{
if (!Valid(i)) continue;
float error = Mathf.Abs(Mathf.DeltaAngle(yaw, sources[i].bestFacingYaw));
if (error < bestError) { best = i; bestError = error; }
}
if (best < 0) { selected = -1; return; } // Hold the last pose on complete tracking loss.
float currentError = Valid(selected)
? Mathf.Abs(Mathf.DeltaAngle(yaw, sources[selected].bestFacingYaw)) : float.PositiveInfinity;
if (!Valid(selected) || bestError + switchMarginDegrees < currentError) selected = best;
Transform pose = sources[selected].calibratedPose;
float alpha = 1 - Mathf.Exp(-Time.deltaTime / Mathf.Max(0.001f, blendSeconds));
output.SetPositionAndRotation(Vector3.Lerp(output.position, pose.position, alpha),
Quaternion.Slerp(output.rotation, pose.rotation, alpha));
}
}
PROJECT MEDIA
실행 화면과 시연
기존 프로젝트 상세 설명 보기
# 특전교 낙하산 시뮬레이터 개발(개발 진행 중 이직)
Unity 기반 특전교 낙하산 시뮬레이터로, VIVE Tracker·Kinect 풀바디 모션캡처, 최대 12인 네트워크 동기화, WGS84·UTM 좌표 연동, 통제/서버 SW와 VR 클라이언트 간 아바타 모션 동기화 기능을 포함합니다.
프로젝트 설명을 위한 이미지 및 영상 Youtube
### 01. 프로젝트 구성 (리소스 개발 인력 제외)
팀 구성 : 3인 (팀장으로 참여)
### 02. 프로젝트 내 본인 작업 내용
1. Unity 관련
1. 회전하는 장비에 대한 키넥트 자세 Merge 기능 개발
2. 프로젝트 관리
1. 프로젝트 고도화 작업 업무 분장 및 일정 관리
### 03. 담당 기능 개발
# Unity 관련
1. 회전하는 장비에 대한 키넥트 자세 Merge 기능 개발
1. 키넥트 자세 Merge/Fade 기능 개발
- 개발 방안 : 키넥트 3개를 이용하여 회전하는 장비의 키넥트마다의 트래킹 데이터를 Merge하여 아바타를 컨트롤 하도록 개발
- 이슈 및 문제점 : 회전하는 장비이다 보니 키넥트간의 데이터를 Merge 하기가 더욱도 어려워짐.
- 해결방안 : 하드웨어 장비의 회전 방향 데이터를 토대로 키넥트가 가장 훈련자를 트래킹 하는 각도 범위를 결정. 이후 해당 방향 각도 데이터에 따라 특정 키넥트의 데이터를 사용하는 방법으로 키넥트 데이터가 어색해지는 순간을 최소화
- 해결 가능 이유 : 오히려 실제로 도는 장비이다 보니, 장비의 회전 데이터를 이용하여 키넥트의 방향과 일치화 하는 방법이 유용했음.
# 프로젝트 관리 관련
1. 프로젝트 고도화 작업 업무 분장 및 일정 관리
1. 프로젝트 일정 관리
- 이전 비상탈출 낙하산 프로젝트에 참여했던 팀원들과 작업하여, SW 측면에서 팀원들과 큰 이슈 사항 없이 작업이 되었음.