[solved] Maybe one "BUG" and one question :-)

General FreeBASIC programming questions.
Post Reply
D.J.Peters
Posts: 8586
Joined: May 28, 2005 3:28
Contact:

[solved] Maybe one "BUG" and one question :-)

Post by D.J.Peters »

First maybe a bug in line 76 in a static member function I return a single ptr "Matrix4f._Temp.m" but the return type is declared as Matrix4f without any error message !

Code: Select all

static function Matrix4f.inverse(byref m4 as const Matrix4f) as Matrix4f
  if Matrix4f.inverse(m4.m,Matrix4f._Temp.m)=true then return Matrix4f._Temp.m ' <--- must be "return Matrix4f._Temp" no error message
  return Matrix4f._Identity
end function
Now the second part my question how can simulate a static member as read only ?
Matrix4f._Identity is a 4x4 identity matrix and I return it in static member function Matrix4f.Identy()
how can I make Matrix4f._Identity it as const so no one can overwrite it ?

Joshy

Code: Select all

#include "crt.bi"
type Matrix4f
  declare destructor
  declare constructor
  declare constructor(byref m0 as const single,byref m1 as const single,byref m2 as const single, byref m3 as const single, _
                      byref m4 as const single,byref m5 as const single, byref m6 as const single,byref m7 as const single, _
                      byref m8 as const single,byref m9 as const single, byref m10 as const single,byref m11 as const single, _
                      byref m12 as const single,byref m13 as const single, byref m14 as const single,byref m15 as const single)
  declare constructor (byref mat4 as const Matrix4f)
  declare constructor (byref p as const single ptr)
  as single ptr m=any
  static _Temp as Matrix4f
  static _Identity as Matrix4f
  declare static function Identity() as Matrix4f
  declare static function Identity(byref result as Matrix4f) as Matrix4f
  declare static function Inverse(byval p4 as const single ptr,byval pResult as single ptr) as boolean
  declare static function Inverse(byref mat4 as const Matrix4f) as Matrix4f
  declare static function Inverse(byref mat4 as const Matrix4f,byref result as Matrix4f) as Matrix4f
end type
' static stuff
dim Matrix4f._Temp as Matrix4f ' default constructor callocates empty ZERO matrix
dim Matrix4f._Identity as Matrix4f=Matrix4f(1,0,0,0, 0,1,0,0, 0,0,1,0, 0,0,0,1)
static function Matrix4f.Identity() as Matrix4f
  return Matrix4f._Identity
end function
static function Matrix4f.Identity(byref result as Matrix4f) as Matrix4f
  memcpy(result.m,Matrix4f._Identity.m,sizeof(single)*16):return result
end function
static function Matrix4f.inverse(byval mat as const single ptr,byval res as single ptr) as boolean
  dim as single A=mat[ 0],B=mat[ 1],C=mat[ 2],D=mat[ 3]
  dim as single E=mat[ 4],F=mat[ 5],G=mat[ 6],H=mat[ 7]
  dim as single I=mat[ 8],J=mat[ 9],K=mat[10],L=mat[11]
  dim as single M=mat[12],N=mat[13],O=mat[14],P=mat[15]
  dim as single Q=-mat[0],R=-mat[1],S=-mat[4],det=0
  ' 4 repeats on right side [ BC]
  dim as single KP=K*P,OL=O*L,JP=J*P,NL=N*L,JO=J*O,NK=N*K,iP=I*P,IO=I*O,IN=I*N,MJ=M*J
  ' 3 repeats on right side [ BC]
  dim as single ML=M*J,MK=M*K
  ' 4 epeats on left   side [AB ]
  dim as single CE=C*E,DE=D*E,BE=B*E
  ' 3 repeats on left  side [AB ]
  dim as single DM=D*M,BM=B*M
  res[ 0] = F*KP  - F*OL  - G*JP  + G*NL  + H*JO  - H*NK
  res[ 4] = S*KP  + E*OL  + G*IP  - G*ML  - H*IO  + H*MK
  res[ 8] = E*JP  - E*NL  - F*IP  + F*ML  + H*IN  - H*MJ
  res[12] = S*JO  + E*NK  + F*IO  - F*MK  - G*IN  + G*MJ
  
  det = A*res[0] + B*res[4] + C*res[8] + D*res[12]
  if det=0 then return false
  
  res[ 1] = R*KP  + B*OL  + C*JP  - C*NL  - D*JO  + D*NK
  res[ 2] = B*G*P - B*O*H - C*F*P + C*N*H + D*F*O - D*N*G
  res[ 3] = R*G*L + B*K*H + C*F*L - C*J*H - D*F*K + D*J*G
    
  res[ 5] = A*KP  - A*OL  - C*IP  + C*ML  + D*IO - DM*K
  res[ 6] = Q*G*P + A*O*H + CE*P  - C*M*H - DE*O + DM*G
  res[ 7] = A*G*L - A*K*H - CE*L  + C*I*H + DE*K - D*I*G
    
  res[ 9] = Q*JP  + A*NL  + B*IP  - BM*L  - D*IN + D*MJ
  res[10] = A*F*P - A*N*H - BE*P  + BM*H  + DE*N - DM*F
  res[11] = Q*F*L + A*J*H + BE*L  - B*I*H - DE*J + D*I*F
    
  res[13] = A*JO  - A*NK  - B*IO  + B*MK  + C*IN - C*MJ
  res[14] = Q*F*O + A*N*G + BE*O  - BM*G  - CE*N + C*M*F
  res[15] = A*F*K - A*J*G - BE*K  + B*I*G + CE*J - C*I*F
  
  det = 1/det
  res[ 0]*= det:res[ 1]*= det:res[ 2]*= det:res[ 3]*= det
  res[ 4]*= det:res[ 5]*= det:res[ 6]*= det:res[ 7]*= det
  res[ 8]*= det:res[ 9]*= det:res[10]*= det:res[11]*= det
  res[12]*= det:res[13]*= det:res[14]*= det:res[15]*= det
  return true 
end function
' NOTE: Matrix4f._Temp.m is a single ptr not a Matrix4f 
static function Matrix4f.inverse(byref m4 as const Matrix4f) as Matrix4f
  if Matrix4f.inverse(m4.m,Matrix4f._Temp.m)=true then return Matrix4f._Temp.m ' must be return Matrix4f._Temp
  return Matrix4f._Identity
end function
static function Matrix4f.inverse(byref m4 as const Matrix4f,byref result as Matrix4f) as Matrix4f
  if Matrix4f.inverse(m4.m, result.m)=true then return result
  result=Matrix4f._Identity
end function

destructor Matrix4f
  deallocate m
end destructor
constructor Matrix4f
  m = callocate(16*sizeof(single))
end constructor
constructor Matrix4f(byref m0 as const single,byref m1 as const single,byref m2 as const single, byref m3 as const single, _
                     byref m4 as const single,byref m5 as const single, byref m6 as const single,byref m7 as const single, _
                     byref m8 as const single,byref m9 as const single, byref m10 as const single,byref m11 as const single, _
                     byref m12 as const single,byref m13 as const single, byref m14 as const single,byref m15 as const single)
  m = allocate(16*sizeof(single))
  m[ 0]=m0 :m[ 1]=m1 :m[ 2]=m2 :m[ 3]=m3
  m[ 4]=m4 :m[ 5]=m5 :m[ 6]=m6 :m[ 7]=m7
  m[ 8]=m8 :m[ 9]=m9 :m[10]=m10:m[11]=m11
  m[12]=m12:m[13]=m13:m[14]=m14:m[15]=m15
end constructor
constructor Matrix4f(byref m4 as const Matrix4f)
  m = allocate(16*sizeof(single))
  memcpy(m,m4.m,16*sizeof(single))
end constructor  
constructor Matrix4f(byref p as const single ptr)
  m = allocate(16*sizeof(single))
  memcpy(m,p,16*sizeof(single))
end constructor
Last edited by D.J.Peters on Jun 14, 2021 16:19, edited 1 time in total.
fxm
Moderator
Posts: 12082
Joined: Apr 22, 2009 12:46
Location: Paris suburbs, FRANCE

Re: Maybe one "BUG" and one question :-)

Post by fxm »

No bug because a matching constructor exists:
  • declare constructor (byref p as const single ptr)
Conversion-constructors:
  • If a Type has a constructor with a single parameter, or if at least all other parameters have a default value, the type of the first argument can be implicitly converted to the type of the Type by the compiler.
    In such expressions, the term 'variable' may be considered as a short-cut of 'typename(variable)'.

    Such conversions can be useful in some cases, but more often they can lead to poor readability (in these cases, it is better to explicitly call the matching constructor).
.....
.....
fxm
Moderator
Posts: 12082
Joined: Apr 22, 2009 12:46
Location: Paris suburbs, FRANCE

Re: Maybe one "BUG" and one question :-)

Post by fxm »

Maybe:
.....
static _Identity as const Matrix4f
.....
dim Matrix4f._Identity as const Matrix4f=Matrix4f(1,0,0,0, 0,1,0,0, 0,0,1,0, 0,0,0,1)
.....
D.J.Peters
Posts: 8586
Joined: May 28, 2005 3:28
Contact:

Re: Maybe one "BUG" and one question :-)

Post by D.J.Peters »

fxm wrote:No bug because a matching constructor exists:
fbc replace
return Matrix4f._Temp.m
with
return Matrix4f(Matrix4f._Temp.m)

I see no bug a feature :-)

dim Matrix4f._Identity as const Matrix4f = Matrix4f(1,0,0,0, 0,1,0,0, 0,0,1,0, 0,0,0,1)

to simple :-)

I'm sure I tried it long time ago without success do you know since fbc supports static const members ?

again thank you

Joshy
fxm
Moderator
Posts: 12082
Joined: Apr 22, 2009 12:46
Location: Paris suburbs, FRANCE

Re: [solved] Maybe one "BUG" and one question :-)

Post by fxm »

For this to work, the initializer term must be able to be evaluated at compile time, which has been the case through constructors since ??? (I don't remember).
Post Reply