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

카테고리

분류 전체보기 (2738)
Unity3D (817)
Programming (475)
Server (33)
Unreal (4)
Gamebryo (56)
Tip & Tech (228)
협업 (58)
3DS Max (3)
Game (12)
Utility (136)
Etc (96)
Link (32)
Portfolio (19)
Subject (90)
iOS,OSX (53)
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
05-05 09:19

1. API에서 참조하는 library의 순서를 확일 할수 있는 명령

 

.net -> 속성 -> linker -> 명령줄 -> 추가 옵션

/verbose:lib


반응형
Posted by blueasa
, |

예외 처리 ~~ tip

Tip & Tech / 2011. 2. 8. 17:11

예외 처리라 하면.. try{} catch(...){} 등을 사용하여 코딩을 하는게

보통이다.

 

하지만.. release 컴파일시 error로 프로그램이 죽어버리게 되면 catch등을 통하지 않고

종료되어. 버그 리포팅을 하기가 힘든데

 

이럴때를 지원해주기 위한 window API 함수를 알아본다.

 

step1 : 프로그램이 죽어버를 경우 무조건 호출될 callback함수를 하나 만든다.

LONG WINAPI  ExceptionCallStack (struct _EXCEPTION_POINTERS *exceptionInfo);

 

step 2 : 예외 처리 핸들러 생성

LPTOP_LEVEL_EXCEPTION_FILTER PrevExceptionFilter = NULL;

 

 

int APIENTRY _tWinMain(..... )

{

 

 // 콜스택 기록용 예외 콜백 함수 등록
 PrevExceptionFilter = SetUnhandledExceptionFilter(ExceptionCallStack);

Run();

 

// 콜스택 기록용 예외 콜백 함수 등록 해제
 SetUnhandledExceptionFilter(PrevExceptionFilter);

 

}

 

=> Thingking

........... ExceptionCallStack 함수에 miniDump나 콜스택 과련 debug코드를 내포하여 release를 배포하면

차후 생각지 못한 버그가 발생했을경우 리포팅이 가능해진다.

[출처] 예외 처리 ~~ tip|작성자 모냐

반응형
Posted by blueasa
, |

무기잔상효과

Gamebryo/Lecture / 2011. 2. 8. 17:05

무기의 잔상효과를 구현하기위해서는 실시간으로 무기가 움직이는 월드상에

폴리곤을 만들어주고 텍스쳐 uv또한 실시간으로 할당해 주어야한다.

또한, 낮은 프레임에서도 부드러운 형태로 폴리곤을 만드려면 셈플링하는 무기의

위치에 대하여 보간처리를 해야한다.


여기서는 동적으로 폴리곤을 생성하고 사용될 텍스쳐의 uv를 결정해주는 방법을 살펴보도록 한다.
스플라인 보간처리부분은 직접 해보세요.
 

무기에 필요한 정보

무기의 잔상효과가 적용될 시작지점과 끝점에 더미를 추가하도록한다.

더미이름은 *point1,*point2라고 칭한다.

 

※ 구현 순서

1. 더미이름으로 각 더미노드 포인터를 찾아 저장해놓는다.

2. 매 프레임마다 더미노드의 변경된 좌표에 대하여 폴리곤을 생성한다.

3. 정해진 출력시간을 초과하면 해당 정보를 리스트에서 제거한다.
4. 일정 비율로 시간이 지남에따라 폴리곤 크기를 줄여준다.
5. 생성된 폴리곤에 대하여 텍스쳐 uv를 할당한다.
 

struct AIPoint

    {

        float       m_fStartTime; // 폴리곤을 생성할 때 현재 시간을 저장한다.

        NiPoint3    m_kPoint[2];  // 생성될때 더미노드 월드좌표를 저장한다.

};

 

    typedef std::vector<AIPoint>    VAIPOINT;

    typedef VAIPOINT::iterator      VAIPOINT_ITER;

VAIPOINT        m_vAIPointList;        // 더미노드 리스트                                  

