[DirectX11] 028 Mesh Sphere, Mesh Cylinder + 구면 좌표계, 원통 좌표계
Mesh Sphere, Mesh Cylinder
구면 좌표계, 원통 좌표계
Mesh Sphere
구면 좌표계

https://blog.naver.com/qio910/221499166816
구면 좌표계(Spherical Coordinate System)
이전 공부 구면 좌표계(Spherical coordinate system)는 3차원 공간의 한 점을 (r, θ, φ)로 나타냅니다....
blog.naver.com
https://www.youtube.com/watch?v=5vUSrA9mqJk
https://www.youtube.com/watch?v=ae6kcOBEZK0
MeshSphere.cpp 내에 void MeshSphere::Create() 이 구면 좌표계 그리는 부분이다.
Vector3 p = Vector3
(
(radius * sinf(phi) * cosf(theta)),
(radius * cos(phi)),
(radius * sinf(phi) * sinf(theta))
);
Mesh Sphere
MeshSphere.h
더보기
#pragma once class MeshSphere : public Mesh { public: MeshSphere(Shader* shader, float radius, UINT stackCount = 20, UINT sliceCount = 20); ~MeshSphere(); private: void Create() override; float radius; //구를 그릴 반지름 UINT stackCount; //몇개로 분할해서 그리는가. 높을수록 정밀 UINT sliceCount; //몇개로 분할해서 그리는가. 높을수록 정밀 };
MeshSphere.cpp
더보기
#include "Framework.h" #include "MeshSphere.h" MeshSphere::MeshSphere(Shader * shader, float radius, UINT stackCount, UINT sliceCount) : Mesh(shader), radius(radius), stackCount(stackCount), sliceCount(sliceCount) { } MeshSphere::~MeshSphere() { } void MeshSphere::Create() { //구면 좌표계 vector<MeshVertex> v; v.push_back(MeshVertex(0, radius, 0, 0, 0, 0, 1, 0));//맨 위점 float phiStep = Math::PI / stackCount; // 180도/분할카운트 float thetaStep = Math::PI * 2.0f / sliceCount; // 360도/분할카운트 for (UINT i = 1; i <= stackCount - 1; i++) //맨 위점과 맨 밑점을 제외한 나머지 { float phi = i * phiStep; for (UINT k = 0; k <= sliceCount; k++) { float theta = k * thetaStep; Vector3 p = Vector3 ( (radius * sinf(phi) * cosf(theta)), (radius * cos(phi)), (radius * sinf(phi) * sinf(theta)) ); Vector3 n; D3DXVec3Normalize(&n, &p); //위치를 Normalize해서 크기를 1로 만들어 방향 벡터로 사용. Vector2 uv = Vector2(theta / (Math::PI * 2), phi / Math::PI); v.push_back(MeshVertex(p.x, p.y, p.z, uv.x, uv.y, n.x, n.y, n.z)); } } v.push_back(MeshVertex(0, -radius, 0, 0, 0, 0, -1, 0));//맨 밑점 vertices = new MeshVertex[v.size()]; vertexCount = v.size(); copy(v.begin(), v.end(), stdext::checked_array_iterator<MeshVertex *>(vertices, vertexCount)); vector<UINT> i; for (UINT k = 1; k <= sliceCount; k++) { i.push_back(0); i.push_back(k + 1); i.push_back(k); } UINT baseIndex = 1; UINT ringVertexCount = sliceCount + 1; for (UINT k = 0; k < stackCount - 2; k++) { for (UINT j = 0; j < sliceCount; j++) { i.push_back(baseIndex + k * ringVertexCount + j); i.push_back(baseIndex + k * ringVertexCount + j + 1); i.push_back(baseIndex + (k + 1) * ringVertexCount + j); i.push_back(baseIndex + (k + 1) * ringVertexCount + j); i.push_back(baseIndex + k * ringVertexCount + j + 1); i.push_back(baseIndex + (k + 1) * ringVertexCount + j + 1); } } UINT southPoleIndex = v.size() - 1; baseIndex = southPoleIndex - ringVertexCount; for (UINT k = 0; k < sliceCount; k++) { i.push_back(southPoleIndex); i.push_back(baseIndex + k); i.push_back(baseIndex + k + 1); } indices = new UINT[i.size()]; indexCount = i.size(); copy(i.begin(), i.end(), stdext::checked_array_iterator<UINT *>(indices, indexCount)); int a = 0; }
원통 좌표계
https://blog.naver.com/qio910/221498312675
원통 좌표계(Cylindrical Coordinate System)
이전 공부 다음 공부 원통 좌표계(cylindrical coordinate system)는 3차원 공간의 한 점을 (r, θ, z)로 ...
blog.naver.com
https://www.youtube.com/watch?v=Y69CuegZIro
Mesh Cylinder
MeshCylinder.h
더보기
#pragma once class MeshCylinder : public Mesh { public: MeshCylinder(Shader* shader, float radius, float height, UINT stackCount, UINT sliceCount); //위,아래 반지름이 같은 경우 그리기 MeshCylinder(Shader* shader, float topRadius, float bottomRadius, float height, UINT stackCount, UINT sliceCount); //위,아래 반지름이 다른 경우 그리기 ~MeshCylinder(); private: void Create() override; private: void BuildTopCap(vector<MeshVertex>& vertices, vector<UINT>& indices); void BuildBottomCap(vector<MeshVertex>& vertices, vector<UINT>& indices); private: float topRadius; //원통 상단 반지름 float bottomRadius;//원통 하단 반지름 float height; UINT stackCount; //몇개로 분할해서 그리는가. 높을수록 정밀 UINT sliceCount; //몇개로 분할해서 그리는가. 높을수록 정밀 };
MeshCylinder.cpp
더보기
#include "Framework.h" #include "MeshCylinder.h" MeshCylinder::MeshCylinder(Shader * shader, float radius, float height, UINT stackCount, UINT sliceCount) : Mesh(shader), topRadius(radius), bottomRadius(radius), height(height), stackCount(stackCount), sliceCount(sliceCount) { } MeshCylinder::MeshCylinder(Shader * shader, float topRadius, float bottomRadius, float height, UINT stackCount, UINT sliceCount) : Mesh(shader), topRadius(topRadius), bottomRadius(bottomRadius), height(height), stackCount(stackCount), sliceCount(sliceCount) { } MeshCylinder::~MeshCylinder() { } void MeshCylinder::Create() { vector<MeshVertex> v; float stackHeight = height / (float)stackCount; float radiusStep = (topRadius - bottomRadius) / (float)stackCount; UINT ringCount = stackCount + 1; for (UINT i = 0; i < ringCount; i++) { float y = -0.5f * height + i * stackHeight; float r = bottomRadius + i * radiusStep; float theta = 2.0f * Math::PI / (float)sliceCount; for (UINT k = 0; k <= sliceCount; k++) { float c = cosf(k * theta); float s = sinf(k * theta); MeshVertex vertex; vertex.Position = Vector3(r * c, y, r * s); vertex.Uv = Vector2((float)k / (float)sliceCount, 1.0f - (float)i / (float)stackCount); Vector3 tangent = Vector3(-s, 0.0f, c); float dr = bottomRadius - topRadius; Vector3 biTangent = Vector3(dr * c, -height, dr * s); D3DXVec3Cross(&vertex.Normal, &tangent, &biTangent); D3DXVec3Normalize(&vertex.Normal, &vertex.Normal); v.push_back(vertex); } } vector<UINT> i; UINT ringVertexCount = sliceCount + 1; for (UINT y = 0; y < stackCount; y++) { for (UINT x = 0; x < sliceCount; x++) { i.push_back(y * ringVertexCount + x); i.push_back((y + 1) * ringVertexCount + x); i.push_back((y + 1) * ringVertexCount + (x + 1)); i.push_back(y * ringVertexCount + x); i.push_back((y + 1) * ringVertexCount + x + 1); i.push_back(y * ringVertexCount + x + 1); } } BuildTopCap(v, i); BuildBottomCap(v, i); vertices = new MeshVertex[v.size()]; vertexCount = v.size(); copy(v.begin(), v.end(), stdext::checked_array_iterator<MeshVertex *>(vertices, vertexCount)); indices = new UINT[i.size()]; indexCount = i.size(); copy(i.begin(), i.end(), stdext::checked_array_iterator<UINT *>(indices, indexCount)); } void MeshCylinder::BuildTopCap(vector<MeshVertex>& vertices, vector<UINT>& indices) { //원통 상단 float y = 0.5f * height; float theta = 2.0f * Math::PI / (float)sliceCount; for (UINT i = 0; i <= sliceCount; i++) { float x = topRadius * cosf(i * theta); float z = topRadius * sinf(i * theta); float u = x / height + 0.5f; float v = z / height + 0.5f; vertices.push_back(MeshVertex(x, y, z, u, v, 0, 1, 0)); } vertices.push_back(MeshVertex(0, y, 0, 0.5f, 0.5f, 0, 1, 0)); UINT baseIndex = vertices.size() - sliceCount - 2; UINT centerIndex = vertices.size() - 1; for (UINT i = 0; i < sliceCount; i++) { indices.push_back(centerIndex); indices.push_back(baseIndex + i + 1); indices.push_back(baseIndex + i); } } void MeshCylinder::BuildBottomCap(vector<MeshVertex>& vertices, vector<UINT>& indices) { //원통 하단 float y = -0.5f * height; float theta = 2.0f * Math::PI / (float)sliceCount; for (UINT i = 0; i <= sliceCount; i++) { float x = bottomRadius * cosf(i * theta); float z = bottomRadius * sinf(i * theta); float u = x / height + 0.5f; float v = z / height + 0.5f; vertices.push_back(MeshVertex(x, y, z, u, v, 0, -1, 0)); } vertices.push_back(MeshVertex(0, y, 0, 0.5f, 0.5f, 0, -1, 0)); UINT baseIndex = vertices.size() - sliceCount - 2; UINT centerIndex = vertices.size() - 1; for (UINT i = 0; i < sliceCount; i++) { indices.push_back(centerIndex); indices.push_back(baseIndex + i); indices.push_back(baseIndex + i + 1); } }
Mesh Demo
MeshDemo.h
더보기
#pragma once #include "Systems/IExecute.h" class MeshDemo : public IExecute { public: virtual void Initialize() override; virtual void Ready() override {} virtual void Destroy() override; virtual void Update() override; virtual void PreRender() override {} virtual void Render() override; virtual void PostRender() override {} virtual void ResizeScreen() override {} private: void CreateMesh(); private: Shader* shader; Vector3 direction = Vector3(-1, -1, 1); ID3DX11EffectVectorVariable* sDirection; MeshCube* cube; MeshCylinder* cylinder[10]; MeshSphere* sphere[10]; MeshGrid* grid; };
MeshDemo.cpp
더보기
#include "stdafx.h" #include "MeshDemo.h" void MeshDemo::Initialize() { Context::Get()->GetCamera()->RotationDegree(20, 0, 0); Context::Get()->GetCamera()->Position(1, 36, -85); shader = new Shader(L"25_Mesh.fx"); sDirection = shader->AsVector("Direction"); CreateMesh(); } void MeshDemo::Destroy() { SafeDelete(shader); SafeDelete(cube); SafeDelete(grid); for (int i = 0; i < 10; i++) { SafeDelete(cylinder[i]); SafeDelete(sphere[i]); } } void MeshDemo::Update() { cube->Update(); grid->Update(); for (int i = 0; i < 10; i++) { cylinder[i]->Update(); sphere[i]->Update(); } } void MeshDemo::Render() { ImGui::SliderFloat3("Direction", direction, -1, +1); sDirection->SetFloatVector(direction); static int pass = 0; ImGui::InputInt("Pass", &pass); pass %= 2; cube->Render(); grid->Render(); for (int i = 0; i < 10; i++) { cylinder[i]->Pass(pass); cylinder[i]->Render(); sphere[i]->Pass(pass); sphere[i]->Render(); } } void MeshDemo::CreateMesh() { cube = new MeshCube(shader); cube->Position(0, 5, 0); cube->Scale(20, 10, 20); cube->DiffuseMap(L"Stones.png"); grid = new MeshGrid(shader, 6, 6); grid->Scale(12, 1, 12); grid->DiffuseMap(L"Floor.png"); //원통 10개, 구 10개 그리기 for (UINT i = 0; i < 5; i++) { cylinder[i * 2] = new MeshCylinder(shader, 0.5f, 3.0f, 20, 20); cylinder[i * 2]->Position(-30, 6, (float)i * 15.0f - 15.0f); cylinder[i * 2]->Scale(5, 5, 5); cylinder[i * 2]->DiffuseMap(L"Bricks.png"); cylinder[i * 2 + 1] = new MeshCylinder(shader, 0.5f, 3.0f, 20, 20); cylinder[i * 2 + 1]->Position(30, 6, (float)i * 15.0f - 15.0f); cylinder[i * 2 + 1]->Scale(5, 5, 5); cylinder[i * 2 + 1]->DiffuseMap(L"Bricks.png"); sphere[i * 2] = new MeshSphere(shader, 0.5f, 20, 20); sphere[i * 2]->Position(-30, 15.5f, (float)i * 15.0f - 15.0f); sphere[i * 2]->Scale(5, 5, 5); sphere[i * 2]->DiffuseMap(L"Wall.png"); sphere[i * 2 + 1] = new MeshSphere(shader, 0.5f, 20, 20); sphere[i * 2 + 1]->Position(30, 15.5f, (float)i * 15.0f - 15.0f); sphere[i * 2 + 1]->Scale(5, 5, 5); sphere[i * 2 + 1]->DiffuseMap(L"Wall.png"); } }
실행화면

'⭐ DirectX > DirectX11 3D' 카테고리의 다른 글
[DirectX11] 031 Framework (0) | 2023.01.30 |
---|---|
[DirectX11] 029~30 Cube Map, Sphere Map (0) | 2023.01.27 |
[DirectX11] 027 Mesh Cube (0) | 2023.01.25 |
[DirectX11] 025~26 Mesh (0) | 2023.01.21 |
[DirectX11] 024 Vertical Raycast (0) | 2023.01.20 |
댓글
이 글 공유하기
다른 글
-
[DirectX11] 031 Framework
[DirectX11] 031 Framework
2023.01.30 -
[DirectX11] 029~30 Cube Map, Sphere Map
[DirectX11] 029~30 Cube Map, Sphere Map
2023.01.27 -
[DirectX11] 027 Mesh Cube
[DirectX11] 027 Mesh Cube
2023.01.25 -
[DirectX11] 025~26 Mesh
[DirectX11] 025~26 Mesh
2023.01.21
댓글을 사용할 수 없습니다.