// OBJ モデルをロード
#include "pch.h"
#include "..\Common\DirectXHelper.h"
#include "Load_OBJ.h"
using namespace App1;
using namespace DirectX;
using namespace Windows::Foundation;
void Load_OBJ::Debug(char *str)
{ WCHAR wk[1000];
MultiByteToWideChar(CP_ACP,MB_PRECOMPOSED,str,-1,wk,1000);
OutputDebugString(wk);
OutputDebugString(L"\r\n");
}
void Load_OBJ::Debug(float3 f3)
{
String^ str = ref new Platform::String(L"float3(");
str += f3.x.ToString();
str += "f , ";
str += f3.y.ToString();
str += "f , ";
str += f3.z.ToString();
str += "f), \r\n";
OutputDebugString(str->Data());
}
void Load_OBJ::Debug(vector<unsigned short> val)
{
String^ str = ref new String(L"short[");
str += val.size().ToString();
str += L"]:";
for (unsigned i = 0; i < val.size(); i++)
{
str += val[i].ToString();
str += " ";
}
str += "\r\n";
OutputDebugString(str->Data());
}
Load_OBJ::Load_OBJ(const std::shared_ptr<DX::DeviceResources>& deviceResources) :
m_deviceResources(deviceResources)
{
}
// Load OBJ Model
void Load_OBJ::Load(
ID3D11Buffer **vertexBuffer,
ID3D11Buffer **indexBuffer,
uint32 *indexCount)
{
float3 wf3;
int num, pt, pw;
m_pos.clear();
m_idxP.clear();
m_idxP3.clear();
str = str1 + str2 + str3;
// str を行で切り分ける(str ⇒ VT)
VT.clear();
num = str.size();
for (pt = 0; pt < num;)
{
pw = pt;
for (pt++; pt < num && str[pt] != '\n'; pt++);
if (pt >= num) break;
pt++;
Word = Word.assign(str, pw, pt - pw);
VT.push_back(Word);
for(; str[pt] == '\r' || str[pt] == '\n' || str[pt] == ' '; pt++);
}
VT_size = VT.size();
for(m_pt=0; m_pt<VT_size; m_pt++) Debug((char *)VT[m_pt].data());
for(m_pt=0; m_pt<VT_size; m_pt++)
{ Token(VT[m_pt]);
if (TK.size() < 1 || TK[0][0]=='#') continue;
switch(TK[0][0])
{ case 'g':
if (TK.size()>1) m_group = TK[1];
break;
case 'v':
wf3.x = (float)atof((char *)TK[1].data());
wf3.y = (float)atof((char *)TK[2].data());
wf3.z = (float)atof((char *)TK[3].data());
m_pos.push_back(wf3);
break;
case 'f':
unsigned nn;
nn = TK.size() - 1;
m_idxP.push_back(nn);
for(unsigned j=1; j<=nn; j++)
{
num = (unsigned short)atoi((char *)TK[j].data());
m_idxP.push_back(num);
}
break;
default:
Debug((char *)VT[m_pt].data());
}
}
/*
float3 f3;
for (unsigned i = 0; i < m_pos.size(); i++)
{
f3 = m_pos[i];
Debug(f3);
}
Debug(m_idxP);
*/
// 4角ポリゴン ⇒ 3角ポリゴン
PX_P3(m_idxP, &m_idxP3);
Debug(m_idxP3);
// 頂点データとインデックスデータを作成
unsigned vtx_size = m_idxP3.size();
VertexPosition *Vertices = new VertexPosition[vtx_size];
unsigned short *Indices = new unsigned short[vtx_size];
for(unsigned i=0; i<vtx_size; i++)
{
Vertices[i].pos.x = m_pos[m_idxP3[i]-1].x;
Vertices[i].pos.y = m_pos[m_idxP3[i]-1].y;
Vertices[i].pos.z = m_pos[m_idxP3[i]-1].z;
Indices[i] = i;
}
// 法線ベクトルの計算
ComputeNorm(Vertices, vtx_size);
*indexCount = m_idxP3.size();
// メッシュを生成
D3D11_SUBRESOURCE_DATA vertexBufferData = {0};
vertexBufferData.pSysMem = Vertices;
vertexBufferData.SysMemPitch = 0;
vertexBufferData.SysMemSlicePitch = 0;
CD3D11_BUFFER_DESC vertexBufferDesc(sizeof(VertexPosition)*(*indexCount), D3D11_BIND_VERTEX_BUFFER);
DX::ThrowIfFailed(
m_deviceResources->GetD3DDevice()->CreateBuffer(
&vertexBufferDesc, &vertexBufferData, vertexBuffer));
// インデックスを生成
D3D11_SUBRESOURCE_DATA indexBufferData = {0};
indexBufferData.pSysMem = Indices;
indexBufferData.SysMemPitch = 0;
indexBufferData.SysMemSlicePitch = 0;
CD3D11_BUFFER_DESC indexBufferDesc(sizeof(unsigned short)*(*indexCount), D3D11_BIND_INDEX_BUFFER);
DX::ThrowIfFailed(
m_deviceResources->GetD3DDevice()->CreateBuffer(
&indexBufferDesc, &indexBufferData, indexBuffer));
// 領域の解放
if (Vertices) delete Vertices;
if (Indices) delete Indices;
// カリング設定
D3D11_RASTERIZER_DESC rasterizerDesc;
ZeroMemory( &rasterizerDesc, sizeof( D3D11_RASTERIZER_DESC ) );
//rasterizerDesc.CullMode = D3D11_CULL_BACK;
rasterizerDesc.CullMode = D3D11_CULL_FRONT;
rasterizerDesc.FillMode = D3D11_FILL_SOLID;
rasterizerDesc.DepthClipEnable = FALSE;
rasterizerDesc.MultisampleEnable = TRUE;
rasterizerDesc.DepthBiasClamp = 0;
rasterizerDesc.SlopeScaledDepthBias = 0;
DX::ThrowIfFailed(
m_deviceResources->GetD3DDevice()->CreateRasterizerState(
&rasterizerDesc, &m_RasterizerState));
}
// VT[m_pt]⇒st をトークンで切り分けて TK に格納
void Load_OBJ::Token(string st)
{
unsigned pt, wk;
TK.clear();
for (pt = 0; pt<st.length(); )
{
wk = st.find_first_not_of(" ,;", pt);
if (st[wk] == '\r' || st[wk] == '\n') return;
pt = wk;
wk = st.find_first_of(" ,;\r\n", pt);
if (wk > pt)
{
Word = Word.assign(st, pt, wk-pt);
TK.push_back(Word);
pt = wk;
}
else pt++;
}
}
// 4角ポリゴン ⇒ 3角ポリゴン
void Load_OBJ::PX_P3(vector<unsigned short> PX, vector<unsigned short> *P3)
{
int i, j, num, pn;
num = PX.size();
for (i = 0; i<num; )
{
pn = (int)PX[i];
i++;
switch (pn)
{
case 3: //TRIANGLESTRIP 3
P3->push_back(PX[i]);
P3->push_back(PX[i + 1]);
P3->push_back(PX[i + 2]);
break;
case 4: //TRIANGLESTRIP 4
P3->push_back(PX[i]);
P3->push_back(PX[i + 1]);
P3->push_back(PX[i + 2]);
P3->push_back(PX[i]);
P3->push_back(PX[i + 2]);
P3->push_back(PX[i + 3]);
break;
default:
for (j = 0; j <= pn - 3; j++)
{
P3->push_back(PX[i]);
P3->push_back(PX[i + 1]);
P3->push_back(PX[i + 2]);
}
break;
}
i += pn;
}
}
// 法線ベクトルの計算
void Load_OBJ::ComputeNorm(VertexPosition *Vertices, int siz)
{
for (int i = 0; i<siz; i += 3)
{
float ax = Vertices[i + 2].pos.x - Vertices[i + 1].pos.x;
float ay = Vertices[i + 2].pos.y - Vertices[i + 1].pos.y;
float az = Vertices[i + 2].pos.z - Vertices[i + 1].pos.z;
float bx = Vertices[i + 0].pos.x - Vertices[i + 1].pos.x;
float by = Vertices[i + 0].pos.y - Vertices[i + 1].pos.y;
float bz = Vertices[i + 0].pos.z - Vertices[i + 1].pos.z;
float nx = ay * bz - az * by;
float ny = az * bx - ax * bz;
float nz = ax * by - ay * bx;
Vertices[i + 0].norm.x = nx;
Vertices[i + 0].norm.y = ny;
Vertices[i + 0].norm.z = nz;
Vertices[i + 1].norm = Vertices[i + 0].norm;
Vertices[i + 2].norm = Vertices[i + 0].norm;
}
}
// カリングの設定
void Load_OBJ:: SetCullMode()
{
auto context = m_deviceResources->GetD3DDeviceContext();
context->RSSetState(m_RasterizerState);
}
|