NiTriShapePtr   m_spAIGeometry;        // 동적으로 만들어진 지오메트리

    NiAVObject*     m_pkPointNode[2];      // 잔상이 적용될 노드포인터

    float           m_fLifeTime;           // 폴리곤이 출력되는 시간

 

매 프레임마다 더미의 월드좌표와 시간정보를 리스트에 추가한다.
   실제 제작시에는 변화가있을때만 추가해야할 것이다. 또는 특정 애니메이션에서만 추가되도록 작성해야한다.
    AIPoint r_kAIPoint;

    r_kAIPoint.m_fStartTime = p_fTime;

    r_kAIPoint.m_kPoint[0]  = m_pkPointNode[0]->GetWorldTranslate();

    r_kAIPoint.m_kPoint[1]  = m_pkPointNode[1]->GetWorldTranslate();

    m_vAIPointList.push_back( r_kAIPoint );

 

※ 매프레임마다 *point2더미 위치를 *point1 더미위치방향으로 줄어들게 한다.

또한 출력시간이 지났다면 해당 AIPoint 객체를 리스트에서 제거하도록 한다.

if( m_vAIPointList.empty() )
        return;
    VAIPOINT_ITER r_iter;

    for( r_iter = m_vAIPointList.begin(); r_iter != m_vAIPointList.end(); )

    {

        float r_fElapsedTime = p_fTime - r_iter->m_fStartTime;

        if( r_fElapsedTime > m_fLifeTime )

        {

            r_iter = m_vAIPointList.erase( r_iter );

        }

        else

        {

            NiPoint3 r_kDirVec =
                     ( r_iter->m_kPoint[0] - r_iter->m_kPoint[1] );

            float r_fLength = r_kDirVec.Length();

            if ( r_fLength > 0.0f )

            {

                NiPoint3::UnitizeVector( r_kDirVec );

                float fAmount = r_fLength / ( m_fLifeTime * 10.0f );

r_kDirVec *= fAmount;

                r_iter->m_kPoint[1] += r_kDirVec;

            }

            ++r_iter;

        }

    }

 

주어진 리스트를 이용하여 동적으로 폴리곤과 uv좌표정보를 갱신한다.

unsigned short  r_usAIPointCount = m_vAIPointList.size();
    // 최소한 3개이상이어야 정상적인 메쉬를 만들 수 있다

    if ( r_usAIPointCount <= 2 )
        return;
   
unsigned short  r_usVertices     = r_usAIPointCount * 2;

    unsigned short  r_usTriangles    = ( r_usAIPointCount - 1 ) * 2;

    unsigned short* r_pusTriList     = NULL;

    NiPoint3*       r_pkVerts        = NiNew NiPoint3[ r_usVertices ];

    NiPoint2*       r_pkTexture      = NiNew NiPoint2[ r_usVertices ];

 

    if ( r_usTriangles )

    {

        r_pusTriList = (unsigned short*)NiMalloc(

            sizeof(unsigned short) * ( 3 * r_usTriangles ) );

    }

 

    for( int r_i = 0; r_i < r_usAIPointCount; ++r_i )

    {

        int r_nNum = r_i * 2;

 

        r_pkVerts[r_nNum]     = m_vAIPointList[r_i].m_kPoint[0];

        r_pkVerts[r_nNum + 1] = m_vAIPointList[r_i].m_kPoint[1];

 

        if( 0 == r_i )

        {

            r_pkTexture[0] = NiPoint2( 0.0f, 0.0f );

            r_pkTexture[1] = NiPoint2( 1.0f, 0.0f );

        }

        else

        {

            float r_uv = (float)( r_i ) / (float)( r_usAIPointCount - 1 );

            r_pkTexture[r_nNum]     = NiPoint2( 0.0f, r_uv );

            r_pkTexture[r_nNum + 1] = NiPoint2( 1.0f, r_uv );

 

            int r_nIndex  = ( r_i - 1 ) * 6;

            int r_nFactor = ( r_i - 1 ) * 2;

 

            r_pusTriList[r_nIndex + 0] = 0 + r_nFactor;

            r_pusTriList[r_nIndex + 1] = 1 + r_nFactor;

            r_pusTriList[r_nIndex + 2] = 2 + r_nFactor;

            r_pusTriList[r_nIndex + 3] = 2 + r_nFactor;

            r_pusTriList[r_nIndex + 4] = 1 + r_nFactor;

            r_pusTriList[r_nIndex + 5] = 3 + r_nFactor;

        }

    }

 

    NiGeometryData* r_pkGeomData = m_spAIGeometry->GetModelData();

    NiTriShapeData* r_pkTriShape = (NiTriShapeData*)r_pkGeomData;

   

    r_pkGeomData->Replace(

        r_usVertices,

        r_pkVerts,

        0,                                  // Normal

        0,                                  // Color

        r_pkTexture,

        1,                                  // TextureSets

        NiGeometryData::NBT_METHOD_NONE );  // Normal Binormal Tangent Method

 

    r_pkTriShape->Replace( r_usTriangles, r_pusTriList );

 

    r_pkGeomData->MarkAsChanged (

            NiGeometryData::VERTEX_MASK |

            NiGeometryData::TEXTURE_MASK |

            NiTriBasedGeomData::TRIANGLE_INDEX_MASK |

            NiTriBasedGeomData::TRIANGLE_COUNT_MASK );

 

    // Perform initial update.

    m_spAIGeometry->Update(0.0f);

    m_spAIGeometry->UpdateProperties();

    m_spAIGeometry->UpdateEffects();

    m_spAIGeometry->UpdateNodeBound();

 

 

-> URL : http://clodymade.tistory.com/entry/무기잔상효과

반응형

'Gamebryo > Lecture' 카테고리의 다른 글

게임브리오 2D Line관련  (0) 2011.10.30
FrameRenderSystem에서.. 커스텀알파소터프로세스..  (0) 2011.09.18
캐릭터 기울기 연산  (0) 2011.02.08
Gamebryo 셋팅  (1) 2011.01.06
게임브리오 강좌(?) 링크  (3) 2010.04.14
Posted by blueasa
, |
필요한 경우는 아래와 같다.
1. 2족 캐릭터가 지형의 경사면에서 죽는 애니메이션.
2. 4족 이상 동물의 지형 경사면 이동.


일단 캐릭터가 서있는 지형에대한 노멀벡터를 알아야한다.
자신의 위치에서 바닥으로 피킹을 해서 얻으면 된다.
캐릭터의 크기가 바닥 그리드에 비해 크다면 캐릭터의 크기에 맞게 삼각형 형태의
3정점에서 피킹을하여 얻어지는 평면의 노멀값을 계산하여 사용하도록 하자.

1. 현재 캐릭터 위치에서 지형으로 피킹을 한다.
2. 피킹으로 얻어진 노멀 벡터와 Z축 벡터를 이용하여 회전행렬을 구한다.
3. 캐릭터의 회전값에 적용한다.


ex)
// 원래 벡터 srcVec, 변환후 벡터 destVec, 회전축 벡터 axisVec
// axisVec = srcVec x destVec                                               // 회전축 벡터
// angle = acos( srcVec * destVec / |srcVec| |destVec| )       // 회전각


// m_spCharRootNode 캐릭터 루트 노드
// m_kPickNormal 현재 위치에대한 노멀 벡터
NiMatrix3 r_kRot;
NiPoint3 r_kAxis = m_kPickNormal.Cross( NiPoint3(0.0f, 0.0f, 1.0f) );
float r_fDot = m_kPickNormal.Dot( NiPoint3(0.0f, 0.0f, 1.0f) );
float r_fRadian = NiACos( r_fDot );
r_kRot.MakeRotation( r_fRadian, r_kAxis );
m_spCharRootNode->SetRotate( r_kRot );


주의사항 : 루트노드를 카메라 회전및 기타 다른용도에
사용되고 있다면 위 코드는 정상적으로 구현되지 않을 수 있습니다.
이럴 경우 노멀벡터값을 루트노드회전행렬과 곱한값을 사용하면 해결 될 수 있습니다.
 
