GSI

UICanvas 전환효과주기 소스


최근에 공부하면서 심플하게 처리하는 방법 정리한 자료 입니다.


유니티_Canvas전환_코드.pdf


UICanvasSwitch2.zip


Posted by gsi
:

Bullet3D 라이브러리를 계속 파오는 동안 벌써 몇달이 지난듯 하다.

 

계속해서 로봇의 움직임을 구동하기 위해서는 객체마다 조건(ex btHingeConstraint)을 걸어줘야 하며,

조건들을 움직이는건 일단 마무리가 되었다

이후에 계속해서 가지고 있던 고민은 다리 하나하나를 움직여야 하니 제일 끝의 객체를

위치 이동을 해보면 좋을거 같았다.

 

그래서 마우스로 객체를 움직일 수 있는 부분을 파 보았다.

두가지의 제어 방식이 보인다.

btGeneric6DofConstraint 이것과 btPoint2PointConstraint 두가지다

 

일단 btPoint2PointConstraint 이걸로 제어를 해보기로 했다.

아래의 코드는 움직임을 제어 하는 방법이다.

 

객체의 변수는 아래와 같이 선언

btPoint2PointConstraint* pConStraint;

 

이 코드는 매번 포인터 객체를 삭제 해야 한다.

if( pConStraint )
{
 m_dynamicsWorld->removeConstraint( pConStraint );
 delete pConStraint;
 pConStraint = NULL;
}

 

// 해당 btRigidBody 를 연결시켜 준다.

btVector3 p1(0, 0, 0);
pConStraint = new btPoint2PointConstraint( *m_rigs[0]->m_bodies[3], p1 );
m_dynamicsWorld->addConstraint( pConStraint, true );
pConStraint->m_setting.m_tau = 1;

 

// 위와 같이 연결하고 나서 아래와 같이 해당 이동값을 적어주면 객체가 움직이게 된다.
btVector3 newPivotB;
newPivotB.setZero();
newPivotB.setZ( 0.1 );
pConStraint->setPivotA( newPivotB );

 

근데 위와 같이 코드를 구성한 이후는 btRigidBody를 Constraint로 연결을 하고

pConStraint->setPivotA( newPivotB ); 를 하고 나면 계속해서 연결이 유지되고

계속해서 움직임을 할 수 있을거라 생각 했지만,

잘 안되서 포인터 객체를 없애고, 다시 연결후에

pConStraint->setPivotA( newPivotB ); 이걸 통해서 위치를 이동시킬 수 있는걸 알았다.

 

이제 앞으로 해야 할것

 

//
pConStraint = NULL;
pConStraint2 = NULL;

//
{
 btVector3 p1(0, 0, 0);
 pConStraint = new btPoint2PointConstraint( *m_rigs[0]->m_bodies[3], p1 );
 m_dynamicsWorld->addConstraint( pConStraint, true );
 pConStraint->m_setting.m_tau = 1;
}
{
 btVector3 p1(0, 0, 0);
 pConStraint2 = new btPoint2PointConstraint( *m_rigs[0]->m_bodies[6], p1 );
 m_dynamicsWorld->addConstraint( pConStraint2, true );
 pConStraint2->m_setting.m_tau = 1;
}

이 코드를 사용해서 해당 객체를 바닥에 고정 시킨다.

 

고정시켜 놓고 나서 시퀀스를 구성하고 하나하나 이동하면서 위치가 앞으로 이동하는지를 보자.

Posted by gsi
:

이 자료는

4족 로봇을 위한 기초자료로서 Bullet3D의 라이브러리 이해를 위해서 정리한 내용임

 

 

 

위의 내용은 로봇암의 한쪽 부분을 설명하기 위한 자료

오른쪽의 마젠타 색상의 사각형이 고정부 그기서 부터 옆으로 관절1, 관절2 형태로 취해진다.

관절2(파란색)을 키보드로 움직이면 중간의 관절1의 각도가 변해야 하는게 목표이다.

 

조금 움직였을때의 모습

 

관절2번을 아래로 회전하게 되면서 관절1번의 각도가 변한 모습이다.

 

위의 화면은 카메라 뷰에서 본 화면이며

객체마다 Axis가 표기 되어 있는데

빨간색 - X

녹색 - Y

파란색 - Z (화면 뒤쪽)

 

아래는 관련된 코드이다.

 

화면에 보이는 객체는 일단 모델링 데이터가 존재 해야 하기 때문에 그 모델링 데이터는

btCollisionShape* m_shapes[2];//BODYPART_COUNT];

이걸로 관리 된다.

이 포인터 객체에 해당 데이터가 생성이 된다.

m_shapes[0] = new btBoxShape(btVector3(fBodySize, fBodySize, fBodySize));
m_shapes[1] = new btBoxShape(btVector3(fBodySize, fBodySize, fBodySize));

이 객체들은 나중에 화면에 객체를 표현하기 위한 인스턴스 객체들이다.

 

아래 코드는 화면에 보여지는 3개의 객체를 만든 내용이다.

  // 높이 0.5에 기본 위치를 잡는다.
  float fHeight = 1.0;
  btTransform offset; offset.setIdentity();
  offset.setOrigin(positionOffset);  

  // root
  // 중앙의 둥근원형을 만든다.
  btVector3 vRoot = btVector3(btScalar(0.), btScalar(fHeight), btScalar(0.));
  btTransform transform;
  transform.setIdentity();
  transform.setOrigin(vRoot);
  // 무게를 0으로 하면 고정형태의 객체가 만들어 진다.
  m_bodies[0] = localCreateRigidBody(btScalar(0.), offset*transform, m_shapes[0]);

  // 다리1
  transform.setIdentity();
  btVector3 vBoneOrigin = btVector3(1.0, 1.0, 0);
  transform.setOrigin(vBoneOrigin);
  btVector3 vToBone = (vBoneOrigin - vRoot).normalize();
  btVector3 vAxis = vToBone.cross(vUp);
  m_bodies[1] = localCreateRigidBody(btScalar(1.), offset*transform, m_shapes[1]);

  // 다리 2
  transform.setIdentity();
  vBoneOrigin = btVector3(2.0, 1.0, 0);
  transform.setOrigin(vBoneOrigin);
  vToBone = (vBoneOrigin - vRoot).normalize();
  vAxis = vToBone.cross(vUp);
  m_bodies[2] = localCreateRigidBody(btScalar(1.), offset*transform, m_shapes[1]);

 

위의 내용으로 화면에 보여지는 객체를 만들고 나면 이제 객체들을 연결하기 위한 조인트를 연결해 줘야 한다.

이걸 하지 않으면 무게 1짜리가 바닥으로 바로 떨어지게 된다. 중력이 있기 때문에.

 

아래 코드는 Hing를 추가 하는 모습이다.

나중에 서보 모터를 연동하기 위함이기 때문에 Hing라는 걸로 연결하도록 한다.

 

  btHingeConstraint* hingeC;
  //btConeTwistConstraint* coneC;

  btTransform localA, localB, localC, localD;

  float fAngle = 0;
  float fSin = sin(fAngle);
  float fCos = cos(fAngle);

  // hip joints
  localA.setIdentity();
  localB.setIdentity();
  localA.getBasis().setEulerZYX(0,0,0); 
  localA.setOrigin(btVector3(0.5, -0.5, 0));
  localB.getBasis().setEulerZYX(0,0,0); 
  localB.setOrigin(btVector3(-0.5, -0.5, 0));

  hingeC = new btHingeConstraint(*m_bodies[0], *m_bodies[1], localA, localB);
  hingeC->setLimit(DEG2RAD(0), DEG2RAD(90));
  m_joints[0] = hingeC;
  m_ownerWorld->addConstraint(m_joints[0], true);

  // hip joints
  localA.setIdentity();
  localB.setIdentity();
  localA.getBasis().setEulerZYX(0,0,0); 
  localA.setOrigin(btVector3(0.5, -0.5, 0));
  localB.getBasis().setEulerZYX(0,0,0); 
  localB.setOrigin(btVector3(-0.5, -0.5, 0));

  hingeC = new btHingeConstraint(*m_bodies[1], *m_bodies[2], localA, localB);
  hingeC->setLimit(0.0f, 0.0f);
  m_joints[1] = hingeC;
  m_ownerWorld->addConstraint(m_joints[1], true);

 

위의 코드와 같이 구성하게 되면 Hing로 3개의 객체가 연결이 되게 된다.

 

위의 모델에서 관절2를 움직이기 위한 코드는 아래와 같이 작성하면 된다.

 

 // 해당 모델을 선택된 상태로 가져와야 한다.

 // 이걸 하지 않으면 객체는 업데이트 자체가 되지 않는다. (왜 인지는 모르겠다.)

 m_rigs[0]->m_bodies[2]->setActivationState(DISABLE_DEACTIVATION);

 // Hing 객체를 찾는다. (미리 알고 있기 때문에 배열값을 바로 가져온다.)

 btHingeConstraint* hingeC = static_cast<btHingeConstraint*>(m_rigs[0]->GetJoints()[1]);
 if( hingeC )
 {
  btScalar hingeAngle = hingeC->getHingeAngle(); // 참고용
  btScalar hingeLow = hingeC->getLowerLimit(); // 참고용
  btScalar hingeHigh = hingeC->getUpperLimit(); // 참고용

  // 이걸 보면 알 수 있듯이 해당 객체의 Hing의 각도를 그냥 하나로 고정시켜서 키보드 값으로 이동 가능하게 처리 하였다.

  hingeC->setLimit(DEG2RAD(n_TestAngle), DEG2RAD(n_TestAngle));

  >> hingeC->setLimit(DEG2RAD(n_TestAngle), DEG2RAD(n_TestAngle), 0, 1, 0); 이걸로 고치면 움직임이 조금더 빠르다. 소프트한게 없어지고..

  // 모델 생성시 아래 코드도 그냥 0으로 바꾸면 움직임이 조금더 빨라진다.

  for (i = 0; i < 3; ++i)
  {
   m_bodies[i]->setDamping(0, 0); // 이 값이 크지면 중력의 영향을 천천히 받아서 모델이 천천히 떨어진다.
   m_bodies[i]->setDeactivationTime(0);
   m_bodies[i]->setSleepingThresholds(0, 0);
  }

 

  // 아래 코드는 굳이 하지 않아도 동작은 한다.
  hingeC->enableAngularMotor(false, 0, 0);
 }

 

아래는 관련 코드입니다.

 

BulletTestApp_분석용_Constraint.zip

 

 

 

 

 

 

 

Posted by gsi
:

mackeybind.exe 이 파일을 실행하고 오른쪽 command, option 키를

누를때 한글 및 한자 키가 먹도록 할 수 있습니다.

 

원래 부트 캠프로 설정이 되었는데

어느 순간부터 되지 않아서

새로 셋팅했습니다.

Posted by gsi
:

[기능]
- 카메라를 통한 사진 선택
- 롤 이미지에서 사진 선택
- 도큐먼트에 이미지 저장
- 새로 실행할때 도큐먼트 이미지 로드 기능

-h 코드

//

//  DocumentTestViewController.h

//  DocumentTest

//

//  Created by 병욱 on 11. 5. 1..

//  Copyright 2011 GsiSystem. All rights reserved.

//


#import <UIKit/UIKit.h>


#define kFilename @"data.plist"

#define kImageFilename @"Test.png"


@interface DocumentTestViewController : UIViewController<UIImagePickerControllerDelegate, UINavigationControllerDelegate> {

IBOutlet UIImageView *imageView;

IBOutlet UIButton *takePictureButton;

IBOutlet UIButton *selectFromCameraRollButton;

IBOutlet UITextField *field1;

IBOutlet UITextField *field2;

IBOutlet UITextField *field3;

IBOutlet UITextField *field4;

}


@property (nonatomic, retain) UIImageView *imageView;

@property (nonatomic, retain) UIButton *takePictureButton;

@property (nonatomic, retain) UIButton *selectFromCameraRollButton;


@property (nonatomic, retain) UITextField *field1;

@property (nonatomic, retain) UITextField *field2;

@property (nonatomic, retain) UITextField *field3;

@property (nonatomic, retain) UITextField *field4;


- (NSString *)dataFilePath;

- (NSString *)dataImageFilePath;

- (void) applicationWillTerminate:(NSNotification *)notification;

- (IBAction)getCameraPicture:(id)sender;

- (IBAction)selectExistingPicture;


@end


- m 코드

//

//  DocumentTestViewController.m

//  DocumentTest

//

//  Created by 병욱 on 11. 5. 1..

//  Copyright 2011 GsiSystem. All rights reserved.

//


#import "DocumentTestViewController.h"


@implementation DocumentTestViewController


@synthesize field1, field2, field3, field4;

@synthesize imageView;

@synthesize takePictureButton;

@synthesize selectFromCameraRollButton;


/*

// The designated initializer. Override to perform setup that is required before the view is loaded.

- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil {

    self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];

    if (self) {

        // Custom initialization

    }

    return self;

}

*/


/*

// Implement loadView to create a view hierarchy programmatically, without using a nib.

- (void)loadView {

}

*/


// Implement viewDidLoad to do additional setup after loading the view, typically from a nib.

- (void)viewDidLoad {

//    [super viewDidLoad];

//

NSString *filePath = [self dataFilePath];

if ([[NSFileManager defaultManager] fileExistsAtPath:filePath]) {

NSArray *array = [[NSArray alloc] initWithContentsOfFile:filePath];

field1.text = [array objectAtIndex:0];

field2.text = [array objectAtIndex:1];

field3.text = [array objectAtIndex:2];

field4.text = [array objectAtIndex:3];

[array release];

}

//

NSString *imageFilePath = [self dataImageFilePath];

if ([[NSFileManager defaultManager] fileExistsAtPath:imageFilePath]) {

UIImage *image = [UIImage imageWithContentsOfFile:imageFilePath];

imageView.image = image;

}

//

UIApplication *app = [UIApplication sharedApplication];

[[NSNotificationCenter defaultCenter] addObserver:self 

selector:@selector(applicationWillTerminate:) 

name:UIApplicationWillTerminateNotification 

  object:app];

[super viewDidLoad];

//

if (![UIImagePickerController isSourceTypeAvailable:

  UIImagePickerControllerSourceTypeCamera]) {

takePictureButton.hidden = YES;

selectFromCameraRollButton.hidden = YES;

}

}


- (NSString *)dataFilePath

{

NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);

NSString *documentsDirectory = [paths objectAtIndex:0];

return [documentsDirectory stringByAppendingPathComponent:kFilename];

}


- (NSString *)dataImageFilePath

{

NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);

NSString *documentsDirectory = [paths objectAtIndex:0];

return [documentsDirectory stringByAppendingPathComponent:kImageFilename];

}


- (void) applicationWillTerminate:(NSNotification *)notification

{

NSMutableArray *array = [[NSMutableArray alloc] init];

[array addObject:field1.text];

[array addObject:field2.text];

[array addObject:field3.text];

[array addObject:field4.text];

[array writeToFile:[self dataFilePath] atomically:YES];

[array release];

}


/*

// Override to allow orientations other than the default portrait orientation.

- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {

    // Return YES for supported orientations

    return (interfaceOrientation == UIInterfaceOrientationPortrait);

}

*/


- (void)didReceiveMemoryWarning {

// Releases the view if it doesn't have a superview.

    [super didReceiveMemoryWarning];

// Release any cached data, images, etc that aren't in use.

}


- (void)viewDidUnload {

// Release any retained subviews of the main view.

// e.g. self.myOutlet = nil;

}



- (void)dealloc {

    [super dealloc];

[field1 release];

[field2 release];

[field3 release];

[field4 release];

[imageView release];

[takePictureButton release];

[selectFromCameraRollButton release];

}


- (IBAction)getCameraPicture:(id)sender

{

UIImagePickerController *picker = 

[[UIImagePickerController alloc] init];

picker.delegate = self;

picker.allowsImageEditing = YES;

picker.sourceType = (sender == takePictureButton) ?

UIImagePickerControllerSourceTypeCamera

UIImagePickerControllerSourceTypeSavedPhotosAlbum;

[self presentModalViewController:picker animated:YES];

[picker release];

}


- (IBAction)selectExistingPicture

{

if ([UIImagePickerController isSourceTypeAvailable:

UIImagePickerControllerSourceTypePhotoLibrary]) {

UIImagePickerController *picker = 

[[UIImagePickerController alloc] init];

picker.delegate = self;

picker.sourceType = UIImagePickerControllerSourceTypePhotoLibrary;

picker.allowsImageEditing = YES;

[self presentModalViewController:picker animated:YES];

[picker release];

}

else {

UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Error accessing photo library"

message:@"Device does not support a photo library"

  delegate:nil

  cancelButtonTitle:@"Drat!"

  otherButtonTitles:nil];

[alert show];

[alert release];

}

}


- (void)imagePickerController:(UIImagePickerController *)picker

didFinishPickingImage:(UIImage *)image

  editingInfo:(NSDictionary *)editingInfo {

imageView.image = image;

printf("Image:%f, %f", image.size.width, image.size.height);

[UIImagePNGRepresentation(image) writeToFile:[self dataImageFilePath]

  atomically:YES];

[picker dismissModalViewControllerAnimated:YES];

}


- (void)imagePickerControllerDidCancel:(UIImagePickerController *)picker

{

[picker dismissModalViewControllerAnimated:YES];

}


@end


- 인터페이스 빌더 내용
캡춰 맥에서 어케 하는지 몰겠군요. ^^
 
Posted by gsi
: