블로그 이미지
Every unexpected event is a path to learning for you. blueasa

카테고리

분류 전체보기 (2797)
Unity3D (853)
Programming (479)
Server (33)
Unreal (4)
Gamebryo (56)
Tip & Tech (185)
협업 (61)
3DS Max (3)
Game (12)
Utility (68)
Etc (98)
Link (32)
Portfolio (19)
Subject (90)
iOS,OSX (55)
Android (14)
Linux (5)
잉여 프로젝트 (2)
게임이야기 (3)
Memories (20)
Interest (38)
Thinking (38)
한글 (30)
PaperCraft (5)
Animation (408)
Wallpaper (2)
재테크 (18)
Exercise (3)
나만의 맛집 (3)
냥이 (10)
육아 (16)
Total
Today
Yesterday
로그 메씨지 & 메씨지박스출력
NiMessageBox::DisplayMessage("MOUT::CreateScene -- W../res/data/script/model.xm Loading script Failed","script error");
본 & 스키닝 구조정리
- NiSkiningInstance
NiAVObject *const* GetBones() : 본의 포인터배열 얻기
본도 오브잭트로 여긴다. 위치정보를가진 일종에 더미로 여긴다.노드와 비슷하나 자식을가지지는 못하는..
그러나 여기서 본의 갯수는알수가없다.
그래서...
이런식으로 스킨데이터를얻어온다.
NiSkinData* pkOldSkinData = spOldSkinInstance->GetSkinData();
- NiSkinData
스킨데이터에서 본의 갯수를알수있다.
pkOldSkinData->GetBoneCount()
본의 정점 링크정보를 얻기
NiSkinData::BoneData* pkOldBoneData = pkOldSkinData->GetBoneData();
본데이터를 카피하는코드의예

for(i=0;i<pkOldSkinData->GetBoneCount();i++)
{
ppkNewBones[i] = spOldSkinInstance->GetBones()[i];
pkNewBoneData[i].m_kBound = pkOldBoneData[i].m_kBound; //본의위치정보계산용
pkNewBoneData[i].m_kSkinToBone = pkOldBoneData[i].m_kSkinToBone; //???
pkNewBoneData[i].m_usVerts = pkOldBoneData[i].m_usVerts; //본에의해 영향을받는 버텍스갯수
pkNewBoneData[i].m_pkBoneVertData = NiNew NiSkinData::BoneVertData[pkNewBoneData[i].m_usVerts]; //본에의해 영향을받는 버텍스링크정보
for (unsigned short us = 0; us < pkNewBoneData[i].m_usVerts; us++)
{
//본에의해 얼마나 영향받을지 가중치
pkNewBoneData[i].m_pkBoneVertData[us].m_fWeight = pkOldBoneData[i].m_pkBoneVertData[us].m_fWeight;
//영향받는 버텍스인덱스
pkNewBoneData[i].m_pkBoneVertData[us].m_usVert = pkOldBoneData[i].m_pkBoneVertData[us].m_usVert;
}
}
//새로운 스키닝 정보만들기
// Create the new NiSkinData and NiSkinInstance objects.
NiSkinData* pkNewSkinData = NiNew NiSkinData(uiNumNewBones, pkNewBoneData,
pkOldSkinData->GetRootParentToSkin(), spNewPartClone->GetVertices());
pkNewSkinData->SortAndMergeBoneData();
NiSkinInstance* pkNewSkinInst = NiNew NiSkinInstance(pkNewSkinData,
spOldSkinInstance->GetRootParent(), ppkNewBones);
// 새로운 스킹닝정보 붙이기
spNewPartClone->SetSkinInstance(pkNewSkinInst);
벡토를각도로
irr::core::vector3df v3Angle;
irr::core::vector3df v3Temp = irr::core::vector3df(Heading.x,Heading.z,Heading.y);
v3Angle = v3Temp.getHorizontalAngle();
SadowGeomerty 분석
UpdateShadowGeometryBound : 컬링되지 않도록 타겟오브잭트와 같은 범위를 지정한다.
아래소스와같이 데칼을 붙이기위한지형에대한 지오메트리(삼각형들)를 얻기위해서 카메라노드(m_spCamera)의 절두체를 조작해서 얻는다. 이동할때마다 회전을 보정하지않는이유는 태양광이기 때문에 방향변화가 거의없기때문이다.
void ShadowGeometry::UpdateShadowCamera(float fTime)
{
// this function moves the shadow camera so that it appears to view the
// target (caster) from infinity, facing a fixed direction. This is done
// by moving the camera so the the desired fixed direction vector is
// always coincident with the line through the caster's bounding volume
// center and the camera location
if (!m_spCamera)
return;
// get the "look at" point
NiPoint3 kTarget = m_spCaster->GetWorldBound().GetCenter();
// translate the camera to a distant point such that the camera is looking
// directly at the target point
m_spCamera->SetTranslate(kTarget - (m_kLightDir * 500.0f));//카메라는 이미빛으 방향과 일치되있다.
// set the field of view of the camera to enclose the bounding sphere of
// the caster object.
float fRadius = m_spCaster->GetWorldBound().GetRadius();
float fFOV = fRadius /
(kTarget - m_spCamera->GetWorldLocation()).Length() * 0.95f;
NiFrustum kFrust = m_spCamera->GetViewFrustum();
kFrust.m_fLeft = -fFOV;
kFrust.m_fRight = fFOV;
kFrust.m_fTop = fFOV;
kFrust.m_fBottom = -fFOV;
m_spCamera->SetViewFrustum(kFrust);
m_spCamera->Update(fTime);
}
특정방향쳐다보기(유도탄공식)
NiPoint3 kYVec = -m_kLightDir.Perpendicular();
NiPoint3 kZVec = m_kLightDir.UnitCross(kYVec);

// Rotate the camera based on the orthonormal frame
NiMatrix3 kRotation(m_kLightDir, kYVec, kZVec);
m_spCamera->SetRotate(kRotation);
m_spCamera->Update(0.0f);

광원과 같은방향으로 바라보기 예..
camera 설정하기
pkRenderer->SetCameraData(m_spCamera);
타입캐스팅
-일반포인터 타입캐스팅
NiNode* pkCamOri;
pkCamOri = NiDynamicCast(NiNode, m_spCharacterRoot->GetObjectByName("camOrient"));
타입이맞지않으면 NULL이된다.
-스마트포인터 타입 캐스팅
NiGeometry* pkGeom = NiSmartPointerCast(NiGeometry,m_kCastingObjects.GetAt(i));
겜브리오엔진 회전 기초
카메라는 기본적으로 시 점벡터가 (1,0,0), 업벡터는 0,0,1 이므로

pitch->roll ->yaw

- 쿼터니온

//쿼터니온 변환
{
NiQuaternion kQua,q1,q2,q3;

q3.FromAngleAxisZ(m_fPitch);// 피치 ..이부분중요 90도 롤하기이전에는 요 이후에 피치가된다.

q1.FromAngleAxisX(NI_PI/2); //롤
q2.FromAngleAxisZ(-m_fHeading); //요

kQua = q2*q1*q3;
m_spCamera->SetRotate(kQua);
}

- 오일러회전

FromEulerAnglesYZX(..)

오일러 회전행렬 만들기 , 접미사의 순서가 거꾸로임 즉 위의 경우 x으로 돌리고,z축돌리고 y축돌리라는뜻

짐벌락 주의...