반응형

'Gamebryo > Lecture' 카테고리의 다른 글

FrameRenderSystem에서.. 커스텀알파소터프로세스..  (0) 2011.09.18
무기잔상효과  (0) 2011.02.08
Gamebryo 셋팅  (1) 2011.01.06
게임브리오 강좌(?) 링크  (3) 2010.04.14
Gamebryo 2.5  (0) 2010.04.12
Posted by blueasa
, |

이펙트 출력

Gamebryo/Effect / 2011. 2. 8. 17:03

이펙트 애니메이션이 종료되는 시점(이펙트 애니메이션 시간)을 알아야한다.
아래 함수는 이펙트 애니메이션 길이(시간)을 알아내는 함수이다.

//////////////////////////////////////////////////////////////////////////////
<이펙트 출력 순서>
1. 이펙트를 로딩한다.
2. 아래 함수를 통해 애니메이션 길이(m_fAnimLength)을 구한다.
3. 이펙트 애니메이션 시작 시간을 정한다.
    NiTimeController::StartAnimations( m_spEffect, m_fStartTime );
4. 이펙트 종료를 체크한다.
    if( fTime - m_fStartTime >= m_fAnimLength )
        m_spEffect = 0;   // 이펙트 노드 제거
    else
        m_spEffect->Update( fTime );
//////////////////////////////////////////////////////////////////////////////

void RecursiveGetAnimRange(NiAVObject* pkObject, float& rfLoKeyTime, float& rfHiKeyTime)
{
    NiTimeController* pkController = pkObject->GetControllers();
    while ( pkController )
    {
        float fLoTime = pkController->GetBeginKeyTime();
        float fHiTime = pkController->GetEndKeyTime();
        if ( fLoTime < rfLoKeyTime )
            rfLoKeyTime = fLoTime;
        if ( fHiTime > rfHiKeyTime )
            rfHiKeyTime = fHiTime;

        pkController->SetAnimType( NiTimeController::APP_INIT );
        pkController = pkController->GetNext();
    }

    // Do the same for any animation controllers attached to the rendering properties
    if ( NiIsKindOf( NiAVObject, pkObject ) )
    {
        NiAVObject* pAVObj = (NiAVObject*)pkObject;
        pAVObj->SetSelectiveUpdate(true);
        pAVObj->SetSelectiveUpdateTransforms(true);
        pAVObj->SetSelectiveUpdatePropertyControllers(true);
        pAVObj->SetSelectiveUpdateRigid(false);

        NiTListIterator kPos = pAVObj->GetPropertyList().GetHeadPos();
        while ( kPos )
        {
            NiProperty *pProp = pAVObj->GetPropertyList().GetNext( kPos );
            if ( pProp )
            {
                for ( pkController = pProp->GetControllers(); pkController; pkController = pkController->GetNext() )
                {
                    float fLoTime = pkController->GetBeginKeyTime();
                    float fHiTime = pkController->GetEndKeyTime();
                    if ( fLoTime < rfLoKeyTime )
                        rfLoKeyTime = fLoTime;
                    if ( fHiTime > rfHiKeyTime )
                        rfHiKeyTime = fHiTime;

                    pkController->SetAnimType( NiTimeController::APP_INIT );
                }
            }
        }

    }

    if ( NiIsKindOf( NiNode, pkObject ) )
    {
        NiNode* pkNode = (NiNode*)pkObject;
        for ( unsigned int i = 0; i < pkNode->GetArrayCount(); ++i )
        {
            NiAVObject* pkChild = pkNode->GetAt( i );
            if ( pkChild )
                RecursiveGetAnimRange( pkChild, rfLoKeyTime, rfHiKeyTime );
        }
    }
}


------------------------------------------------------------------
ex)
    float fLoTime =  NI_INFINITY;
    float fHiTime = -NI_INFINITY;
    RecursiveGetAnimRange( m_spModel, fLoTime, fHiTime );
    m_fAnimLength = fHiTime - fLoTime;    // 애니메이션 전체 시간 계산

