Results 1 to 6 of 6

Thread: 3D Vector Math include file.

  1. #1

    3D Vector Math include file.

    i tested the ext floating point type but ist's too slow for my needs.

    so here is what i use as include file.

    currently i use 3D vectors as array

    dim a(3) as single
    dim b(3) as single
    dim c(3) as single
    dim d as single
    a(1) = 1,2,3
    b(1) = 2,3,4


    VecCrossAB(c,a,b) ' c = a x b
    VecAdd(a,b) ' a += b
    VecSub(a,b) ' a -= b
    VecAddAB(c,a,b) ' c = a + b
    VecSubAB(c,a,b) ' c = a - b
    VecMulS(a,123.45) ' a*=scalar
    VecMulABS(a,b,123.45) ' a=b*scalar
    d=Length(a) ' sqr(ax*ax + ay*ay + az*az)
    d=VecDistanceAB(a,b) ' d = srq((az-bz)*(az-bz) + (ay-by)*(ay-by) + (ax-bx)*(ax-bx))
    d=dot(a) ' d=ax*ax + ay*ay + az*az
    d=dotAB(a,B) ' d=ax*bx + ay*by + az*bz
    ...

    happy coding

    Joshy
    [code=thinbasic]' litle bit vector math
    uses "OXYGEN"

    Begin Const
    %BUFFER_SET = 1
    %BUFFER_COPY
    %BUFFER_ADD
    %BUFFER_SUB
    %BUFFER_ADDAB
    %BUFFER_SUBAB
    %BUFFER_MULS
    %BUFFER_MULABS
    %BUFFER_DOT
    %BUFFER_DOTAB
    %BUFFER_DISTANCEAB2 ' squared
    %BUFFER_DISTANCEAB
    %BUFFER_LENGTH
    %BUFFER_NORMALIZE2 ' v*=1/sqr(squared)
    %BUFFER_CROSSAB
    %BUFFER_SQRT
    End Const

    Dim src As String


    '######################
    ' VecSet(R(),X,Y,Z)
    '######################
    src = "
    mov edi,[esp+ 4] ; r()
    mov eax,[esp+ 8]
    mov [edi],eax ; r(1)=x
    mov eax,[esp+12]
    mov [edi+4],eax ; r(2)=y
    mov eax,[esp+16]
    mov [edi+8],eax ; r(3)=z

    ret 16
    "
    O2_BUF %BUFFER_SET : O2_ASMO src
    If Len(O2_ERROR) Then
    MsgBox 0,O2_ERROR()+O2_VIEW (src)
    Stop
    End If

    '######################
    ' VecCopy(R(),A())
    ' r()=a()
    '######################
    src = "
    mov edi,[esp+ 4] ; r()
    mov esi,[esp+ 8] ; a()

    mov eax,[esi]
    mov [edi],eax ; r(1)=a(1)
    mov eax,[esi+4]
    mov [edi+4],eax ; r(2)=a(2)
    mov eax,[esi+8]
    mov [edi+8],eax ; r(3)=a(3)

    ret 8
    "
    O2_BUF %BUFFER_COPY : O2_ASMO src
    If Len(O2_ERROR) Then
    MsgBox 0,O2_ERROR()+O2_VIEW (src)
    Stop
    End If


    '######################
    ' VecAdd(A(),B())
    ' a()+=b()
    '######################
    src = "
    mov edi,[esp+ 4] ; a()
    mov esi,[esp+ 8] ; b()

    fld dword [edi ]
    fadd dword [esi ]
    fstp dword [edi ] ; ax+=bx

    fld dword [edi+4]
    fadd dword [esi+4]
    fstp dword [edi+4] ; ay+=by

    fld dword [edi+8]
    fadd dword [esi+8]
    fstp dword [edi+8] ; az+=bz

    ret 8
    "
    O2_BUF %BUFFER_ADD : O2_ASMO src
    If Len(O2_ERROR) Then
    MsgBox 0,O2_ERROR()+O2_VIEW (src)
    Stop
    End If

    '######################
    ' VecSub(A(),B())
    ' a()-=b()
    '######################
    src = "
    mov edi,[esp+ 4] ; a()
    mov esi,[esp+ 8] ; b()

    fld dword [edi ]
    fsub dword [esi ]
    fstp dword [edi ] ; ax-=bx

    fld dword [edi+4]
    fsub dword [esi+4]
    fstp dword [edi+4] ; ay-=by

    fld dword [edi+8]
    fsub dword [esi+8]
    fstp dword [edi+8] ; az-=bz

    ret 8
    "
    O2_BUF %BUFFER_SUB: O2_ASMO src
    If Len(O2_ERROR) Then
    MsgBox 0,O2_ERROR()+O2_VIEW (src)
    Stop
    End If

    '#######################
    ' VecAddAB(R(),A(),B())
    ' r()=a()+b()
    '#######################
    src = "
    mov eax,[esp+ 4] ; r()
    mov esi,[esp+ 8] ; a()
    mov edi,[esp+12] ; b()

    fld dword [esi ]
    fadd dword [edi ]
    fstp dword [eax ] ; rx = (ax+bx)

    fld dword [esi+4]
    fadd dword [edi+4]
    fstp dword [eax+4] ; ry = (ay+by)

    fld dword [esi+8]
    fadd dword [edi+8]
    fstp dword [eax+8] ; rz = (az+bz)

    ret 12
    "
    O2_BUF %BUFFER_ADDAB: O2_ASMO src
    If Len(O2_ERROR) Then
    MsgBox 0,O2_ERROR()+O2_VIEW (src)
    Stop
    End If

    '#######################
    ' VecSubAB(R(),A(),B())
    ' r()=a()-b()
    '#######################
    src = "
    mov eax,[esp+ 4] ; r()
    mov esi,[esp+ 8] ; a()
    mov edi,[esp+12] ; b()

    fld dword [esi ]
    fsub dword [edi ]
    fstp dword [eax ] ; rx = (ax-bx)

    fld dword [esi+4]
    fsub dword [edi+4]
    fstp dword [eax+4] ; ry = (ay-by)

    fld dword [esi+8]
    fsub dword [edi+8]
    fstp dword [eax+8] ; rz = (az-bz)

    ret 12
    "
    O2_BUF %BUFFER_SUBAB: O2_ASMO src
    If Len(O2_ERROR) Then
    MsgBox 0,O2_ERROR()+O2_VIEW (src)
    Stop
    End If

    '################
    ' VecMulS(A(),S)
    ' a()*=s
    '################
    src = ";
    mov esi , [esp+4]
    fld dword [esp+8] ; s

    fmul dword [esi ] ;s*x,s
    fstp dword [esi ] ; s

    fmul dword [esi+4] ;s*y,s
    fstp dword [esi+4] ;s

    fmulp dword [esi+8] ;s*z
    fstp dword [esi+8]

    ret 8
    "
    O2_BUF %BUFFER_MULS : O2_ASMO src
    If Len(O2_ERROR) Then
    MsgBox 0,O2_ERROR()+O2_VIEW (src)
    Stop
    End If

    '######################
    ' VecMulABS(R(),A(),S)
    ' r()=b()*s
    '######################
    src = "
    mov edi , [esp+ 4] ; r()
    mov esi , [esp+ 8] ; b()
    fld dword [esp+12] ; s

    fld dword [esi ] ; bx,s
    fmul ; ax*s,s
    fstp dword [edi ] ; s

    fld dword [esi+4] ; by,s
    fmul ; ay*s,s
    fstp dword [edi+4] ; s

    fld dword [esi+8] ; bz,s
    fmulp ; az*s
    fstp dword [edi+8]

    ret 12
    "
    O2_BUF %BUFFER_MULABS : O2_ASMO src
    If Len(O2_ERROR) Then
    MsgBox 0,O2_ERROR()+O2_VIEW (src)
    Stop
    End If

    '#######################
    ' s = VecDot(a())
    ' s = ax*ax+ay*ay+az*az
    '#######################
    src = ";
    mov esi , [esp+4]
    fld dword [esi ] ; (x)
    fld st(0) ; (x),(x)
    fmulp ; (x*x)
    fld dword [esi+4] ; (y),(x*x)
    fld st(0) ; (y),(y),(x*x)
    fmulp ; (y*y),(x*x)
    fld dword [esi+8] ; (z),(y*y),(x*x)
    fld st(0) ; (z),(z),(y*y),(x*x)
    fmulp ; (z*z),(y*y),(x*x)
    faddp ; (z*z + y*y),(x*x)
    faddp ; (z*z + y*y + x*x)
    ret 4
    "
    O2_BUF %BUFFER_DOT : O2_ASMO src
    If Len(O2_ERROR) Then
    MsgBox 0,O2_ERROR()+O2_VIEW (src)
    Stop
    End If

    '#######################
    ' s = VecDotAB(a(),b())
    ' s = ax*bx+ay*by+az*bz
    '#######################
    src = "
    mov esi, [esp+4]
    mov edi, [esp+8]
    fld dword [edi ] ; (bx)
    fmul dword [esi ] ; (ax*bx)
    fld dword [edi+4] ; (by),(ax*bx)
    fmul dword [esi+4] ; (ay*by),(ax*bx)
    fld dword [edi+8] ; (bz),(ay*by),(ax*bx)
    fmul dword [esi+8] ; (az*bz),(ay*by),(ax*bx)
    faddp ; (az*bz + ay*by),(ax*bx)
    faddp ; (az*bz + ay*by + ax*bx)
    ret 8
    "
    O2_BUF %BUFFER_DOTAB : O2_ASMO src
    If Len(O2_ERROR) Then
    MsgBox 0,O2_ERROR()+O2_VIEW (src)
    Stop
    End If

    '###########################
    ' s = VecDistanceAB2(a(),b())
    ' s = dot(a()-b())
    '###########################
    src = "
    mov esi,[esp+4]
    mov edi,[esp+8]

    fld dword [esi ] ; (ax)
    fsub dword [edi ] ; (ax-bx)
    fld st(0) ; (ax-bx),(ax-bx)
    fmulp ; (ax-bx)*(ax-bx)


    fld dword [esi+4] ; (ay),(ax-bx)*(ax-bx)
    fsub dword [edi+4] ; (ay-by),(ax-bx)*(ax-bx)
    fld st(0) ; (ay-by),(ay-by),(ax-bx)*(ax-bx)
    fmulp ; (ay-by)*(ay-by),(ax-bx)*(ax-bx)

    fld dword [esi+8] ; (az),(ay-by)*(ay-by),(ax-bx)*(ax-bx)
    fsub dword [edi+8] ; (az-bz),(ay-by)*(ay-by),(ax-bx)*(ax-bx)
    fld st(0) ; (az-bz),(az-bz),(ay-by)*(ay-by),(ax-bx)*(ax-bx)
    fmulp ; (az-bz)*(az-bz),(ay-by)*(ay-by),(ax-bx)*(ax-bx)

    faddp ; (az-bz)*(az-bz)+(ay-by)*(ay-by),(ax-bx)*(ax-bx)
    faddp ; (az-bz)*(az-bz)+(ay-by)*(ay-by)+(ax-bx)*(ax-bx)
    ret 8
    "
    O2_BUF %BUFFER_DISTANCEAB2 : O2_ASMO src
    If Len(O2_ERROR) Then
    MsgBox 0,O2_ERROR()+O2_VIEW (src)
    Stop
    End If

    '############################
    ' s = VecDistanceAB(a(),b())
    ' s = Sqr(Distance2(a()-b())
    '############################
    src = "
    mov esi,[esp+4]
    mov edi,[esp+8]

    fld dword [esi ] ; (ax)
    fsub dword [edi ] ; (ax-bx)
    fld st(0) ; (ax-bx),(ax-bx)
    fmulp ; (ax-bx)*(ax-bx)


    fld dword [esi+4] ; (ay),(ax-bx)*(ax-bx)
    fsub dword [edi+4] ; (ay-by),(ax-bx)*(ax-bx)
    fld st(0) ; (ay-by),(ay-by),(ax-bx)*(ax-bx)
    fmulp ; (ay-by)*(ay-by),(ax-bx)*(ax-bx)

    fld dword [esi+8] ; (az),(ay-by)*(ay-by),(ax-bx)*(ax-bx)
    fsub dword [edi+8] ; (az-bz),(ay-by)*(ay-by),(ax-bx)*(ax-bx)
    fld st(0) ; (az-bz),(az-bz),(ay-by)*(ay-by),(ax-bx)*(ax-bx)
    fmulp ; (az-bz)*(az-bz),(ay-by)*(ay-by),(ax-bx)*(ax-bx)

    faddp ; (az-bz)*(az-bz)+(ay-by)*(ay-by),(ax-bx)*(ax-bx)
    faddp ; (az-bz)*(az-bz)+(ay-by)*(ay-by)+(ax-bx)*(ax-bx)

    fsqrt ; srq(distance2(a(),b())
    ret 8
    "
    O2_BUF %BUFFER_DISTANCEAB : O2_ASMO src
    If Len(O2_ERROR) Then
    MsgBox 0,O2_ERROR()+O2_VIEW (src)
    Stop
    End If

    '############################
    ' s = VecLength(a())
    ' s = sqr(ax*ax+ay*ay+az*az)
    '############################
    src = ";
    mov esi , [esp+4]
    fld dword [esi ] ; (x)
    fld st(0) ; (x),(x)
    fmulp ; (x*x)
    fld dword [esi+4] ; (y),(x*x)
    fld st(0) ; (y),(y),(x*x)
    fmulp ; (y*y),(x*x)
    fld dword [esi+8] ; (z),(y*y),(x*x)
    fld st(0) ; (z),(z),(y*y),(x*x)
    fmulp ; (z*z),(y*y),(x*x)
    faddp ; (z*z + y*y),(x*x)
    faddp ; (z*z + y*y + x*x)
    fsqrt
    ret 4
    "
    O2_BUF %BUFFER_LENGTH : O2_ASMO src
    If Len(O2_ERROR) Then
    MsgBox 0,O2_ERROR()+O2_VIEW (src)
    Stop
    End If

    '############################
    ' s = VecNormlize2(a(),squared)
    ' a()*1/sqr(squared)
    '############################
    src = "
    mov esi,[esp+4] ; a()
    fld dword [esp+8] ; x*x+y*y+z*z
    fsqrt ; sqr(x*x+y*y+z*z)
    fld1 ; 1.0,sqr(x*x+y*y+z*z)
    fdiv ; invsqr
    fld dword [esi] ; x,invsqr
    fmul ; x*invsqr,invsqr
    fstp dword [esi] ; invsqr

    fld dword [esi+4] ; y,invsqr
    fmul ; y*invsqr,invsqr
    fstp dword [esi+4] ; invsqr

    fld dword [esi+8] ; z,invsqr
    fmulp ; z*invsqr
    fstp dword [esi+8]

    ret 8
    "
    O2_BUF %BUFFER_NORMALIZE2 : O2_ASMO src
    If Len(O2_ERROR) Then
    MsgBox 0,O2_ERROR()+O2_VIEW (src)
    Stop
    End If

    '############################
    ' s = SQRT(a)
    '############################
    src = "
    fld dword [esp+4]
    fsqrt
    ret 4
    "
    O2_BUF %BUFFER_SQRT : O2_ASMO src
    If Len(O2_ERROR) Then
    MsgBox 0,O2_ERROR()+O2_VIEW (src)
    Stop
    End If

    '#####################################
    ' VecCrossAB(r(),a(),b())
    ' r(1)=(a[Y] * b[Z]) - (a[Z] * b[Y])
    ' r(2)=(a[Z] * b[X]) - (a[X] * b[Z])
    ' r(3)=(a[X] * b[Y]) - (a[Y] * b[X])
    '#####################################
    src = "
    mov edi , [esp+ 4] ; r()
    mov eax , [esp+ 8] ; a()
    mov esi , [esp+12] ; b()

    fld dword [esi+4] ; by
    fld dword [eax+8] ; az ,by
    fmulp ; az*by
    fld dword [esi+8] ; bz ,az*by
    fld dword [eax+4] ; ay ,bz ,az*by
    fmulp ; ay*bz,az*by
    fsub ; ay*bz-az*by
    fstp dword [edi ] ; rx=ay*bz-az*by


    fld dword [esi+8] ; bz
    fld dword [eax ] ; ax,bz
    fmulp ; ax*bz
    fld dword [esi ] ; bx,ax*bz
    fld dword [eax+8] ; az,bx,ax*bz
    fmulp ; az*bx,ax*bz
    fsub ; az*bx-ax*bz
    fstp dword [edi+4] ; ry=az*bx-ax*bz


    fld dword [esi ] ; bx
    fld dword [eax+4] ; ay,bx
    fmulp ; ay*bx
    fld dword [esi+4] ; by,ay*bx
    fld dword [eax ] ; ax,by,ay*bx
    fmulp ; ax*by,ay*bx
    fsub ; ax*by-ay*bx
    fstp dword [edi+8] ; rz=ax*by-ay*bx
    ffree st(2)
    ffree st(1)
    ffree st(0)
    ret 12
    "
    O2_BUF %BUFFER_CROSSAB : O2_ASMO src
    If Len(O2_ERROR) Then
    MsgBox 0,O2_ERROR()+O2_VIEW (src)
    Stop
    End If

    Declare Sub VecSet (ByRef a() As Single, ByVal x As Single,ByVal y As Single,ByVal z As Single) At O2_BUF %BUFFER_SET
    Declare Sub VecCopy (ByRef a() As Single, ByRef b() As Single) At O2_BUF %BUFFER_COPY
    Declare Sub VecAdd (ByRef a() As Single, ByRef b() As Single) At O2_BUF %BUFFER_ADD
    Declare Sub VecSub (ByRef a() As Single, ByRef b() As Single) At O2_BUF %BUFFER_SUB
    Declare Sub VecAddAB (ByRef r() As Single, ByRef a() As Single, ByRef b() As Single) At O2_BUF %BUFFER_ADDAB
    Declare Sub VecSubAB (ByRef r() As Single, ByRef a() As Single, ByRef b() As Single) At O2_BUF %BUFFER_SUBAB
    Declare Function VecMulS (ByRef a() As Single, ByVal s As Single) As Single At O2_BUF %BUFFER_MULS
    Declare Function VecMulAS (ByRef r() As Single, ByRef a() As Single, ByVal s As Single) As Single At O2_BUF %BUFFER_MULABS
    Declare Function VecDot (ByRef a() As Single) As Single At O2_BUF %BUFFER_DOT
    Declare Function VecDotAB (ByRef a() As Single,ByRef b() As Single) As Single At O2_BUF %BUFFER_DOTAB
    Declare Function VecDistanceAB2(ByRef a() As Single,ByRef b() As Single) As Single At O2_BUF %BUFFER_DISTANCEAB2
    Declare Function VecDistanceAB (ByRef a() As Single,ByRef b() As Single) As Single At O2_BUF %BUFFER_DISTANCEAB
    Declare Function VecLength (ByRef a() As Single) As Single At O2_BUF %BUFFER_LENGTH
    Declare Sub VecNormalize2 (ByRef a() As Single,ByVal Lenght2 As Single) As Single At O2_BUF %BUFFER_NORMALIZE2
    Declare Sub VecCrossAB (ByRef r() As Single, ByRef a() As Single, ByRef b() As Single) At O2_BUF %BUFFER_CROSSAB
    Declare Function Sqrt (ByVal v As Single) As Single At O2_BUF %BUFFER_SQRT

    Sub VecNormalize(ByRef a() As Single)
    Local s As Single
    s=VecDot(a)
    If s=0 Then Return
    VecNormalize2(a,s)
    End Sub

    Function VecCos(ByRef a() As Single, ByRef b() As Single) As Single
    Dim l1,l2 As Single
    l1 = VecDot(a) ' x*0=0
    If l1=0 Then Return 0
    l2 = VecDot(b) ' y*0=0
    If l2=0 Then Return 0
    l2 = SQRT(l1)*SQRT(l2)
    l1 = VecDot(a,b)
    Return l1/l2 ' acos(l1/l2)
    End Function
    [/code]
    (Sorry about my bad English.)

  2. #2
    thinBasic author ErosOlmi's Avatar
    Join Date
    Sep 2004
    Location
    Milan - Italy
    Age
    50
    Posts
    8,187
    Blog Entries
    2
    Rep Power
    10

    Re: 3D Vector Math include file.

    Very very nice usage of Oxygen.

    Charles will be happy
    www.thinbasic.com | www.thinbasic.com/community/ | psch.thinbasic.com
    Win10Pro 64bit - 8GB Ram - Intel i7 M620 2.67GHz - NVIDIA Quadro FX1800M 1GB

  3. #3

    Re: 3D Vector Math include file.


    Thanks Joshy!

    Looking at your code I have just realised that it would be useful to be able to generate DLLs with exportable assembler functions (as well as BASIC). So I am going to add this facility to Oxygen now.

    proposed syntax for an exported label:

    MyAsmFunction: alias "MyAsmFunction" export


    Charles

  4. #4

    Re: 3D Vector Math include file.

    Looks like the function call from interpreter to inline assembler functions are very slow.
    I wrote a short test raytracer program where you can switch between interpreter
    vector math and the inline assembler math.

    But both results was near 46 seconds for one ray per pixel and a scene with 3 spheres.

    Normaly the inline assembler math should be 10-100 times faster as the interpreter math.

    Joshy

    (i hat closed source codes )

    (Sorry about my bad English.)

  5. #5

    Re: 3D Vector Math include file.

    Hi Joshy,

    Ray tracing sounds hard work for an interpreter!

    If you would like to post your test ray tracer here, I will try to accelerate it with Oxygen Basic and see whether we can get it to run at an acceptable speed.

    Charles

  6. #6

    Re: 3D Vector Math include file.


    One observation on your Assembler functions:

    The esi and edi registers normally need to be preserved. ThinBasic does this already but in a general DLL this would be a necessity for STDCALL or CDECL calls. For these vector functions I would use the ecx and edx registers instead.

    Charles

Similar Threads

  1. Big Integer Math include file
    By Johannes in forum Math scripts
    Replies: 14
    Last Post: 08-02-2011, 01:31
  2. Include file for GDI/GPI+?
    By Michael Hartlef in forum General
    Replies: 4
    Last Post: 20-03-2010, 11:57

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •