Author Topic: Matrice operation (v1[x] = v[0][x] - v[1][x])  (Read 24 times)

TouEnMasm

  • Member
  • *****
  • Posts: 1730
    • EditMasm
Matrice operation (v1[x] = v[0][x] - v[1][x])
« on: July 28, 2021, 06:21:13 PM »
Hello,
Is someone  have written macros to solve this form of operations: v1
  • = v[0]
  • - v[1]
  •     ?

Fa is a musical note to play with CL

HSE

  • Member
  • *****
  • Posts: 1728
  • <AMD>< 7-32>
Re: Matrice operation (v1[x] = v[0][x] - v[1][x])
« Reply #1 on: July 28, 2021, 10:33:30 PM »
Hi Yves!

Using macros in mtx.inc : http://masm32.com/board/index.php?topic=8398.0. Requiere JWasm family because there are macros creating macros.

 Using Matrix.inc in ObjAsm: http://masm32.com/board/index.php?topic=8583.0.  Examples of use are in ObjAsm32. This Matrix.inc is a modification in progress of that.

A litle more specific and in development, perhaps using a more advanced mtx.inc (I have to see :biggrin:). Also in ObjAsm I'm translating some C++ code:
Code: (Matri2D_OOP.inc) [Select]
;/*!
; * \file
; * Scanline edge-flag algorithm for antialiasing <br>
; * Copyright (c) 2005-2007 Kiia Kallio
; *
; * http://mlab.uiah.fi/~kkallio/antialiasing/
; *
; * This code is distributed under the three-clause BSD license.
; * Read the LICENSE file or visit the URL above for details.
; *
; * \brief A simple 2d matrix class.
; *
; *
; * $Id: $
; * $Date: $
; * $Revision: $
; */


MATRIX2D textequ <POINTER>
defMATRIX2D macro var1
DefineVariable &var1, MATRIX2D, 0
endm

;//! A simple 2d matrix class.
Object Matrix2D,, Primer

    ; Makes a rotation matrix.
    ;void makeRotation(RATIONAL aAngle);
    VirtualMethod makeRotation, RATIONAL

    ; Makes a translation matrix.
    ;void makeTranslation(const Vector2d &aTranslation);
    VirtualMethod makeTranslation, POINTER
   
    ; Makes a scaling matrix.
    ;void makeScaling(const Vector2d &aScale);
    VirtualMethod makeScaling, POINTER

    ; Makes an identity matrix.
    ;void makeIdentity();
    VirtualMethod makeIdentity

    ; Rotates the matrix by an angle
    ;void rotate(RATIONAL rotate);
    VirtualMethod rotate, RATIONAL

    ; Translates the matrix with a vector.
    ;void translate(const Vector2d &aTranslation);
    VirtualMethod translate, POINTER

    ; Scales the matrix with a vector.
    ;void scale(const Vector2d &aScale);
    VirtualMethod scale, POINTER

    ; Multiplies the matrix with another matrix.
    ;void multiply(const Matrix2d &aMatrix);
    VirtualMethod multiply, POINTER

    ; Transforms a point with the matrix.
    ;void transform(const Vector2d &aSource, Vector2d &aTarget) const;
    VirtualMethod transform, POINTER, POINTER

    DIMOA mMatrix, RATIONAL, 3, 2
   
ObjectEnd

;#define MATRIX2D_MAKEROTATION(aMatrix,aAngle) aMatrix.makeRotation(aAngle)
;#define MATRIX2D_MAKETRANSLATION(aMatrix,aTranslation) aMatrix.makeTranslation(aTranslation)
MATRIX2D_MAKESCALING macro aMatrix, aScale
OCall &aMatrix::Matrix2D.makeScaling, &aScale
endm
MATRIX2D_MAKEIDENTITY macro aMatrix
OCall &aMatrix::Matrix2D.makeIdentity
endm
;#define MATRIX2D_ROTATE(aMatrix,aAngle) aMatrix.rotate(aAngle)
MATRIX2D_TRANSLATE macro aMatrix, aTranslation
OCall &aMatrix::Matrix2D.translate, &aTranslation
endm
;#define MATRIX2D_SCALE(aMatrix,aScale) aMatrix.scale(aScale)
MATRIX2D_MULTIPLY macro aMatrix, aMultiplier
OCall &aMatrix::Matrix2D.multiply, &aMultiplier
endm

