まあWDDM hookなんてしないでも、普通にIDirect3DDevice9のfuction table書き換えでもいいのと、それのほうがBeginSceneとEndSceneに処理突っ込めれてやりやすいんだけど、書き直すのが面倒だから、また次やる気出たときに作り直します。
AVA SDKはUE3 SDK Generatorを用いて各自用意してください。
AVA SDKからクラスやら取得するのが割りと重いから(処理的に)、PFND3DDDI_PRESENTに入れるのはちょっとアレかな...?
余談ですが、オブジェクトの座標取得の基本的な流れとしては、プレイヤーを描画する時は他より比較的に頂点数が多い(?)ので、それを基に3D座標を取得して2D(スクリーン座標)に変換する~って感じなので、OpenGLの場合はglVertex3f/v関数でVertexCount(頂点数)が一定数以上の時に座標を格納して、変換するだけで簡単に取れるのですが、D3Dは自分が知っている限りでは、少し手間のかかる方法しか知りません...
DrawIndexedPrimitive関数にオブジェクトの種類によって渡される引数(PrimitiveCount?)があり、その値から判断するという方法もありますが、Loggerなどを用いてログを調べないといけないのと、ゲームによって違うというのが面倒です...
何か良い方法ありませんかね..? もう少し調べてみます。
FLOAT APIENTRY GetDistance(__in FLOAT *LocationA, __in FLOAT *LocationB) { FLOAT DistanceX = LocationA[0] - LocationB[0]; FLOAT DistanceY = LocationA[1] - LocationB[1]; FLOAT DistanceZ = LocationA[2] - LocationB[2]; return (FLOAT)sqrt((DistanceX * DistanceX) + (DistanceY * DistanceY) + (DistanceZ * DistanceZ)); } HRESULT APIENTRY DrawBox(IDirect3DDevice9 *pDevice, FLOAT x, FLOAT y, FLOAT Width, FLOAT Height, D3DCOLOR Color) { D3DRECT Rect = { x, y, x + Width, y + Height }; return pDevice->Clear(1, &Rect, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, Color, 0, 0); } HRESULT APIENTRY DrawLine(ID3DXLine *pLine, FLOAT x, FLOAT y, FLOAT x2, FLOAT y2, D3DCOLOR Color) { D3DXVECTOR2 vLine[2]; vLine[0].x = x; vLine[0].y = y; vLine[1].x = x2; vLine[1].y = y2; if (pLine) { pLine->SetWidth(1); pLine->SetAntialias(FALSE); pLine->SetGLLines(FALSE); pLine->Begin(); pLine->Draw(vLine, 2, Color); pLine->End(); } return S_OK; } HRESULT APIENTRY DDICreateQuery(__in HANDLE hDevice, __in_opt D3DDDIARG_CREATEQUERY *pCreateQuery) { if (pCreateQuery && pCreateQuery->QueryType == D3DDDIQUERYTYPE_OCCLUSION) pCreateQuery->QueryType = D3DDDIQUERYTYPE_EVENT; return _DDICreateQuery(hDevice, pCreateQuery); } HRESULT APIENTRY DDIDrawIndexedPrimitive(__in HANDLE hDevice, __in_opt const D3DDDIARG_DRAWINDEXEDPRIMITIVE *pDPI) { CGraphicsContext *pGraphicsContext = CGraphicsContext::GetInstance(); IDirect3DDevice9 *pDevice = Direct3D9::GetInstance()->GetDevice(); // get entity 2D position for (int i = 0; i < MaxEnts; i++) { D3DXMATRIX mProjection, mViewProj, mWorldProj; D3DXVECTOR3 vScreen2D, vWorld3D; vWorld3D.x = Ents[i].Origin[0]; vWorld3D.y = Ents[i].Origin[1]; vWorld3D.z = Ents[i].Origin[2]; if (pDevice) { pDevice->GetViewport(&Viewport); pDevice->GetVertexShaderConstantF(0, mProjection, 4); pDevice->GetVertexShaderConstantF(231, mViewProj, 4); D3DXMatrixIdentity(&mWorldProj); D3DXVec3Project(&vScreen2D, &vWorld3D, &Viewport, &mProjection, &mViewProj, &mWorldProj); if (vScreen2D.z < 1.0f && mProjection._44 > 1.0f) { Ents[i].ESP.x = vScreen2D.x; Ents[i].ESP.y = vScreen2D.y; } } } // draw esp for (int i = 0; i < MaxEnts; i++) { FLOAT x = Ents[i].ESP.x; FLOAT y = Ents[i].ESP.y; UCHAR r, g, b, a; if (Ents[i].IsVisible == TRUE) { r = 20; g = 255; b = 20; a = 200; } else { r = 255; g = 255; b = 20; a = 200; } // draw esp box on target if (pGraphicsContext->IsDrawEspBoxActivated()) { DrawBox(pDevice, Ents[i].ESP.x, Ents[i].ESP.y, 5, 5, D3DCOLOR_RGBA(r, g, b, a)); } // draw esp line on foot to target if (pGraphicsContext->IsDrawEspLineActivated()) { ID3DXLine *pLine = NULL; D3DXCreateLine(pDevice, &pLine); if (pLine) { DrawLine(pLine, x, y, Viewport.Width / 2.0f, Viewport.Height, D3DCOLOR_RGBA(r, g, b, a)); } } } // reset MaxEnts = 0; return _DDIDrawIndexedPrimitive(hDevice, pDPI); } HRESULT APIENTRY DDIPresent(__in HANDLE hDevice, __in_opt const D3DDDIARG_PRESENT *pPresent) { CGameManager *pGameManager = CGameManager::GetInstance(); UGameEngine* pGameEngine; AavaPlayerController* pAvaPC; AavaPawn* pAvaPawn; pGameEngine = pGameManager->GetEngine(); if (pGameEngine && pGameEngine->GamePlayers.Data) { pAvaPC = (AavaPlayerController*)pGameEngine->GamePlayers.Data[0]->Actor; if (pAvaPC && pAvaPC->IsA(AavaPlayerController::StaticClass())) { pAvaPawn = (AavaPawn*)pAvaPC->Pawn; // Validate the pawn and the WorldInfo pointer required for pawn looping if (pAvaPawn && pAvaPawn->IsA(AavaPawn::StaticClass()) && pAvaPawn->WorldInfo) { if (MaxEnts = 0) { // Loop through the pawns for (APawn* pTarget = pAvaPawn->WorldInfo->PawnList; pTarget; pTarget = pTarget->NextPawn) { // Validate the current target if (pTarget != pAvaPawn && pTarget->IsA(AavaPawn::StaticClass()) && pGameManager->IsValidTarget(pTarget)) { // player hp Ents[MaxEnts].Health = (INT)pTarget->Health; // player position Ents[MaxEnts].Origin[0] = pTarget->Location.X; Ents[MaxEnts].Origin[1] = pTarget->Location.Y; Ents[MaxEnts].Origin[2] = pTarget->Location.Z; // Next Entity MaxEnts++; } } } } } } return _DDIPresnet(hDevice, pPresent); }