Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Additionnal functions and a few remarks #65

Open
flintforge opened this issue Feb 27, 2023 · 1 comment
Open

Additionnal functions and a few remarks #65

flintforge opened this issue Feb 27, 2023 · 1 comment

Comments

@flintforge
Copy link

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 !

@treeform
Copy link
Owner

treeform commented Mar 4, 2023

Sorry, I am not into the many suggests that are here. This vector stuff hard enough and I just see me making bugs where I pass a vec2 into a vec3 and it just magically works. Some amount of magic is nice, while too much can lead to all kind of confusion its totally personal taste.

Sorry not a fan of array or tuples acting like vectors, I feel like if you have a type it should stay that type. Nim is all about type safety I don't want to throw it a way.

You are probably right about the names: translate, rotate, scale. I don't think they are that bad that it all needs chaining and breaking backward compatibility.

I actually like the idea of "allow int parameter given to vec2f ctor" and maybe I'll do some thing like this. I do feel like vec3 is a typed thing and should except integers etc... up-casting to a higher precession.

When you create a mat4() its already an identity mat, why do you want another one?

And quat to mat4 already exists. It just takes a vec4 which is what GLSL does.

I probably need to add other quat functions though.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants