평면방정식

programming/etc 2024. 7. 26. 10:21 |

 

*평면방정식

-평면의 법선벡터와 원점간의 거리d를 알고있을때 점P가 평면에 대해 어느 위치에 있는지 판별 할 수 있다.

-법선벡터 N(a,b,c), 점P(x,y,z), 거리d

- ax + by + cz + d = 0

 

- 점P의 위치 판별

ax + by + cz + d = 0 일때 점P는 평면 위에 존재한다.

ax + by + cz + d > 0 일때 점P는 평면 앞에 존재한다.

ax + by + cz + d < 0 일때 점P는 평면 뒤에 존재한다.

( 법선벡터가 향하는 방향을 앞이라 둔다. )

 

-

사각형을 이루는 A,B,C,D 네 점이 있다.

 

A----B

l l

l l

C----D

 

이때

벡터 v1 = B - A

벡터 v2 = C - A

 

이 두 벡터를 외적연산하여 법선벡터 N을 구할 수 있다.

N.x = v1.y * v2.z - v1.z * v2.y

N.y = v1.z * v2.x - v1.x * v2.z

N.z = v1.x * v2.y - v1.y * v2.x

 

여기서 구한 N에 벡터를 구했던 A, B, C 세 점중 아무 한 점을 내적하면 d값을 구할 수 있다.

( 내적 값이 -d가 되므로 내적 * -1 = d )

 

* D3DXPlaneFromPoints()

- 세점을 인자로 평면 D3DXPLANE을 반환한다.

 

* D3DXPlaneDotCoord()

- D3DXPLANE과 D3DXVECTOR3를 인자로 받아 평면방정식을 연산한다.

- ax + by + cz + d의 값을 반환한다.

 

 

 

'programming > etc' 카테고리의 다른 글

카메라  (0) 2024.07.26
렌더링 파이프 라인  (0) 2024.07.26
외적  (0) 2024.07.26
내적  (0) 2024.07.26
사업자등록 통신판매업  (0) 2024.07.26
Posted by mainep
:

외적

programming/etc 2024. 7. 26. 10:20 |

 

*외적 : 두 벡터에 대해 각각 직각을 이루는 벡터

 

벡터 : A, B, C

 

A * B

Cx = Ay * Bz - Az * By

Cy = Az * Bx - Ax * Bz

Cz = Ax * By - Ay * Bx

 

외적연산을 통해 구한 C벡터는

A, B와 직교한다.

 

*d3dx함수

 

D3DXVec3Cross()

 

'programming > etc' 카테고리의 다른 글

카메라  (0) 2024.07.26
렌더링 파이프 라인  (0) 2024.07.26
평면방정식  (0) 2024.07.26
내적  (0) 2024.07.26
사업자등록 통신판매업  (0) 2024.07.26
Posted by mainep
:

내적

programming/etc 2024. 7. 26. 10:20 |

 

*내적 : 두 벡터의 같은 축의 원소끼리 곱하여 모두 더한 값

 

벡터 : A, B

내적 : dot

 

dot = Ax * Bx + Ay * By + Az * Bz

 

1.

내적(A, B) = llAll * llBll * cos@ 이다.

 

단위벡터인 A, B가 있을때

 

dot = cos@가 된다.

 

양번에 acos을 곱해주면 각도(호도법)만 남게 된다.

 

acos( dot ) = acos( cos@ )

acos( dot ) = @

 

2.

내적은 두 벡터의 크기의 곱을 속성으로 가지며 두 벡터 사이의 각을 판별할 수 있다.

dot = 0 일때 A,B는 직교한다.

dot > 0 일때 A,B 사이의 각은 예각이다.

dot < 0 일때 A,B 사이의 각은 둔각이다.

 

*d3dx함수

D3DXVec3Dot()

 

'programming > etc' 카테고리의 다른 글

카메라  (0) 2024.07.26
렌더링 파이프 라인  (0) 2024.07.26
평면방정식  (0) 2024.07.26
외적  (0) 2024.07.26
사업자등록 통신판매업  (0) 2024.07.26
Posted by mainep
:

애니메이션을 띄우고 그간 많은 시간이 지난거 같다. 

추가사항이나 변경사항의 갯수로 따지면 얼마 되지 않지만

프레임을 높히기 위해 intersect함수를 전부 갈아업었고

로딩된 하나의 스킨드 메쉬를 이용해 필요한 오브젝트의 정보만 따로 담아

하나의 스킨드메쉬로 여러개의 오브젝트를 출력할수 있게 만들었고

지형의 높이에따라 오브젝트의 높이를 업데이트 하게 만들었다.

그리고 지정된 방식에 따라 해당 애니메이션이 나오도록 만들었다 .

 

몇가지 안되지만 헤메고 돌아오느라 시간이 늦어진듯하다. 

'programming > direct3d' 카테고리의 다른 글

높이맵 ( Heightmap )  (0) 2024.07.26
picking  (0) 2024.07.26
dirextx xFile 띄우기  (0) 2024.07.26
directx 지형 알파 멀티텍스쳐의 복수 사용  (0) 2024.07.26
directx 지형 알파 텍스쳐 입히기  (0) 2024.07.26
Posted by mainep
:

xFile을 로드하여 뷰포트상에 뿌려주려면

orig메쉬와 변환된 행렬을 곱해주어야한다.

하지만 이러한 작업을 소프트웨어적으로 하게되면 성능적 문제가 있기에

하드웨어적으로 처리할수 있도록 버텍스 쉐이더를 사용해야한다.

 

xFile로드는 이전에 한번 실패한 경험이 있어

건드리기 두려웠지만 이전보다는 생각하는 힘이 발전했나보다.

많은 시간을 투자하긴 하였지만

스킨을 가지는 케릭터 부분과

스킨이 없는 아이템부분까지 띄우는걸 완성하였다.

다음에는 에니메이션을 컨트롤 해볼까한다.

Posted by mainep
:

 

스쳐는 정말 쉽지 않은 부분인것 같다 ㅜㅜ 뙇

 

리스트박스와 텍스쳐미리보기

그리고 제일 중요한 여러장의 멀티텍스쳐의 사용

그중 하나 쉽게 풀린게 없는듯하다.

 

정말 스스로 프로그래밍을 즐기지 못하면

못할짓이라는걸 작업하는 내내 다시한번 깨닿게 되었다.

정말 다행인것같다.

 

프로그래머가 아니라

그래픽 모델러를 목표로

향해가는듯한 이 기분은 뭘까 ㅋㅋ

 

'programming > direct3d' 카테고리의 다른 글

directx terrain 약 2주간 업데이트 사항  (0) 2024.07.26
dirextx xFile 띄우기  (0) 2024.07.26
directx 지형 알파 텍스쳐 입히기  (0) 2024.07.26
directx 지형 수정사항  (0) 2024.07.26
directx 지형 추가사항  (0) 2024.07.26
Posted by mainep
:

 

생각보다 시간이 오래걸렸다.

대충 알파값 넣으면 쉽게 될줄알았는데

여러장의 텍스쳐가 합쳐지는 SetTextureStageState에 있는 연산자를 이해해야한다.

 

프로젝트가 점점 산으로서의 구색을 갖추어

두덕리 온라인으로 진화중인것 같다.

 

다음 목표는 다수의 알파 텍스쳐를 사용하고

그것을 저장하고 로딩하는것이다 .

 

'programming > direct3d' 카테고리의 다른 글

dirextx xFile 띄우기  (0) 2024.07.26
directx 지형 알파 멀티텍스쳐의 복수 사용  (0) 2024.07.26
directx 지형 수정사항  (0) 2024.07.26
directx 지형 추가사항  (0) 2024.07.26
다이렉트x 3d 지형 - 맵툴  (0) 2024.07.26
Posted by mainep
:

 

for( DWORD i = 0; i < m_rCheckIBZ ; i++ )
{
if( intersect ) break;
for( DWORD k = 0; k < m_rCheckIBX ; k++)
{
if( intersect ) break;
long tempVB = rSNum + (((m_rIndexSizeZ) ) * i) + ( k * 3 ) - m_fixedRPoint;
static DWORD ibNum = 0;
if( tempVB < 0 ) { continue ; }
else if( tempVB >= ((long)m_rIndexTotalSize)-3 ) { break ; }
else { ibNum = tempVB ;}
if( IntersectTriangle( m_pickOrig, m_pickDir,
m_pReferVB[m_pReferIB[ibNum]], m_pReferVB[m_pReferIB[ibNum+1]], m_pReferVB[m_pReferIB[ibNum+2]],
&scale[0], &scale[1], &scale[2] ) )
{
m_pickPos = m_pickOrig + ( m_pickDir * scale[0] );
D3DXVECTOR2 transV(0.0f, 0.0f);
DWORD transX = 0, transZ = 0 ;
transV.x = m_pickPos.x / 8.0f * m_intervalRate + m_checkX ;
transV.y = m_pickPos.z / 8.0f * m_intervalRate - m_checkZ ;
transX = (DWORD)( ( transV.x < 0 ) ? transV.x * -1.0f : transV.x );
transZ = (DWORD)( ( transV.y < 0 ) ? transV.y * -1.0f : transV.y );
sNum = transX + transZ * m_vbSizeX ;


m_pLineVB->Lock( 0, 0, (void**)&pVertices, 0 ) ;
pVertices[0].v = m_pickPos ;
pVertices[1].v = D3DXVECTOR3( m_pickPos.x, m_maxminY, m_pickPos.z ) ;
m_pLineVB->Unlock() ;
rSNum = ( ibNum%2 == 0 ) ? ibNum : ibNum - 3 ;
intersect = TRUE ;
break;
}
}
}

 

 

최적화를위해 일반 메모리의 픽킹에서

실제 좌표를 이용해 해당 VB의 번호를 직접 구해냄

 

일반메모리의 참조 범위를

횡렬 리딩에서 범위 리딩으로 수정함

 

Posted by mainep
:

 

업데이트된 맵툴은 각각의 역활을 클래스화를 하여 세분화 하였다.

 

기반인 D3DMain문을 시작으로

유틸리티로 카메라와 다이얼로그를 갖고 프로그램의 목적인 Terrain이 있다.

그곳에 드로잉을 위한 오브젝트 클래스들이 있다.

 

이번 업데이트의 핵심은

다이얼로그의 클래스화와 카메라의 추가이다.

우선 유연한 카메라를 심어줌으로인해 여러 시각에서 바라볼수있다.

 

지형을 만드는 툴이라는 프로그램을 설계중이니

다이얼로그의 클래스화로 내입맛에 맞는 방식대로 툴을 만들수있게되었다.

 

그리고 지형을 만드는 동안과 만드는 후의 사용을 위해

데이터의 저장되 로드를 추가하였다.

 

다음 추가목표는 이미지를 선택하여 지형에 텍스쳐를 입히는것이다 .

 

Posted by mainep
:

 

기본적인 vertex up & down, 다이얼로그를 사용한 증감률과 반지름 조절이 가능하다.

 

