Skip to content

Commit

Permalink
Add support for animating morph mesh vobs
Browse files Browse the repository at this point in the history
  • Loading branch information
SaiyansKing committed Sep 29, 2021
1 parent fb85f3e commit 9283484
Show file tree
Hide file tree
Showing 10 changed files with 105 additions and 17 deletions.
12 changes: 11 additions & 1 deletion D3D11Engine/D2DSettingsDialog.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -222,9 +222,19 @@ XRESULT D2DSettingsDialog::InitControls() {
compressBackBufferCheckbox->SetChecked( Engine::GAPI->GetRendererState().RendererSettings.CompressBackBuffer );
compressBackBufferCheckbox->SetCheckedChangedCallback( CompressBackBufferCheckedChanged, this );

SV_Checkbox* animateStaticModelsCheckbox = new SV_Checkbox( MainView, MainPanel );
animateStaticModelsCheckbox->SetSize( D2D1::SizeF( 160, 20 ) );
switch ( userLanguage ) {
case LANGUAGE_POLISH: animateStaticModelsCheckbox->SetCaption( L"Animuj Statyczne Voby" ); break;
default: animateStaticModelsCheckbox->SetCaption( L"Animate Static Vobs" ); break;
}
animateStaticModelsCheckbox->SetDataToUpdate( &Engine::GAPI->GetRendererState().RendererSettings.AnimateStaticVobs );
animateStaticModelsCheckbox->AlignUnder( compressBackBufferCheckbox, 5 );
animateStaticModelsCheckbox->SetChecked( Engine::GAPI->GetRendererState().RendererSettings.AnimateStaticVobs );

SV_Label* fpsLimitLabel = new SV_Label( MainView, MainPanel );
fpsLimitLabel->SetPositionAndSize( D2D1::Point2F( 10, 10 ), D2D1::SizeF( 150, 12 ) );
fpsLimitLabel->AlignUnder( compressBackBufferCheckbox, 10 );
fpsLimitLabel->AlignUnder( animateStaticModelsCheckbox, 10 );
switch ( userLanguage ) {
case LANGUAGE_POLISH: fpsLimitLabel->SetCaption( L"Limit Klatek(FPS):" ); break;
default: fpsLimitLabel->SetCaption( L"Framerate Limit:" ); break;
Expand Down
15 changes: 15 additions & 0 deletions D3D11Engine/D3D11GraphicsEngine.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3264,6 +3264,18 @@ void XM_CALLCONV D3D11GraphicsEngine::DrawWorldAround( FXMVECTOR position,
Engine::GAPI->GetRendererState().BlendState.SetDirty();
}

/** Update morph mesh visual */
void D3D11GraphicsEngine::UpdateMorphMeshVisual() {
const std::unordered_map<zCProgMeshProto*, MeshVisualInfo*>& staticMeshVisuals =
Engine::GAPI->GetStaticMeshVisuals();

for ( auto const& staticMeshVisual : staticMeshVisuals ) {
if ( !staticMeshVisual.second->MorphMeshVisual ) continue;
if ( staticMeshVisual.second->Instances.empty() ) continue;
WorldConverter::UpdateMorphMeshVisual( staticMeshVisual.second->MorphMeshVisual, staticMeshVisual.second );
}
}

/** Draws the static vobs instanced */
XRESULT D3D11GraphicsEngine::DrawVOBsInstanced() {
START_TIMING();
Expand Down Expand Up @@ -3319,6 +3331,9 @@ XRESULT D3D11GraphicsEngine::DrawVOBsInstanced() {
Engine::GAPI->CollectVisibleVobs( vobs, lights, mobs );
}
}
if ( Engine::GAPI->GetRendererState().RendererSettings.AnimateStaticVobs ) {
UpdateMorphMeshVisual();
}

// Need to collect alpha-meshes to render them laterdy
std::list<std::pair<MeshKey, std::pair<MeshVisualInfo*, MeshInfo*>>>
Expand Down
3 changes: 3 additions & 0 deletions D3D11Engine/D3D11GraphicsEngine.h
Original file line number Diff line number Diff line change
Expand Up @@ -228,6 +228,9 @@ class D3D11GraphicsEngine : public D3D11GraphicsEngineBase {
bool noNPCs = false,
std::list<VobInfo*>* renderedVobs = nullptr, std::list<SkeletalVobInfo*>* renderedMobs = nullptr, std::map<MeshKey, WorldMeshInfo*, cmpMeshKey>* worldMeshCache = nullptr );

/** Update morph mesh visual */
void UpdateMorphMeshVisual();

/** Draws the static vobs instanced */
XRESULT DrawVOBsInstanced();

Expand Down
2 changes: 1 addition & 1 deletion D3D11Engine/GSky.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -404,4 +404,4 @@ float3 GSky::GetSunColor() {
float3 suncolor_return;
suncolor_return = suncolor_convert;
return suncolor_return;
}
}
5 changes: 5 additions & 0 deletions D3D11Engine/GothicAPI.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1546,6 +1546,9 @@ void GothicAPI::OnAddVob( zCVob* vob, zCWorld* world ) {

// Load the new visual
MeshVisualInfo* mi = new MeshVisualInfo;
if ( ext == ".MMS" )
mi->MorphMeshVisual = (void*)vob->GetVisual();

WorldConverter::Extract3DSMeshFromVisual2( pm, mi );
StaticMeshVisuals[pm] = mi;
}
Expand Down Expand Up @@ -3671,6 +3674,7 @@ XRESULT GothicAPI::SaveMenuSettings( const std::string& file ) {
WritePrivateProfileStringA( "General", "EnableInactiveFpsLock", std::to_string( s.EnableInactiveFpsLock ? TRUE : FALSE ).c_str(), ini.c_str() );
WritePrivateProfileStringA( "General", "MultiThreadResourceManager", std::to_string( s.MTResoureceManager ? TRUE : FALSE ).c_str(), ini.c_str() );
WritePrivateProfileStringA( "General", "CompressBackBuffer", std::to_string( s.CompressBackBuffer ? TRUE : FALSE ).c_str(), ini.c_str() );
WritePrivateProfileStringA( "General", "AnimateStaticVobs", std::to_string( s.AnimateStaticVobs ? TRUE : FALSE ).c_str(), ini.c_str() );

/*
* Draw-distance is saved on a per World basis using SaveRendererWorldSettings
Expand Down Expand Up @@ -3757,6 +3761,7 @@ XRESULT GothicAPI::LoadMenuSettings( const std::string& file ) {
s.EnableInactiveFpsLock = GetPrivateProfileBoolA( "General", "EnableInactiveFpsLock", defaultRendererSettings.EnableInactiveFpsLock, ini );
s.MTResoureceManager = GetPrivateProfileBoolA( "General", "MultiThreadResourceManager", defaultRendererSettings.MTResoureceManager, ini );
s.CompressBackBuffer = GetPrivateProfileBoolA( "General", "CompressBackBuffer", defaultRendererSettings.CompressBackBuffer, ini );
s.AnimateStaticVobs = GetPrivateProfileBoolA( "General", "AnimateStaticVobs", defaultRendererSettings.AnimateStaticVobs, ini );

/*
* Draw-distance is Loaded on a per World basis using LoadRendererWorldSettings
Expand Down
2 changes: 2 additions & 0 deletions D3D11Engine/GothicGraphicsState.h
Original file line number Diff line number Diff line change
Expand Up @@ -640,6 +640,7 @@ struct GothicRendererSettings {
EnableInactiveFpsLock = true;
MTResoureceManager = false;
CompressBackBuffer = false;
AnimateStaticVobs = true;
RunInSpacerNet = false;
}

Expand Down Expand Up @@ -782,6 +783,7 @@ struct GothicRendererSettings {
bool EnableInactiveFpsLock;
bool MTResoureceManager;
bool CompressBackBuffer;
bool AnimateStaticVobs;
bool RunInSpacerNet;
};

Expand Down
74 changes: 60 additions & 14 deletions D3D11Engine/WorldConverter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1375,7 +1375,44 @@ void WorldConverter::Extract3DSMeshFromVisual2PNAEN( zCProgMeshProto* visual, Me
meshInfo->Visual = visual;
}

/** Updates a Morph-Mesh visual */
void WorldConverter::UpdateMorphMeshVisual( void* v, MeshVisualInfo* meshInfo ) {
zCMorphMesh* visual = (zCMorphMesh*)v;
visual->GetTexAniState()->UpdateTexList();
visual->AdvanceAnis();
visual->CalcVertexPositions();

zCProgMeshProto* morphMesh = visual->GetMorphMesh();
if ( !morphMesh )
return;

DirectX::XMFLOAT3* posList = (DirectX::XMFLOAT3*)morphMesh->GetPositionList()->Array;
for ( int i = 0; i < morphMesh->GetNumSubmeshes(); i++ ) {
std::vector<ExVertexStruct> vertices;

zCSubMesh* s = morphMesh->GetSubmesh( i );
vertices.reserve( s->WedgeList.NumInArray );
for ( int v = 0; v < s->WedgeList.NumInArray; v++ ) {
zTPMWedge& wedge = s->WedgeList.Array[v];
vertices.emplace_back();
ExVertexStruct& vx = vertices.back();
vx.Position = posList[wedge.position];
vx.Normal = wedge.normal;
vx.TexCoord = wedge.texUV;
vx.Color = 0xFFFFFFFF;
}

for ( auto const& it : meshInfo->Meshes ) {
const std::vector<MeshInfo*>& mlist = it.second;
for ( unsigned int x = 0; x < mlist.size(); x++ ) {
MeshInfo* mi = mlist[x];
if ( mi->MeshIndex == i ) {
mi->MeshVertexBuffer->UpdateBuffer( &vertices[0], vertices.size() * sizeof( ExVertexStruct ) );
}
}
}
}
}

/** Extracts a 3DS-Mesh from a zCVisual */
void WorldConverter::Extract3DSMeshFromVisual2( zCProgMeshProto* visual, MeshVisualInfo* meshInfo ) {
Expand Down Expand Up @@ -1436,27 +1473,36 @@ void WorldConverter::Extract3DSMeshFromVisual2( zCProgMeshProto* visual, MeshVis

mi->Vertices = vertices;
mi->Indices = indices;
mi->MeshIndex = i;

// Create the buffers
Engine::GraphicsEngine->CreateVertexBuffer( &mi->MeshVertexBuffer );
Engine::GraphicsEngine->CreateVertexBuffer( &mi->MeshIndexBuffer );

// Optimize faces
mi->MeshVertexBuffer->OptimizeFaces( &mi->Indices[0],
(byte*)&mi->Vertices[0],
mi->Indices.size(),
mi->Vertices.size(),
sizeof( ExVertexStruct ) );
if ( meshInfo->MorphMeshVisual ) {
// We need to keep original indices so that we can reuse them(we can't optimize them)
// Use dynamic buffer since we'll reupload it every frame we see this visual

// Then optimize vertices
mi->MeshVertexBuffer->OptimizeVertices( &mi->Indices[0],
(byte*)&mi->Vertices[0],
mi->Indices.size(),
mi->Vertices.size(),
sizeof( ExVertexStruct ) );
// Init and fill it
mi->MeshVertexBuffer->Init( &mi->Vertices[0], mi->Vertices.size() * sizeof( ExVertexStruct ), D3D11VertexBuffer::B_VERTEXBUFFER, D3D11VertexBuffer::U_DYNAMIC, D3D11VertexBuffer::CA_WRITE );
} else {
// Optimize faces
mi->MeshVertexBuffer->OptimizeFaces( &mi->Indices[0],
(byte*)&mi->Vertices[0],
mi->Indices.size(),
mi->Vertices.size(),
sizeof( ExVertexStruct ) );

// Init and fill it
mi->MeshVertexBuffer->Init( &mi->Vertices[0], mi->Vertices.size() * sizeof( ExVertexStruct ), D3D11VertexBuffer::B_VERTEXBUFFER, D3D11VertexBuffer::U_IMMUTABLE );
// Then optimize vertices
mi->MeshVertexBuffer->OptimizeVertices( &mi->Indices[0],
(byte*)&mi->Vertices[0],
mi->Indices.size(),
mi->Vertices.size(),
sizeof( ExVertexStruct ) );

// Init and fill it
mi->MeshVertexBuffer->Init( &mi->Vertices[0], mi->Vertices.size() * sizeof( ExVertexStruct ), D3D11VertexBuffer::B_VERTEXBUFFER, D3D11VertexBuffer::U_IMMUTABLE );
}
mi->MeshIndexBuffer->Init( &mi->Indices[0], mi->Indices.size() * sizeof( VERTEX_INDEX ), D3D11VertexBuffer::B_INDEXBUFFER, D3D11VertexBuffer::U_IMMUTABLE );

Engine::GAPI->GetRendererState().RendererInfo.VOBVerticesDataSize += mi->Vertices.size() * sizeof( ExVertexStruct );
Expand Down
3 changes: 3 additions & 0 deletions D3D11Engine/WorldConverter.h
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,9 @@ class WorldConverter {
static void Extract3DSMeshFromVisual2( zCProgMeshProto* visual, MeshVisualInfo* meshInfo );
static void Extract3DSMeshFromVisual2PNAEN( zCProgMeshProto* visual, MeshVisualInfo* meshInfo );

/** Updates a Morph-Mesh visual */
static void UpdateMorphMeshVisual( void* visual, MeshVisualInfo* meshInfo );

/** Extracts a skeletal mesh from a zCModel */
static void ExtractSkeletalMeshFromVob( zCModel* model, SkeletalMeshVisualInfo* skeletalMeshInfo );

Expand Down
4 changes: 4 additions & 0 deletions D3D11Engine/WorldObjects.h
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,7 @@ struct MeshInfo {
MeshVertexBuffer = nullptr;
MeshIndexBuffer = nullptr;
BaseIndexLocation = 0;
MeshIndex = -1;
MeshIndexBufferPNAEN = nullptr;
}

Expand All @@ -112,6 +113,7 @@ struct MeshInfo {
std::vector<VERTEX_INDEX> IndicesPNAEN;
std::vector<ExVertexStruct> VerticesPNAEN;
unsigned int BaseIndexLocation;
unsigned int MeshIndex;
};

struct WorldMeshInfo : public MeshInfo {
Expand Down Expand Up @@ -224,6 +226,7 @@ class zCTexture;
struct MeshVisualInfo : public BaseVisualInfo {
MeshVisualInfo() {
Visual = nullptr;
MorphMeshVisual = nullptr;
UnloadedSomething = false;
StartInstanceNum = 0;
FullMesh = nullptr;
Expand Down Expand Up @@ -255,6 +258,7 @@ struct MeshVisualInfo : public BaseVisualInfo {

/** This is true if we can't actually render something on this. TODO: Try to fix this! */
bool UnloadedSomething;
void* MorphMeshVisual;
};

/** Holds the converted mesh of a VOB */
Expand Down
2 changes: 1 addition & 1 deletion D3D11Engine/pch.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@
#define stdext std
#endif

#define VERSION_NUMBER "17.7-dev23"
#define VERSION_NUMBER "17.7-dev24"
__declspec(selectany) const char* VERSION_NUMBER_STR = VERSION_NUMBER;

extern bool FeatureLevel10Compatibility;
Expand Down

0 comments on commit 9283484

Please sign in to comment.