응애맘마조

230718 강의 본문

공부/3D강의

230718 강의

TH.Wert 2023. 7. 18. 18:24

매달 셋째 주 월요일은 학원이 쉬는 날이라 강의가 없었습니다. 오늘은 맵 위에 다른 맵 이미지가 보이도록 하는 강의를 했었고 동시에 과제였습니다.

#pragma once

struct Brush
{
	int		shape = 0;
	int		texture = 1;
	int     type = 0;
	float 	range = 10.0f;
	float	YScale = 3.0f;
};

class Main : public Scene
{
private:
	Camera* Cam;
	Actor* Grid;

	Terrain* terrain;
	Actor*	mousePoint;

	int		brushIdx;
	Brush	brush[3];
	bool	textureBrush = false;

public:
	Main();
	~Main();
	virtual void Init() override;
	virtual void Release() override;
	virtual void Update() override;
	virtual void LateUpdate() override;
	virtual void Render() override;
	virtual void PreRender() override;
	virtual void ResizeScreen() override;
	void NormalizeWeight(Vector4& in);
};
#include "stdafx.h"
#include "Main.h"

Main::Main()
{
}

Main::~Main()
{
}

void Main::Init()
{
    Cam = Camera::Create();
    Cam->LoadFile("Cam.xml");
    Camera::main = Cam;

    Grid = Actor::Create();
    Grid->LoadFile("Grid.xml");
	Cam->width = App.GetWidth();
	Cam->height = App.GetHeight();
	Cam->viewport.width = App.GetWidth();
	Cam->viewport.height = App.GetHeight();

	terrain = Terrain::Create();
	terrain->CreateStructuredBuffer();

	mousePoint = Actor::Create();
	mousePoint->LoadFile("Deadpool.xml");

	brushIdx = 0;
}

void Main::Release()
{
}

void Main::Update()
{
	ImGui::Text("Select Brush");
	ImGui::Checkbox("textureBrush", &textureBrush);

	for (int i = 0; i < 3; i++)
	{
		string temp = "Brush" + to_string(i);
		if (ImGui::Button(temp.c_str()))
		{
			brushIdx = i;
		}
		if(i<2)
			ImGui::SameLine();
	}

	ImGui::SliderFloat("brushRange", &brush[brushIdx].range, 1.0f, 100.0f);
	ImGui::SliderFloat("brushYScale", &brush[brushIdx].YScale, -100.0f, 100.0f);
	ImGui::SliderInt("brushType", &brush[brushIdx].type, 0, 2);
	if (ImGui::Button("[]"))
	{
		brush[brushIdx].shape = 1;
	}
	ImGui::SameLine();
	if (ImGui::Button("()"))
	{
		brush[brushIdx].shape = 0;
	}

	if (terrain->material->ambient.w)
	{
		ImVec2 size;
		size.x = 20; size.y = 20;
		if (ImGui::ImageButton((void*)terrain->material->normalMap->srv, size))
		{
			brush[brushIdx].texture = 0;
		}
		ImGui::SameLine();
	}
	if (terrain->material->diffuse.w)
	{
		ImVec2 size;
		size.x = 20; size.y = 20;
		if (ImGui::ImageButton((void*)terrain->material->diffuseMap->srv, size))
		{
			brush[brushIdx].texture = 1;
		}
		ImGui::SameLine();
	}
	if (terrain->material->specular.w)
	{
		ImVec2 size;
		size.x = 20; size.y = 20;
		if (ImGui::ImageButton((void*)terrain->material->specularMap->srv, size))
		{
			brush[brushIdx].texture = 2;
		}
		ImGui::SameLine();
	}
	if (terrain->material->emissive.w)
	{
		ImVec2 size;
		size.x = 20; size.y = 20;
		if (ImGui::ImageButton((void*)terrain->material->emissiveMap->srv, size))
		{
			brush[brushIdx].texture = 3;
		}
	}

	Camera::ControlMainCam();

	ImGui::Text("FPS: %d", TIMER->GetFramePerSecond());
	ImGui::Begin("Hierarchy");
	Cam->RenderHierarchy();
	Grid->RenderHierarchy();
	terrain->RenderHierarchy();
	mousePoint->RenderHierarchy();
	ImGui::End();
	Cam->Update();
	Grid->Update();
	terrain->Update();
	mousePoint->Update();
}

void Main::LateUpdate()
{
	Vector3 Hit;
	if (terrain->ComPutePicking(Util::MouseToRay(), Hit))
	{
		mousePoint->SetWorldPos(Hit);

		if (INPUT->KeyPress(VK_MBUTTON))
		{
			VertexTerrain* vertices = (VertexTerrain*)terrain->mesh->vertices;

			Matrix Inverse = terrain->W.Invert();
			Hit = Vector3::Transform(Hit, Inverse);
			float YScale = brush[brushIdx].YScale / terrain->S._22;
			float Range = brush[brushIdx].range / terrain->S._11;

			for (UINT i = 0; i < terrain->mesh->vertexCount; i++)
			{
				Vector3 v1 = Vector3(Hit.x, 0.0f, Hit.z);
				Vector3 v2 = Vector3(vertices[i].position.x,
					0.0f, vertices[i].position.z);
				float w;
				Vector3 temp = v2 - v1;
				float Dis = temp.Length();
				if (brush[brushIdx].shape == 1)
				{
					if (fabs(v1.x - v2.x) < brush[brushIdx].range and
						fabs(v1.z - v2.z) < brush[brushIdx].range)
					{
						//nomalize
						w = Dis / (Range * 1.414f);
						// 0 ~ 1
						w = Util::Saturate(w);

						w = (1.0f - w);
					}
					else
					{
						w = 0.0f;
					}
				}
				if (brush[brushIdx].shape == 0)
				{
					//nomalize
					w = Dis / Range;
					// 0 ~ 1
					w = Util::Saturate(w);

					w = (1.0f - w);
				}

				if(brush[brushIdx].type == 1)
				w = sin(w * PI * 0.5f);

				if (brush[brushIdx].type == 2)
				w = w ? 1 : 0;

				if (textureBrush)
				{
					if (brush[brushIdx].texture == 0)
					{
						vertices[i].weights.x += w * YScale * DELTA;
						vertices[i].weights.y -= w * YScale * DELTA;
						vertices[i].weights.z -= w * YScale * DELTA;
						vertices[i].weights.w -= w * YScale * DELTA;
					}
					if (brush[brushIdx].texture == 1)
					{
						vertices[i].weights.x -= w * YScale * DELTA;
						vertices[i].weights.y += w * YScale * DELTA;
						vertices[i].weights.z -= w * YScale * DELTA;
						vertices[i].weights.w -= w * YScale * DELTA;
					}
					if (brush[brushIdx].texture == 2)
					{
						vertices[i].weights.x -= w * YScale * DELTA;
						vertices[i].weights.y -= w * YScale * DELTA;
						vertices[i].weights.z += w * YScale * DELTA;
						vertices[i].weights.w -= w * YScale * DELTA;
					}
					if (brush[brushIdx].texture == 3)
					{
						vertices[i].weights.x -= w * YScale * DELTA;
						vertices[i].weights.y -= w * YScale * DELTA;
						vertices[i].weights.z -= w * YScale * DELTA;
						vertices[i].weights.w += w * YScale * DELTA;
					}
					NormalizeWeight(vertices[i].weights);
				}
				else
				vertices[i].position.y += w * YScale * DELTA;
			}
			terrain->mesh->Update();
		}
	}

	if (INPUT->KeyUp(VK_MBUTTON))
	{
		terrain->UpdateMeshNormal();
		terrain->DeleteStructuredBuffer();
		terrain->CreateStructuredBuffer();
	}
}
void Main::PreRender()
{
}

void Main::Render()
{
	Cam->Set();
	Grid->Render();
	terrain->Render();
	mousePoint->Render();
}

void Main::ResizeScreen()
{
	Cam->width = App.GetWidth();
	Cam->height = App.GetHeight();
	Cam->viewport.width = App.GetWidth();
	Cam->viewport.height = App.GetHeight();
}

void Main::NormalizeWeight(Vector4& in)
{
	float* weight = (float*)&in;
	float	sum = 0;
	for (int i = 0; i < 4; i++)
	{
		weight[i] = Util::Saturate(weight[i]);
		sum += weight[i];
	}
	for (int i = 0; i < 4; i++)
	{
		weight[i] /= sum;
	}
}

int WINAPI wWinMain(HINSTANCE instance, HINSTANCE prevInstance, LPWSTR param, int command)
{
	App.SetAppName(L"Game1");
	App.SetInstance(instance);
    WIN->Create();
    D3D->Create();
	Main * main = new Main();
    main->Init();

	int wParam = (int)WIN->Run(main);

    main->Release();
	SafeDelete(main);
    D3D->DeleteSingleton();
	WIN->DeleteSingleton();

	return wParam;
}

메인의 클래스입니다. ImGui를 통해 모양과 맵 이미지를 불러올 수 있도록 하였습니다.

동영상 첨부에 오류가 나서 파일로 첨부했습니다.

Game1 2023-07-18 18-13-21.mp4
19.05MB

읽어주셔서 감사합니다.

'공부 > 3D강의' 카테고리의 다른 글

230720 강의  (0) 2023.07.20
230719 강의  (0) 2023.07.19
230714 강의  (0) 2023.07.14
230713 강의  (0) 2023.07.13
230712 강의  (0) 2023.07.12
Comments