Kinectを使ってキャラクターを動かす

フォーラム(掲示板)ルール
フォーラム(掲示板)ルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら
イフリナ=フリード
記事: 5
登録日時: 10年前

Kinectを使ってキャラクターを動かす

#1

投稿記事 by イフリナ=フリード » 10年前

KinectとHDMを使用してゲームの制作で現在、Kinectから得られる情報を使い、ボーンの入ったモデルを動かそうとしています。

現状:FBXで作成したキャラクターの表示は成功。
    スケルトンを使いボーン名の取得に成功。
    FbxCulusterを使いボーン数の取得に成功。
    そのボーンに対するウェイト取得にも成功。
    Kinectからの情報も取得完了。 
Fbxmatrixをxmmatrixに変換しその値を返すことに成功。
    ボーン情報入りのhlslの作成にも成功。(たぶん)
まではできました。
あとは、キャラクターの持つ各ボーンに情報を与えてやれば動くはず。
そこで、まずはkinectを使わず内部的に値を与えて動かそうとしました。
しかし、キャラクターが動くどころかピクリともしません。
返ってきた値はちゃんと正しく入っていました。

動かないのは返ってきた値がちゃんとシェーダーに渡されていないからなのでしょうか・・・・・・・。

追記1/30>g_pImmediateContext->PSSetShader(g_ppsFBX_skin, NULL, 0);
と新たにシェーダーを追加するとキャラが表示されなくなってしまいます・・・。

主軸となる部分

コード:

  
#pragma once
#include <d3dcompiler.h>
#include <SpriteFont.h>
#include <d3d11.h>
#include "DDSTextureLoader.h"
#include "resource.h"
#include "stdafx.h"
#include "SimpleMath.h"
//#include "BoneInfo.h"
#include "CFBXRendererDX11.h"
#include "FBXanim.h"
using namespace DirectX;
#include "Model.h"
//--------------------------------------------------------------------------------------
// Global Variables
//--------------------------------------------------------------------------------------
HINSTANCE                           g_hInst = NULL;
HWND                                g_hWnd = NULL;
D3D_DRIVER_TYPE                     g_driverType = D3D_DRIVER_TYPE_NULL;
D3D_FEATURE_LEVEL                   g_featureLevel = D3D_FEATURE_LEVEL_11_0;
ID3D11Device*                       g_pd3dDevice = NULL;
ID3D11DeviceContext*                g_pImmediateContext = NULL;
IDXGISwapChain*                     g_pSwapChain = NULL;
ID3D11RenderTargetView*             g_pRenderTargetView = NULL;
ID3D11Texture2D*                    g_pDepthStencil = NULL;
ID3D11DepthStencilView*             g_pDepthStencilView = NULL;
ID3D11DepthStencilState*			g_pDepthStencilState = NULL;

XMMATRIX                            g_World;
XMMATRIX                            g_View;
XMMATRIX                            g_Projection;
XMFLOAT4                            g_vMeshColor(0.7f, 0.7f, 0.7f, 1.0f);

// グラフィックス診断用
ID3DUserDefinedAnnotation*			g_pUserAnotation = nullptr;
//--------------------------------------------------------------------------------------
// Forward declarations
//--------------------------------------------------------------------------------------
HRESULT InitWindow(HINSTANCE hInstance, int nCmdShow);
HRESULT InitDevice();
void CleanupDevice();
LRESULT CALLBACK    WndProc(HWND, UINT, WPARAM, LPARAM);
void Render();

// 追加記述
const DWORD	NUMBER_OF_MODELS = 1;

HRESULT InitApp();
void CleanupApp();
void UpdateApp();
HRESULT SetupTransformSRV();
void	SetMatrix();
FBX_LOADER::MATERIAL_DATA* lm_p;
FBX_LOADER::CFBXRenderDX11*	g_pFbxDX11[NUMBER_OF_MODELS];
char g_files[NUMBER_OF_MODELS][256] =
{
	  "Assets\\bonebox.FBX",
	//"Assets\\minorin.fbx",
	//"Assets\\model3.fbx",
};

struct CBFBXMATRIX
{
	XMMATRIX mWorld;
	XMMATRIX mView;
	XMMATRIX mProj;
	XMMATRIX mWVP;
};
ID3D11BlendState*				g_pBlendState = nullptr;
ID3D11RasterizerState*			g_pRS = nullptr;
ID3D11Buffer*					g_pcBuffer = nullptr;
ID3D11VertexShader*                 g_pvsFBX = nullptr;
ID3D11PixelShader*                  g_ppsFBX = nullptr;
ID3D11PixelShader*                  g_ppsFBX_skin = nullptr;

// Instancing
bool	g_bInstancing = false;
struct SRVPerInstanceData
{
	XMMATRIX mWorld;
};

//ポリゴン頂点構造体
struct Vertex3D {
	float pos[3];	//x-y-z
	float col[4];	//r-g-b-a
};

const int TYOUTEN = 3;	//ポリゴンの頂点数



//頂点データ(三角ポリゴン1枚)
Vertex3D hVectorData[TYOUTEN] = {
	{ { +0.0f, +0.5f, +0.5f }, { 1.0f, 1.0f, 1.0f, 1.0f } },
	{ { +0.5f, -0.5f, +0.5f }, { 1.0f, 1.0f, 1.0f, 1.0f } },
	{ { -0.5f, -0.5f, +0.5f }, { 1.0f, 1.0f, 1.0f, 1.0f } }
};


const uint32_t g_InstanceMAX = 32;
ID3D11VertexShader*             g_pvsFBXInstancing = nullptr;

//---------------------
//
//各種バッファ
//
//---------------------
ID3D11Buffer* g_pTransformStructuredBuffer = nullptr;
ID3D11Buffer* g_pConstantBuffer0 = NULL;//アプリ←→シェーダー架け橋 コンスタントバッファー  ライト、カメラ
ID3D11Buffer* g_pConstantBuffer1 = NULL;//アプリ←→シェーダー架け橋 コンスタントバッファー 変換行列、マテリアル
ID3D11Buffer* g_pConstantBufferBone = NULL;//アプリ←→シェーダー架け橋 コンスタントバッファー  ボーン


ID3D11ShaderResourceView*	g_pTransformSRV = nullptr;

DirectX::SpriteBatch*		g_pSpriteBatch = nullptr;
DirectX::SpriteFont*		g_pFont = nullptr;


//-----------------------------
//
//スキンメッシュ用シェーダー(アプリ側の構造体)
//
//-----------------------------
//XMFLOAT ◯ ← Vector ◯

//シェーダーに渡す値
struct SHADER_GLOBAL0
{
	XMFLOAT4 vLightDir;//ライト方向
	XMFLOAT4 vEye;//カメラ位置
};

struct SHADER_GLOBAL1
{
	XMMATRIX mW;//ワールド行列
	XMMATRIX mWVP;//ワールドから射影までの変換行列
	XMFLOAT4 vAmbient;//アンビエント光
	XMFLOAT4 vDiffuse;//ディフューズ色
	XMFLOAT4 vSpecular;//鏡面反射
};

#define MAX_BONES 255
//シェーダーに渡すボーン行列配列
struct SHADER_GLOBAL_BONES
{
	XMMATRIX mBone[MAX_BONES];
	SHADER_GLOBAL_BONES()
	{
		for (int i = 0; i < MAX_BONES; i++)
		{
			XMMatrixIdentity();
		}
	}
};
//---------------------------------------------


// オリジナル マテリアル構造体
struct MY_MATERIAL
{
	CHAR szName[100];
	XMFLOAT4 Ka;//アンビエント
	XMFLOAT4 Kd;//ディフューズ
	XMFLOAT4 Ks;//スペキュラー
	CHAR szTextureName[100];//テクスチャーファイル名
	ID3D11ShaderResourceView* pTexture;
	DWORD dwNumFace;//そのマテリアルであるポリゴン数
	MY_MATERIAL()
	{
		ZeroMemory(this, sizeof(MY_MATERIAL));
	}
	~MY_MATERIAL()
	{

	}
};
MY_MATERIAL *m_pMaterial;

XMFLOAT3 g_vLightDir(1, -1, 1);
//XMFLOAT4 g_vEyeDir(1.0f, -1.0f, 1.0f, 1.0f);

BoneInfo* boneifo = nullptr;

BoneInfo::BONE* boneinfo_to_BONEp;
//--------------------------------------------------------------------------------------
// Entry point to the program. Initializes everything and goes into a message processing 
// loop. Idle time is used to render the scene.
//--------------------------------------------------------------------------------------
int WINAPI wWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPWSTR lpCmdLine, int nCmdShow)
{
	
	UNREFERENCED_PARAMETER(hPrevInstance);
	UNREFERENCED_PARAMETER(lpCmdLine);

	if (FAILED(InitWindow(hInstance, nCmdShow)))
		return 0;
	int posP = 0;
	if (FAILED(InitDevice()))
	{
		CleanupApp();
		CleanupDevice();
		return 0;
	}
	static int iFrame = 0;
	
	// Main message loop
	MSG msg = { 0 };
	while (WM_QUIT != msg.message)
	{
		if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
		{
			TranslateMessage(&msg);
			DispatchMessage(&msg);
		}
		else
		{
			Render();
			
		}
	}
	
	CleanupApp();
	CleanupDevice();

	return (int) msg.wParam;
}


//--------------------------------------------------------------------------------------
// Register class and create window
//--------------------------------------------------------------------------------------
HRESULT InitWindow(HINSTANCE hInstance, int nCmdShow)
{
	// Register class
	WNDCLASSEX wcex;
	wcex.cbSize = sizeof(WNDCLASSEX);
	wcex.style = CS_HREDRAW | CS_VREDRAW;
	wcex.lpfnWndProc = WndProc;
	wcex.cbClsExtra = 0;
	wcex.cbWndExtra = 0;
	wcex.hInstance = hInstance;
	wcex.hIcon = LoadIcon(hInstance, (LPCTSTR) IDI_FBX2015LOADER4DX11);
	wcex.hCursor = LoadCursor(NULL, IDC_ARROW);
	wcex.hbrBackground = (HBRUSH) (COLOR_WINDOW + 1);
	wcex.lpszMenuName = NULL;
	wcex.lpszClassName = L"TutorialWindowClass";
	wcex.hIconSm = LoadIcon(wcex.hInstance, (LPCTSTR) IDI_FBX2015LOADER4DX11);
	if (!RegisterClassEx(&wcex))
		return E_FAIL;

	// Create window
	g_hInst = hInstance;
	RECT rc = { 0, 0, 1920, 1080 };
	AdjustWindowRect(&rc, WS_OVERLAPPEDWINDOW, FALSE);
	g_hWnd = CreateWindow(L"TutorialWindowClass", L"Direct3D 11 FBX Sample", WS_OVERLAPPEDWINDOW,
		CW_USEDEFAULT, CW_USEDEFAULT, rc.right - rc.left, rc.bottom - rc.top, NULL, NULL, hInstance,
		NULL);
	if (!g_hWnd)
		return E_FAIL;

	ShowWindow(g_hWnd, nCmdShow);

	return S_OK;
}


//--------------------------------------------------------------------------------------
// Helper for compiling shaders with FBX_LOADER::CFBXRenderDX11D3DCompile
//
// With VS 11, we could load up prebuilt .cso files instead...
//--------------------------------------------------------------------------------------
HRESULT CompileShaderFromFile(WCHAR* szFileName, LPCSTR szEntryPoint, LPCSTR szShaderModel, ID3DBlob** ppBlobOut)
{
	HRESULT hr = S_OK;   

	DWORD dwShaderFlags = D3DCOMPILE_ENABLE_STRICTNESS;
#if defined( DEBUG ) || defined( _DEBUG )
	// Set the D3DCOMPILE_DEBUG flag to embed debug information in the shaders.
	// Setting this flag improves the shader debugging experience, but still allows 
	// the shaders to be optimized and to run exactly the way they will run in 
	// the release configuration of this program.
	dwShaderFlags |= D3DCOMPILE_DEBUG;
#endif

	ID3DBlob* pErrorBlob;
	hr = D3DCompileFromFile(szFileName, NULL, NULL, szEntryPoint, szShaderModel,

		dwShaderFlags, 0, ppBlobOut, &pErrorBlob);
	if (FAILED(hr))
	{
		if (pErrorBlob != NULL)
			OutputDebugStringA((char*) pErrorBlob->GetBufferPointer());
		if (pErrorBlob) pErrorBlob->Release();
		return hr;
	}
	if (pErrorBlob) pErrorBlob->Release();

	return S_OK;
}


//--------------------------------------------------------------------------------------
// Create Direct3D device and swap chain
//--------------------------------------------------------------------------------------
HRESULT InitDevice()
{
	HRESULT hr = S_OK;

	RECT rc;
	GetClientRect(g_hWnd, &rc);
	UINT width = rc.right - rc.left;
	UINT height = rc.bottom - rc.top;

	UINT createDeviceFlags = 0;
#ifdef _DEBUG
	createDeviceFlags |= D3D11_CREATE_DEVICE_DEBUG;
#endif

	D3D_DRIVER_TYPE driverTypes [] =
	{
		D3D_DRIVER_TYPE_HARDWARE,
		D3D_DRIVER_TYPE_WARP,
		D3D_DRIVER_TYPE_REFERENCE,
	};
	UINT numDriverTypes = ARRAYSIZE(driverTypes);

	D3D_FEATURE_LEVEL featureLevels [] =
	{
		D3D_FEATURE_LEVEL_11_0,
		D3D_FEATURE_LEVEL_10_1,
		D3D_FEATURE_LEVEL_10_0,
	};
	UINT numFeatureLevels = ARRAYSIZE(featureLevels);

	DXGI_SWAP_CHAIN_DESC sd;
	ZeroMemory(&sd, sizeof(sd));
	sd.BufferCount = 1;
	sd.BufferDesc.Width = width;
	sd.BufferDesc.Height = height;
	sd.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
	sd.BufferDesc.RefreshRate.Numerator = 60;
	sd.BufferDesc.RefreshRate.Denominator = 1;
	sd.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
	sd.OutputWindow = g_hWnd;
	sd.SampleDesc.Count = 1;
	sd.SampleDesc.Quality = 0;
	sd.Windowed = TRUE;

	for (UINT driverTypeIndex = 0; driverTypeIndex < numDriverTypes; driverTypeIndex++)
	{
		g_driverType = driverTypes[driverTypeIndex];
		hr = D3D11CreateDeviceAndSwapChain(NULL, g_driverType, NULL, createDeviceFlags, featureLevels, numFeatureLevels,
			D3D11_SDK_VERSION, &sd, &g_pSwapChain, &g_pd3dDevice, &g_featureLevel, &g_pImmediateContext);
		if (SUCCEEDED(hr))
			break;
	}
	if (FAILED(hr))
		return hr;

	//
	g_pImmediateContext->QueryInterface( __uuidof(ID3DUserDefinedAnnotation), (void**)&g_pUserAnotation);

	// Create a render target view
	ID3D11Texture2D* pBackBuffer = NULL;
	hr = g_pSwapChain->GetBuffer(0, __uuidof(ID3D11Texture2D), (LPVOID*) &pBackBuffer);
	if (FAILED(hr))
		return hr;

	hr = g_pd3dDevice->CreateRenderTargetView(pBackBuffer, NULL, &g_pRenderTargetView);
	pBackBuffer->Release();
	if (FAILED(hr))
		return hr;

	// Create depth stencil texture
	D3D11_TEXTURE2D_DESC descDepth;
	ZeroMemory(&descDepth, sizeof(descDepth));
	descDepth.Width = width;
	descDepth.Height = height;
	descDepth.MipLevels = 1;
	descDepth.ArraySize = 1;
	descDepth.Format = DXGI_FORMAT_D24_UNORM_S8_UINT;
	descDepth.SampleDesc.Count = 1;
	descDepth.SampleDesc.Quality = 0;
	descDepth.Usage = D3D11_USAGE_DEFAULT;
	descDepth.BindFlags = D3D11_BIND_DEPTH_STENCIL;
	descDepth.CPUAccessFlags = 0;
	descDepth.MiscFlags = 0;
	hr = g_pd3dDevice->CreateTexture2D(&descDepth, NULL, &g_pDepthStencil);
	if (FAILED(hr))
		return hr;

	// Create the depth stencil view
	D3D11_DEPTH_STENCIL_VIEW_DESC descDSV;
	ZeroMemory(&descDSV, sizeof(descDSV));
	descDSV.Format = descDepth.Format;
	descDSV.ViewDimension = D3D11_DSV_DIMENSION_TEXTURE2D;
	descDSV.Texture2D.MipSlice = 0;
	hr = g_pd3dDevice->CreateDepthStencilView(g_pDepthStencil, &descDSV, &g_pDepthStencilView);
	if (FAILED(hr))
		return hr;

	g_pImmediateContext->OMSetRenderTargets(1, &g_pRenderTargetView, g_pDepthStencilView);

	// Create depth stencil state
	D3D11_DEPTH_STENCIL_DESC descDSS;
	ZeroMemory(&descDSS, sizeof(descDSS));
	descDSS.DepthEnable = TRUE;
	descDSS.DepthWriteMask = D3D11_DEPTH_WRITE_MASK_ALL;
	descDSS.DepthFunc = D3D11_COMPARISON_LESS;
	descDSS.StencilEnable = FALSE;
	hr = g_pd3dDevice->CreateDepthStencilState(&descDSS, &g_pDepthStencilState);

	// Setup the viewport
	D3D11_VIEWPORT vp;
	vp.Width = (FLOAT) width;
	vp.Height = (FLOAT) height;
	vp.MinDepth = 0.0f;
	vp.MaxDepth = 1.0f;
	vp.TopLeftX = 0;
	vp.TopLeftY = 0;
	g_pImmediateContext->RSSetViewports(1, &vp);

	// Initialize the world matrices
	g_World = XMMatrixIdentity();

	hr = InitApp();
	if (FAILED(hr))
		return hr;
	hr = SetupTransformSRV();
	if (FAILED(hr))
		return hr;

	return S_OK;
}

// FBX描画用初期化
HRESULT InitApp()
{
	HRESULT hr = S_OK;
	FbxNode * pnode = nullptr;
	// FBXの読み取り
	// 注:頂点バッファやインデックスバッファはこの時点で生成されるがInputLayoutは作成しない

	for (DWORD i = 0; i<NUMBER_OF_MODELS; i++)
	{
		g_pFbxDX11[i] = new FBX_LOADER::CFBXRenderDX11;
		hr = g_pFbxDX11[i]->LoadFBX(g_files[i], g_pd3dDevice);
	}
	if (FAILED(hr))
	{
		MessageBox(NULL,
			L"FBX Error", L"Error", MB_OK);
		return hr;
	}

	
	// Compile the vertex shader
	ID3DBlob* pVSBlob = NULL;
	hr = CompileShaderFromFile(L"simpleRenderVS.hlsl", "vs_main", "vs_4_0", &pVSBlob);
	if (FAILED(hr))
	{
		MessageBox(NULL,
			L"The FX file cannot be compiled.  Please run this executable from the directory that contains the FX file.", L"Error", MB_OK);
		return hr;
	}

	// Create the vertex shader
	hr = g_pd3dDevice->CreateVertexShader(pVSBlob->GetBufferPointer(), pVSBlob->GetBufferSize(), NULL, &g_pvsFBX);
	if (FAILED(hr))
	{
		pVSBlob->Release();
		return hr;
	}

	// Compile the vertex shader
	pVSBlob->Release();
	hr = CompileShaderFromFile(L"simpleRenderInstancingVS.hlsl", "vs_main", "vs_4_0", &pVSBlob);
	if (FAILED(hr))
	{
		MessageBox(NULL,
			L"The FX file cannot be compiled.  Please run this executable from the directory that contains the FX file.", L"Error", MB_OK);
		return hr;
	}

	// Create the vertex shader
	hr = g_pd3dDevice->CreateVertexShader(pVSBlob->GetBufferPointer(), pVSBlob->GetBufferSize(), NULL, &g_pvsFBXInstancing);
	if (FAILED(hr))
	{
		pVSBlob->Release();
		return hr;
	}

	pVSBlob->Release();
	hr = CompileShaderFromFile(L"cubeMP.hlsl", "VS", "vs_4_0", &pVSBlob);
	if (FAILED(hr))
	{
		pVSBlob->Release();
		return hr;
	}

	// Define the input layout
	D3D11_INPUT_ELEMENT_DESC layout [] =
	{
		{ "POSITION"    ,  0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0,     D3D11_INPUT_PER_VERTEX_DATA, 0 },
		{ "NORMAL"      ,  0, DXGI_FORMAT_R32G32B32_FLOAT, 0, D3D11_APPEND_ALIGNED_ELEMENT, D3D11_INPUT_PER_VERTEX_DATA, 0 },
		{ "TEXCOORD"    ,  0, DXGI_FORMAT_R32G32_FLOAT   , 0, D3D11_APPEND_ALIGNED_ELEMENT, D3D11_INPUT_PER_VERTEX_DATA, 0 },
		{ "BONE_INDEX"  ,  0, DXGI_FORMAT_R32G32B32A32_UINT , 0, 32, D3D11_INPUT_PER_VERTEX_DATA, 0 },
		{ "BONE_WEIGHT" ,  0, DXGI_FORMAT_R32G32B32A32_FLOAT, 0, 48, D3D11_INPUT_PER_VERTEX_DATA, 0 },	
	};
	UINT numElements = ARRAYSIZE(layout);

	for (DWORD i = 0; i<NUMBER_OF_MODELS; i++)
	{
		hr = g_pFbxDX11[i]->CreateInputLayout(g_pd3dDevice, pVSBlob->GetBufferPointer(), pVSBlob->GetBufferSize(), layout, numElements);
	}
	pVSBlob->Release();
	if (FAILED(hr))
		return hr;

	// Compile the pixel shader
	ID3DBlob* pPSBlob = NULL;
	hr = CompileShaderFromFile(L"simpleRenderPS.hlsl", "PS", "ps_4_0", &pPSBlob);
	if (FAILED(hr))
	{
		MessageBox(NULL,
			L"The FX file cannot be compiled.  Please run this executable from the directory that contains the FX file.", L"Error", MB_OK);
		return hr;
	}

	// Create the pixel shader
	hr = g_pd3dDevice->CreatePixelShader(pPSBlob->GetBufferPointer(), pPSBlob->GetBufferSize(), NULL, &g_ppsFBX);
	pPSBlob->Release();
	if (FAILED(hr))
		return hr;


	 //Compile the pixel shader
	ID3DBlob* pPSBlob2 = NULL;
	hr = CompileShaderFromFile(L"SkinmeshforPixelShaders.hlsl", "PS", "ps_4_0", &pPSBlob2);
	if (FAILED(hr))
	{
		MessageBox(NULL,
			L"The FX file cannot be compiled.  Please run this executable from the directory that contains the FX file.", L"Error", MB_OK);
		return hr;
	}
	

	// Create the pixel shader
	hr = g_pd3dDevice->CreatePixelShader(pPSBlob2->GetBufferPointer(), pPSBlob2->GetBufferSize(), NULL, &g_ppsFBX_skin);
	pPSBlob2->Release();
	if (FAILED(hr))
		return hr;



	// Create Constant Buffer
	D3D11_BUFFER_DESC bd;
	ZeroMemory(&bd, sizeof(bd));
	bd.Usage = D3D11_USAGE_DYNAMIC;
	bd.ByteWidth = sizeof(CBFBXMATRIX);
	bd.BindFlags = D3D11_BIND_CONSTANT_BUFFER;
	bd.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
	hr = g_pd3dDevice->CreateBuffer(&bd, NULL, &g_pcBuffer);
	if (FAILED(hr))
		return hr;


	//------------------------------------------------------------------------------------------------
	//-------------------------------------------
	//
	//ボーン情報入りシェーダ用各種バッファ
	//
	//-------------------------------------------
	//コンスタントバッファー0作成
	D3D11_BUFFER_DESC cb;
	cb.BindFlags = D3D11_BIND_CONSTANT_BUFFER;
	cb.ByteWidth = sizeof(SHADER_GLOBAL0);
	cb.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
	cb.MiscFlags = 0;
	cb.StructureByteStride = 0;
	cb.Usage = D3D11_USAGE_DYNAMIC;

	g_pd3dDevice->CreateBuffer(&cb, NULL, &g_pConstantBuffer0);
	
	//コンスタントバッファー1作成  
	cb.BindFlags = D3D11_BIND_CONSTANT_BUFFER;
	cb.ByteWidth = sizeof(SHADER_GLOBAL1);
	cb.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
	cb.MiscFlags = 0;
	cb.StructureByteStride = 0;
	cb.Usage = D3D11_USAGE_DYNAMIC;

	g_pd3dDevice->CreateBuffer(&cb, NULL, &g_pConstantBuffer1);
	
	//コンスタントバッファーボーン用 作成  
	cb.BindFlags = D3D11_BIND_CONSTANT_BUFFER;
	cb.ByteWidth = sizeof(SHADER_GLOBAL_BONES);
	cb.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
	cb.MiscFlags = 0;
	cb.StructureByteStride = 0;
	cb.Usage = D3D11_USAGE_DYNAMIC;
	
	if (FAILED(g_pd3dDevice->CreateBuffer(&cb, NULL, &g_pConstantBufferBone)))
	{
		return E_FAIL;
	}
	
	//---------------------------------------------
	D3D11_RASTERIZER_DESC rsDesc;
	ZeroMemory(&rsDesc, sizeof(D3D11_RASTERIZER_DESC));
	rsDesc.FillMode = D3D11_FILL_SOLID;
	rsDesc.CullMode = D3D11_CULL_BACK;
	rsDesc.FrontCounterClockwise = false;
	rsDesc.DepthClipEnable = FALSE;
	g_pd3dDevice->CreateRasterizerState(&rsDesc, &g_pRS);
	g_pImmediateContext->RSSetState(g_pRS);

	D3D11_BLEND_DESC blendDesc;
	ZeroMemory(&blendDesc, sizeof(D3D11_BLEND_DESC));
	blendDesc.AlphaToCoverageEnable = false;
	blendDesc.IndependentBlendEnable = false;
	blendDesc.RenderTarget[0].BlendEnable = true;
	blendDesc.RenderTarget[0].SrcBlend = D3D11_BLEND_SRC_ALPHA;
	blendDesc.RenderTarget[0].DestBlend = D3D11_BLEND_INV_SRC_ALPHA;
	blendDesc.RenderTarget[0].BlendOp = D3D11_BLEND_OP_ADD;
	blendDesc.RenderTarget[0].SrcBlendAlpha = D3D11_BLEND_ZERO;      ///tryed D3D11_BLEND_ONE ... (and others desperate combinations ... )
	blendDesc.RenderTarget[0].DestBlendAlpha = D3D11_BLEND_ZERO;     ///tryed D3D11_BLEND_ONE ... (and others desperate combinations ... )
	blendDesc.RenderTarget[0].BlendOpAlpha = D3D11_BLEND_OP_ADD;
	blendDesc.RenderTarget[0].RenderTargetWriteMask = D3D11_COLOR_WRITE_ENABLE_ALL;

	g_pd3dDevice->CreateBlendState(&blendDesc, &g_pBlendState);

	/*boneifo->m_pDevice = g_pd3dDevice;
	boneifo->m_pDeviceContext = g_pImmediateContext;
	boneifo->m_pSampleLinear = lm_p->pSampler;
	boneifo->m_pConstantBuffer = g_pConstantBuffer1;*/

	// SpriteBatch
	g_pSpriteBatch = new DirectX::SpriteBatch(g_pImmediateContext);
	// SpriteFont
	g_pFont = new DirectX::SpriteFont(g_pd3dDevice, L"Assets\\Arial.spritefont");


	return hr;
}

HRESULT SetupTransformSRV()
{
	HRESULT hr = S_OK;

	const uint32_t count = g_InstanceMAX;
	const uint32_t stride = static_cast<uint32_t>(sizeof(SRVPerInstanceData));

	// Create StructuredBuffer
	D3D11_BUFFER_DESC bd;
	ZeroMemory(&bd, sizeof(bd));
	bd.Usage = D3D11_USAGE_DYNAMIC;
	bd.ByteWidth = stride * count;
	bd.BindFlags = D3D11_BIND_SHADER_RESOURCE;
	bd.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
	bd.MiscFlags = D3D11_RESOURCE_MISC_BUFFER_STRUCTURED;
	bd.StructureByteStride = stride;
	hr = g_pd3dDevice->CreateBuffer(&bd, NULL, &g_pTransformStructuredBuffer);
	if (FAILED(hr))
		return hr;

	// Create ShaderResourceView
	D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc;
	ZeroMemory(&srvDesc, sizeof(D3D11_SHADER_RESOURCE_VIEW_DESC));
	srvDesc.ViewDimension = D3D11_SRV_DIMENSION_BUFFEREX;   // 拡張されたバッファーであることを指定する
	srvDesc.BufferEx.FirstElement = 0;
	srvDesc.Format = DXGI_FORMAT_UNKNOWN;
	srvDesc.BufferEx.NumElements = count;                  // リソース内の要素の数

	// 構造化バッファーをもとにシェーダーリソースビューを作成する
	hr = g_pd3dDevice->CreateShaderResourceView(g_pTransformStructuredBuffer, &srvDesc, &g_pTransformSRV);
	if (FAILED(hr))
		return hr;

	return hr;
}

//
void CleanupApp()
{
	if (g_pUserAnotation)
	{
		g_pUserAnotation->Release();
		g_pUserAnotation = nullptr;
	}

	if (g_pSpriteBatch)
	{
		delete g_pSpriteBatch;
		g_pSpriteBatch = nullptr;
	}
	if (g_pFont)
	{
		delete g_pFont;
		g_pFont = nullptr;
	}

	if (g_pTransformSRV)
	{
		g_pTransformSRV->Release();
		g_pTransformSRV = nullptr;
	}
	if (g_pTransformStructuredBuffer)
	{
		g_pTransformStructuredBuffer->Release();
		g_pTransformStructuredBuffer = nullptr;
	}

	if (g_pBlendState)
	{
		g_pBlendState->Release();
		g_pBlendState = nullptr;
	}

	for (DWORD i = 0; i<NUMBER_OF_MODELS; i++)
	{
		if (g_pFbxDX11[i])
		{
			delete g_pFbxDX11[i];
			g_pFbxDX11[i] = nullptr;
		}
	}

	if (g_pRS)
	{
		g_pRS->Release();
		g_pRS = nullptr;
	}

	if (g_pvsFBXInstancing)
	{
		g_pvsFBX->Release();
		g_pvsFBX = nullptr;
	}

	if (g_pvsFBX)
	{
		g_pvsFBX->Release();
		g_pvsFBX = nullptr;
	}

	if (g_ppsFBX)
	{
		g_ppsFBX->Release();
		g_ppsFBX = nullptr;
	}
	if (g_ppsFBX_skin)
	{
		g_ppsFBX_skin->Release();
		g_ppsFBX_skin = nullptr;
	}
	if (g_pcBuffer)
	{
		g_pcBuffer->Release();
		g_pcBuffer = nullptr;
	}
}


//--------------------------------------------------------------------------------------
// Clean up the objects we've created
//--------------------------------------------------------------------------------------
void CleanupDevice()
{
	if (g_pImmediateContext) g_pImmediateContext->ClearState();

	if (g_pDepthStencilState) g_pDepthStencilState->Release();
	if (g_pDepthStencil) g_pDepthStencil->Release();
	if (g_pDepthStencilView) g_pDepthStencilView->Release();
	if (g_pRenderTargetView) g_pRenderTargetView->Release();
	if (g_pSwapChain) g_pSwapChain->Release();
	if (g_pImmediateContext) g_pImmediateContext->Release();
	if (g_pd3dDevice) g_pd3dDevice->Release();
}


//--------------------------------------------------------------------------------------
// Called every time the application receives a message
//--------------------------------------------------------------------------------------
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
	PAINTSTRUCT ps;
	HDC hdc;

	switch (message)
	{
	case WM_KEYUP:
		if (wParam == VK_F2)
		{
			g_bInstancing = !g_bInstancing;
		}
		break;
	case WM_PAINT:
		hdc = BeginPaint(hWnd, &ps);
		EndPaint(hWnd, &ps);
		break;

	case WM_DESTROY:
		PostQuitMessage(0);
		break;

	default:
		return DefWindowProc(hWnd, message, wParam, lParam);
	}

	return 0;
}

//
void SetMatrix()
{
	HRESULT hr = S_OK;
	const uint32_t count = g_InstanceMAX;
	const float offset = -(g_InstanceMAX*60.0f / 2.0f);
	XMMATRIX mat;

	D3D11_MAPPED_SUBRESOURCE MappedResource;
	hr = g_pImmediateContext->Map(g_pTransformStructuredBuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &MappedResource);

	SRVPerInstanceData*	pSrvInstanceData = (SRVPerInstanceData*) MappedResource.pData;

	for (uint32_t i = 0; i<count; i++)
	{
		mat = XMMatrixTranslation(0, 0, i*60.0f + offset);
		pSrvInstanceData[i].mWorld = (mat);
	}

	g_pImmediateContext->Unmap(g_pTransformStructuredBuffer, 0);
}

//--------------------------------------------------------------------------------------
// Render a frame
//--------------------------------------------------------------------------------------
void Render()
{
	RECT rc;
	GetClientRect(g_hWnd, &rc);
	UINT width = rc.right - rc.left;
	UINT height = rc.bottom - rc.top;
	int kval = 0;

	// Initialize the world matrices
	g_World = XMMatrixIdentity();

	// Initialize the view matrix
	XMVECTOR Eye = XMVectorSet(0.0f, 200.0f, -500.0f, 0.0f);
	XMVECTOR At = XMVectorSet(0.0f, 150.0f, 0.0f, 0.0f);
	XMVECTOR Up = XMVectorSet(0.0f, 1.0f, 0.0f, 0.0f);



	//---------------------------------------------------
	//
	//モデル確認用(雑)色々とおかしい所があるが
	//まぁ確認はできるでしょう。
	//
	//
	//機能概要:Ctrキーで左回転:Altキーで右回転
	//
	//---------------------------------------------------
	if (GetKeyState(VK_ADD))
	{
		XMVECTOR Eye = XMVectorSet(0.0f, 150.0f, -350.0f, 0.0f);
	}
	if (GetKeyState(VK_SUBTRACT))
	{
		XMVECTOR Eye = XMVectorSet(0.0f, 150.0f, -350.0f, 0.0f);
	}

	if (GetKeyState(VK_NUMPAD2)) //テンキー2番 下
	{
		Eye = XMVectorSet(0.0f, 150.0f, -650.0f, 0.0f);

	}
	if (GetKeyState(VK_NUMPAD4)) //テンキー4番 左
	{
		Eye = XMVectorSet(300 + 150.0f, 150.0f, -350.0f, 0.0f);
	}
	if (GetKeyState(VK_NUMPAD6)) //テンキー6番 右
	{
		Eye = XMVectorSet(-300 - 150.0f, 150.0f, -350.0f, 0.0f);
	}
	if (GetKeyState(VK_NUMPAD8)) //テンキー8番 上
	{
		Eye = XMVectorSet(0.0f, 150.0f, 650.0f, 0.0f);
	}
	g_View = XMMatrixLookAtLH(Eye, At, Up);

	// Initialize the projection matrix
	g_Projection = XMMatrixPerspectiveFovLH(XM_PIDIV4, width / (FLOAT)height, 0.01f, 10000.0f);

	// Update our time
	static float t = 0.0f;
	if (g_driverType == D3D_DRIVER_TYPE_REFERENCE)
	{

		if (GetKeyState(VK_MENU))
		{
			//t += (float)XM_PI * 0.0125f;
		}
		//if (GetKeyState(VK_CONTROL))
		//{
		//	//t += (float)XM_PI * 0.0125f;
		//}
	}
	else
	{
		static DWORD dwTimeStart = 0;
		DWORD dwTimeCur = GetTickCount();
		if (dwTimeStart == 0)
			dwTimeStart = dwTimeCur;
		if (GetKeyState(VK_MENU) < 0)
		{
			t = (dwTimeCur + dwTimeStart) / 1000.0f;
			// Rotate cube around the origin
			g_World = XMMatrixRotationY(-t);
		}
		else
		{
			g_World = g_World;
		}

		if (GetKeyState(VK_CONTROL) < 0)
		{
			t = (dwTimeCur - dwTimeStart) / 1000.0f;

			// Rotate cube around the origin
			g_World = XMMatrixRotationY(t);
		}
	}
	//---------------------------------------------------------
	//
	// Clear the back buffer
	//
	float ClearColor[4] = { 0.0f, 0.125f, 0.3f, 1.0f }; // red, green, blue, alpha
	g_pImmediateContext->ClearRenderTargetView(g_pRenderTargetView, ClearColor);
	//
	// Clear the depth buffer to 1.0 (max depth)
	//
	g_pImmediateContext->ClearDepthStencilView(g_pDepthStencilView, D3D11_CLEAR_DEPTH, 1.0f, 0);

	float blendFactors[4] = { D3D11_BLEND_ZERO, D3D11_BLEND_ZERO, D3D11_BLEND_ZERO, D3D11_BLEND_ZERO };
	g_pImmediateContext->RSSetState(g_pRS);
	g_pImmediateContext->OMSetBlendState(g_pBlendState, blendFactors, 0xffffffff);
	g_pImmediateContext->OMSetDepthStencilState(g_pDepthStencilState, 0);

	g_pUserAnotation->BeginEvent(L"ModelDraw");

	// モデルを順番に描画
	for (DWORD i = 0; i < NUMBER_OF_MODELS; i++)
	{
		// FBX Modelのnode数を取得
		size_t nodeCount = g_pFbxDX11[i]->GetNodeCount();

		WCHAR wstr[256];
		swprintf_s(wstr, L"Model0%d", i);
		g_pUserAnotation->BeginEvent(wstr);

		ID3D11VertexShader* pVS = g_bInstancing ? g_pvsFBXInstancing : g_pvsFBX;
		g_pImmediateContext->VSSetShader(pVS, NULL, 0);
		g_pImmediateContext->VSSetConstantBuffers(0, 1, &g_pcBuffer);
		g_pImmediateContext->PSSetShader(g_ppsFBX_skin, NULL, 0);
		g_pImmediateContext->PSSetShader(g_ppsFBX, NULL, 0);
	
		// 全ノードを描画
		for (size_t j = 0; j < nodeCount; j++)
		{
			int brcnt = 0;
			XMMATRIX mLocal;
			g_pFbxDX11[i]->GetNodeMatrix(j, &mLocal.r[0].m128_f32[0]);	// このnodeのMatrix

			D3D11_MAPPED_SUBRESOURCE MappedResource;

			if (j == 0)
			{
				FBX_LOADER::MATERIAL_DATA material = g_pFbxDX11[i]->GetNodeMaterial(j);
				
				g_pImmediateContext->Map(g_pcBuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &MappedResource);
				SHADER_GLOBAL1 sg;
				sg.mW = g_World;
				sg.mWVP = XMMatrixTranspose(mLocal*g_World*g_View*g_Projection);

				XMMatrixTranspose(sg.mWVP * sg.mWVP);

				sg.vAmbient = material.ambient;
				sg.vDiffuse = material.diffuse;
				sg.vSpecular = material.specular;

				memcpy_s(MappedResource.pData, MappedResource.RowPitch, (void*)&sg, sizeof(SHADER_GLOBAL1));
				g_pImmediateContext->Unmap(g_pcBuffer, 0);
				
			}

			CBFBXMATRIX*	cbFBX = (CBFBXMATRIX*)MappedResource.pData;

			// 左手系
			cbFBX->mWorld = (g_World);
			cbFBX->mView = (g_View);
			cbFBX->mProj = (g_Projection);

			cbFBX->mWVP = XMMatrixTranspose(mLocal*g_World*g_View*g_Projection);

			g_pImmediateContext->Unmap(g_pcBuffer, 0);

			SetMatrix();

			FBX_LOADER::MATERIAL_DATA material = g_pFbxDX11[i]->GetNodeMaterial(j);

			if (material.pMaterialCb)
				g_pImmediateContext->UpdateSubresource(material.pMaterialCb, 0, NULL, &material.materialConstantData, 0, 0);

			g_pImmediateContext->VSSetShaderResources(0, 1, &g_pTransformSRV);
			g_pImmediateContext->PSSetShaderResources(0, 1, &material.pSRV);
			g_pImmediateContext->PSSetConstantBuffers(0, 1, &material.pMaterialCb);
			g_pImmediateContext->PSSetSamplers       (0, 1, &material.pSampler);



			if (g_bInstancing)
				g_pFbxDX11[i]->RenderNodeInstancing(g_pImmediateContext, j, g_InstanceMAX);
			else
				g_pFbxDX11[i]->RenderNode(g_pImmediateContext, j);
		
	
				brcnt = boneifo->BoneNumReturn();
				//フレームを進めたことにより変化したポーズ(ボーンの行列)をシェーダーに渡す
				g_pImmediateContext->Map(g_pConstantBufferBone, 0, D3D11_MAP_WRITE_DISCARD, 0, &MappedResource);

				SHADER_GLOBAL_BONES sg;
				for (int i = 0; i < brcnt; i++)
				{
					XMMATRIX mat = boneifo->GetCurrentPoseMatrix(i);
					XMMatrixTranspose(mat);
					sg.mBone[i] = mat;
				}

				memcpy_s(MappedResource.pData, MappedResource.RowPitch, (void*)&sg, sizeof(SHADER_GLOBAL_BONES));
				g_pImmediateContext->Unmap(g_pConstantBufferBone, 0);

				g_pImmediateContext->PSSetConstantBuffers(2, 1, &g_pConstantBufferBone);

			


			//g_pImmediateContext->VSSetConstantBuffers(2, 1, &g_pConstantBufferBone);
			
			//使用するシェーダーの登録 (effectの”テクニック”に相当)
			//g_pImmediateContext->VSSetShader(g_pvsFBX, NULL, 0);
			//g_pImmediateContext->PSSetShader(g_ppsFBX_skin, NULL, 0);
			g_pUserAnotation->EndEvent();
		}
	/*	static int iFrame = 24;
		iFrame++;*/
		//	boneifo->Get_Bone_frame();

		//メッシュをレンダー
		//FbxVector4* fvec = nullptr;
		static float fAngle = 0;
		fAngle += 0.0002f;
		XMMATRIX* mWorld = nullptr;
		//XMMatrixRotationY(fAngle);
		g_pUserAnotation->EndEvent();

		g_pUserAnotation->BeginEvent(L"RenderText");

		// Text
		//WCHAR wstr[512];
		g_pSpriteBatch->Begin();
		g_pFont->DrawString(g_pSpriteBatch, L"FBX Loader : F2 Change Render Mode", XMFLOAT2(0, 0), DirectX::Colors::Yellow, 0, XMFLOAT2(0, 0), 0.5f);

		if (g_bInstancing)
			swprintf_s(wstr, L"Render Mode: Instancing");
		else
			swprintf_s(wstr, L"Render Mode: Single Draw");
		g_pFont->DrawString(g_pSpriteBatch, wstr, XMFLOAT2(0, 16), DirectX::Colors::Yellow, 0, XMFLOAT2(0, 0), 0.5f);
		g_pSpriteBatch->End();

		g_pUserAnotation->EndEvent();

		g_pImmediateContext->VSSetShader(NULL, NULL, 0);
		g_pImmediateContext->PSSetShader(NULL, NULL, 0);
		//g_pImmediateContext->PSSetShader(NULL, NULL, 0);
		//g_pImmediateContext->PSSetShader(g_ppsFBX_skin, NULL, 0);
		//
		// Present our back buffer to our front buffer
		//
	
		//	boneifo->Render(mWorld);
		//-----------------------
		//
		//ボーンの初期姿勢を取る
		//
		//-----------------------
		bool attitubleSW = false;
		if (attitubleSW = false)
		{
			boneifo->GetInitial_attitude();

			attitubleSW = true;
		}
		//-------------------------

		boneifo->GetCurrentPoseMatrix(0);


		//boneinfo_to_BONEp->mNewPose[2].mData[1];
		//mWorld = XMMatrixRotationY(fAngle);

		g_pSwapChain->Present(0, 0);
	}
}
ボーンに関する部分