MATRIX2D_TRANSFORM macro aMatrix,aSource,aResult
  OCall &aMatrix::Matrix2D.transform, &aSource, &aResult
endm
;#define MATRIX2D_GET_M11(aMatrix) aMatrix.mMatrix[0][0]
;#define MATRIX2D_GET_M12(aMatrix) aMatrix.mMatrix[0][1]
;#define MATRIX2D_GET_M21(aMatrix) aMatrix.mMatrix[1][0]
;#define MATRIX2D_GET_M22(aMatrix) aMatrix.mMatrix[1][1]
;#define MATRIX2D_GET_DX(aMatrix) aMatrix.mMatrix[2][0]
;#define MATRIX2D_GET_DY(aMatrix) aMatrix.mMatrix[2][1]

Code: (Matrix2D_PROC.inc) [Select]
; * Scanline edge-flag algorithm for antialiasing <br>
; * Copyright (c) 2005-2007 Kiia Kallio
; *
; * http:;mlab.uiah.fi/~kkallio/antialiasing/
; *
; * This code is distributed under the three-clause BSD license.
; * Read the LICENSE file or visit the URL above for details.
; *
; * \brief A simple 2d matrix class.


; Makes a rotation matrix.
Method Matrix2D.makeRotation, uses xsi, aAngle : RATIONAL
local sinRot : RATIONAL
local cosRot : RATIONAL

SetObject xsi
   
    fSlv8 sinRot = sin(aAngle)
    fSlv8 cosRot = cos(aAngle)

    fSlv8 mMatrix(0,0) = cosRot
    fSlv8 mMatrix(0,1) = sinRot
    fSlv8 mMatrix(1,0) = -sinRot
    fSlv8 mMatrix(1,1) = cosRot
    fSlv8 mMatrix(2,0) = 0
    fSlv8 mMatrix(2,1) = 0
   
MethodEnd

; Makes a translation matrix.
Method Matrix2D.makeTranslation, uses xsi, aTranslation : POINTER

SetObject xsi
SetObject xdx, Vector2D, aTranslation

    fSlv8 mMatrix(0,0) = 1
    fSlv8 mMatrix(0,1) = 0
    fSlv8 mMatrix(1,0) = 0
    fSlv8 mMatrix(1,1) = 1
    fSlv8 mMatrix(2,0) = [xdx].mX
    fSlv8 mMatrix(2,1) = [xdx].mY

MethodEnd

; Makes a scaling matrix.
Method Matrix2D.makeScaling, uses xsi, aScale :POINTER

    SetObject xsi
    SetObject xdx, Vector2D, aScale
   
    fSlv8 mMatrix(0,0) = [xdx].mX;
    fSlv8 mMatrix(0,1) = 0
    fSlv8 mMatrix(1,0) = 0
    fSlv8 mMatrix(1,1) = [xdx].mY;
    fSlv8 mMatrix(2,0) = 0
    fSlv8 mMatrix(2,1) = 0
   
MethodEnd

; Makes an identity matrix.
Method Matrix2D.makeIdentity, uses xsi

    SetObject xsi
   
    fSlv8 mMatrix(0,0) = 1
    fSlv8 mMatrix(0,1) = 0
    fSlv8 mMatrix(1,0) = 0
    fSlv8 mMatrix(1,1) = 1
    fSlv8 mMatrix(2,0) = 0
    fSlv8 mMatrix(2,1) = 0
   
MethodEnd

; Rotates the matrix by an angle
Method Matrix2D.rotate, uses xsi, rotate : RATIONAL
local tmp : POINTER

    SetObject xsi

    New Matrix2D
    mov tmp, xax
    OCall tmp::Matrix2D.makeRotation, rotate
    OCall xsi.multiply, tmp
    Destroy tmp
MethodEnd


; Translates the matrix with a vector.
Method Matrix2D.translate, uses xsi, aTranslation : POINTER
local tmp : POINTER

    SetObject xsi

;SetObject xdx, Vector2D, aTranslation ;pointer to Vector2d
    New Matrix2D
    mov tmp, xax
    OCall tmp::Matrix2D.makeTranslation, aTranslation
    OCall xsi.multiply, tmp
    Destroy tmp
   
MethodEnd

; Scales the matrix with a vector.
Method Matrix2D.scale, uses xsi, aScale : POINTER
local tmp : POINTER

    SetObject xsi
;Vector2d
    New Matrix2D; tmp;
    mov tmp, xax
    OCall tmp::Matrix2D.makeScaling, aScale
    OCall xsi.multiply, tmp
    Destroy tmp
   
MethodEnd


; Multiplies the matrix with another matrix.
Method Matrix2D.multiply, uses xsi xdi, aMatrix : POINTER
local tmp : POINTER

SetObject xsi

New Matrix2D
    mov tmp, eax
   
    CopiaObjeto OA_Matrix2D, tmp
   
SetObject xdi, Matrix2D, aMatrix
SetObject xdx, Matrix2D, tmp
   
    fSlv8 mMatrix(0,0) = mMatrixP(xdx,0,0) * mMatrixP(xdi,0,0) +\
                    mMatrixP(xdx,0,1) * mMatrixP(xdi,1,0);
    fSlv8 mMatrix(0,1) = mMatrixP(xdx,0,0) * mMatrixP(xdi,0,1) +\
                    mMatrixP(xdx,0,1) * mMatrixP(xdi,1,1);
    fSlv8 mMatrix(1,0) = mMatrixP(xdx,1,0) * mMatrixP(xdi,0,0) +\
                    mMatrixP(xdx,1,1) * mMatrixP(xdi,1,0);
    fSlv8 mMatrix(1,1) = mMatrixP(xdx,1,0) * mMatrixP(xdi,0,1) +\
                    mMatrixP(xdx,1,1) * mMatrixP(xdi,1,1);
    fSlv8 mMatrix(2,0) = mMatrixP(xdx,2,0) * mMatrixP(xdi,0,0) +\
                    mMatrixP(xdx,2,1) * mMatrixP(xdi,1,0) +\
                    mMatrixP(xdi,2,0);
    fSlv8 mMatrix(2,1) = mMatrixP(xdx,2,0) * mMatrixP(xdi,0,1) +\
                    mMatrixP(xdx,2,1) * mMatrixP(xdi,1,1) +\
                    mMatrixP(xdi,2,1);
   DbgFloat mMatrix(0,0)                 
   DbgFloat mMatrix(0,1)                 
   DbgFloat mMatrix(1,0)                 
   DbgFloat mMatrix(1,1)                 
   DbgFloat mMatrix(2,0)                 
   DbgFloat mMatrix(2,1)                 
             ;Ç
    Destroy tmp
             
MethodEnd


; Transforms a point with the matrix.
Method Matrix2D.transform, uses xsi xdi, aSource : POINTER, aTarget :POINTER
local vector2D : $Obj(Vector2D)

DbgMtit
    SetObject xsi

SetObject xdi, Vector2D, aSource
DbgHex xdi
DbgHex aTarget

.if xdi == aTarget
lea xax, vector2D
SetObject xdx, Vector2D, xax
.else
SetObject xdx, Vector2D, aTarget
.endif
DbgHex xdx

    fSlv8 [xdx].mX = mMatrix(0,0) * [xdi].mX + mMatrix(1,0) * [xdi].mY + mMatrix(2,0)
fSlv8 [xdx].mY = mMatrix(0,1) * [xdi].mX + mMatrix(1,1) * [xdi].mY + mMatrix(2,1)
.if xdi == aTarget
lea xax, vector2D
SetObject xdi, Vector2D, xax
SetObject xdx, Vector2D, aTarget
fSlv8 [xdx].mX = [xdi].mX
fSlv8 [xdx].mY = [xdi].mY
.endif

DbgMsal
MethodEnd

Yes. To include matrix in objects  requiere this:
Code: (mtx.inc) [Select]
;* @ArgI - Macro function returns an argument specified by number
;* from a VARARG list.
;*
;* Params:  index - one-based number of the argument to be returned
;*          arglist - argument list
@ArgI MACRO index:REQ, arglist:VARARG
    LOCAL count,retstr
    count = 0
    FOR arg,<arglist>
        count = count + 1
        IF count EQ index
            retstr TEXTEQU <arg>
        ENDIF
    ENDM
    EXITM retstr
ENDM


;mtx_tls_warning_line = -1
;@mtxTLS_warning macro
; IF mtx_tls_warning_line NE @Line
; %echo @FileCur: WARNING: code not thread save: line @CatStr(%@Line)
; ENDIF
; mtx_tls_warning_line = @Line
;endm

mtxTLS_curr_line = -1
mtxTLS_curr_file textequ <>


; mod1 0 = variable, 1 = structure
; mod2 0 = standard, 1 = SmplMath
; mod3 0 = plain, 1 = ObjAsm

DIM_MASTER macro isStruct, isSmpMth, isOA, nombre, tipo, dimensions:VARARG
   local value1
   value1 textequ <1>
   count = 0
    FOR dimension, <&dimensions>
        value1 CATSTR value1 , <*>, %dimension
    ENDM
    if isOA eq 0
    if isStruct eq 0
        nombre&_mtx &tipo value1 dup (?)
    else
        nombre&_mtx &tipo value1 dup (<?>)
    endif
    else
    nombre&_mtx_type textequ <&tipo>
    if isStruct eq 0
        DefineVariable nombre&_mtx, &tipo, value1 dup (?)
    else
        DefineVariable nombre&_mtx, &tipo, value1 dup (<?>)
    endif
    endif

    &nombre MACRO dimensionsn:VARARG
        LOCAL count, dwidth, dist, hayc, hayv, dewidth2, nombrestore

        count = 0
        dwidth = 1
        dist = 0
        hayc = 0
        hayv = 0

        if 0   
        if &isSmpMth eq 1
        IF mtxTLS_curr_line NE @Line
        mtxTLS_curr_line = @Line
        mtxTLS_usados = 0
        ENDIF
        endif
        endif

        FOR arg,<&dimensionsn>
            oa = OPATTR arg
            if oa and 0100b
                hayc = 1
            else
                hayv = 1
            endif
        ENDM

        if hayv
            mov eax, 0
        endif

        FOR arg,<&dimensionsn>
            count = count + 1
            oa = OPATTR arg
            if oa and 0100b
            if isOA eq 0
                dwidth2 = dwidth * TYPE nombre&_mtx
                else
                dwidth2 = dwidth * TYPE nombre&_mtx_type
                endif
                dist = dist + (arg * dwidth2)
            else
                push eax
                mov eax, arg
                mov ecx, dwidth
                mul ecx       
                pop ecx
                add eax, ecx
            endif
            dwidth = dwidth * @ArgI(%count, <dimensions>)
 
        ENDM

        if hayv
            if isStruct eq 1
            if isOA eq 0
                mov ecx,  TYPE nombre&_mtx
                else
                mov ecx,  TYPE nombre&_mtx_type
                endif
                mul ecx
            endif
            if isSmpMth eq 1
            %   add eax, offset @CatStr(&nombre,<_mtx>)
                mtxTLS_usados = mtxTLS_usados + 1
           ;;     % echo @CatStr(%mtxTLS_usados)
           %     if mtxTLS_usados gt mtxTLS_reservados
                    .err   incrementar reserva mtxTLS() en @FileCur
                endif
                if hayc
                %    add eax, dist
                endif
           %     mov dword ptr SS:[ebp - mtxTLS_usados*@WordSize ], eax
            endif
        endif

        if hayv and hayc
            if isStruct eq 0   
                if isSmpMth eq 0
                if isOA eq 0
                    EXITM @CatStr(&nombre,<_mtx>,<[>,eax * TYPE nombre&_mtx+ %dist ,<]>)
                    else
                    EXITM @CatStr(<[esi].>,&nombre,<_mtx>,<[>,eax * TYPE nombre&_mtx_type+ %dist ,<]>)
                    endif
                else
                   % echo @CatStr(<add dword ptr [ebp - >,%mtxTLS_usados*@WordSize,< ],>, %dist)
                   % @CatStr(<add dword ptr SS:[ebp - >,%mtxTLS_usados*@WordSize,< ],>, %dist)
     % echo                   EXITM <@CatStr(tipo,< ptr [ebp->,%mtxTLS_usados*@WordSize,<]>)>

                    EXITM <@CatStr(tipo,< ptr [ebp->,%mtxTLS_usados*@WordSize,<]>)>
                endif
            else
                if isSmpMth eq 0
                    EXITM @CatStr(&nombre,<_mtx>,<[>,eax + %dist ,<]>)
                else
                    add dword ptr SS:[ebp - mtxTLS_usados*@WordSize ], %dist
                    EXITM <@CatStr(<[ebp->,mtxTLS_usados*@WordSize,<].>,&tipo)>
                endif
            endif

        elseif hayv
            if isStruct eq 0   
                if isSmpMth eq 0
                if isOA eq 0
                    EXITM @CatStr(&nombre,<_mtx>,<[>,eax * TYPE nombre&_mtx ,<]>)
                    else
                    EXITM @CatStr(<[esi].>,&nombre,<_mtx>,<[>,eax * TYPE nombre&_mtx_type ,<]>)
                    endif
                else
                    EXITM <@CatStr(&nombre,<_mtx>,<[ebp->,mtxTLS_usados*@WordSize,<]>)>
                endif
            else
                if isSmpMth eq 0
                if isOA eq 0
                    EXITM @CatStr(&nombre,<_mtx>,<[>,eax,<]>)
                    else
                    EXITM @CatStr(<[esi].>,&nombre,<_mtx>,<[>,eax,<]>)
                    endif
                else
                    EXITM <@CatStr(<[ebp->,mtxTLS_usados*@WordSize,<].>,&tipo)>
                endif
            endif
        elseif hayc
        if isOA eq 0
            EXITM @CatStr(&nombre,<_mtx>,<[>, %dist ,<]>)
            else
                EXITM @CatStr(<[esi].>,&nombre,<_mtx>,<[>, %dist ,<]>)
endif
        endif
    ENDM

;-------------------------------------------------------------------------------
    &nombre&P MACRO PuntReg:=<esi>, dimensionsn:VARARG
        LOCAL count, dwidth, dist, hayc, hayv, dewidth2, nombrestore

        count = 0
        dwidth = 1
        dist = 0
        hayc = 0
        hayv = 0

        if 0   
        if &isSmpMth eq 1
        IF mtxTLS_curr_line NE @Line
        mtxTLS_curr_line = @Line
        mtxTLS_usados = 0
        ENDIF
        endif
        endif

        FOR arg,<&dimensionsn>
            oa = OPATTR arg
            if oa and 0100b
                hayc = 1
            else
                hayv = 1
            endif
        ENDM

        if hayv
            mov eax, 0
        endif

        FOR arg,<&dimensionsn>
            count = count + 1
            oa = OPATTR arg
            if oa and 0100b
            if isOA eq 0
                dwidth2 = dwidth * TYPE nombre&_mtx
                else
                dwidth2 = dwidth * TYPE nombre&_mtx_type
                endif
                dist = dist + (arg * dwidth2)
            else
                push eax
                mov eax, arg
                mov ecx, dwidth
                mul ecx       
                pop ecx
                add eax, ecx
            endif
            dwidth = dwidth * @ArgI(%count, <dimensions>)
 
        ENDM

        if hayv
            if isStruct eq 1
            if isOA eq 0
                mov ecx,  TYPE nombre&_mtx
                else
                mov ecx,  TYPE nombre&_mtx_type
                endif
                mul ecx
            endif
            if isSmpMth eq 1
            %   add eax, offset @CatStr(&nombre,<_mtx>)
                mtxTLS_usados = mtxTLS_usados + 1
           ;;     % echo @CatStr(%mtxTLS_usados)
           %     if mtxTLS_usados gt mtxTLS_reservados
                    .err   incrementar reserva mtxTLS() en @FileCur
                endif
                if hayc
                %    add eax, dist
                endif
           %     mov dword ptr SS:[ebp - mtxTLS_usados*@WordSize ], eax
            endif
        endif

        if hayv and hayc
            if isStruct eq 0   
                if isSmpMth eq 0
                if isOA eq 0
                    EXITM @CatStr(&nombre,<_mtx>,<[>,eax * TYPE nombre&_mtx+ %dist ,<]>)
                    else
                    EXITM @CatStr(<[>,&PuntReg,<].>,&nombre,<_mtx>,<[>,eax * TYPE nombre&_mtx_type+ %dist ,<]>)
                    endif
                else
                   % echo @CatStr(<add dword ptr [ebp - >,%mtxTLS_usados*@WordSize,< ],>, %dist)
                   % @CatStr(<add dword ptr SS:[ebp - >,%mtxTLS_usados*@WordSize,< ],>, %dist)
     % echo                   EXITM <@CatStr(tipo,< ptr [ebp->,%mtxTLS_usados*@WordSize,<]>)>

                    EXITM <@CatStr(tipo,< ptr [ebp->,%mtxTLS_usados*@WordSize,<]>)>
                endif
            else
                if isSmpMth eq 0
                    EXITM @CatStr(&nombre,<_mtx>,<[>,eax + %dist ,<]>)
                else
                    add dword ptr SS:[ebp - mtxTLS_usados*@WordSize ], %dist
                    EXITM <@CatStr(<[ebp->,mtxTLS_usados*@WordSize,<].>,&tipo)>
                endif
            endif

        elseif hayv
            if isStruct eq 0   
                if isSmpMth eq 0
                if isOA eq 0
                    EXITM @CatStr(&nombre,<_mtx>,<[>,eax * TYPE nombre&_mtx ,<]>)
                    else
                    EXITM @CatStr(<[>,&PuntReg,<].>,&nombre,<_mtx>,<[>,eax * TYPE nombre&_mtx_type ,<]>)
                    endif
                else
                    EXITM <@CatStr(&nombre,<_mtx>,<[ebp->,mtxTLS_usados*@WordSize,<]>)>
                endif
            else
                if isSmpMth eq 0
                if isOA eq 0
                    EXITM @CatStr(&nombre,<_mtx>,<[>,eax,<]>)
                    else
                    EXITM @CatStr(<[>,&PuntReg,<].>,&nombre,<_mtx>,<[>,eax,<]>)
                    endif
                else
                    EXITM <@CatStr(<[ebp->,mtxTLS_usados*@WordSize,<].>,&tipo)>
                endif
            endif
        elseif hayc
        if isOA eq 0
            EXITM @CatStr(&nombre,<_mtx>,<[>, %dist ,<]>)
            else
                EXITM @CatStr(<[>,&PuntReg,<].>,&nombre,<_mtx>,<[>, %dist ,<]>)
endif
        endif
    ENDM




endm

DIM macro nombre, tipo, dimensions:VARARG
%    DIM_MASTER 0, 0, 0, nombre, tipo, <dimensions>
ENDM

DIMS macro nombre, tipo, dimensions:VARARG
%    DIM_MASTER 1, 0, 0, nombre, tipo, <dimensions>
ENDM

DIMOA macro nombre, tipo, dimensions:VARARG
%    DIM_MASTER 0, 0, 1, nombre, tipo, <dimensions>
ENDM
DIMSOA macro nombre, tipo, dimensions:VARARG
%    DIM_MASTER 0, 0, 1, nombre, tipo, <dimensions>
ENDM



mtxTLS macro punteros
    ifb <punteros>
    %    mtxTLS_reservados = 4*@WordSize
    else
    %    mtxTLS_reservados = &punteros*@WordSize
    endif
    mtxTLS_usados = 0
    %EXITM <mtxTLS_puntero[mtxTLS_reservados]:byte>
endm

Regards, HSE.