void CTERRAIN::Intersect( BOOL RBT, BOOL LBT, HWND gm_hWnd, BOOL mouseMove )
{
LPCUSTOMVERTEX pVertices, pCirVertices; //VB에 사용할 구조체 포인터
WORD *pIndices; //IB에 사용될 WORD 포인터
D3DXVECTOR3 centerPos; //삼각형을 이루는 각 한쌍의 인덱스중 좌측 상단의 vetex
BOOL intersect = FALSE; //픽킹의 성공여부
float scale[3] = {0.0f,}; //IntersectTriangle에 인자로 넘겨줄 scale배열
D3DXVECTOR3 orig, dir( 0.0f, -1.0f, 0.0f ); //원의 픽킹에 사용될 변수
static WORD realIBTotalSize = 8 * 8 * 6; //index의 총 길이
static BOOL first = TRUE; //첫 로딩의 판단
static DWORD sNum = 0; //VB의 번호
static DWORD referSNum = 0, referENum = 0; //참조메모리의 시작인덱스와 끝인덱스
static float lenthMinSize = (m_radiusSize * m_intervalRate -0.5f * m_intervalRate)*(m_radiusSize * m_intervalRate -0.5f * m_intervalRate); //원의 최소값의 제곱
static float lenthMaxSize = (m_radiusSize * m_intervalRate +0.5f * m_intervalRate)*(m_radiusSize * m_intervalRate +0.5f * m_intervalRate); //원의 최대값의 제곱
//원 리사이즈시 변수 초기화
if( m_reSize )
{
first = TRUE;
sNum = 0;
referSNum = 0, referENum = 0;
lenthMinSize = (m_radiusSize * m_intervalRate -0.5f * m_intervalRate)*(m_radiusSize * m_intervalRate -0.5f * m_intervalRate);
lenthMaxSize = (m_radiusSize * m_intervalRate +0.5f * m_intervalRate)*(m_radiusSize * m_intervalRate +0.5f * m_intervalRate);
m_reSize = FALSE;
}
//첫 로딩
if( first )
{
//가상 메모리로 픽킹된 삼각형의 좌측 상단 vertex를 구한다.
for( DWORD i = 0; i < m_rIndexTotalSize; i+=3 )
{
if( IntersectTriangle( m_pickOrig, m_pickDir,
m_pReferVB[m_pReferIB[i]], m_pReferVB[m_pReferIB[i+1]], m_pReferVB[m_pReferIB[i+2]],
&scale[0], &scale[1], &scale[2] ) )
{
m_pickPos = m_pickOrig + ( m_pickDir * scale[0] );
centerPos = m_pReferVB[m_pReferIB[(i%2 == 0) ? i+1 : i]] + D3DXVECTOR3( 1.0f, 0.0f, -1.0f);
referSNum = ((i - m_rIndexRoadSize[0])) > m_rIndexTotalSize ? 0 : (i - m_rIndexRoadSize[0]);
referENum = (referSNum + m_rIndexRoadSize[1]) > m_rIndexTotalSize ? m_rIndexTotalSize : (referSNum + m_rIndexRoadSize[1]);
first = FALSE;
}
}
//위에서 구한 centerPos로 VB의 시작 번호를 구한다.
for( short i = m_virtualVBSize / 2; i < m_vbSizeZ-m_virtualVBSize/2; i++ )
{
for( short k = m_virtualVBSize / 2; k < m_vbSizeX-m_virtualVBSize/2; k++ )
{
WORD vbNum = i * m_vbSizeX + k;
DWORD cnt = 0;
m_ppTerVB[vbNum]->Lock( 0, 0, (void**)&pVertices, 0 );
for( WORD a = 0; a < 9; a++ )
{
for( WORD b = 0; b < 9; b++)
{
D3DXVECTOR3 tempV = pVertices[cnt++].v;
tempV.y = 0.0f;
if( tempV == centerPos )
{
sNum = i * m_vbSizeX + k;
}
}
}
m_ppTerVB[vbNum]->Unlock();
}
}
}
//이후의 로딩
else if( !first )
{
for( DWORD i = referSNum; i < referENum; i+=3 )
{
if( IntersectTriangle( m_pickOrig, m_pickDir,
m_pReferVB[m_pReferIB[i]], m_pReferVB[m_pReferIB[i+1]], m_pReferVB[m_pReferIB[i+2]],
&scale[0], &scale[1], &scale[2] ) )
{
m_pickPos = m_pickOrig + ( m_pickDir * scale[0] );
centerPos = m_pReferVB[m_pReferIB[(i%2 == 0) ? i+1 : i]] + D3DXVECTOR3( 1.0f, 0.0f, -1.0f);
referSNum = ((i - m_rIndexRoadSize[0])) > m_rIndexTotalSize ? 0 : (i - m_rIndexRoadSize[0]);
referENum = (referSNum + m_rIndexRoadSize[1]) > m_rIndexTotalSize ? m_rIndexTotalSize : (referSNum + m_rIndexRoadSize[1]);
break;
}
}
DWORD cnt = 0;
m_pCirVB->Lock(0, 0, (void**)&pCirVertices, 0 );
m_pTerIB->Lock(0, 0, (void**)&pIndices, 0 );
for( short i =0; i < m_virtualVBSize; i++ )
{
for( short k = 0; k < m_virtualVBSize; k++)
{
DWORD vbNum = sNum + ((m_vbSizeX) * i) + k - m_fixedVBPoint;
m_ppTerVB[vbNum]->Lock( 0, 0, (void**)&pVertices, 0 );
if( !intersect )
{
DWORD cnt = 0;
for( WORD a = 0; a < 9; a++ )
{
for( WORD b = 0; b < 9; b++)
{
D3DXVECTOR3 tempV = pVertices[cnt++].v;
tempV.y = 0.0f;
if( tempV == centerPos )
{
sNum = vbNum;
intersect = TRUE;
}
}
}
}
if( mouseMove )
{


//가상의 원의 위치와 VB의 삼각형이 픽킹을 하지는지 구해낸후
//실제 원의 y값을 증감 시킨다.
for( WORD m = 0; m < realIBTotalSize; m+=3 )
{
D3DXVECTOR3 tempV = pVertices[pIndices[m]].v;
tempV.y = 0.0f;
float checkLen = D3DXVec3LengthSq(&(tempV - m_pickPos));
if(checkLen < lenthMaxSize && checkLen > lenthMinSize)
{
for(short b = 0; b < m_cirTic; b++)
{
pCirVertices[b].v.x = m_pReferCir[b].x + m_pickPos.x;
pCirVertices[b].v.z = m_pReferCir[b].z + m_pickPos.z;
orig = pCirVertices[b].v;
orig.y = 1000.0f;
if(IntersectTriangle( orig, dir,
pVertices[pIndices[m]].v, pVertices[pIndices[m+1]].v, pVertices[pIndices[m+2]].v,
&scale[0], &scale[1], &scale[2]))
{
cnt++;
pCirVertices[b].v.y = (orig + dir * scale[0]).y+0.1f;
}
}
}
}
}
m_ppTerVB[vbNum]->Unlock();
}
}
m_pTerIB->Unlock();
m_pCirVB->Unlock();
}
if(intersect && LBT)
{
float checkRadius = ( m_radiusSize * m_intervalRate - 1.5f ) * (m_radiusSize * m_intervalRate - 1.5f); //원의 반지름보다 조금 작은값의 제곱
float checkSELine = m_realVBSize * 8.0f * m_intervalRate / 2.0f; //실제 VB의 총 길이
//픽킹된 VB의 vertex의 y값을 증감시킨다.
for( WORD i = 0; i < m_virtualVBSize; i++ )
{
for( WORD k = 0; k < m_virtualVBSize; k++)
{
DWORD vbNum = sNum + ((m_vbSizeX) * i) + k - m_fixedVBPoint;
m_ppTerVB[vbNum]->Lock(0, 0, (void**)&pVertices, 0);
for( WORD a = 0; a < 9; a++)
{
for( WORD b = 0; b < 9; b++)
{
WORD count = 9*a+b;
D3DXVECTOR3 checkV = pVertices[count].v;
checkV.y = 0.0f;
float d = D3DXVec3LengthSq(&(checkV - m_pickPos));
float r = checkRadius;
if( d < r && checkV.x > -checkSELine && checkV.x < checkSELine && checkV.z > -checkSELine && checkV.z < checkSELine)
{
float increaseY = sinf(D3DXToRadian( 90.0f - (90.0f * d / r) ) )*(m_increaseRate);
pVertices[count].v.y += increaseY;
}
}
}
m_ppTerVB[vbNum]->Unlock();
}
}
}
//vertex 초기화
if( RBT )
{
DWORD cnt = 0;
for( WORD i = 0; i < m_vbSizeZ; i++)
{
for( WORD k = 0; k < m_vbSizeX; k++)
{
m_ppTerVB[cnt]->Lock(0, 0, (void**)&pVertices, 0);
DWORD cnt2 = 0;
for( WORD a = 0; a < 9; a++ )
{
for(WORD b = 0; b < 9; b++)
{
pVertices[cnt2++].v.y = 0.0f;
}
}
m_ppTerVB[cnt++]->Unlock();
}
}
m_pCirVB->Lock( 0, 0, (void**)&pCirVertices, 0 );
for( WORD i = 0; i < m_cirTic; i++)
{
pCirVertices[i].v.y = 0.0f;
}
m_pCirVB->Unlock();
}
}

 

 

일반 메모리를 사용하여 픽킹된곳의 실제 좌표값을 얻어내어

VB의 배열을 탐색한 후 해당 VB의 실제 번호를 알아내고

픽킹된 좌표와 탐색한 vertex의 차백터한 백터의 크기가 반지름의 제곱에 크기보다 작은

vertex들의 y값을 증가시킨다.

 

차후에 카메라 클래스를 구현하여 맵툴에 적용시킨후

다른 세부사항을 추가할 계획이다.

 

'programming > direct3d' 카테고리의 다른 글

directx 지형 알파 멀티텍스쳐의 복수 사용  (0) 2024.07.26
directx 지형 알파 텍스쳐 입히기  (0) 2024.07.26
directx 지형 수정사항  (0) 2024.07.26
directx 지형 추가사항  (0) 2024.07.26
IntersectTriangle 픽킹  (0) 2024.07.26
Posted by mainep
: