Пишу 3D движок, помогите с оптимизацией

Тема в разделе "WASM.BEGINNERS", создана пользователем Programmer1, 4 фев 2006.

  1. Programmer1

    Programmer1 New Member

    Публикаций:
    0
    Регистрация:
    26 янв 2006
    Сообщения:
    1
    Адрес:
    Russia
    Народ помогите плиз с оптимизацией.

    Необходимо оптимизировать ф-цию:



    //-------------------------------------------------------------------- ---------

    // hs > 0 - Точка в положительном полупространстве

    // hs = 0 - Точка лежит на плоскости

    // hs < 0 - Точка в отрицательном полупространстве

    //-------------------------------------------------------------------- ---------

    float

    math::CmPlane3d::ComputePointInPlane3d( CmPoint4d *pt_Src )

    {

    float hs =

    m_n.m_x*(pt_Src->m_x - m_p.m_x) +

    m_n.m_y*(pt_Src->m_y - m_p.m_y) +

    m_n.m_z*(pt_Src->m_z - m_p.m_z);



    // Указывает полупространство в котором содержится точка.

    return(hs);

    }



    //-------------------------------------------------------------------- ---------

    // Пересечение 3D плоскости 3D линией

    // 0 - Прямая параллельна плоскости

    // 1 - Прямая лежит на плоскости

    // 2 - Точка пересечения вне отрезка

    // 3 - Отрезок пересекается с плоскостью

    //-------------------------------------------------------------------- ---------

    INT

    math::CmPlane3d::IntersectParamLine3d( CmParamLine3d *lpPrmLine_Src, float *t_Dst, CmPoint4d *pt_Dst )

    {

    float plane_dot_line = m_n.Dot3(&lpPrmLine_Src->m_v);



    if (fabs(plane_dot_line) <= EPSILON_E5)

    {

    //sadf::MBf(L"%f",plane_dot_line );

    // Прямая параллельна плоскости. Не лежит ли

    // она на плоскости

    if (fabs(ComputePointInPlane3d(&lpPrmLine_Src->m_pa)) <= EPSILON_E5)

    return(1); // Прямая лежит на плоскости

    else

    return(0); // Прямая параллельна плоскости

    }



    //sadf::MBf( L"class %f", plane_dot_line );



    // Поиск точки пересечения по ф-ле пересечения прямой и плоскости.

    *t_Dst = -(

    m_n.m_x * lpPrmLine_Src->m_pa.m_x +

    m_n.m_y * lpPrmLine_Src->m_pa.m_y +

    m_n.m_z * lpPrmLine_Src->m_pa.m_z -

    m_n.m_x * m_p.m_x -

    m_n.m_y * m_p.m_y -

    m_n.m_z * m_p.m_z ) / (plane_dot_line);



    //sadf::MBf( L"class %f", *t_Dst );



    // Подставляя t в уравнение прямой находим точку пересечения.

    pt_Dst->m_x = lpPrmLine_Src->m_pa.m_x + lpPrmLine_Src->m_v.m_x*(*t_Dst);

    pt_Dst->m_y = lpPrmLine_Src->m_pa.m_y + lpPrmLine_Src->m_v.m_y*(*t_Dst);

    pt_Dst->m_z = lpPrmLine_Src->m_pa.m_z + lpPrmLine_Src->m_v.m_z*(*t_Dst);



    // Проверяем пересечение отрезка с плоскостью

    if( *t_Dst>=0.0 && *t_Dst<=1.0 )

    return(3); // Отрезок пересекается с плоскостью

    else

    return(2); // Точка пересечения вне отрезка

    }



    Я и так и сяк писал на ASMe. Причем в консольных приложениях результаты правильные выдает, а в оконных с использованием DirectX все сразу виснет. Вот один из вариантов:



    //-------------------------------------------------------------------- ---------

    // hs > 0 - Точка в положительном полупространстве

    // hs = 0 - Точка лежит на плоскости

    // hs < 0 - Точка в отрицательном полупространстве

    __declspec(naked) FLOAT __fastcall

    math::mPlane3dComputePoint4d( CmPlane3d *lpPlane_Src, CmPoint4d *Pt_Src )

    {

    /*float hs =

    m_n.m_x*(pt_Src->m_x - m_p.m_x) +

    m_n.m_y*(pt_Src->m_y - m_p.m_y) +

    m_n.m_z*(pt_Src->m_z - m_p.m_z);



    // Указывает полупространство в котором содержится точка.

    return(hs);*/

    __asm{

    fld dword ptr [edx]

    fsub dword ptr [ecx]

    fmul dword ptr [ecx+10h]



    fld dword ptr [edx+04h]

    fsub dword ptr [ecx+04h]

    fmul dword ptr [ecx+14h]



    fadd



    fld dword ptr [edx+08h]

    fsub dword ptr [ecx+08h]

    fmul dword ptr [ecx+18h]



    fadd



    ret

    }

    }



    //-------------------------------------------------------------------- ---------

    // Пересечение 3D плоскости 3D линией

    // 0 - Прямая параллельна плоскости

    // 1 - Прямая лежит на плоскости

    // 2 - Точка пересечения вне отрезка

    // 3 - Отрезок пересекается с плоскостью

    //-------------------------------------------------------------------- ---------

    INT __fastcall

    math::mPlane3dIntersectParamLine3d( CmPlane3d *lpPlane_Src, CmParamLine3d *lpPrmLine_Src, FLOAT *t_Dst, CmPoint4d *pt_Dst )

    {

    //float plane_dot_line;// = mVec4dDot3( &lpPlane_Src->m_n, &lpPrmLine_Src->m_v );



    __asm{

    mov ecx, [lpPlane_Src]

    mov edx, [lpPrmLine_Src]

    fld dword ptr [ecx+10h]

    fmul dword ptr [edx+20h]

    fld dword ptr [ecx+14h]

    fmul dword ptr [edx+24h]

    fadd

    fld dword ptr [ecx+18h]

    fmul dword ptr [edx+28h]

    fadd

    mov eax, t_Dst

    fst dword ptr [eax]//[plane_dot_line]

    fabs

    // fstp dword ptr [plane_dot_line]

    //}



    // fld dword ptr [plane_dot_line]

    fcomp dword ptr [EPSILON_E5]

    fnstsw ax

    test ah,41h

    jp jamp2



    //__asm int 3

    //if (/*fabs(*t_Dst*/plane_dot_line <= EPSILON_E5)

    //{

    // Прямая параллельна плоскости. Не лежит ли

    // она на плоскости

    // float Compute;

    // __asm{

    mov ecx, [lpPlane_Src]

    mov edx, [lpPrmLine_Src]

    fld dword ptr [edx]

    fsub dword ptr [ecx]

    fmul dword ptr [ecx+10h]



    fld dword ptr [edx+04h]

    fsub dword ptr [ecx+04h]

    fmul dword ptr [ecx+14h]



    fadd



    fld dword ptr [edx+08h]

    fsub dword ptr [ecx+08h]

    fmul dword ptr [ecx+18h]



    fadd

    fabs

    //fstp dword ptr [Compute]

    // }



    // int 3

    // if (Compute/*fabs(mPlane3dComputePoint4d( lpPlane_Src, &lpPrmLine_Src->m_pa))*/ <= EPSILON_E5)

    // return(1); // Прямая лежит на плоскости

    // else

    // return(0); // Прямая параллельна плоскости



    //fld dword ptr [Compute]

    fcomp dword ptr [EPSILON_E5]

    fnstsw ax

    test ah,41h

    jp jamp1//nre::math::mPlane3dIntersectParamLine3d+9Ah

    // return(1); // Прямая лежит на плоскости

    mov eax,1

    jmp jampe//nre::math::mPlane3dIntersectParamLine3d+154h

    // else

    // return(0); // Прямая параллельна плоскости

    jamp1:

    xor eax,eax

    jmp jampe//nre::math::mPlane3dIntersectParamLine3d+154h

    // }

    // }



    // Поиск точки пересечения по ф-ле пересечения прямой и плоскости.

    /**t_Dst = -(

    lpPlane_Src->m_n.m_x * lpPrmLine_Src->m_pa.m_x +

    lpPlane_Src->m_n.m_y * lpPrmLine_Src->m_pa.m_y +

    lpPlane_Src->m_n.m_z * lpPrmLine_Src->m_pa.m_z -

    lpPlane_Src->m_n.m_x * lpPlane_Src->m_p.m_x -

    lpPlane_Src->m_n.m_y * lpPlane_Src->m_p.m_y -

    lpPlane_Src->m_n.m_z * lpPlane_Src->m_p.m_z ) / (plane_dot_line);*/



    // __asm{

    jamp2:

    mov ecx, [lpPlane_Src]

    movaps xmm0, xmmword ptr [ecx+10h]

    mov edx, [lpPrmLine_Src]

    movaps xmm1, xmmword ptr [edx]

    movaps xmm4, xmm0

    movaps xmm5, xmmword ptr [ecx]



    movaps xmm7, xmm1



    mulps xmm0, xmm1

    mulps xmm4, xmm5



    movaps xmm1, xmm0

    movaps xmm2, xmm0

    movaps xmm5, xmm4

    movaps xmm6, xmm4



    shufps xmm1, xmm1, 01010101b

    shufps xmm2, xmm2, 10101010b

    shufps xmm5, xmm5, 01010101b

    shufps xmm6, xmm6, 10101010b



    addss xmm0, xmm1

    addss xmm0, xmm2



    subss xmm0, xmm4

    subss xmm0, xmm5

    subss xmm0, xmm6



    mov eax, t_Dst

    movss xmm1, dword ptr [eax]

    divss xmm0, xmm1

    mov eax, t_Dst

    movss dword ptr [eax], xmm0



    fld dword ptr [eax]

    fchs

    fstp dword ptr [eax]



    movaps xmm2, xmmword ptr [edx+20h]

    movss xmm0, dword ptr [eax]

    shufps xmm0, xmm0, 0

    //movups xmm1, xmmword ptr [edx]

    mulps xmm2, xmm0

    addps xmm7, xmm2

    mov eax, pt_Dst

    movaps xmmword ptr [eax], xmm7

    mov dword ptr [eax+0Ch], 3f800000h

    //}



    // Подставляя t в уравнение прямой находим точку пересечения.

    /*pt_Dst->m_x = lpPrmLine_Src->m_pa.m_x + lpPrmLine_Src->m_v.m_x*(*t_Dst);

    pt_Dst->m_y = lpPrmLine_Src->m_pa.m_y + lpPrmLine_Src->m_v.m_y*(*t_Dst);

    pt_Dst->m_z = lpPrmLine_Src->m_pa.m_z + lpPrmLine_Src->m_v.m_z*(*t_Dst);*/



    /* __asm int 3

    // Проверяем пересечение отрезка с плоскостью

    if( *t_Dst>=0.0 && *t_Dst<=1.0 )

    return(3); // Отрезок пересекается с плоскостью

    else

    return(2); // Точка пересечения вне отрезка*/



    mov eax,dword ptr [t_Dst]

    fld dword ptr [eax]

    fcomp dword ptr [ZERO]//dword ptr [__real@00000000]

    fnstsw ax

    test ah,1

    jne jampe1

    mov ecx,dword ptr [t_Dst]

    fld dword ptr [ecx]

    fcomp dword ptr [ONE]//qword ptr [__real@3ff0000000000000]

    fnstsw ax

    test ah,41h

    jp jampe1

    //return(3); // Отрезок пересекается с плоскостью

    mov eax,3

    jmp jampe

    //else

    //return(2); // Точка пересечения вне отрезка

    jampe1:

    mov eax,2

    }



    jampe:

    return;

    }



    Где CmPlane3d - это плоскость

    struct CmPlane3d

    {

    CmPoint4d m_p; // Точка на плоскости, m_w неиспользуется

    CmVector4d m_n; // Нормальный (необязательно единичный) вектор, m_w неиспользуется

    }



    CmParamLine3d - это параметрическая прямая

    struct CmParamLine3d

    {

    CmPoint4d m_pa;// Начальная точка

    CmPoint4d m_pb;// Конечная точка

    CmVector4d m_v;// Вектор направления |v|=|p0->p1| };