Panel użytkownika
Nazwa użytkownika:
Hasło:
Nie masz jeszcze konta?

grawitacja obiektów 3D

Ostatnio zmodyfikowano 2015-10-21 12:57
Autor Wiadomość
shadow999
Temat założony przez niniejszego użytkownika
grawitacja obiektów 3D
» 2015-10-20 18:54:54
Witam, zajmuję się trochę Directx 11 i pomyślałem, że przyszła pora na włączenie silnika fizycznego, wybór oczywiście padł na PhysX, a że dokumentacja podaje przykłady tylko w Ogl to zwracam się do was.

Jeżeli dobrze rozumiem to PhysX i Directx mają być oddzielnymi bytami, tzn. Tworzę sobie w directx powiedzmy prostą, czerwoną kostkę, kostka o takich samych wymiarach istnieje również w silniku Physx, następnie pobieram jedynie położenie i przekształcenia kostki do macierzy directx, a następnie wszystko leci standardowo jak w directx.

Poprawcie mnie proszę jeżeli źle to zrozumiałem.

Oczywiście tutaj samo nasuwa się pytanie, jak przenieść wszystkie przekształcenia z formatu PhysX na macierze directx?

Poniżej rzucam kod generujący prostą kostkę, plik efektu jest zbędny więc nie będę go wklejał, gdyby ktoś mi zaimplementował tu silnik fizyczny, powiedzmy z podstawową funkcją-grawitacją, to byłbym wdzięczny do końca życia, jako, że gryzę się już 2 dni jak zapewnić komunikację physx->directx , a internet milczy podając jedyny, żałosny przykład na DXUT. Pewnie będę musiał szukać pomocy na forach zagranicznych ale może akurat znajdzie się ekspert. Trochę mnie zaskakuje brak informacji w internecie bo przecież wiele gier i symulacji powstaje właśnie w tym połączeniu.
C/C++
#include "PxPhysicsAPI.h"
#include "vehicle/PxVehicleSDK.h"
#include "d3dApp.h"
#include "d3dx11Effect.h"
#include "MathHelper.h"




struct Vertex
{
    XMFLOAT3 Pos;
    XMFLOAT4 Color;
};

class BoxApp
    : public D3DApp
{
public:
    BoxApp( HINSTANCE hInstance );
    ~BoxApp();
   
    bool Init();
    void OnResize();
    void UpdateScene( float dt );
    void DrawScene();
   
    void OnMouseDown( WPARAM btnState, int x, int y );
    void OnMouseUp( WPARAM btnState, int x, int y );
    void OnMouseMove( WPARAM btnState, int x, int y );
   
private:
    void BuildGeometryBuffers();
    void BuildFX();
    void BuildVertexLayout();
   
private:
    ID3D11Buffer * mBoxVB;
    ID3D11Buffer * mBoxIB;
   
    ID3DX11Effect * mFX;
    ID3DX11EffectTechnique * mTech;
    ID3DX11EffectMatrixVariable * mfxWorldViewProj;
   
    ID3D11InputLayout * mInputLayout;
   
    XMFLOAT4X4 mWorld;
    XMFLOAT4X4 mView;
    XMFLOAT4X4 mProj;
   
    float mTheta;
    float mPhi;
    float mRadius;
   
    POINT mLastMousePos;
};

int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE prevInstance,
PSTR cmdLine, int showCmd )
{
    // Sprawdzenie pamięci w trybie debugowania.
    #if defined(DEBUG) | defined(_DEBUG)
    _CrtSetDbgFlag( _CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF );
    #endif
   
    BoxApp theApp( hInstance );
   
    if( !theApp.Init() )
         return 0;
   
    return theApp.Run();
}


BoxApp::BoxApp( HINSTANCE hInstance )
    : D3DApp( hInstance )
     , mBoxVB( 0 )
     , mBoxIB( 0 )
     , mFX( 0 )
     , mTech( 0 )
     , mfxWorldViewProj( 0 )
     , mInputLayout( 0 )
     , mTheta( 1.5f * MathHelper::Pi )
     , mPhi( 0.25f * MathHelper::Pi )
     , mRadius( 5.0f )
{
    mMainWndCaption = L"Box Demo";
   
    mLastMousePos.x = 0;
    mLastMousePos.y = 0;
   
    XMMATRIX I = XMMatrixIdentity();
    XMStoreFloat4x4( & mWorld, I );
    XMStoreFloat4x4( & mView, I );
    XMStoreFloat4x4( & mProj, I );
}

BoxApp::~BoxApp()
{
    ReleaseCOM( mBoxVB );
    ReleaseCOM( mBoxIB );
    ReleaseCOM( mFX );
    ReleaseCOM( mInputLayout );
}

bool BoxApp::Init()
{
    if( !D3DApp::Init() )
         return false;
   
    BuildGeometryBuffers();
    BuildFX();
    BuildVertexLayout();
   
    return true;
}

void BoxApp::OnResize()
{
    D3DApp::OnResize();
   
    // Rozmiar okna zmieniony, aktualizuj proporcje obrazu i oblicz ponownie macierz rzutowania
    XMMATRIX P = XMMatrixPerspectiveFovLH( 0.25f * MathHelper::Pi, AspectRatio(), 1.0f, 1000.0f );
    XMStoreFloat4x4( & mProj, P );
}

void BoxApp::UpdateScene( float dt )
{
    // Zamień współrzędne sferyczne na kartezjańskie.
    float x = mRadius * sinf( mPhi ) * cosf( mTheta );
    float z = mRadius * sinf( mPhi ) * sinf( mTheta );
    float y = mRadius * cosf( mPhi );
   
    // Zbuduj macierz widoku.
    XMVECTOR pos = XMVectorSet( x, y, z, 1.0f );
    XMVECTOR target = XMVectorZero();
    XMVECTOR up = XMVectorSet( 0.0f, 1.0f, 0.0f, 0.0f );
   
    XMMATRIX V = XMMatrixLookAtLH( pos, target, up );
    XMStoreFloat4x4( & mView, V );
}

void BoxApp::DrawScene()
{
    md3dImmediateContext->ClearRenderTargetView( mRenderTargetView, reinterpret_cast < const float *>( & Colors::LightSteelBlue ) );
    md3dImmediateContext->ClearDepthStencilView( mDepthStencilView, D3D11_CLEAR_DEPTH | D3D11_CLEAR_STENCIL, 1.0f, 0 );
   
    md3dImmediateContext->IASetInputLayout( mInputLayout );
    md3dImmediateContext->IASetPrimitiveTopology( D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST );
   
    UINT stride = sizeof( Vertex );
    UINT offset = 0;
    md3dImmediateContext->IASetVertexBuffers( 0, 1, & mBoxVB, & stride, & offset );
    md3dImmediateContext->IASetIndexBuffer( mBoxIB, DXGI_FORMAT_R32_UINT, 0 );
   
    // Ustaw stałe
    XMMATRIX world = XMLoadFloat4x4( & mWorld );
    XMMATRIX view = XMLoadFloat4x4( & mView );
    XMMATRIX proj = XMLoadFloat4x4( & mProj );
    XMMATRIX worldViewProj = world * view * proj;
   
    mfxWorldViewProj->SetMatrix( reinterpret_cast < float *>( & worldViewProj ) );
   
    D3DX11_TECHNIQUE_DESC techDesc;
    mTech->GetDesc( & techDesc );
    for( UINT p = 0; p < techDesc.Passes; ++p )
    {
        mTech->GetPassByIndex( p )->Apply( 0, md3dImmediateContext );
       
        // 36 indeksów prostopadłościanu.
        md3dImmediateContext->DrawIndexed( 36, 0, 0 );
    }
   
    HR( mSwapChain->Present( 0, 0 ) );
}

void BoxApp::OnMouseDown( WPARAM btnState, int x, int y )
{
    mLastMousePos.x = x;
    mLastMousePos.y = y;
   
    SetCapture( mhMainWnd );
}

void BoxApp::OnMouseUp( WPARAM btnState, int x, int y )
{
    ReleaseCapture();
}

void BoxApp::OnMouseMove( WPARAM btnState, int x, int y )
{
    if(( btnState & MK_LBUTTON ) != 0 )
    {
        // Każdy piksel powinien odpowiadać jednej czwartej stopnia.
        float dx = XMConvertToRadians( 0.25f * static_cast < float >( x - mLastMousePos.x ) );
        float dy = XMConvertToRadians( 0.25f * static_cast < float >( y - mLastMousePos.y ) );
       
        // Aktualizuj kąty wyznaczające położenie kamery względem prostopadłościanu na podstawie danych wejściowych.
        mTheta += dx;
        mPhi += dy;
       
        // Ogranicz kąt mPhi.
        mPhi = MathHelper::Clamp( mPhi, 0.1f, MathHelper::Pi - 0.1f );
    }
    else if(( btnState & MK_RBUTTON ) != 0 )
    {
        // Każdy piksel powinien być odpowiednikiem 0,005 jednostki w scenie.
        float dx = 0.005f * static_cast < float >( x - mLastMousePos.x );
        float dy = 0.005f * static_cast < float >( y - mLastMousePos.y );
       
        // Aktualizuj promień kamery na podstawie danych wejściowych.
        mRadius += dx - dy;
       
        // Ogranicz promień.
        mRadius = MathHelper::Clamp( mRadius, 3.0f, 15.0f );
    }
   
    mLastMousePos.x = x;
    mLastMousePos.y = y;
}

void BoxApp::BuildGeometryBuffers()
{
    // Utwórz bufor indeksów.
    Vertex vertices[] =
    {
        { XMFLOAT3( - 1.0f, - 1.0f, - 1.0f ),( const float * ) & Colors::White },
        { XMFLOAT3( - 1.0f, + 1.0f, - 1.0f ),( const float * ) & Colors::Black },
        { XMFLOAT3( + 1.0f, + 1.0f, - 1.0f ),( const float * ) & Colors::Red },
        { XMFLOAT3( + 1.0f, - 1.0f, - 1.0f ),( const float * ) & Colors::Green },
        { XMFLOAT3( - 1.0f, - 1.0f, + 1.0f ),( const float * ) & Colors::Blue },
        { XMFLOAT3( - 1.0f, + 1.0f, + 1.0f ),( const float * ) & Colors::Yellow },
        { XMFLOAT3( + 1.0f, + 1.0f, + 1.0f ),( const float * ) & Colors::Cyan },
        { XMFLOAT3( + 1.0f, - 1.0f, + 1.0f ),( const float * ) & Colors::Magenta }
    };
   
    D3D11_BUFFER_DESC vbd;
    vbd.Usage = D3D11_USAGE_IMMUTABLE;
    vbd.ByteWidth = sizeof( Vertex ) * 8;
    vbd.BindFlags = D3D11_BIND_VERTEX_BUFFER;
    vbd.CPUAccessFlags = 0;
    vbd.MiscFlags = 0;
    vbd.StructureByteStride = 0;
    D3D11_SUBRESOURCE_DATA vinitData;
    vinitData.pSysMem = vertices;
    HR( md3dDevice->CreateBuffer( & vbd, & vinitData, & mBoxVB ) );
   
   
    // Utwórz bufor indeksów
   
    UINT indices[] = {
        // przednia ściana
        0, 1, 2,
        0, 2, 3,
       
        // tylna ściana
        4, 6, 5,
        4, 7, 6,
       
        // lewa ściana
        4, 5, 1,
        4, 1, 0,
       
        // prawa ściana
        3, 2, 6,
        3, 6, 7,
       
        // górna ściana
        1, 5, 6,
        1, 6, 2,
       
        // dolna ściana
        4, 0, 3,
        4, 3, 7
    };
   
    D3D11_BUFFER_DESC ibd;
    ibd.Usage = D3D11_USAGE_IMMUTABLE;
    ibd.ByteWidth = sizeof( UINT ) * 36;
    ibd.BindFlags = D3D11_BIND_INDEX_BUFFER;
    ibd.CPUAccessFlags = 0;
    ibd.MiscFlags = 0;
    ibd.StructureByteStride = 0;
    D3D11_SUBRESOURCE_DATA iinitData;
    iinitData.pSysMem = indices;
    HR( md3dDevice->CreateBuffer( & ibd, & iinitData, & mBoxIB ) );
}

void BoxApp::BuildFX()
{
    DWORD shaderFlags = 0;
    #if defined( DEBUG ) || defined( _DEBUG )
    shaderFlags |= D3D10_SHADER_DEBUG;
    shaderFlags |= D3D10_SHADER_SKIP_OPTIMIZATION;
    #endif
   
    ID3D10Blob * compiledShader = 0;
    ID3D10Blob * compilationMsgs = 0;
    HRESULT hr = D3DX11CompileFromFile( L"FX/color.fx", 0, 0, 0, "fx_5_0", shaderFlags,
    0, 0, & compiledShader, & compilationMsgs, 0 );
   
    // compilationMsgs przechowuje komunikaty o błędach lub ostrzeżenia.
    if( compilationMsgs != 0 )
    {
        MessageBoxA( 0,( char * ) compilationMsgs->GetBufferPointer(), 0, 0 );
        ReleaseCOM( compilationMsgs );
    }
   
    // Nawet jeśli compilationMsg jest pusta, upewnij się, że nie było innych błędów.
    if( FAILED( hr ) )
    {
        DXTrace( __FILE__,( DWORD ) __LINE__, hr, L"D3DX11CompileFromFile", true );
    }
   
    HR( D3DX11CreateEffectFromMemory( compiledShader->GetBufferPointer(), compiledShader->GetBufferSize(),
    0, md3dDevice, & mFX ) );
   
    // Koniec pracy ze skompilowanym shaderem.
    ReleaseCOM( compiledShader );
   
    mTech = mFX->GetTechniqueByName( "ColorTech" );
    mfxWorldViewProj = mFX->GetVariableByName( "gWorldViewProj" )->AsMatrix();
}

void BoxApp::BuildVertexLayout()
{
    // Stwórz format wejścia wierzchołków.
    D3D11_INPUT_ELEMENT_DESC vertexDesc[] =
    {
        { "POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0 },
        { "COLOR", 0, DXGI_FORMAT_R32G32B32A32_FLOAT, 0, 12, D3D11_INPUT_PER_VERTEX_DATA, 0 }
    };
   
    // Stwórz format wejścia.
    D3DX11_PASS_DESC passDesc;
    mTech->GetPassByIndex( 0 )->GetDesc( & passDesc );
    HR( md3dDevice->CreateInputLayout( vertexDesc, 2, passDesc.pIAInputSignature,
    passDesc.IAInputSignatureSize, & mInputLayout ) );
}
P-138952
shadow999
Temat założony przez niniejszego użytkownika
» 2015-10-20 23:26:12
Naprawdę nikt nie zajmuje się na tym forum programowaniem w 3D?, ja rozumiem, że Directx i OGL to kombajny, w porównaniu z tym 2d to tępe nożyczki ale myślałem, że chociaż kilka osób na forum się tym interesuje :(

Wystarczą mi nawet porządne przykłady w Ogl-u, chodzi o samą komunikację silnik fizyczny->renderowanie grafiki
P-138971
RazzorFlame
» 2015-10-21 12:12:42
O ile pamiętam to PhysX korzysta z tego samego układu współrzędnych. Robisz coś takiego:
C/C++
PhysicsModule::Step( DeltaTime );

for( auto It = ActorsOnScene.begin(); It != ActorsOnScene.end(); It++ )
{
    Vector PositionAfterPhys =( * It ).GetPhysicsVolume()->GetPosition();
    ( * It )->SetPosition( PositionAfterPhys );
}
To jest po prostu updatowanie każdego elementu na scenie a raczej jego pozycji. Z obrotem będzie ciężej, będziesz musiał się pobawić quaternionami.
PhysicsVolume to np. cube ale taki z PhysXa.
P-138977
shadow999
Temat założony przez niniejszego użytkownika
» 2015-10-21 12:57:37
Z tego co udało mi się znaleźć:

actor->getGlobalPose().getColumnMajor44( d3dMat );

Tylko, czy to uwzględni przekształcenia nie mam pojęcia ale z tego co wiem getGlobalPose() powinien podać zarówno położenie jak i rotację obiektu, a getColumnMajor44 umożliwia transkrypcję na macierz DX. Jakby ktoś mógł potwierdzić lub obalić ten zapis jako, że nie mam teraz dostępu do komputera to byłbym wdzięczny.
P-138978
« 1 »
  Strona 1 z 1