[출처] GameBryo - 이펙트 출력|작성자 모냐

반응형

'Gamebryo > Effect' 카테고리의 다른 글

강의자료 - 파티클 예제  (0) 2011.03.22
Setup about Effect Dumy…  (0) 2011.03.21
파티클 컨트롤 해보기  (0) 2011.02.24
이펙트 작업에 필요한 기능  (0) 2011.01.27
검광, 검기 잔상 효과에 대하여...  (1) 2011.01.21
Posted by blueasa
, |
    문자열(std::string)을 키로 가지는 맵 같은 경우, 문자열 비교 자체에 걸리는 시간 때문에 검색이 느려질 수 있다. 이 경우, 키로 사용하는 문자열이 별로 중요한 내용이 아니라면 아래와 같은 클래스를 사용함으로서 성능을 약간 증가시킬 수 있다. 
    ////////////////////////////////////////////////////////////////////////////////
    /// \class cStringKey
    /// \brief STL 컨테이너를 위한 문자열 키
    ////////////////////////////////////////////////////////////////////////////////
    
    class cStringKey
    {
    private:
        enum
        {
            BYTE_SIZE = 32,
        };
    
        char m_Text[BYTE_SIZE]; ///< 문자열
    
    
    public:
        /// \brief 생성자
        cStringKey()
        {
            memset(m_Text, 0, sizeof(m_Text));
        }
    
        /// \brief 생성자
        cStringKey(const char* text)
        {
            memset(m_Text, 0, sizeof(m_Text));
            memcpy_s(m_Text, sizeof(m_Text), text, std::min(sizeof(m_Text), strlen(text)));
        }
    
        /// \brief 생성자
        cStringKey(const std::string& text)
        {
            memset(m_Text, 0, sizeof(m_Text));
            memcpy_s(m_Text, sizeof(m_Text), text.c_str(), std::min(sizeof(m_Text), text.size()));
        }
    
        /// \brief 복사 생성자
        cStringKey(const cStringKey& rhs)
        {
            memcpy_s(m_Text, sizeof(m_Text), rhs.m_Text, sizeof(m_Text));
        }
    
    
    public:
        /// \brief 대입 연산자
        inline const cStringKey& operator = (const cStringKey& rhs)
        {
            if (this != &rhs)
                memcpy_s(m_Text, sizeof(m_Text), rhs.m_Text, sizeof(m_Text));
    
            return *this;
        }
    
        /// \brief 비교 연산자
        ///
        /// 이 함수는 약간 유의해야 하는데, 속도를 위해 루프를 풀어버렸기 때문이다.
        /// 클래스의 크기가 변경되면, 이 함수도 같이 변경해줘야 한다.
        inline bool operator < (const cStringKey& rhs) const
        {
            const int* buf1 = reinterpret_cast<const int*>(this);
            const int* buf2 = reinterpret_cast<const int*>(&rhs);
    
            if (*buf1 != *buf2) return *buf1 < *buf2; // 0-3
    
            ++buf1; ++buf2;
            if (*buf1 != *buf2) return *buf1 < *buf2; // 4-7
    
            ++buf1; ++buf2;
            if (*buf1 != *buf2) return *buf1 < *buf2; // 8-11
    
            ++buf1; ++buf2;
            if (*buf1 != *buf2) return *buf1 < *buf2; // 12-15
    
            ++buf1; ++buf2;
            if (*buf1 != *buf2) return *buf1 < *buf2; // 16-19
    
            ++buf1; ++buf2;
            if (*buf1 != *buf2) return *buf1 < *buf2; // 20-23
    
            ++buf1; ++buf2;
            if (*buf1 != *buf2) return *buf1 < *buf2; // 24-27
    
            ++buf1; ++buf2;
            return *buf1 < *buf2; // 28-31
        }
    };

    대소문자 구별없이 비교를 할 수 없다는 점이 좀 아쉽다. 어셈블리도 좀 안다면 비교 연산자를 좀 더 깔끔하게 만들 수 있을 텐데. 어쨌든 테스트해보니, 릴리즈 빌드에서 약 25~33% 정도의 성능이 향상되었다. 
    typedef std::map<std::string, std::string> OLD_MAP;
    typedef std::map<cStringKey, std::string> NEW_MAP;
    
    OLD_MAP oldMap;
    NEW_MAP newMap;
    
    for (int i=0; i<1000; ++i)
    {
        std::string key = generic::to_string(rand() % 1000, 4);
        std::string value = generic::to_string(rand() % 1000, 4);
        oldMap.insert(OLD_MAP::value_type(key, value));
        newMap.insert(NEW_MAP::value_type(key, value));
    }
    
    DWORD begin = 0, oldTime = 0, newTime = 0;
    int repetition = 200000;
    
    begin = timeGetTime();
    for (int i=0; i<repetition; ++i)
    {
        oldMap.find(generic::to_string(rand() % 1000, 4));
    }
    oldTime = timeGetTime() - begin;
    
    begin = timeGetTime();
    for (int i=0; i<repetition; ++i)
    {
        newMap.find(generic::to_string(rand() % 1000, 4));
    }
    newTime = timeGetTime() - begin;
    
    std::cout << "OLD: " << oldTime << std::endl;
    std::cout << "NEW: " << newTime << std::endl;


반응형
Posted by blueasa
, |

define DEBUG_OUTPUT
//------------------------------------------------------------------------
// 2010/01/22 [19:56:32]
// jedikim72
// - 디버깅출력함수
//------------------------------------------------------------------------
#ifdef DEBUG_OUTPUT
 #define debugLog(...) { char acTemp[2048]; \
                                      char acTemp2[2048]; \
                                      NiSprintf(acTemp, 2048, __VA_ARGS__); \
                                      NiSprintf(acTemp2, 2048, "[L%d]:%s - %s", __LINE__, __FUNCTION__, acTemp ); \
                                      OutputDebugString( acTemp2 ); \
                                    }
#else
 #define debugLog(...) ((void)0)
#endif
//------------------------------------------------------------------------

 

빌딩모드와 상관없이 디버깅 메세지를 출력하는 메써드가 필요해서 부랴부랴 만든 매크로.

(기존 매크로는 사용하기 불편해서... - -a)

 

매크로 가변인자를 사용하여 가변인수를 받아 출력할 수 있다.

사용예) debugLog("%.2f, %.2f, %.2f\n", pos.x, pos.y, pos.z);

또한 VS IDE 출력창 뿐만 아니라, 실행파일만 독립적으로 실행해도 DebugView 유틸을 통해 디버깅 출력 메세지를 볼 수 있다는 장점이 있다.

 

 

이제까진 TraceWindow를 써서 출력했는데, 프로젝트에 매번 관련 모듈 삽입하는 것도 귀찮고 해서 아예 매크로로 빼버려 간단한 구문 삽입만으로 간편하게 작업을 완료할 수 있게 했다.

 

 

 

DebugView와 함께 구동시킨 작업중인 데모 스크린샷

그나저나,

DebugView 유틸은 첨부파일로~!



출처  : http://jedikim72.blog.me/10079110907

반응형
Posted by blueasa
, |

이펙트 작업을 위해서... 이런것들이 필요 합니다.^^

 

회사를 옮길때 마다 부탁을 해야 하는 겨우가 생기더군요.^^

그렇게 중요한 내용은 아니지만 작업 할때 가끔 필요하다라고 생각이 드는 경우가 있어서...

나중에 프로그래머님들게 부탁 좀 할려고 정리좀 해봅니다.^^

 

간혹 지원을 하지 않는 엔진이 있어서...^^ 

 

 

------------------ Tip ------------------

오른손 좌표계: OpenGL 사용.

 

왼손 좌표계: Direct 3D 사용.

 

[축:axis]

-월드 축: 항상 고정이 되어 있는 축. 변화지 않는 축 입니다.

             (지구의 남과 북이 변화지 않는것 처럼, X, Y, Z,절대 절대 변화지 않는 축)

 

