Kayns Lab.

プログラミング、魚釣り、MUGEN、たまにゲーム  淫夢要素はありません
Information
あまり活動してませんが自分のニコニコミュニティです
Elecbyte様が403エラーで
入れない間の救済措置

私のワンドラで
Winmugen~MUGEN 1.1beta1
までを公開中です。

本体のダウンロード
クリエイトチーム
A.G.Factory
@AGFactory_info

スポンサーサイト

上記の広告は1ヶ月以上更新のないブログに表示されています。
新しい記事を書く事で広告が消せます。
[ --/--/-- --:-- ] スポンサー広告 | TB(-) | CM(-)

【Fate/Grand Order】 ダメージシミュアプリを作った 2



こちらの動画でギルガメッシュの神性分ダメージが貫通しているのを確認できます。
固定ダメージは分割されるらしいので攻撃回数は関係ありませんでした。僕が何か見間違えたのかもしれないですね・・・
多少の欠陥がないとプログラミングした甲斐がないですから、新たな発見ができて良かったです。
スポンサーサイト
[ 2017/06/08 01:14 ] ゲーム | TB(0) | CM(0)

【Fate/Grand Order】ダメージシミュアプリを作った



いつも使ってるダメージシミュサイトの情報が古いので解析Wikiの計算式を参考にして自分で作りました。
ちなみにシミュレートサンプルはうちの100レベきよひーです。
使用言語は使い慣れてるVB.Netです。あまり好みじゃないのでC#が使いたかったですが、こっちの言語仕様はあまり理解してないので・・・
計算式入力後のコンパイル1発目からうまいこと計算できてたので逆にどこか間違ってないか不安で仕方ないのですが、画像右側に載せてるシミュサイトの乱数0.9倍と値が同じなので計算結果としては正しいかと思います。乱数1.1倍の誤差は僕の作ったアプリでは1.0999倍にしているからだと思います。解析情報では1.0999倍となっていたのでこちらを適用させました。
それと、ダメージプラスバフはネロ祭のジークフリート戦をやった人なら分かると思いますが、攻撃1つ1つに適用されるので攻撃回数分のダメージを計算するべきだと考えました。なので、他のシミュサイトにはない項目も追加されています。
特攻周りの処理が、シミュサイトと比較しているとけっこうあいまいだったのでその場しのぎの処理にしています。解析では、宝具特攻は特性特攻と状態特攻の乗算だったりしてますが、実際に2つの特効持ちなんていないのでひとまとめにしてます。

作った感想としては、まあまあ納得のいくものができたと思います。公開は今のところ考えてないです。(要望があれば・・・)
プログラマとしての感想は、フォームを作るのやっぱりめんどくせえってことですかね・・・。特に宝具使用チェックを入れた時に一部の項目を入力無効にするなどユーザ視点で考えるとキリがないので。
普段から3Dプログラミングしかやってないのでイベントドリブンにはどうしても慣れないです。あとは計算結果をもう少し見やすく改良していきたいです。
[ 2017/06/04 22:41 ] ゲーム | TB(0) | CM(0)

【DirectX11】FBXファイルから剛体メッシュのロード.mp12【FBX SDK 2016】

頂点整合・データ作成・マテリアル情報読み込み

//------------------------------------------------------------------------------------------------------
//頂点整合・データ作成
//------------------------------------------------------------------------------------------------------

auto MeshNode = Mesh->GetNode(); //ノードを取得
int MatCount = MeshNode->GetMaterialCount(); //メッシュのマテリアル数を取得
int MatElemCount = Mesh->GetElementMaterialCount();
MeshObj->MeshInfo.reserve(MatCount); //マテリアル数分の領域確保

//マテリアルインデックスで頂点情報を整合
if(MatCount > 1){
for(int emc = 0; emc < MatElemCount; emc++){
//マテリアル要素を取得
FbxGeometryElementMaterial* leMat = Mesh->GetElementMaterial(emc);

//マテリアル要素が存在する場合
if(leMat){

if(leMat->GetMappingMode() == FbxGeometryElement::eByPolygon && leMat->GetReferenceMode() == FbxGeometryElement::eIndexToDirect){
vector<int> MatIndexCount(MatCount);
//各ポリゴンをマテリアル別にカウント
int IndexArrayCount = leMat->GetIndexArray().GetCount();
for(int iac = 0; iac < IndexArrayCount; iac++){
MatIndexCount[leMat->GetIndexArray().GetAt(iac)]++;
}

//領域確保
for(int idx = 0; idx < MatCount; idx++){
MESH_INFO meshinfo;
meshinfo.VertexInfo.Pos.reserve(MatIndexCount[idx]);
meshinfo.VertexInfo.Normal.reserve(MatIndexCount[idx]);
meshinfo.VertexInfo.Color.reserve(MatIndexCount[idx]);
meshinfo.VertexInfo.UV.reserve(MatIndexCount[idx]);
meshinfo.VertexInfo.VertexCount = MatIndexCount[idx] * 3;
MeshObj->MeshInfo.push_back(meshinfo);
}

//マテリアル振り分け
for(int iac = 0; iac < IndexArrayCount; iac++){
int midx = leMat->GetIndexArray().GetAt(iac);
MeshObj->MeshInfo[midx].VertexInfo.Pos.push_back( {MeshPos[iac * 3].x, MeshPos[iac * 3].y, MeshPos[iac * 3].z});
MeshObj->MeshInfo[midx].VertexInfo.Normal.push_back({MeshNormal[iac * 3].x, MeshNormal[iac * 3].y, MeshNormal[iac * 3].z});
MeshObj->MeshInfo[midx].VertexInfo.Color.push_back( {MeshColor[iac * 3].r, MeshColor[iac * 3].g, MeshColor[iac * 3].b, MeshColor[iac * 3].a});
MeshObj->MeshInfo[midx].VertexInfo.UV.push_back( {MeshUV[iac * 3].u, MeshUV[iac * 3].v});

MeshObj->MeshInfo[midx].VertexInfo.Pos.push_back( {MeshPos[iac * 3 + 2].x, MeshPos[iac * 3 + 2].y, MeshPos[iac * 3 + 2].z});
MeshObj->MeshInfo[midx].VertexInfo.Normal.push_back({MeshNormal[iac * 3 + 2].x, MeshNormal[iac * 3 + 2].y, MeshNormal[iac * 3 + 2].z});
MeshObj->MeshInfo[midx].VertexInfo.Color.push_back( {MeshColor[iac * 3 + 2].r, MeshColor[iac * 3 + 2].g, MeshColor[iac * 3 + 2].b, MeshColor[iac * 3 + 2].a});
MeshObj->MeshInfo[midx].VertexInfo.UV.push_back( {MeshUV[iac * 3 + 2].u, MeshUV[iac * 3 + 2].v});

MeshObj->MeshInfo[midx].VertexInfo.Pos.push_back( {MeshPos[iac * 3 + 1].x, MeshPos[iac * 3 + 1].y, MeshPos[iac * 3 + 1].z});
MeshObj->MeshInfo[midx].VertexInfo.Normal.push_back({MeshNormal[iac * 3 + 1].x, MeshNormal[iac * 3 + 1].y, MeshNormal[iac * 3 + 1].z});
MeshObj->MeshInfo[midx].VertexInfo.Color.push_back( {MeshColor[iac * 3 + 1].r, MeshColor[iac * 3 + 1].g, MeshColor[iac * 3 + 1].b, MeshColor[iac * 3 + 1].a});
MeshObj->MeshInfo[midx].VertexInfo.UV.push_back( {MeshUV[iac * 3 + 1].u, MeshUV[iac * 3 + 1].v});
}
}
}
}
}else{
MESH_INFO meshinfo;

//領域確保
meshinfo.VertexInfo.Pos.reserve(IndexCount);
meshinfo.VertexInfo.Normal.reserve(IndexCount);
meshinfo.VertexInfo.Color.reserve(IndexCount);
meshinfo.VertexInfo.UV.reserve(IndexCount);
meshinfo.VertexInfo.VertexCount = IndexCount;

unsigned int idx = IndexCount / 3;
for(unsigned int ic = 0; ic < idx; ic++){
meshinfo.VertexInfo.Pos.push_back( {MeshPos[ic * 3].x, MeshPos[ic * 3].y, MeshPos[ic * 3].z});
meshinfo.VertexInfo.Normal.push_back({MeshNormal[ic * 3].x, MeshNormal[ic * 3].y, MeshNormal[ic * 3].z});
meshinfo.VertexInfo.Color.push_back( {MeshColor[ic * 3].r, MeshColor[ic * 3].g, MeshColor[ic * 3].b, MeshColor[ic * 3].a});
meshinfo.VertexInfo.UV.push_back( {MeshUV[ic * 3].u, MeshUV[ic * 3].v});

meshinfo.VertexInfo.Pos.push_back( {MeshPos[ic * 3 + 2].x, MeshPos[ic * 3 + 2].y, MeshPos[ic * 3 + 2].z});
meshinfo.VertexInfo.Normal.push_back({MeshNormal[ic * 3 + 2].x, MeshNormal[ic * 3 + 2].y, MeshNormal[ic * 3 + 2].z});
meshinfo.VertexInfo.Color.push_back( {MeshColor[ic * 3 + 2].r, MeshColor[ic * 3 + 2].g, MeshColor[ic * 3 + 2].b, MeshColor[ic * 3 + 2].a});
meshinfo.VertexInfo.UV.push_back( {MeshUV[ic * 3 + 2].u, MeshUV[ic * 3 + 2].v});

meshinfo.VertexInfo.Pos.push_back( {MeshPos[ic * 3 + 1].x, MeshPos[ic * 3 + 1].y, MeshPos[ic * 3 + 1].z});
meshinfo.VertexInfo.Normal.push_back({MeshNormal[ic * 3 + 1].x, MeshNormal[ic * 3 + 1].y, MeshNormal[ic * 3 + 1].z});
meshinfo.VertexInfo.Color.push_back( {MeshColor[ic * 3 + 1].r, MeshColor[ic * 3 + 1].g, MeshColor[ic * 3 + 1].b, MeshColor[ic * 3 + 1].a});
meshinfo.VertexInfo.UV.push_back( {MeshUV[ic * 3 + 1].u, MeshUV[ic * 3 + 1].v});
}

MeshObj->MeshInfo.push_back(meshinfo);
}


//------------------------------------------------------------------------------------------------------
//マテリアル情報読み込み
//------------------------------------------------------------------------------------------------------

for(int mc = 0; mc < MatCount; mc++){
//マテリアルを取得
auto Mat = MeshNode->GetMaterial(mc);
auto Prop = Mat->FindProperty(FbxSurfaceMaterial::sDiffuse);

unsigned int TexCount;

//FbxFileTextureの数を取得
TexCount = static_cast<unsigned int>(Prop.GetSrcObjectCount<FbxFileTexture>());

//FbxFileTextureが存在する場合
if(TexCount > 0){
for(unsigned int ftc = 0; ftc < TexCount; ftc++){
//テクスチャ情報を読み込む
auto FileTex = Prop.GetSrcObject<FbxFileTexture>(ftc);

if(FileTex){
//ファイル名を取得
string TexName = FileTex->GetRelativeFileName();
//相対パスを取得
wstring tp = curdir + conv(TexName);

//UV名を取得
string uvSetName = FileTex->UVSet.Get().Buffer();
//同じUV名がなければ格納する
if(find(MeshObj->UVSetName.begin(), MeshObj->UVSetName.end(), uvSetName) != MeshObj->UVSetName.end()){
MeshObj->UVSetName.push_back(uvSetName);
}

//Mapへ既に読み込まれていないか確認
MeshObj->MeshInfo[mc].MaterialInfo.Texture = TexMap.Get(tp.c_str());
//テクスチャが存在しない場合
if(!MeshObj->MeshInfo[mc].MaterialInfo.Texture){
//相対パスをセット
MeshObj->MeshInfo[mc].MaterialInfo.TexPath = tp;
//多重読み込み防止のためMapにセット
MeshObj->MeshInfo[mc].MaterialInfo.Texture = TexMap.Set(tp.c_str());
//テクスチャを読み込む
MeshObj->MeshInfo[mc].MaterialInfo.Texture->Load(MeshObj->MeshInfo[mc].MaterialInfo.TexPath);
}

MeshObj->MeshInfo[mc].MaterialInfo.TexSRV = MeshObj->MeshInfo[mc].MaterialInfo.Texture->GetShaderResourceView();

D3D11_SAMPLER_DESC samplerdesc;
samplerdesc.Filter = D3D11_FILTER_MIN_MAG_MIP_LINEAR;
samplerdesc.AddressU = D3D11_TEXTURE_ADDRESS_WRAP;
samplerdesc.AddressV = D3D11_TEXTURE_ADDRESS_WRAP;
samplerdesc.AddressW = D3D11_TEXTURE_ADDRESS_WRAP;
samplerdesc.MipLODBias = 0.0f;
samplerdesc.MaxAnisotropy = 2;
samplerdesc.ComparisonFunc = D3D11_COMPARISON_NEVER;
samplerdesc.BorderColor[0] = 0.0f;
samplerdesc.BorderColor[1] = 0.0f;
samplerdesc.BorderColor[2] = 0.0f;
samplerdesc.BorderColor[3] = 0.0f;
samplerdesc.MinLOD = -FLT_MAX;
samplerdesc.MaxLOD = FLT_MAX;

HRESULT hr = Graphics.GetDevice()->CreateSamplerState(&samplerdesc, &MeshObj->MeshInfo[mc].MaterialInfo.SamplerState);
if(FAILED(hr)){
//サンプラステートの作成に失敗
}
}
}
}
}

頂点整合処理では、2枚以上のテクスチャが存在する場合のデータ並び替えと、反転した描画順を正しくするため2番目と3番目の入れ替えを同時にやっています。
まずは、どのポリゴンにどのテクスチャが適用されているかの情報が格納されているマテリアルインデックスを利用して、1つのオブジェクトをマテリアルごとに分割します。
例えるなら頭と体は別テクスチャが適用されているがモデルとしては1セットになっているbodyというオブジェクトを頭のオブジェクトと体のオブジェクトに分割します。
データはインデックス順に並び替えられていますので、分割する際に先頭から3つずつ取り出していきますが、その時にオフセットの順番を変えて2番目と3番目を入れ替えながら格納していきます。
マテリアルが1つの場合は描画順を正しながら移し替えていく作業となります。

解説としてはこんなところです。
もう少しモチベがあれば昨年中にまとめられたと思うんですが・・・
ここにまとめたやり方は他にどこにもまとめられてなかったので、まさに実験の繰り返しでした。
以前に書いたスキンメッシュの実装が不安というのはオブジェクトを複数に分割したところがスキンメッシュに影響するんじゃないかということです。
FBXファイルをVSで開けるようにするぐらいなら読み込み実行もできるようにして欲しかったんですがね・・・
[ 2017/01/14 22:44 ] プログラミング | TB(0) | CM(0)

【DirectX11】FBXファイルから剛体メッシュのロード.mp11【FBX SDK 2016】

法線情報・頂点カラー情報・UV情報読み込み

//------------------------------------------------------------------------------------------------------
//法線情報読み込み
//------------------------------------------------------------------------------------------------------
for(unsigned int nec = 0; nec < NormalElemCount; nec++){
auto Normal = Mesh->GetElementNormal(nec); //メッシュからNormal要素を取得
auto NormalMapping = Normal->GetMappingMode(); //マッピングモードを取得
auto NormalReference = Normal->GetReferenceMode(); //リファレンスモードを取得

//PolygonVertex -- Direct
//インデックスごとに格納されている場合の処理
if((NormalMapping == FbxGeometryElement::eByPolygonVertex) && (NormalReference == FbxGeometryElement::eDirect)){
for(unsigned int nc = 0; nc < IndexCount; nc++){

XMFLOAT3 convert;

convert.x = static_cast<float>(Normal->GetDirectArray().GetAt(nc)[0]);
convert.y = static_cast<float>(Normal->GetDirectArray().GetAt(nc)[1]);
convert.z = static_cast<float>(Normal->GetDirectArray().GetAt(nc)[2]);

XMStoreFloat3(&convert, XMVector3TransformNormal(XMLoadFloat3(&convert), Rot));
XMStoreFloat3(&convert, XMVector3TransformNormal(XMLoadFloat3(&convert), Scale));

MeshNormal[nc].x = convert.x;
MeshNormal[nc].y = convert.y;
MeshNormal[nc].z = convert.z;
}

continue;
}
}


//------------------------------------------------------------------------------------------------------
//頂点カラー情報読み込み
//------------------------------------------------------------------------------------------------------
for(unsigned int vcc = 0; vcc < ColorElemCount; vcc++){
auto Color = Mesh->GetElementVertexColor(vcc);
auto VColorMapping = Color->GetMappingMode();
auto VColorReference = Color->GetReferenceMode();

if(VColorMapping == FbxGeometryElement::eByPolygonVertex && VColorReference == FbxGeometryElement::eIndexToDirect){
int IndexCount = Color->GetIndexArray().GetCount();

for(int vcic = 0; vcic < IndexCount; vcic++){
int idx = Color->GetIndexArray().GetAt(vcic);
MeshColor[vcic].r = static_cast<float>(Color->GetDirectArray().GetAt(idx)[0]);
MeshColor[vcic].g = static_cast<float>(Color->GetDirectArray().GetAt(idx)[1]);
MeshColor[vcic].b = static_cast<float>(Color->GetDirectArray().GetAt(idx)[2]);
MeshColor[vcic].a = static_cast<float>(Color->GetDirectArray().GetAt(idx)[3]);
}
}
}


//------------------------------------------------------------------------------------------------------
//UV情報読み込み
//------------------------------------------------------------------------------------------------------
for(unsigned int uvec = 0; uvec < UVElemCount; uvec++){
auto UV = Mesh->GetElementUV(uvec);
auto UVMapping = UV->GetMappingMode();
auto UVReference = UV->GetReferenceMode();
MeshObj->UVSetName.push_back(UV->GetName());

//PolygonVertex -- IndexToDirect
if((UVMapping == FbxGeometryElement::eByPolygonVertex) && (UVReference == FbxGeometryElement::eIndexToDirect)){
int UVIndexCount = UV->GetIndexArray().GetCount();
for(int uvic = 0; uvic < UVIndexCount; uvic++){
int idx = UV->GetIndexArray().GetAt(uvic);
MeshUV[uvic].u = static_cast<float>(UV->GetDirectArray().GetAt(idx)[0]);
MeshUV[uvic].v = 1.0f - static_cast<float>(UV->GetDirectArray().GetAt(idx)[1]);
}

continue;
}
}

この辺は特に変更がない箇所ですが、法線情報は頂点情報と同じく回転・反転させてやります。
[ 2017/01/14 21:38 ] プログラミング | TB(0) | CM(0)

【DirectX11】FBXファイルから剛体メッシュのロード.mp10【FBX SDK 2016】

初期化

//------------------------------------------------------------------------------------------------------
//初期化
//------------------------------------------------------------------------------------------------------

unsigned int VertexCount; //頂点数
unsigned int IndexCount; //インデックス数
unsigned int NormalElemCount; //法線セット数
unsigned int ColorElemCount; //頂点色セット数
unsigned int UVElemCount; //UVセット数

//各種バッファ
vector<VERTEX_XYZ> MeshPos; //頂点情報バッファ
vector<int> MeshIndex; //インデックス情報バッファ
vector<VERTEX_XYZ> MeshNormal; //法線情報バッファ
vector<VERTEX_RGBA> MeshColor; //頂点色情報バッファ
vector<VERTEX_UV> MeshUV; //UV情報バッファ

VertexCount = Mesh->GetControlPointsCount(); //頂点セット数を取得
IndexCount = Mesh->GetPolygonVertexCount(); //インデックスセット数を取得
NormalElemCount = Mesh->GetElementNormalCount(); //法線セット数を取得 (通常:1)
ColorElemCount = Mesh->GetElementVertexColorCount(); //頂点カラーセット数を取得
UVElemCount = Mesh->GetElementUVCount(); //UVセット数を取得 TODO 現段階ではUV1つのみ対応

MeshPos.resize(IndexCount,{0.0f, 0.0f, 0.0f}); //頂点セットの領域を確保
MeshIndex.resize(IndexCount, 0); //インデックスセットの領域を確保
MeshNormal.resize(IndexCount,{0.0f, 0.0f, 0.0f}); //法線セットの領域を確保
MeshColor.resize(IndexCount, {0.0f, 0.0f, 0.0f, 0.0f}); //頂点カラーセットの領域を確保
MeshUV.resize(IndexCount, {0.0f, 0.0f}); //UVセットの領域を確保


インデックス読み込み→頂点情報読み込み

//------------------------------------------------------------------------------------------------------
//インデックス情報読み込み
//------------------------------------------------------------------------------------------------------
int* index = Mesh->GetPolygonVertices();
for(unsigned int ic = 0; ic < IndexCount; ic++){
//インデックス情報がそのまま格納されているので抽出
MeshIndex[ic] = index[ic];
}


//------------------------------------------------------------------------------------------------------
//頂点情報読み込み
//------------------------------------------------------------------------------------------------------

//DirectX限定 頂点・法線回転 TODO
XMMATRIX Rot;
Rot = XMMatrixIdentity();
Rot = XMMatrixRotationX(ToRadian(-90));

XMMATRIX Scale;
Scale = XMMatrixIdentity();
Scale = XMMatrixScaling(1.0f, 1.0f, -1.0f);

{
//頂点取得→回転→バッファに格納→インデックス順に格納

//インデックス変換用バッファ
vector<VERTEX_XYZ> pos;
pos.reserve(VertexCount);

//回転・反転させてバッファに格納
for(unsigned int vc = 0; vc < VertexCount; vc++){
auto CtrlPoint = Mesh->GetControlPointAt(vc);

XMFLOAT3 convert;

convert.x = static_cast<float>(CtrlPoint[0]);
convert.y = static_cast<float>(CtrlPoint[1]);
convert.z = static_cast<float>(CtrlPoint[2]);

XMStoreFloat3(&convert, XMVector3TransformNormal(XMLoadFloat3(&convert), Rot));
XMStoreFloat3(&convert, XMVector3TransformNormal(XMLoadFloat3(&convert), Scale));

VERTEX_XYZ buf;

buf.x = convert.x;
buf.y = convert.y;
buf.z = convert.z;

pos.push_back(buf);
}

//インデックス順に格納
for(unsigned int vc = 0; vc < IndexCount; vc++){
MeshPos[vc].x = pos[MeshIndex[vc]].x;
MeshPos[vc].y = pos[MeshIndex[vc]].y;
MeshPos[vc].z = pos[MeshIndex[vc]].z;
}
}


頂点情報読み込みの前にX-90°にする回転行列とZ反転の拡大行列を作成します。
そして回転→拡大の順に適用させてバッファに保存します。

私が学生の時は回転と拡大はどちらが先でもよいと教わった記憶がありますが、軸反転の拡大行列が入っていると拡大→回転の順では明らかに結果がおかしくなるので注意しましょう。
加えて補足すると回転→拡大→移動の順で行列を適用させます。
[ 2017/01/13 22:39 ] プログラミング | TB(0) | CM(0)
Admin Info

kayns

Author:kayns
Twitter




    


『ましろ色シンフォニー *mutsu-no-hana』応援中です!

Access Counter
Link
Site Search
Friend Request Form
QR
QR


上記広告は1ヶ月以上更新のないブログに表示されています。新しい記事を書くことで広告を消せます。