Closed dudedude1234 closed 5 years ago
A lot of that code is working with the legacy "Direct3D Effects" technology from Direct3D 9--for Direct3D 11 there is an Effects 11, which is a different solution for shader management than DirectXTK's BasicEffect
, SkinnedEffect
, etc.
The main issue is you need to solve to use SkinnedEffect
is map the matrix array to bone indices. See the IEffectSkininng interface which is implemented by SkinnedEffect
.
About this
// Simple time-based uniform scaling float s = 1 + sin(time * 1.7f) * 0.5f; XMMATRIX scale = XMMatrixScaling(s, s, s);
I setup this:
DX::StepTimer time
and I got this error:
E0349 no operator "*" matches these operands
And when I rendered the model
`m_model->Draw(context, *m_states, bones, m_world, m_view, m_proj);
`
I get this error:
E0312 no suitable user-defined conversion from "std::unique_ptr<DirectX::XMMATRIX [], aligned_deleter>" to "DirectX::XMMATRIX" exists
Model::Draw
doesn't take an array of matrices, so the 3rd parameter is not valid.
void XM_CALLCONV Draw(_In_ ID3D11DeviceContext* deviceContext, const CommonStates& states,
FXMMATRIX world, CXMMATRIX view, CXMMATRIX projection,
bool wireframe = false, _In_opt_ std::function<void __cdecl()> setCustomState = nullptr) const;
You have to do something like:
m_model->UpdateEffects([&](IEffect* effect)
{
auto skinnedEffect = dynamic_cast<IEffectSkinning*>(effect);
if (skinnedEffect)
skinnedEffect->SetBoneTransforms(bones.get(), SkinnedEffect::MaxBones);
});
m_model->Draw(context, *m_states, m_world, m_view, m_proj);
With the October 2021 release of DirectX Tool Kit, there is now a DrawSkinned
method for Model.
See https://github.com/microsoft/DirectXTK/wiki/Using-skinned-models
I managed to build a skinned model file
pch.h `typedef struct ID3DXSkinInfo *LPD3DXSKININFO;
typedef struct ID3DXMesh *LPD3DXMESH;
typedef interface ID3DXBuffer ID3DXBuffer; typedef interface ID3DXBuffer *LPD3DXBUFFER;
typedef enum D3DXEFFECTDEFAULTTYPE { D3DXEDT_STRING = 1, D3DXEDT_FLOATS = 2, D3DXEDT_DWORD = 3, D3DXEDT_FORCEDWORD = 0x7fffffff } D3DXEFFECTDEFAULTTYPE, *LPD3DXEFFECTDEFAULTTYPE;
typedef interface ID3DXEffect ID3DXEffect; typedef interface ID3DXEffect *LPD3DXEFFECT;
typedef interface ID3DXAnimationSet ID3DXAnimationSet; typedef interface ID3DXAnimationSet *LPD3DXANIMATIONSET;
typedef struct ID3DXPatchMesh *LPD3DXPATCHMESH;
typedef struct D3DMATERIAL9 { D3DCOLORVALUE Diffuse; D3DCOLORVALUE Ambient; D3DCOLORVALUE Specular; D3DCOLORVALUE Emissive; float Power; } D3DMATERIAL9, *LPD3DMATERIAL9;
typedef enum D3DXMESHDATATYPE { D3DXMESHTYPE_MESH = 0x001, D3DXMESHTYPE_PATCHMESH = 0x003, D3DXMESHTYPE_FORCE_DWORD = 0x7fffffff } D3DXMESHDATATYPE, *LPD3DXMESHDATATYPE;
typedef struct D3DXEFFECTDEFAULT { LPSTR pParamName; D3DXEFFECTDEFAULTTYPE Type; DWORD NumBytes; LPVOID pValue; } D3DXEFFECTDEFAULT, *LPD3DXEFFECTDEFAULT;
typedef struct D3DXMATERIAL { D3DMATERIAL9 MatD3D; LPSTR pTextureFilename; } D3DXMATERIAL, *LPD3DXMATERIAL;
typedef struct D3DXMESHDATA { D3DXMESHDATATYPE Type; union { LPD3DXMESH pMesh; LPD3DXPATCHMESH pPatchMesh; }; } D3DXMESHDATA, *LPD3DXMESHDATA;
typedef struct D3DXEFFECTINSTANCE { LPSTR pEffectFilename; DWORD NumDefaults; LPD3DXEFFECTDEFAULT pDefaults; } D3DXEFFECTINSTANCE, *LPD3DXEFFECTINSTANCE;
typedef struct D3DXMESHCONTAINER { LPSTR Name; D3DXMESHDATA MeshData; LPD3DXMATERIAL pMaterials; LPD3DXEFFECTINSTANCE pEffects; DWORD NumMaterials; DWORD pAdjacency; LPD3DXSKININFO pSkinInfo; D3DXMESHCONTAINER pNextMeshContainer; } D3DXMESHCONTAINER, *LPD3DXMESHCONTAINER;
typedef enum D3DXPRIORITY_TYPE { D3DXPRIORITY_LOW = 0, D3DXPRIORITY_HIGH = 1, D3DXPRIORITY_FORCE_DWORD = 0x7fffffff } D3DXPRIORITY_TYPE, *LPD3DXPRIORITY_TYPE;
typedef struct D3DXFRAME { LPSTR Name; XMMATRIX TransformationMatrix; LPD3DXMESHCONTAINER pMeshContainer; D3DXFRAME pFrameSibling; D3DXFRAME pFrameFirstChild; } D3DXFRAME, *LPD3DXFRAME;
typedef struct D3DXKEY_CALLBACK { FLOAT Time; LPVOID pCallbackData; } D3DXKEY_CALLBACK, *LPD3DXKEY_CALLBACK;
LPD3DXFRAME D3DXFrameFind( In const D3DXFRAME *pFrameRoot, In LPCSTR Name );
struct BoxerCallbackInfo { float* theta; };`
SkinnedMesh.cpp `
include "Mechanics/SkinnedMesh.h"
D3DXFRAME SkinnedMesh::findNodeWithMesh(D3DXFRAME frame) { if (frame->pMeshContainer) if (frame->pMeshContainer->MeshData.pMesh != 0)
return frame; D3DXFRAME* f = 0;
if (frame->pFrameSibling)
if (f = findNodeWithMesh(frame->pFrameSibling))
return f; if (frame->pFrameFirstChild)
if (f = findNodeWithMesh(frame->pFrameFirstChild))
return f; return 0; }
void SkinnedMesh::buildSkinnedMesh(ModelMesh mesh) { DWORD numBoneComboEntries = 0; ID3DXBuffer boneComboTable = 0; THROW_DXERR(_skinInfo->ConvertToIndexedBlendedMesh(mesh, D3DXMESH_MANAGED | D3DXMESH_WRITEONLY, SkinnedMesh::MAX_NUM_BONES_SUPPORTED, 0, // ignore adjacency in
0, // ignore adjacency out
0, // ignore face remap
0, // ignore vertex remap
&_maxVertInfluences,
&numBoneComboEntries,
&boneComboTable,
&m_Model) ) // We do not need the bone table, so just release it.
ReleaseCOM(boneComboTable); }
void SkinnedMesh::buildCombinedTransforms() { for (UINT i = 0; i < _numBones; ++i) {
// Find the frame that corresponds with the ith
// bone offset matrix.
const char boneName = _skinInfo->GetBoneName(i);
D3DXFRAME frame = D3DXFrameFind(_root, boneName);
if( frame )
{
FrameEx frameEx = static_cast<FrameEx>( frame );
_combinedTransforms[i] = &frameEx->combinedTransform;
}
} }
void SkinnedMesh::frameMove(float deltaTime, meshMatrix worldViewProj) { _animCtrl->AdvanceTime(deltaTime, 0); meshMatrix identity; XMMatrixIdentity(&identity);
combineTransforms(static_cast<FrameEx>(_root), identity); meshMatrix offsetTemp, combinedTemp; for (UINT i = 0; i < _numBones; ++i) { offsetTemp = _skinInfo->GetBoneOffsetMatrix(i);
combinedTemp = _combinedTransforms[i];
_finalTransforms[i] = offsetTemp combinedTemp; } _effect->SetMatrix(_hWorldViewProj, &worldViewProj);
}
void SkinnedMesh::render() { _effect->SetTechnique(_hTech);
UINT numPasses = 0; _effect->Begin(&numPasses, 0); for (UINT i = 0; i < numPasses; ++i) { _effect->BeginPass(i); // Draw the one and only subset. _skinnedMesh->DrawSubset(0); _effect->EndPass(); } _effect->End(); }`
`//----------------------------------------------------------------------
void Boxer::LoadMesh() { auto device = m_deviceResources->GetD3DDevice(); m_states = std::make_unique(device);
}
void Boxer::setupCallbackKeyframes(float theta) { // Remark: ‘theta’ is a pointer to the camera’s theta // coordinate. // Grab the current animation set for 'tiny.x'
// (we know there is only one.) ID3DXKeyframedAnimationSet animSetTemp = 0; _animCtrl->GetAnimationSet( 0, (ID3DXAnimationSet*)&animSetTemp); // Compress it. ID3DXBuffer compressedInfo = 0;
animSetTemp->Compress(D3DXCOMPRESS_DEFAULT, 0.5f, 0, &compressedInfo); // Setup two callback keys.
UINT numCallbacks = 2;
D3DXKEY_CALLBACK keys[2]; // Make static so it does not pop off the stack.
static BoxerCallbackInfo CallbackData;
}
void Boxer::playIdle() { ID3DXAnimationSet* loiter = 0; _animCtrl->GetAnimationSet(LOITER_INDEX, &loiter); _animCtrl->SetTrackAnimationSet(0, loiter);
_animCtrl->ResetTime(); }
void Boxer::Update() {
}
void Boxer::Render() { auto context = m_deviceResources->GetD3DDeviceContext(); SkinnedMesh->render(); }`
is there any way I can load this
void SkinnedMesh::buildSkinnedMesh(ModelMesh* mesh) { DWORD numBoneComboEntries = 0; ID3DXBuffer* boneComboTable = 0; THROW_DXERR(_skinInfo->ConvertToIndexedBlendedMesh(mesh, D3DXMESH_MANAGED | D3DXMESH_WRITEONLY, SkinnedMesh::MAX_NUM_BONES_SUPPORTED, 0, // ignore adjacency in 0, // ignore adjacency out 0, // ignore face remap 0, // ignore vertex remap &_maxVertInfluences, &numBoneComboEntries, &boneComboTable, &m_Model) ) // We do not need the bone table, so just release it. ReleaseCOM(boneComboTable); }
through this
switch (Boxers) { case GaryTurbo: SkinnedMesh::buildSkinnedMesh break; }