Skip to content

Additionnal functions and a few remarks #65

@flintforge

Description

@flintforge

These are a few personal notes I wrote when I first tried vmath.
I was hoping to get some time to code some nim, unfortunately I don't have that time.
and didn't keep a very closed eye on the project, so it is perfectly possible these remarks fall flat.
(I saw something on the swizzle ops passing by), still, hoping they will be helpful :

#+Date:[2022-06-18 15:25:23]

# additional functions to suiggest in vmath

import vmath

type
  GV2 = Vec2 | array[2,float32] | tuple[x,y:float32]  # a generic vector of size 2
  GV3 = Vec3 | array[3,float32] | tuple[x,y,z:float32]  # a generic vector of size 3
  GV4 = Vec4 | array[4,float32] | tuple[x,y,z,w:float32]  # a generic vector of size 4

  GVec234[T] = GVec2[T] | GVec3[T] | GVec4[T]

  Vec4f* = Vec4 
  Mat4f* = Mat4

template `=`*[T](a: var GVec234[T], b:GV2) = (a[0], a[1])            = (b[0], b[1])
template `=`*[T](a: var GVec234[T], b:GV3) = (a[0], a[1], a[2])      = (b[0], b[1], b[3])
template `=`*[T](a: var GVec234[T], b:GV4) = (a[0], a[1], a[2],a[3]) = (b[0], b[1], b[2], b[3])

template `xy=`*[T](a: var GVec234[T], b: GV2) = (a[0], a[1]) = (b[0], b[1])

# add or mul of a vec with a smaller one is accepted
proc `*=`*(a: var Vec3, b:GV2) = a.x *= b[0]; a.y *= b[1]
proc `+=`*(a: var Vec3, b:GV2) = a.x += b[0]; a.y += b[1]

template `=`*(a: var Vec3, b:Vec2) = (a[0], a[1], a[2]) = (b[0], b[1], 0.0)

# allow int parameter given to vec2f ctor
proc vec2*(x,y:int):Vec2 = return vec2(float(x), float(y))

when isMainModule:
  let a:int=0
  assert vec2(a,1) is GVec2[float32]

# vec2f accept a vec3 as ctor
proc vec2*(v:Vec3):Vec2 = return vec2(v.xy)

when isMainModule:
  assert type(vec2(vec3())) is GVec2[float32]


# the identity. Often requested, must be passed by copy  
const IDT*:Mat4f = gmat4(1.0f, 0.0f, 0.0f, 0.0f,
                         0.0f, 1.0f, 0.0f, 0.0f,
                         0.0f, 0.0f, 1.0f, 0.0f,
                         0.0f, 0.0f, 0.0f, 1.0f  )
# If passed bycopy is the following still necessary ?
# proc Identity(m:var Mat4f)=  m = IDT

const DEGREE_TO_RADIAN* = 0.01745329251994329576  


proc mat4[T](Q:Quat):GMat4[T]=
  # create a matrix from a quaterniop located at origin
  let (w, x, y, z) = Q
    
  result = [[1.f-2.f*(y*y+z*z), 2.f*(x*y+w*z),     2.f*(x*z-w*y),     0.f],
            [2.f*(x*y-w*z),     1.f-2.f*(x*x+z*z), 2.f*(y*z+w*x),     0.f],
            [2.f*(x*z+w*y),     2.f*(y*z-w*x),     1.f-2.f*(x*x+y*y), 0.f],
            [0.f,               0.f,               0.f,               1.f]]

Aren't those naming dubious :
translate, rotate, scale ?

If they aren't performing operations
but returning the corresponing
matrices in canonical base,
then they should be named
translation, rotation, and scaling

while translate would modify the given matrix as parameter

# aren't we missing quaternion templates ?
# proc `*`(p,q:Quat):Quat=
#     let
#       w1 = p[0] # w
#       v1 = vec3(p[1],p[2],p[3])
#       w2 = q[0]
#       v2 = vec3(q[1],q[2], q[3])
#       (x,y,z) = (w1 * v2 + w2 * v1 + cross(v1, v2)).xyz
#     result = quat(w1*w2 - dot(v1, v2), x,y,z )


from math import sqrt
    
proc arcball*(x, y : float32):Quat=
  # TODO 
  let h2 = x*x + y*y
  var v:Vec3
  
  if h2 > 1.0f:
    let h = sqrt(h2)
    v = vec3(x/h, y/h, 0f)
  else:
    v = vec3(x, y, sqrt(1.0f-h2))
    
  return quat(v.x, v.y, v.z, 0.0f)


proc translate*[T](m: var GMat4[T], v:GVec3[T]): GMat4[T] =
  ## Create translation matrix.
  m[0][3] += v[0]
  m[1][3] += v[1]
  m[2][3] += v[2]
  m

I really wish I could do more than that.
Keep up the good work !

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions