Archive for the ·

Creativity

· Category...

비(非)마커 증강현실 엔진 개발되다.

2 comments

관련 기사 : 증강현실, ‘재미’로 승부한다…제니텀

제니텀은 최근 이용자 주변에 있는 커피전문점의 위치를 찾아주는 애플리케이션 ‘아이니드커피(ineedcoffee)’를 애플 앱스토어에 등록한 업체이고, 제니텀은 현재 비(非)마커 증강현실 엔진도 개발이 되었다고 한다.

이것 외에 애플 앱스토어에서 다양한 정보들을 GPS를 통하여 만들어진 콘텐츠도 보았다.
“놀랍다. 대단하다.”와 같은 느낌은 대부분의 관련 업계에 있는 사람들일것이라 생각하고,

“재밌다. 신기하다.”

이러한 것들이 소비자들이 콘텐츠를 구매하는 포인트가 아닌가 싶다.

증강현실 시스템을 도입한 콘텐츠들이 UCC를 통하여 많이 알려져있기 때문에
앞으로도 괜찮은 비즈니스가 이루어질 것이라고 생각이 든다.

내가 속해 있는 곳(Flash Player)에서도 증강현실 비즈니스 아이템을 창출하기 위하여
FLARToolKit에 관하여 연구중인데 쉽지가 않다. 현재는 연구와 적용 사례들을 분석중에 있다.

하지만, 증강현실은 온라인과 오프라인으로 나뉘어 질 것으로 추측하고,
연결 매개체와 구현은 Flash Player로도 충분히 시장에 들어 갈 수 있다고 생각하고있다.

Flash Player가 갖고 있는 장점이 바로 “재밌다. 신기하다. 화려하다.”
포커스가 잡혀있기 때문이다.

FLAR Tutorial 3 : 멀티 마커들의 멀티 객체 표현.

no comments

FLARToolKit : How to – Multiple Instances of Multiple Markers.

요번에는 지난번에 말했던 다중(이하 ‘멀티’로 표기) 마커들에 대한 부분들을 다뤄볼까 한다.

요번 알고리즘으로 멀티 마커에 의한 멀티 객체 표현을 다룬 squidder.com의 소스를 사용할 것이다. 아래 관련 문서와 소스를 다운 받자.

원문 포스트 :
FLAR how-to: Multiple instances of multiple markers.
다운로드 :
Download Source Code

우선 어떻게 작동이 되는지와 좌표계가 어떻게 출력이 되는지 아래 영상으로 우선 확인해 보자.

하단의 trace 결과를 보면 x, y, z축의 값을 알 수 있다.
일반 웹캠으로는 퀄리티와 속도가 안나온다. 하나 사야하나... 흠

패키지 구조는 다음과 같다.

Package
Class public class MultiFLARExample
Inheritance MultiFLARExample →  PVFLARBaseApplication → FLARBaseApplication

요번에도 다이어그램 문서와 다이어그램을 확인해 봐야 한다.
(분석하는데 반나절이란 시간을 소요했다.)

아래와 같은 API 문서와 다이어그램을 살펴본 후에 중요한 작동 포인트를 살펴보겠다.

API Documentation :
FLARSquidderKit/docs/index.htm

Basic Diagram :

분석하기 위해서 다이어그램을 만들었는데, 이거 주인에게 말하고 해야 하는게 아닌가 싶다.
하지만 많은 사람들이 한눈에 구조를 파악할 수 있게 만들어준 것을 고마워 할지도 모르겠다는 생각도 해본다. ㅡㅡ;

소스와 api 문서와 다이어그램을 자세히 보았다면 어떤 구조인지 알 것이다.
실행 순서를 파악하는 것도 중요하다. 아래는 작동되는 순서를 출력한 결과이다.

## MultiFLARExample : constructor
## PVFLARBaseApplication : constructor
## FLARBaseApplication : constructor
## FLARBaseApplication : _loadMarkersAndCamera()
## MultiFLARExample : _init( [Event type="complete" bubbles=false cancelable=false eventPhase=2] )
## PVFLARBaseApplication : _init( [Event type="complete" bubbles=false cancelable=false eventPhase=2] )
## FLARBaseApplication : _init( [Event type="complete" bubbles=false cancelable=false eventPhase=2] )
## FLARBaseApplication : _setUpMarkers()
## FLARBaseApplication : _attachWebCam()
INFO: Papervision3D 2.1 rev920 (August 11th, 2009)
 
## PVFLARBaseApplication : startRendering()
## PVFLARBaseApplication : _onRenderTick(event)
## MultiFLARExample : _detectMarkers()
## PVFLARBaseApplication : _onRenderTick(event)
## MultiFLARExample : _detectMarkers()

