From c8b1a82229bb1cb08b6aae55c62661a5b94afae9 Mon Sep 17 00:00:00 2001 From: Carlos Sanchez Date: Thu, 1 Aug 2024 23:11:50 -0400 Subject: [PATCH] Trying to setup camera --- renderer1/hrend/math.go | 139 +++++++++++++++++++++++++++++++++++++--- renderer1/main.go | 53 +++++++++++---- 2 files changed, 169 insertions(+), 23 deletions(-) diff --git a/renderer1/hrend/math.go b/renderer1/hrend/math.go index d8e644e..661899b 100644 --- a/renderer1/hrend/math.go +++ b/renderer1/hrend/math.go @@ -2,6 +2,7 @@ package hrend // This is the linear algebra junk? Vectors, matrices, etc import ( + //"log" "math" ) @@ -31,6 +32,54 @@ func (m *Mat44f) ZeroFill() { m[i] = 0 } } + +// Multiply the entire matrix by the given value +func (m *Mat44f) MultiplySelf(f float32) { + for i := range m { + m[i] *= f + } +} + +// Copied from https://github.com/go-gl/mathgl/blob/master/mgl32/matrix.go +func (m *Mat44f) Determinant() float32 { + return m[0]*m[5]*m[10]*m[15] - m[0]*m[5]*m[11]*m[14] - m[0]*m[6]*m[9]*m[15] + m[0]*m[6]*m[11]*m[13] + m[0]*m[7]*m[9]*m[14] - m[0]*m[7]*m[10]*m[13] - m[1]*m[4]*m[10]*m[15] + m[1]*m[4]*m[11]*m[14] + m[1]*m[6]*m[8]*m[15] - m[1]*m[6]*m[11]*m[12] - m[1]*m[7]*m[8]*m[14] + m[1]*m[7]*m[10]*m[12] + m[2]*m[4]*m[9]*m[15] - m[2]*m[4]*m[11]*m[13] - m[2]*m[5]*m[8]*m[15] + m[2]*m[5]*m[11]*m[12] + m[2]*m[7]*m[8]*m[13] - m[2]*m[7]*m[9]*m[12] - m[3]*m[4]*m[9]*m[14] + m[3]*m[4]*m[10]*m[13] + m[3]*m[5]*m[8]*m[14] - m[3]*m[5]*m[10]*m[12] - m[3]*m[6]*m[8]*m[13] + m[3]*m[6]*m[9]*m[12] +} + +// Copied from https://github.com/go-gl/mathgl/blob/master/mgl32/matrix.go +func (m *Mat44f) Inverse() *Mat44f { + det := m.Determinant() + + if det == float32(0.0) { + return &Mat44f{} + } + + // How the hell am I supposed to know if this is correct? Oh well... + result := Mat44f{ + -m[7]*m[10]*m[13] + m[6]*m[11]*m[13] + m[7]*m[9]*m[14] - m[5]*m[11]*m[14] - m[6]*m[9]*m[15] + m[5]*m[10]*m[15], + m[3]*m[10]*m[13] - m[2]*m[11]*m[13] - m[3]*m[9]*m[14] + m[1]*m[11]*m[14] + m[2]*m[9]*m[15] - m[1]*m[10]*m[15], + -m[3]*m[6]*m[13] + m[2]*m[7]*m[13] + m[3]*m[5]*m[14] - m[1]*m[7]*m[14] - m[2]*m[5]*m[15] + m[1]*m[6]*m[15], + m[3]*m[6]*m[9] - m[2]*m[7]*m[9] - m[3]*m[5]*m[10] + m[1]*m[7]*m[10] + m[2]*m[5]*m[11] - m[1]*m[6]*m[11], + m[7]*m[10]*m[12] - m[6]*m[11]*m[12] - m[7]*m[8]*m[14] + m[4]*m[11]*m[14] + m[6]*m[8]*m[15] - m[4]*m[10]*m[15], + -m[3]*m[10]*m[12] + m[2]*m[11]*m[12] + m[3]*m[8]*m[14] - m[0]*m[11]*m[14] - m[2]*m[8]*m[15] + m[0]*m[10]*m[15], + m[3]*m[6]*m[12] - m[2]*m[7]*m[12] - m[3]*m[4]*m[14] + m[0]*m[7]*m[14] + m[2]*m[4]*m[15] - m[0]*m[6]*m[15], + -m[3]*m[6]*m[8] + m[2]*m[7]*m[8] + m[3]*m[4]*m[10] - m[0]*m[7]*m[10] - m[2]*m[4]*m[11] + m[0]*m[6]*m[11], + -m[7]*m[9]*m[12] + m[5]*m[11]*m[12] + m[7]*m[8]*m[13] - m[4]*m[11]*m[13] - m[5]*m[8]*m[15] + m[4]*m[9]*m[15], + m[3]*m[9]*m[12] - m[1]*m[11]*m[12] - m[3]*m[8]*m[13] + m[0]*m[11]*m[13] + m[1]*m[8]*m[15] - m[0]*m[9]*m[15], + -m[3]*m[5]*m[12] + m[1]*m[7]*m[12] + m[3]*m[4]*m[13] - m[0]*m[7]*m[13] - m[1]*m[4]*m[15] + m[0]*m[5]*m[15], + m[3]*m[5]*m[8] - m[1]*m[7]*m[8] - m[3]*m[4]*m[9] + m[0]*m[7]*m[9] + m[1]*m[4]*m[11] - m[0]*m[5]*m[11], + m[6]*m[9]*m[12] - m[5]*m[10]*m[12] - m[6]*m[8]*m[13] + m[4]*m[10]*m[13] + m[5]*m[8]*m[14] - m[4]*m[9]*m[14], + -m[2]*m[9]*m[12] + m[1]*m[10]*m[12] + m[2]*m[8]*m[13] - m[0]*m[10]*m[13] - m[1]*m[8]*m[14] + m[0]*m[9]*m[14], + m[2]*m[5]*m[12] - m[1]*m[6]*m[12] - m[2]*m[4]*m[13] + m[0]*m[6]*m[13] + m[1]*m[4]*m[14] - m[0]*m[5]*m[14], + -m[2]*m[5]*m[8] + m[1]*m[6]*m[8] + m[2]*m[4]*m[9] - m[0]*m[6]*m[9] - m[1]*m[4]*m[10] + m[0]*m[5]*m[10], + } + + result.MultiplySelf(1 / det) + //log.Print(m) + //log.Print(result) + + return &result +} + func (m *Mat44f) SetIdentity() { m.ZeroFill() for i := range 4 { @@ -85,6 +134,51 @@ func (m *Mat44f) SetTranslation(x, y, z float32) { m.Set(2, 3, z) // Get farther away from the face (user) } +func (m *Mat44f) SetRotationX(radang float32) { + m.SetIdentity() + m[5] = float32(math.Cos(float64(radang))) + m[10] = m[5] + m[6] = float32(math.Sin(float64(radang))) + m[9] = -m[6] +} + +func (m *Mat44f) SetRotationY(radang float32) { + m.SetIdentity() + m[0] = float32(math.Cos(float64(radang))) + m[10] = m[0] + m[8] = float32(math.Sin(float64(radang))) + m[2] = -m[8] +} + +func (m *Mat44f) SetRotationZ(radang float32) { + m.SetIdentity() + m[0] = float32(math.Cos(float64(radang))) + m[5] = m[0] + m[4] = float32(math.Sin(float64(radang))) + m[2] = -m[4] +} + +// Note: use {0,1,0} for up for normal use +func (m *Mat44f) SetLookAt(from *Vec3f, to *Vec3f, up *Vec3f) { + forward := from.Sub(to).Normalize() + // IDK if you have to normalize but whatever + right := up.CrossProduct(forward).Normalize() + realup := forward.CrossProduct(right) + m.SetIdentity() + m.Set(0, 0, right.X) + m.Set(1, 0, right.Y) + m.Set(2, 0, right.Z) + m.Set(0, 1, realup.X) + m.Set(1, 1, realup.Y) + m.Set(2, 1, realup.Z) + m.Set(0, 2, forward.X) + m.Set(1, 2, forward.Y) + m.Set(2, 2, forward.Z) + m.Set(0, 3, from.X) + m.Set(1, 3, from.Y) + m.Set(2, 3, from.Z) +} + func (m *Mat44f) SetViewport(tl Vec3f, br Vec3f) { //width, height, depth int) { m.ZeroFill() m.Set(0, 0, (br.X-tl.X)/2) @@ -123,8 +217,9 @@ func (m *Mat44f) MultiplyPoint3(p Vec3f) Vec3f { return out } -// Multiply two 4x4 matrices together (not optimized) -func (m *Mat44f) Multiply(m2 *Mat44f) Mat44f { +// Multiply two 4x4 matrices together (not optimized). May +// mess with garbage collector?? IDK +func (m *Mat44f) Multiply(m2 *Mat44f) *Mat44f { var result Mat44f // This is the x and y of our resulting matrix for y := 0; y < 4; y++ { @@ -134,9 +229,27 @@ func (m *Mat44f) Multiply(m2 *Mat44f) Mat44f { } } } - return result + return &result } +// Multiply two matrices, storing the result in the first one +// func (m *Mat44f) MultiplyInto(m2 *Mat44f) { +// var orig Mat44f +// for i := 0; i < 16; i++ { +// orig[i] = m[i] +// } +// // This is the x and y of our resulting matrix +// for y := 0; y < 4; y++ { +// for x := 0; x < 4; x++ { +// m[x+y*4] = 0 +// for i := 0; i < 4; i++ { +// m[x+y*4] += orig[i+y*4] * m2[x+i*4] +// } +// } +// } +// return &result +// } + func (vi *Vec2i) ToF() Vec2f { return Vec2f{float32(vi.X), float32(vi.Y)} } @@ -145,16 +258,24 @@ func (vi *Vec3f) ToVec2i() Vec2i { return Vec2i{int(vi.X), int(vi.Y)} } -func (v0 *Vec3f) Sub(v1 Vec3f) Vec3f { - return Vec3f{ +func (v0 *Vec3f) Add(v1 *Vec3f) *Vec3f { + return &Vec3f{ + X: v0.X + v1.X, + Y: v0.Y + v1.Y, + Z: v0.Z + v1.Z, + } +} + +func (v0 *Vec3f) Sub(v1 *Vec3f) *Vec3f { + return &Vec3f{ X: v0.X - v1.X, Y: v0.Y - v1.Y, Z: v0.Z - v1.Z, } } -func (v0 *Vec3f) CrossProduct(v1 Vec3f) Vec3f { - return Vec3f{ +func (v0 *Vec3f) CrossProduct(v1 *Vec3f) *Vec3f { + return &Vec3f{ X: v0.Y*v1.Z - v0.Z*v1.Y, Y: v0.Z*v1.X - v0.X*v1.Z, Z: v0.X*v1.Y - v0.Y*v1.X, @@ -163,9 +284,9 @@ func (v0 *Vec3f) CrossProduct(v1 Vec3f) Vec3f { //func (v -func (v *Vec3f) Normalize() Vec3f { +func (v *Vec3f) Normalize() *Vec3f { l := float32(math.Sqrt(float64(v.MultSimp(v)))) - return Vec3f{ + return &Vec3f{ X: v.X / l, Y: v.Y / l, Z: v.Z / l, diff --git a/renderer1/main.go b/renderer1/main.go index 58e441c..aca0d95 100644 --- a/renderer1/main.go +++ b/renderer1/main.go @@ -21,8 +21,9 @@ const ( NearClip = 0.1 FarClip = 100 FOV = 90.0 - ZOffset = -1.5 + ZOffset = 1.5 Movement = 1.0 + Rotation = 1.0 Fps = 60 ObjectFile = "../head.obj" TextureFile = "../head.jpg" @@ -99,7 +100,7 @@ func main() { var thing hrend.Vec2i log.Print(thing) - var projection, worldToCamera, viewport hrend.Mat44f + var projection, viewport hrend.Mat44f // These don't really change projection.SetProjection(float32(FOV), float32(Width)/float32(Height), NearClip, FarClip) @@ -111,37 +112,61 @@ func main() { frameCount := 0 frameAverage := 0.0 - xofs := float32(0.0) - yofs := float32(0.0) - zofs := float32(ZOffset) + camtrans := hrend.Vec3f{X: 0, Y: 0, Z: ZOffset} + camup := hrend.Vec3f{X: 0, Y: 1, Z: 0} + + //xrot := float32(0.0) + //zrot := float32(0.0) + lookvec := hrend.Vec3f{X: 0, Y: 0, Z: -1} + + // in all three directions... I think?? + //yrot := float32(0.0) + + //var camrotation, camtrans hrend.Mat44f + //camrotation.SetIdentity() + //var camrotx, camroty, camrotz hrend.Mat44f + var camera hrend.Mat44f for !rl.WindowShouldClose() { start := time.Now() if rl.IsKeyDown(rl.KeyD) { - xofs += Movement / Fps + camtrans.X += Movement / Fps } if rl.IsKeyDown(rl.KeyA) { - xofs -= Movement / Fps + camtrans.X -= Movement / Fps } + // Moving forward moves in the negative z direction, since we FACE + // the -z axis if rl.IsKeyDown(rl.KeyW) { - zofs += Movement / Fps + camtrans.Z -= Movement / Fps } if rl.IsKeyDown(rl.KeyS) { - zofs -= Movement / Fps + camtrans.Z += Movement / Fps } if rl.IsKeyDown(rl.KeySpace) { - yofs -= Movement / Fps + camtrans.Y += Movement / Fps } if rl.IsKeyDown(rl.KeyLeftShift) { - yofs += Movement / Fps + camtrans.Y -= Movement / Fps } - // This might (thought not currently) - worldToCamera.SetTranslation(xofs, yofs, zofs) + mouse := rl.GetMouseDelta() + mouse.X *= 1 / Fps + mouse.Y *= 1 / Fps - screenmat := worldToCamera.Multiply(&projection) + //camrotx.SetRotationX(xrot) + //camroty.SetRotationY(yrot) + //camrotz.SetRotationZ(zrot) + //camrotation = *camrotation.Multiply( + // This might (thought not currently) + //camtrans.SetTranslation(xofs, yofs, zofs) + + camera.SetLookAt(&camtrans, camtrans.Add(&lookvec), &camup) + + //screenmat := camrotx.Multiply(&camroty).Multiply(&camrotz).Multiply(&camtrans).Inverse().Multiply(&projection) + screenmat := camera.Inverse().Multiply(&projection) screenmat = screenmat.Multiply(&viewport) for i := 0; i < Width*Height; i++ {