NiNode의역활
이름그대로그밑으로자식을달수있는노드를말한다.
재귀적으로노드를 순회할때...
재귀호출함수(..)
{
들어가면서처리해야될꺼.....
if (NiIsKindOf(NiNode, pkObject))
{
NiNode* pkNode = (NiNode*) pkObject;
for (unsigned int ui = 0; ui < pkNode->GetArrayCount(); ui++)
{
재귀호출함수()
}
}
트리 끝까지 들어 간 다음 처리 해야될꺼 .....
}
식으로 코드구성할수있다.
즉 NiNode가이닌것은(상속개체포함) 밑으로 자식을가질수없다.
예제>
static void DisableZBuffer(NiAVObject* pkObject)
{
NiProperty* pkProp = pkObject->GetProperty(NiZBufferProperty::GetType());
if (pkProp)
{
((NiZBufferProperty*)pkProp)->SetZBufferTest(false);
((NiZBufferProperty*)pkProp)->SetZBufferWrite(false);
}
if (NiIsKindOf(NiNode, pkObject))
{
NiNode* pkNode = (NiNode*)pkObject;
for (unsigned int i = 0; i < pkNode->GetArrayCount(); i++)
{
NiAVObject* pkChild = pkNode->GetAt(i);
if (pkChild)
DisableZBuffer(pkChild);
}
}
}
static void DisableZBuffer(NiAVObject* pkObject)
{
NiProperty* pkProp = pkObject->GetProperty(NiZBufferProperty::GetType());
if (pkProp)static void DisableZBuffer(NiAVObject* pkObject)
{
NiProperty* pkProp = pkObject->GetProperty(NiZBufferProperty::GetType());
if (pkProp)
{
((NiZBufferProperty*)pkProp)->SetZBufferTest(false);
((NiZBufferProperty*)pkProp)->SetZBufferWrite(false);
}
if (NiIsKindOf(NiNode, pkObject))
{
NiNode* pkNode = (NiNode*)pkObject;
for (unsigned int i = 0; i < pkNode->GetArrayCount(); i++)
{
NiAVObject* pkChild = pkNode->GetAt(i);
if (pkChild)
DisableZBuffer(pkChild);
}
}
}
디파인 2개 검사해보기
#if defined(MYDEBUG) || defined(_DEBUG)
#endif
정적라이브러리링크시유의사항

-정적인 데이터 모듈관리(NiStaticDataManager)

기능별로 로더를따로등록한다.
int NiStream::RegisterLoader(const char* pcName, CreateFunction pfnFunc)

라이브러리별로 로더를 묶어서 올리는 함수지정
static void AddLibrary(InitFunction pfnInit, ShutdownFunction pfnShutdown);

기본외예 Animation,Collision 관련 로더를 활성시키려면 관련헤더파일을 인크루드시켜야한다.
예>
#include <collision.h>
#include <animation.h>

Nif파일로드시 이점에 주의하지않으면 로더가 없는부분은 데이터를 읽어들이지않는다.
2 D텍스춰 기능정리
-스크린텍스춰 만들기 & 사용하기 기본

//소스텍스춰 생성
NiSourceTexture* pkTexture = NiSourceTexture::Create(NiApplication::ConvertMediaFilename("emergentlogo.tga"));

NiScreenTexture* pkScreenTexture = NiNew NiScreenTexture(pkTexture);
pkScreenTexture->AddNewScreenRect(32, 32,pkTexture->GetWidth(), pkTexture->GetHeight(), 0, 0);

-NiScreenTexture 주요기능
AddNewScreenRect(찍을위치x,찍을위치y,끈어올크기가로,세로,끈어올위치x,y) ;

SetTexture(pkTexture) //소스 텍스춰지정

-스크린텍스춰 변경하기

먼저 변경공지를때려준다.
m_spScreenTexture->MarkAsChanged(NiScreenTexture::EVERYTHING_MASK);
AddNewScreenRect,또는 RemoveScreenRect 를 써서 추가삭제를한다.

-화면에출력
NiScreenTextureArray m_kScreenTextures;
를 화면 랜더링큰난후 한번씩찍어준다.
예>
void NiApplication::RenderScreenItems()
{
m_spRenderer->SetScreenSpaceCameraData();
const unsigned int uiSESize = m_kScreenElements.GetSize();
unsigned int i;
for (i = 0; i < uiSESize; i++)
{
NiScreenElements* pkElements = m_kScreenElements.GetAt(i);
if (pkElements)
pkElements->Draw(m_spRenderer);
}

const unsigned int uiSTSize = m_kScreenTextures.GetSize();
for (i = 0; i < uiSTSize; i++)
{
NiScreenTexture* pkTexture = m_kScreenTextures.GetAt(i);
if (pkTexture)
pkTexture->Draw(m_spRenderer);
}
}


반응형

'Gamebryo' 카테고리의 다른 글

Gamebryo Default Coordinate  (0) 2011.06.17
[Link] 게임브리오 강의  (0) 2011.03.28
gamebryotip  (1) 2011.03.21
Posted by blueasa
, |