기본 셋팅이 완료되면 PVFLARBaseApplication.startRendering() 메서드가 작동이 되면서 반복문(Event.EnterFrame)이 시작된다.

반복에서 사용되는 메서드 호출은 PVFLARBaseApplication._onRenderTick(), MultiFLARExample._detectMarkers() 두 곳이다. 여기에서 멀티 객체와 멀티 마커 인식을 체크하는 것이다.

코드 중에 PVFLARBaseApplication.transformMatrix( target : DisplayObject3D , r:FLARTransMatResult) 메서드가 있다. 이 부분에서 좌표값을 확인 할 수 있다.

화면 표시 방식을 mirror(역 방향 처리) 시키면 x 축의 +, -가 반대로 출력이 되는 현상이 있어서 우선은 헛갈리겠지만 반대로 제스처(행동, 행위)를 해줘야 했다. 반대로 계산하도록 만들려다가 좌표계가 복잡한 관계로 그냥 두었다. ㅡㅡ;

잘 짜여진 구조이긴 한데, 이걸 간단히 설명을 하자니 힘들고,
자세히 설명하자니 깊이 파고 들어가야 하는데… 우선 시작해 보자.

우선 아래의 구조를 좀 더 자세히 살펴봐야 한다.
MultiFLARExample PVFLARBaseApplication FLARBaseApplication

위 상속 구조에서 핵심적으로 작동하는 것은 FLARBaseApplication 이라고 할 수 있다. 이곳에서 카메라 인식 및 멀티 마커 등록과 작동이 행해진다.
내부 구조에서 다음과 같은 객체 속성 멤버를 확인해야 한다.

/** flar::FLARBaseApplication */
protected var _flarDetector : FLARSquidderMarkerDetector;
protected var _baseLoader : BaseLoader;
protected var _markers : Array;

protected‘로 되어있다는 것은 상속 구조에서 접근 허용을 뜻한다. 그리고 메서드일 경우,
상위에서 호출이 되면 최초 클래스의 동일 ‘override‘된 메서드도 같이 호출이 된다.
아래 코드에서 선언된 이벤트 같은 경우를 말한다. 이곳에서는 아래 코드 부분의 이벤트가 중요한 역할을 한다.

/** flar::FLARBaseApplication */
protected function _init( event : Event ) : void {
	// ...
	_flarDetector = new FLARSquidderMarkerDetector( _flarParam , _flarCodes , _sizes , _sizes.length );
	_flarDetector.addEventListener( FLARDetectorEvent.MARKER_ADDED , _handleMarkerAdded );
	_flarDetector.addEventListener( FLARDetectorEvent.MARKER_REMOVED , _handleMarkerRemove );
}
protected function _handleMarkerAdded( event : FLARDetectorEvent ) : void {
}
protected function _handleMarkerRemove( event : FLARDetectorEvent ) : void {
}
 
// 최상위 클래스에서 이벤트가 발생하면 MultiFLARExample  클래스의 메서드가 호출이 일어난다.
 
/** MultiFLARExample */
override protected function _handleMarkerAdded( event : FLARDetectorEvent ) : void {
	// 큐브 생성 이벤트 핸들러
	_addCube( event.codeId , event.codeIndex );
}
override protected function _handleMarkerRemove( event : FLARDetectorEvent ) : void {
	// 큐브 삭제 이벤트 핸들러
	_removeCube( event.codeId , event.codeIndex );
}
핵심 포인트 : 복잡한 마커들을 사용할 경우 알고 넘어가기...
 
위 코드에서 사용된 flar:detector:FLARSquidderMarkerDetector 클래스는 FLARToolKit API를 변경한 것으로써
마커가 단순한 패턴인 경우에 퍼포먼스를 향상 시킨는 코드이다.
 
만약, 다른 복잡한 마커를 사용하게 된다면 아래 코드를 원래 계산으로 변경해야 한다.
 
var borderWidth:Number = (100 - i_code[0].markerPercentWidth) / 20;
//マーカの枠高を算出
var borderHeight:Number = (100 - i_code[0].markerPercentHeight) / 20;
↓
var borderWidth:Number = i_code[0].markerPercentWidth / 10;
//マーカの枠高を算出
var borderHeight:Number = i_code[0].markerPercentHeight / 10;

이제 하나씩 살펴보고 작동 원리를 이해해 보자.

최초에 FLARBaseApplication Constructor에서 _loadMarkersAndCamera( ) 메서드가 호출이 된다.
이곳에서 MultiFLARExample Constructor에서 등록된 _markers Array 객체에 있는 패턴들이 FLARMarkerObj 클래스에 등록을 시키고 _baseLoader 객체에 등록이 되고, load가 이루어 진 후 완료 시 _init 메서드가 호출이 되며, 최초  MultiFLARExample 클래스에서 super를 사용하여 ’override‘된 메서들이 호출이 되며 셋팅이 완료 된다.

아래 코드들을 확인해 보면 한 눈에 알 수 있을 것이다.

/** flar::FLARBaseApplication */
public function FLARBaseApplication() {
	super( );
 
	_loadMarkersAndCamera( );
}
protected function _loadMarkersAndCamera() : void {
	_baseLoader = new BaseLoader( );
	_baseLoader.addAsset( "assets/flar/camera_para.dat" , { id:"FLARCamera" , type:"Binary" } );
 
	for ( var i : int = 0 ; i < _markers.length ; i++ ) {
 
		var markerObj : FLARMarkerObj = FLARMarkerObj( _markers[ i ] );
		_baseLoader.addAsset( markerObj.markerSrc , { id:"FLARPattern" + i } );
	}
 
	_baseLoader.addEventListener( Event.COMPLETE , _init );
	_baseLoader.load();
}
 
// 여기서 알아야 할 것은 _init 메서드가 일어날 경우 추상 클래스의 메서드가 작동하는 것이 아니다.
// 최초 클래스인 MultiFLARExampled의 _init(event)가 실행이 되면서 
// super._init(event);를 사용하여 추상(구상) 클래스 초기 셋팅을 실행한다.
// 아래 코드는 실행 우선 순위로 _init 메서드의 표시하였고, 작동에 대한 설명을 달았다.
 
/** MultiFLARExample */
protected function _init( event : Event ) : void {
	super._init( event );
	// PointLight3D 객체를 생성하여 큐브 생성시 사용된다.
}
 
/** flar::PVFLARBaseApplication*/
override protected function _init( event : Event ) : void {
	super._init( event );
	// FLAR과 PV3D가 셋팅이 된다.
}
 
/** flar::FLARBaseApplication*/
protected function _init( event : Event ) : void {
	// camera_para.dat 및 *.pat 파일들을 셋팅한다.
}
protected function _setUpMarkers() : void {
	// 마커를 셋업시킨다.
}
protected function _attachWebCam() : void {
	// 카메라와 비디오를 셋팅한다.
}
 
/** flar::PVFLARBaseApplication - _init(event) 메서드에서 실행이 된다. */
public function startRendering() : void {
	// 반복 이벤트 등록.
	addEventListener( Event.ENTER_FRAME , _onRenderTick );
}
protected function _onRenderTick( event : Event = null ) : void {
	// 반복하며 비디오를 그리고 마커를 찾고, 화면을 렌더링한다.
	_flarBitmap.bitmapData.draw( _video );
	_detectMarkers();
	renderer.renderScene( scene , _camera , viewport );
}
 
/** MultiFLARExample */
override protected function _detectMarkers() : void {
	// 마커를 찾고, 좌표를 업데이트 한다.
}

이제 어떻게 작동이 되는지 파악이 될 듯 싶다.
이해를 돕기 위해 코드 대신 간략한 코멘트를 작성을 하였다. 코드는 해당 클래스를 클릭하여 보길 바란다.
만약, 파악이 안된다면 API 문서와 다이어그램을 다시 한번 살펴보길 바란다.

이렇게 하여 반복문이 실행이 되면서 마커들을 찾고 마커에 의해 반응 처리가 이루어지는 것이다.

작성 후기 :
마커가 너무 단순하면 카메라와 비디오 처리에서 비슷한 표면을 찾아 마커로 잘못 인식하는 경우가 발생한다.
좀 더 명확한 심볼을 갖고 작업을 해야 오작동을 막을 수 있다.
웹캠으로 녹화시 현재의 심볼 때문에 촬영하기 힘들었다.

3D Car in Augmented Reality.

no comments

플래시에서 AR(Augmented Reality)로 UI적으로는 문제가 많다고 판단을 하고 있다.
그런데 위와 같은 아이디어가 나를 자극한다.

3DMax의 DAE를 사용하여 다양한 퍼포먼스를 보여줄 수 있을 듯 싶다.
대중에게 보여주는 광고 마케팅으로 사용이 되어진다면 적절한 경쟁 마켓을 형성할 수 있지 않을까?

주절주절 : jin_u
모든 것이 질리고 새로운 것이 매번 찾아온다.
그 속에서 자신을 계발 시켜지 않는다면 패자가 될 것이다.