-로컬 축: 움직임에 따라, 축이 바라 보는 방향이 변화는 축

             ( 오브젝트 생성시 가지고 있던 축. 움직임에 따라 항상  축은 유지하되, 바라 보는 방향은

                변한다.)

-----------------------------------------

 

[ 이펙트 작업에 필요한 기능 ]

 

1) 캐릭터에 이펙트 작업시 링크 기능 지원.

-아래 이미지 처럼 각각의 Biped와 Bone, Dummy, 특정네임(프로그래머가 설정해준 네임), 등등... 이펙트가 필요로 하는 모든 네임에 링크가 가능 해야 한다.

 

-빨강점은 이펙트와 링크가 되면 위치하는 지점.

 

-캐릭터의 이펙트 작업시.

 *Biped와 Bone, Dummy, center, 특정네임에 로컬 축, 월드 축을 지원.

 *Biped와 Bone, Dummy, center, 특정네임에 링크 방식과 비 링크 방식 지원.

  (비 링크 방식일때는 워치또는 회전 값만을 사용 할뿐 Biped와 Bone, Dummy, center

   특정네임에 움직임에 반응 하지 않는다.)

*버프 계열 이펙트 작업시 머리에 생성 되는 이펙트 지원.

 (머리에서의 일정 높이를 항상 유지 하며, 캐릭터의 이동시 같이 움직인다. 단 캐릭터의 회전

  값을 인식 해서는 안된다.)

 

 

2) 메쉬 오브젝트가 지원.

-맥스에서 작업한 메쉬 오브젝트의 move, rotate, scale, UVmap 애님, opasity 등을 지원 해야 한다.

 

-씨퀀스 및 16분할 맵 소스 지원.

 

-2-sided 지원.

 

 

 3) 다양한 쉐이더 모드 / 레이어 모드 지원.

-add, multiply, alpha인식, overlay, colorkey.. 등등 다양한 레이어 모드 지원.

(포토샾의 레이어 기능을 참고)

 

-맥스에서의 기본적인 meterrial 과 글로우 효과, 고스트 효과, 카멜레온 효과, 굴절 효과 같은 특수한 쉐이더 효과들이 지원 되야 한다.

(아래 이미지는 쉐이더 효과를 합성툴에서 만들어 본 이미지)

 

4) 기본 빌보드 지원

-기본 적으로 이펙트 툴에 파티클, 빌보드 방식이 포함 되어 있지만, 모든 엔진이 그런 것이 아님으로 필요시 프로그래머에게 요청을 해야 한다.

 

-빌보드는 (단독1~5정도)으로 사용 할때는 메쉬와 비슷 하지만, 여러개(10개 이상)를 사용 하며, 파티클과 비슷한 개념으로 생각 해야 한다.

(파티클 하나 하나를 보면 빌보드와 비슷 하다고 보면 된다. 간다하게 맥스에서 파티클에 맵을 한번 해보면 알수 있다.)

 

-기본 빌보드는 맥스 Plane[정 사각형 판]이라고 보시면 되고, 기본 빌보드는 항상 카메라만을 주시 하면서 정면만을 보여준다.

 

-기본 빌보드의 갯수 증가 기능 및 위치 랜덤 생성 기능.

(파티클의 기능에 누가 되지 않는 만큰의 갯수 약 5~8개 정도이며, 생성시에는

  위치가 랜덤하게 발생 해야 한다.)

 

-2-sided 지원.

 

-빌보드 종류.

 *기본적인 빌보드.(항상 카메라만 본다)

 *방향을 바꿀수 있는 빌보드.(원하는 방향을 설정 할수 있다.)

 *박스 형태의 빌보드.(위/아래는 면이 없다.)

 *원통형의 빌보드.(위/아래는 면이 없으며, 면을 수를 조절이 가능 해야 한다.)

 *한쪽 축이 고정된 빌보드이며, 카메라만 항상 바라 본다.

  ( 기본 빌보드에 1개의 축을 고정 해준다.)

 *기타... 엔진에서 지원되는 빌보드.

 

-빌보드 지원 기능

 *move, rotate, scale, opasity 기능 지원.

 *씨퀀스 및 16분할 맵 소스 지원.

 *loop 기능 지원

 *Biped와 Bone, Dummy, center, 특정네임에 로컬 축, 월드 축을 지원.

 *Biped와 Bone, Dummy, center, 특정네임에 링크 방식과 비 링크 방식 지원.

  (비 링크 방식일때는 워치또는 회전 값만을 사용 할뿐 Biped와 Bone, Dummy, center

   특정네임에 움직임에 반응 하지 않는다.)

 

5) 트레일 효과 지원.

 -검의 잔상 기능.

  (맥스에서고스트 트레일 효과와 비슷 기능.)

 

-잔상의 왜곡 효과.

 (굴절 현상)

 

5) 파티클 툴의 부수적인 기능 지원.

-기본적으로 particleIllusion정도의 툴.

 

- Biped와 Bone, Dummy, center, 특정네임에 로컬 축, 월드 축을 지원.

 

-Biped와 Bone, Dummy, center, 특정네임에 링크 방식과 비 링크 방식 지원.

  (비 링크 방식일때는 워치또는 회전 값만을 사용 할뿐 Biped와 Bone, Dummy, center

   특정네임에 움직임에 반응 하지 않는다.)

 

-파티클을 모으는 방식 지원.

 (보통은 퍼지는 기능은 되지만, 기를 모을때 사용할수 있는 기능은 지원 안 하는 경우가 많다.)

 

-링크된 파티클과 파티클 사이에 보간 기능 지원.

 (Bip01 R Thigh와 Bip01 R Calf 사이에 파티클 링크시, 링크된 위치에서만 파티클이 발생 하기

  때문에, 링크된 사이에는 파티클이 발생 할수 있게 해준다.)

 

-파티클의 트레일 발생 지원.

 (귀무자의 기를 빨라 드리는 효과를 참고 하면 된다.)

 

-파티클 타이밍 조절 지원.

(1프레임에 100개의 파티클을 전부 불출 또는 10프레임 있다가 100프레임을 전주 분출 등등..)

 

-파티클 발생 방식.

 *움직임에 영향을 받지 않는 방식.

   (별이 반짝이는 것처럼, 처음 생성 위치에서 발생 하면 아무런 영향을 받지 않으며, 파티클의

    꼬리가 생기지 않는다.)

 *움직임에 영향을 받는 방식

   (대표적으로 파티클의 꼬리가 발생 한다.)

 

6) 데칼 기능 지원.

-마법진과 또는 바닥 이펙트 처리에 사용 되는 방식.

(바닥의 왜곡면과 상관 없이, 발생 하는 기능. 간혹 왜곡이 아주 심한 경우에는

 이펙트 모양이 늘러지게 보이는 경우가 있다.)

 

==========================================================================================

아래의내용들은 이펙트 작업시 필요 하다라고 느끼거나, 있어으면 하는 것들을 적어 본 것입니다.

 그렇다고, 꼭! 이 기능이 이었야 작업을 잘 할수 있는 것은 더더욱 아닙니다.

부족함에 약간의 도움을 주기 위해서 라는것을 알아 주시길....^^

==========================================================================================

반응형

'Gamebryo > Effect' 카테고리의 다른 글

강의자료 - 파티클 예제  (0) 2011.03.22
Setup about Effect Dumy…  (0) 2011.03.21
파티클 컨트롤 해보기  (0) 2011.02.24
이펙트 출력  (0) 2011.02.08
검광, 검기 잔상 효과에 대하여...  (1) 2011.01.21
Posted by blueasa
, |

Delta3D API Documentation

Link / 2011. 1. 25. 01:49
반응형
Posted by blueasa
, |
반응형

'Utility > Doxygen' 카테고리의 다른 글

[삽질] KingsTools 함수등 정보가 안보일 때..  (0) 2012.06.12
자주쓰는 DoxyGen 주석  (0) 2011.06.17
Posted by blueasa
, |