コード:

  
#include <vector>
#include <set>
#include <string>
#include "BoneInfo.h"
#pragma warning(disable : 4996)
using namespace DirectX;

DWORD m_dwNumVert = NULL;
DWORD m_dwNumUV = NULL;
int iNumBone = 0;
FbxCluster** ppCluster;

float angle = 1.0f;
BoneInfo::BoneInfo()
{
	//mesh = nullptr;
	//iNumVertex = 0;
}

BoneInfo::~BoneInfo()
{
	mesh->Reset();
}

//-----------------------------------
//
//FbxMatrixをXMMATRIXにキャストする関数(これ重要)
//作成者:
//作成日1月26日
//-----------------------------------
XMMATRIX BoneInfo::Convert_from_FbxMatrix_to_XMMATRIX(FbxAMatrix& pSrc)
{
	XMMATRIX  mmx;

	 mmx =
	 XMMatrixSet(
		static_cast<FLOAT>(pSrc.Get(0, 0)), static_cast<FLOAT>(pSrc.Get(0, 1)), static_cast<FLOAT>(pSrc.Get(0, 2)), static_cast<FLOAT>(pSrc.Get(0, 3)),
		static_cast<FLOAT>(pSrc.Get(1, 0)), static_cast<FLOAT>(pSrc.Get(1, 1)), static_cast<FLOAT>(pSrc.Get(1, 2)), static_cast<FLOAT>(pSrc.Get(1, 3)),
		static_cast<FLOAT>(pSrc.Get(2, 0)), static_cast<FLOAT>(pSrc.Get(2, 1)), static_cast<FLOAT>(pSrc.Get(2, 2)), static_cast<FLOAT>(pSrc.Get(2, 3)),
		static_cast<FLOAT>(pSrc.Get(3, 0)), static_cast<FLOAT>(pSrc.Get(3, 1)), static_cast<FLOAT>(pSrc.Get(3, 2)), static_cast<FLOAT>(pSrc.Get(3, 3)));
	 
	
	 return mmx;
}

//-----------------------------------------------------------
//機能概要:クラスター(ボーン一本)の情報を取り出す
//追加日2014/12/18
//
//-----------------------------------------------------------
void BoneInfo::GetCluster(int vxCnt, FbxMesh* lMesh, FBX_VERTEX* pvVB)
{
	m_dwNumVert = lMesh->GetControlPointsCount();
	
	//一時的なメモリ確保(頂点バッファとインデックスバッファ)
	 pvVB = new FBX_VERTEX[m_dwNumVert];

	//FBXから抽出すべき情報は、頂点ごとのボーンインデックス、頂点ごとのボーンウェイト、バインド行列、ポーズ行列 の4項目

	int* piReadCount = new int[vxCnt];
	ZeroMemory(piReadCount, sizeof(int)*vxCnt);

	//FbxSkin* pSkinInfo = static_cast<FbxSkin*>(lMesh->GetDeformer(0, FbxDeformer::eSkin));

	FbxSkin* pSkinInfo = nullptr;
	//
	int DeformerCount = lMesh->GetDeformerCount(FbxDeformer::eSkin);
	
	for (int i = 0; i < DeformerCount; ++i)
	{
		pSkinInfo = static_cast<FbxSkin*>(lMesh->GetDeformer(i, FbxDeformer::eSkin));
	}

	if (DeformerCount == 1)
	{
		//ボーンを得る
		 iNumBone = pSkinInfo->GetClusterCount();
		FbxCluster*  clusterTmp = nullptr;
		
		ppCluster = new  FbxCluster*[iNumBone];
		for (int ib = 0; ib < iNumBone; ib++)
		{
			ppCluster[ib] = pSkinInfo->GetCluster(ib);
		}
	
		//それぞれのボーンに影響を受ける頂点を調べる そこから逆に、頂点ベースでボーンインデックス・重みを整頓する
		for (int inb = 0; inb < iNumBone; inb++)
		{
			int     iNumIndex = ppCluster[inb]->GetControlPointIndicesCount();//このボーンに影響を受ける頂点数
			int*    piIndex   = ppCluster[inb]->GetControlPointIndices();
			double* pdWeight  = ppCluster[inb]->GetControlPointWeights();

			//頂点側からインデックスをたどって、頂点サイドで整理する
			for (int k = 0; k < iNumIndex; k++)
			{
				for (int m = 0; m < 4; m++)//FBXやCGソフトがボーン4本以内とは限らない。5本以上の場合は、重みの大きい順に4本に絞る 
				{
					int tmpk = k;


					if (pdWeight[tmpk] > pvVB[piIndex[tmpk]].bBoneWeight[m])
					{
						pvVB[piIndex[tmpk]].bBoneIndex [m] = inb;
						pvVB[piIndex[tmpk]].bBoneWeight[m] = pdWeight[tmpk];
						break;
					}
				}
				if (piReadCount[piIndex[k]] < 3)
				{
					piReadCount[piIndex[k]]++;
				}
			}
		}
		//
		//ボーンを生成
		int m_iNumBone = iNumBone;

		//ボーン構造体アクセス用ポインター
		BONE    * m_BoneArray = new BONE[iNumBone];

		for (int i = 0; i < m_iNumBone; i++)
		{
			FbxAMatrix  mat;
			ppCluster[i]->GetTransformLinkMatrix(mat);
		
			for (int x = 0; x < 4; x++)
			{
				for (int y = 0; y < 4; y++)
				{
					m_BoneArray->mBindPose[i] = mat.Get(y, x);
				}
			}
		}
		//delete
		delete[] piReadCount;
	}
}
//-------------------------------------------------------------
//-------------------------------------------
//機能概要:ボーン数を返す
//追加日2014/12/18
//
//-------------------------------------------
int BoneInfo::BoneNumReturn()
{
	int bnum = iNumBone;

	return bnum;
}
//-------------------------------------------
//機能概要:ボーンの初期姿勢を取得する
//追加日2014/12/18
//
//-------------------------------------------
void BoneInfo::GetInitial_attitude()
{
	FbxAMatrix initMat;
	cluster->GetTransformLinkMatrix(initMat);
}
//-------------------------------------------
//-------------------------------------------
//機能概要:○○フレームの骨の姿勢を取得する  手法1(たぶん使わないかな)
//追加日2014/12/18
//
//-------------------------------------------
void BoneInfo::Get_Bone_frame()
{

	FbxAMatrix initMat;
	cluster->GetTransformLinkMatrix(initMat);

	//int frameNum = 24;  // フレーム数(ここでは適当です)
	//FbxTime start, period;  // スタート時間と単位時間

	//for (int i = 0; i < frameNum; ++i) {
	//	FbxMatrix mat;
	//	FbxTime time = start + period * i;
	//	mat = cluster->GetLink()->EvaluateGlobalTransform(time);

	//}
}
//-------------------------------------------
//機能概要:○○フレームの骨の姿勢を取得する 手法2
//追加日2014/12/18
//
//-------------------------------------------
void BoneInfo::SetNewPoseMatrices(int frame)
{
	int i;
	FbxTime time;
	frame =  24;
	BONE    * m_BoneArray = new BONE[iNumBone];
	time.SetTime(0, 0, 0, frame, 0, FbxTime::eFrames30);//30フレーム/秒 と推定 厳密には状況ごとに調べる必要あり

	for (i = 0; i < iNumBone; i++)
	{
		FbxAMatrix mat = ppCluster[i]->GetLink()->EvaluateGlobalTransform(time);

		for (int x = 0; x < 4; x++)
		{
			for (int y = 0; y < 4; y++)
			{                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                       

				m_BoneArray->mBindPose[i] = mat.Get(y, x);
			}
		}
	}
	
}
//-------------------------------------------
//機能概要:ボーン行列を変化させる(後にキネクトの情報とリンクさせる形に変える)
//追加日2015/01/22
//
//-------------------------------------------
void BoneInfo::TransformBorneMatrix()
{
	//BONE    * m_BoneArray = new BONE[iNumBone];	
}

//-------------------------------------------
//機能概要:ボーン行列を返す
//追加日2015/01/22
//
//-------------------------------------------
XMMATRIX BoneInfo::GetCurrentPoseMatrix(int index)
{
	BONE               * m_BoneArray = new BONE[iNumBone];
	FbxAMatrix newMat  = m_BoneArray[index].mNewPose;
	
	XMMATRIX  invmat = Convert_from_FbxMatrix_to_XMMATRIX(m_BoneArray[index].mBindPose);
	XMVECTOR * inv = nullptr;

	/*static float fAngle = 0;
	fAngle +=1.0f;
	XMMATRIX* mWorld = nullptr;
*/
	//Convert_from_FbxMatrix_to_XMMATRIX(m_BoneArray[index].mNewPose) = XMMatrixRotationY(fAngle);
	
	XMMatrixInverse(inv,invmat);


	XMMATRIX ret = invmat * Convert_from_FbxMatrix_to_XMMATRIX(m_BoneArray[index].mNewPose);//バインドポーズの逆行列とフレーム姿勢行列をかける。なお、バインドポーズ自体が既に逆行列であるとする考えもある。(FBXの場合は違うが)
	
	
	angle += 1.0f;
	if (angle == 10.0f)
	{
		angle = 0.0f;
	}
	ret = XMMatrixRotationX(angle);
	
	return ret;
}
FBXロード部分

コード:

  
#include "BoneInfo.h"
#include "CFBXLoader.h"
#include "SkeltonAdminister.h"

#include <string.h>
#include <tchar.h>

BoneInfo             * binfo;
SkeletonInfo         * sinfo;
FBXSkeletonAnalizer  * finfo;

FBX_VERTEX* pvVB = nullptr;

namespace FBX_LOADER
{

CFBXLoader::CFBXLoader()
{
	mSdkManager = nullptr;
	mScene = nullptr;
}

CFBXLoader::~CFBXLoader()
{
	Release();
}

//
void CFBXLoader::Release()
{
	m_meshNodeArray.clear();

	if(mImporter)
	{
		mImporter->Destroy();
		mImporter = nullptr;
	}

	if(mScene)
	{
		mScene->Destroy();
		mScene = nullptr;
	}

	if( mSdkManager )
	{
		mSdkManager->Destroy();
		mSdkManager = nullptr;
	}
}

HRESULT CFBXLoader::LoadFBX(const char* filename, const eAXIS_SYSTEM axis)
{
	if(!filename)
		return E_FAIL;

	HRESULT hr = S_OK;

	InitializeSdkObjects( mSdkManager, mScene );
	if(!mSdkManager)
		return E_FAIL;

	// インポータ作成
    int lFileFormat = -1;
    mImporter = FbxImporter::Create(mSdkManager,"");

	if (!mSdkManager->GetIOPluginRegistry()->DetectReaderFileFormat(filename, lFileFormat) )
    {
        // Unrecognizable file format. Try to fall back to FbxImporter::eFBX_BINARY
        lFileFormat = mSdkManager->GetIOPluginRegistry()->FindReaderIDByDescription( "FBX binary (*.fbx)" );;
    }

     // Initialize the importer by providing a filename.
    if(!mImporter || mImporter->Initialize(filename, lFileFormat) == false)
		return E_FAIL;
  
	//
	if( !mImporter || mImporter->Import(mScene) == false )
		return E_FAIL;

	FbxAxisSystem OurAxisSystem = FbxAxisSystem::DirectX;

	if(axis==eAXIS_OPENGL)
		OurAxisSystem = FbxAxisSystem::OpenGL;
		
	// DirectX系
    FbxAxisSystem SceneAxisSystem = mScene->GetGlobalSettings().GetAxisSystem();
	if(SceneAxisSystem != OurAxisSystem)
	{
		FbxAxisSystem::DirectX.ConvertScene(mScene);
	}

    // 単位系の統一
	// 不要でもいいかも
    FbxSystemUnit SceneSystemUnit = mScene->GetGlobalSettings().GetSystemUnit();
    if( SceneSystemUnit.GetScaleFactor() != 1.0 )
    {
        // センチメーター単位にコンバートする
        FbxSystemUnit::cm.ConvertScene( mScene );
    }

	// 三角形化(三角形以外のデータでもコレで安心)
	TriangulateRecursive(mScene->GetRootNode());

	Setup();

	return hr;
}

//
void CFBXLoader::InitializeSdkObjects(FbxManager*& pManager, FbxScene*& pScene)
{
    //The first thing to do is to create the FBX Manager which is the object allocator for almost all the classes in the SDK
    pManager = FbxManager::Create();
    if( !pManager )
    {
        FBXSDK_printf("Error: Unable to create FBX Manager!\n");
        exit(1);
    }
	else FBXSDK_printf("Autodesk FBX SDK version %s\n", pManager->GetVersion());

	//Create an IOSettings object. This object holds all import/export settings.
	FbxIOSettings* ios = FbxIOSettings::Create(pManager, IOSROOT);
	pManager->SetIOSettings(ios);

	//Load plugins from the executable directory (optional)
	FbxString lPath = FbxGetApplicationDirectory();
	pManager->LoadPluginsDirectory(lPath.Buffer());

    //Create an FBX scene. This object holds most objects imported/exported from/to files.
    pScene = FbxScene::Create(pManager, "My Scene");
	if( !pScene )
    {
        FBXSDK_printf("Error: Unable to create FBX scene!\n");
        exit(1);
    }
}

// 三角形化
void CFBXLoader::TriangulateRecursive(FbxNode* pNode)
{
	FbxNodeAttribute* lNodeAttribute = pNode->GetNodeAttribute();

	if (lNodeAttribute)
	{
		if (lNodeAttribute->GetAttributeType() == FbxNodeAttribute::eSkeleton)
		{
			const FbxSkeleton* skeleton = (const FbxSkeleton*)(lNodeAttribute);
			finfo->analize(pNode, skeleton);
		}

	}
    if (lNodeAttribute)
    {
        if (lNodeAttribute->GetAttributeType() == FbxNodeAttribute::eMesh ||
            lNodeAttribute->GetAttributeType() == FbxNodeAttribute::eNurbs ||
            lNodeAttribute->GetAttributeType() == FbxNodeAttribute::eNurbsSurface ||
            lNodeAttribute->GetAttributeType() == FbxNodeAttribute::ePatch)
        {
			FbxGeometryConverter lConverter(pNode->GetFbxManager());
			// これでどんな形状も三角形化
#if 0
            lConverter.TriangulateInPlace(pNode);	// 古い手法
#endif // 0
			lConverter.Triangulate( mScene, true );
        }
    }

	const int lChildCount = pNode->GetChildCount();
    for (int lChildIndex = 0; lChildIndex < lChildCount; ++lChildIndex)
    {
		// 子ノードを探索
        TriangulateRecursive(pNode->GetChild(lChildIndex));
    }
}

//
FbxNode&	CFBXLoader::GetRootNode()
{
	return *mScene->GetRootNode();
}

void CFBXLoader::Setup()
{
	// RootNodeから探索していく
	if(mScene->GetRootNode())
	{
 		SetupNode(mScene->GetRootNode(), "null");
	}
}

void CFBXLoader::SetupNode(FbxNode* pNode, std::string parentName)
{
	int Bonenum = 0;
	int CulusterCnt = 0;

	FbxMesh* lMesh = pNode->GetMesh();
	FbxSkin* lSkin = nullptr;

	//CulusterCnt = lSkin->GetClusterCount();

	if(!pNode)
		return ;

	FBX_MESH_NODE meshNode;
	HRESULT vertexCheck = S_OK;

	meshNode.name = pNode->GetName();
	meshNode.parentName = parentName;

	ZeroMemory( &meshNode.elements, sizeof(MESH_ELEMENTS) );
	
	if(lMesh)
	{
		int lVertexCount = lMesh->GetControlPointsCount();
		
		
		//m_dwNumUV = lMesh->GetTextureUVCount();


		//if (m_dwNumVert<m_dwNumUV)//本サンプルではUVの数だけ頂点が必要
		//{
		//	//共有頂点等で、頂点数が足りない時
		//	MessageBox(0, L"UVの数だけ頂点が必要です(UVを置く場所が必要です)テクスチャーは正しく貼られないと思われます", NULL, MB_OK);
		//}

		if (lVertexCount > 0)
		{
			//スキンを取得

			// 頂点があるならノードにコピー
			CopyVertexData(lMesh, &meshNode);

			const int lChildCount = pNode->GetChildCount();
			for (int lChildIndex = 0; lChildIndex < lChildCount; ++lChildIndex)
			{
				// 子ノードを探索
				TriangulateRecursive(pNode->GetChild(lChildIndex));
			}
		}
		binfo->GetCluster(lVertexCount, lMesh, pvVB);		
	}
	

	// マテリアル
	const int lMaterialCount = pNode->GetMaterialCount();
	for(int i=0;i<lMaterialCount;i++)
	{
		FbxSurfaceMaterial* mat = pNode->GetMaterial(i);
		if(!mat)
			continue;

		FBX_MATERIAL_NODE destMat;
		CopyMatrialData(mat, &destMat);

		meshNode.m_materialArray.push_back(destMat);
	}

	//
	ComputeNodeMatrix(pNode, &meshNode);

	m_meshNodeArray.push_back(meshNode);

	const int lCount = pNode->GetChildCount();
	for (int i = 0; i < lCount; i++)
	{
		SetupNode(pNode->GetChild(i), meshNode.name);
	}
}

//
void CFBXLoader::SetFbxColor(FBX_MATRIAL_ELEMENT& destColor,const FbxDouble3 srcColor)
{
	destColor.a = 1.0f;
	destColor.r = static_cast<float>(srcColor[0]);
	destColor.g = static_cast<float>(srcColor[1]);
	destColor.b = static_cast<float>(srcColor[2]);
}

//
FbxDouble3 CFBXLoader::GetMaterialProperty(
		const FbxSurfaceMaterial * pMaterial,
		const char * pPropertyName,
        const char * pFactorPropertyName,
        FBX_MATRIAL_ELEMENT*			pElement)
{
	pElement->type = FBX_MATRIAL_ELEMENT::ELEMENT_NONE;

    FbxDouble3 lResult(0, 0, 0);
    const FbxProperty lProperty = pMaterial->FindProperty(pPropertyName);
    const FbxProperty lFactorProperty = pMaterial->FindProperty(pFactorPropertyName);
    if (lProperty.IsValid() && lFactorProperty.IsValid())
    {
        lResult = lProperty.Get<FbxDouble3>();
        double lFactor = lFactorProperty.Get<FbxDouble>();
        if (lFactor != 1)
        {
            lResult[0] *= lFactor;
            lResult[1] *= lFactor;
            lResult[2] *= lFactor;
        }

		pElement->type = FBX_MATRIAL_ELEMENT::ELEMENT_COLOR;
    }

    if (lProperty.IsValid())
    {
		int existTextureCount = 0;
        const int lTextureCount = lProperty.GetSrcObjectCount<FbxFileTexture>();

		for(int i=0;i<lTextureCount;i++)
		{
			FbxFileTexture* lFileTexture = lProperty.GetSrcObject<FbxFileTexture>(i);
			if(!lFileTexture)
				continue;

			FbxString uvsetName = lFileTexture->UVSet.Get();
			std::string uvSetString = uvsetName.Buffer();
			std::string filepath = lFileTexture->GetFileName();

			pElement->textureSetArray[uvSetString].push_back(filepath);
			existTextureCount++;
		}
	
		const int lLayeredTextureCount = lProperty.GetSrcObjectCount<FbxLayeredTexture>();

		for(int i=0;i<lLayeredTextureCount;i++)
		{
			FbxLayeredTexture* lLayeredTexture = lProperty.GetSrcObject<FbxLayeredTexture>(i);

			const int lTextureFileCount = lLayeredTexture->GetSrcObjectCount<FbxFileTexture>();

			for(int j=0;j<lTextureFileCount;j++)
			{
				FbxFileTexture* lFileTexture = lLayeredTexture->GetSrcObject<FbxFileTexture>(j);
				if(!lFileTexture)
					continue;

				FbxString uvsetName = lFileTexture->UVSet.Get();
				std::string uvSetString = uvsetName.Buffer();
				std::string filepath = lFileTexture->GetFileName();

				pElement->textureSetArray[uvSetString].push_back(filepath);
				existTextureCount++;
			}
		}

		if(existTextureCount > 0)
		{
			if(pElement->type == FBX_MATRIAL_ELEMENT::ELEMENT_COLOR)
				pElement->type = FBX_MATRIAL_ELEMENT::ELEMENT_BOTH;
			else
				pElement->type = FBX_MATRIAL_ELEMENT::ELEMENT_TEXTURE;
		}
     }

    return lResult;
}

//
void CFBXLoader::CopyMatrialData(FbxSurfaceMaterial* mat, FBX_MATERIAL_NODE* destMat)
{
	if(!mat)
		return ;

	if ( mat->GetClassId().Is( FbxSurfaceLambert::ClassId ) ) 
	{
		destMat->type = FBX_MATERIAL_NODE::MATERIAL_LAMBERT;
	}
	else if ( mat->GetClassId().Is( FbxSurfacePhong::ClassId ) ) 
	{
		destMat->type = FBX_MATERIAL_NODE::MATERIAL_PHONG;
	}

	const FbxDouble3 lEmissive = GetMaterialProperty(mat,
		FbxSurfaceMaterial::sEmissive, FbxSurfaceMaterial::sEmissiveFactor, &destMat->emmisive);
	SetFbxColor(destMat->emmisive, lEmissive );

    const FbxDouble3 lAmbient = GetMaterialProperty(mat,
        FbxSurfaceMaterial::sAmbient, FbxSurfaceMaterial::sAmbientFactor, &destMat->ambient);
	SetFbxColor(destMat->ambient, lAmbient );

    const FbxDouble3 lDiffuse = GetMaterialProperty(mat,
        FbxSurfaceMaterial::sDiffuse, FbxSurfaceMaterial::sDiffuseFactor, &destMat->diffuse);
	SetFbxColor(destMat->diffuse, lDiffuse );

    const FbxDouble3 lSpecular = GetMaterialProperty(mat,
        FbxSurfaceMaterial::sSpecular, FbxSurfaceMaterial::sSpecularFactor, &destMat->specular);
	SetFbxColor(destMat->specular, lSpecular );

	//
	FbxProperty lTransparencyFactorProperty = mat->FindProperty(FbxSurfaceMaterial::sTransparencyFactor);
	if(lTransparencyFactorProperty.IsValid())
	{
		double lTransparencyFactor = lTransparencyFactorProperty.Get<FbxDouble>();
		destMat->TransparencyFactor = static_cast<float>(lTransparencyFactor);
	}

	// Specular Power
    FbxProperty lShininessProperty = mat->FindProperty(FbxSurfaceMaterial::sShininess);
    if (lShininessProperty.IsValid())
    {
        double lShininess = lShininessProperty.Get<FbxDouble>();
		destMat->shininess = static_cast<float>(lShininess);
	}
}

//
void CFBXLoader::ComputeNodeMatrix(FbxNode* pNode, FBX_MESH_NODE* meshNode)
{
	if(!pNode || !meshNode)
	{
		return ;
	}

	FbxAnimEvaluator* lEvaluator = mScene->GetAnimationEvaluator();
	FbxMatrix lGlobal;
	lGlobal.SetIdentity();

	if(pNode != mScene->GetRootNode())
	{
		lGlobal= lEvaluator->GetNodeGlobalTransform(pNode);

		FBXMatrixToFloat16( &lGlobal, meshNode->mat4x4 );
	}
	else
	{
		FBXMatrixToFloat16( &lGlobal, meshNode->mat4x4 );
	}
}

//
void CFBXLoader::CopyVertexData(FbxMesh*	pMesh, FBX_MESH_NODE* meshNode)
{
	if(!pMesh)
		return ;

	int lPolygonCount = pMesh->GetPolygonCount();

	FbxVector4 pos, nor;
	
	meshNode->elements.numPosition = 1;
	meshNode->elements.numNormal = 1;

	unsigned int indx = 0;
	
	for(int i=0;i<lPolygonCount;i++)
	{
		// ポリゴン内の頂点数(一応、三角形化してるので3点のはずだがチェック)
		int lPolygonsize = pMesh->GetPolygonSize(i);

		for(int pol=0;pol<lPolygonsize;pol++)
		{
			int index = pMesh->GetPolygonVertex(i, pol);
			meshNode->indexArray.push_back(indx);

			pos = pMesh->GetControlPointAt(index);
			pMesh->GetPolygonVertexNormal(i,pol,nor);

			meshNode->m_positionArray.push_back( pos );
			meshNode->m_normalArray.push_back( nor );
	
			++indx;
		}

		/*if (lVertexCount == lMesh->GetControlPointsCount)
		{

		}
		else
		{
		MessageBox(nullptr, _T("頂点数が一致しません"), nullptr, MB_OK);
		}*/
	}

	// UV処理(UVは2つ以上ある場合があるので別処理)
	FbxStringList	uvsetName;
	pMesh->GetUVSetNames(uvsetName);
	int numUVSet = uvsetName.GetCount();
	meshNode->elements.numUVSet = numUVSet;

	bool unmapped = false;

	for(int uv=0;uv<numUVSet;uv++)
	{
		meshNode->uvsetID[uvsetName.GetStringAt(uv)] = uv;
		for(int i=0;i<lPolygonCount;i++)
		{
			int lPolygonsize = pMesh->GetPolygonSize(i);

			for(int pol=0;pol<lPolygonsize;pol++)
			{
				FbxString name = uvsetName.GetStringAt(uv);
				FbxVector2 texCoord;
				pMesh->GetPolygonVertexUV( i, pol, name, texCoord, unmapped);
				meshNode->m_texcoordArray.push_back(texCoord);
			}
		}
	}
}

FBX_MESH_NODE& CFBXLoader::GetNode(const unsigned int id)
{
	return m_meshNodeArray[id];
}

}	// FBX_LOADER
どうかご教授いただけたらと思います。
よろしくお願いします。
最後に編集したユーザー イフリナ=フリード on 2015年1月30日(金) 12:18 [ 編集 1 回目 ]

イフリナ=フリード
記事: 5
登録日時: 10年前

Re: Kinectを使ってキャラクターを動かす

#2

投稿記事 by イフリナ=フリード » 10年前

載せきれなかったHlslの中身です。

simpleRenderInstancingVS.hlsl

struct PerInstanceData
{
matrix instanceMat;
};

StructuredBuffer<PerInstanceData> g_pInstanceData :register( t0 );

cbuffer cbGlobal : register( b0 )
{
matrix World;
matrix View;
matrix Projection;
matrix WVP;
};

struct VS_INPUT
{
float4 Pos : POSITION;
float3 Nor : NORMAL;
float2 Tex : TEXCOORD;
};

struct VS_OUTPUT
{
float4 Pos : SV_POSITION;
float2 Tex : TEXCOORD;
};

VS_OUTPUT vs_main(VS_INPUT input, uint instanceID : SV_InstanceID)
{
VS_OUTPUT output;
matrix instanceWVP = mul(Projection, View);
instanceWVP = mul(instanceWVP, World);
instanceWVP = mul(instanceWVP, g_pInstanceData[instanceID].instanceMat);

instanceWVP = transpose(instanceWVP);

output.Pos = mul( input.Pos, instanceWVP );
output.Tex = input.Tex;
return output;
}

simpleRenderPS.hlsl

Texture2D txDiffuse : register( t0 );
SamplerState samLinear : register( s0 );

cbuffer cbMaterial : register( b0 )
{
float4 ambient;
float4 diffuse;
float3 specular;
float power;
float4 emmisive;
};

struct PS_INPUT
{
float4 Pos : SV_POSITION;
float3 Nor : NORMAL;
float2 Tex : TEXCOORD;
};

float4 PS( PS_INPUT input) : SV_Target
{
return txDiffuse.Sample( samLinear, input.Tex );
// return diffuse;
}

simpleRenderVS.hlsl

cbuffer cbGlobal : register( b0 )
{
matrix World;
matrix View;
matrix Projection;
matrix WVP;
};

struct VS_INPUT
{
float4 Pos : POSITION;
float3 Nor : NORMAL;
float2 Tex : TEXCOORD;
};

struct VS_OUTPUT
{
float4 Pos : SV_POSITION;
float2 Tex : TEXCOORD;
};

VS_OUTPUT vs_main(VS_INPUT input, uint instanceID : SV_InstanceID)
{
VS_OUTPUT output;

output.Pos = mul( input.Pos, WVP );
output.Tex = input.Tex;
return output;
}

SkinmeshforPixelShaders.hlsl

Texture2D txDiffuse : register( t0 );
SamplerState samLinear : register( s0 );

//#include"SkinmeshforPixelShader.hlsli"

struct SCBScene
{
matrix mtxProj;
matrix mtxView;
};

struct SCBLight
{
float4 vDirLight[4];
float4 colDirLight[4];
float4 vHemiDir;
float4 colHemiSky;
float4 colHemiGrd;
float4 posPLight[4];
float4 colPLight[4];
float4 prmPLight[4];
};

struct SBCModel
{
float4 colModel;
};

struct SBCObject
{
matrix mtxWorld;
};

struct SBCBoneMatrix
{
matrix mtxBone[4];
};

cbuffer CB1 : register(b1)
{
SCBScene Scene;
};


cbuffer CB2 : register(b2)
{
SCBLight Light;
};

cbuffer CB3 : register(b3)
{
SBCModel Model;
};

cbuffer CB4 : register(b4)
{
SBCObject Object;
}

cbuffer CB5 : register(b5)
{
float4 vDiffuse;
}
cbuffer CB7 : register(b7)
{
float4x3 BoneMatrix[2] : packoffset(c0);
float4x3 BoneMatrixDmmy[253] : packoffset(c6);
float4x3 BoneMatrixEnd : packoffset(c765);
}
float4x3 getBoneMatrix(int idx)
{
return BoneMatrix[idx];
}

cbuffer cbMaterial : register( b0 )
{
float4 ambient;
float4 diffuse;
float3 specular;
float power;
float4 emmisive;
};

struct VS_INPUT
{
float4 Pos : POSITION;
float3 Nor : NORMAL;
float2 Tex : TEXCOORD0;
uint4 Bidx : BONE_INDEX;
uint4 Bwgt : BONE_WEIGHT;
};
struct PS_INPUT
{
float4 Pos : SV_POSITION;
float3 Nor : NORMAL;
float2 Tex : TEXCOORD;
};

PS_INPUT VSBlend(VS_INPUT input)
{
PS_INPUT output = (PS_INPUT)0;
float4 pos = input.Pos;
float3 bpos0 = input.Bwgt[0] * mul(pos, getBoneMatrix(input.Bidx.x));
float3 bpos1 = input.Bwgt[1] * mul(pos, getBoneMatrix(input.Bidx.y));
float3 bpos2 = input.Bwgt[2] * mul(pos, getBoneMatrix(input.Bidx.z));
float3 bpos3 = input.Bwgt[3] * mul(pos, getBoneMatrix(input.Bidx.w));
pos.xyz = (bpos0.xyz + bpos1.xyz + bpos2.xyz + bpos3.xyz) / 100;

pos = mul(pos, Object.mtxWorld);
pos = mul(pos, Scene.mtxView);
output.Pos = mul(pos, Scene.mtxProj);
output.Tex = input.Tex;
output.Nor = input.Nor;
return output;
//return txDiffuse.Sample( samLinear, input.Tex );
// return diffuse;
}
// ---------------------------
//輪郭線用ボーン変形&頂点ブレンド
PS_INPUT vsOutlineBlend(VS_INPUT input)
{
PS_INPUT output = (PS_INPUT)0;
float4 pos = input.Pos;
pos.xyz += input.Nor*0.05;
float3 bpos0 = input.Bwgt[0] * mul(pos, getBoneMatrix(input.Bidx.x));
float3 bpos1 = input.Bwgt[1] * mul(pos, getBoneMatrix(input.Bidx.y));
float3 bpos2 = input.Bwgt[2] * mul(pos, getBoneMatrix(input.Bidx.z));
float3 bpos3 = input.Bwgt[3] * mul(pos, getBoneMatrix(input.Bidx.w));
pos.xyz = (bpos0.xyz + bpos1.xyz + bpos2.xyz + bpos3.xyz) / 100;
pos = mul(pos, Object.mtxWorld);
pos = mul(pos, Scene.mtxView);
output.Pos = mul(pos, Scene.mtxProj);
output.Tex = input.Tex;
return output;
}
//-------------------------
//ピクセルシェーダ
float4 PS(PS_INPUT input) : SV_Target
{
float3 nor = normalize(input.Nor);

float l = saturate(dot(nor, Light.vDirLight[0].xyz));
if (l > 0.25){
l = 1;
}
else{
l = 0.9;
}
return float4(l, l, l, 1)*txDiffuse.Sample(samLinear, input.Tex)*vDiffuse;
}
//-------------------------
//輪郭線用ピクセルシェーダ
float4 psBlack(PS_INPUT input) : SV_Target
{
return float4(0.5, 0.5, 0.5, 1)*txDiffuse.Sample(samLinear, input.Tex)*vDiffuse;
}

//-------------------------
//シェーダエフェクト定義
#ifdef ZGFX

technique BasicBlend
{
pass P0
{
CullMode = FRONT;
VertexShader = compile vs_4_0 vsOutlineBlend();
PixelShader = compile ps_4_0 psBlack();
}
pass P1
{
CullMode = NONE;
VertexShader = compile vs_4_0 vsBasicBlend();
PixelShader = compile ps_4_0 psBasic();
}
}

#endif

閉鎖

“C言語何でも質問掲示板” へ戻る