// Copyright 2016 The G3N Authors. All rights reserved. // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. // Package camera contain common camera types used for rendering 3D scenes. package camera import ( "github.com/g3n/engine/core" "github.com/g3n/engine/math32" ) // ICamera is interface for all camera types type ICamera interface { GetCamera() *Camera ViewMatrix(*math32.Matrix4) ProjMatrix(*math32.Matrix4) Project(*math32.Vector3) *math32.Vector3 Unproject(*math32.Vector3) *math32.Vector3 SetRaycaster(rc *core.Raycaster, x, y float32) } // Camera is the base camera which is normally embedded in other camera types type Camera struct { core.Node // Embedded Node target math32.Vector3 // camera target in world coordinates up math32.Vector3 // camera Up vector viewMatrix math32.Matrix4 // last calculated view matrix } // Initialize initializes the base camera. // It is used by other camera types which embed this base camera func (cam *Camera) Initialize() { cam.Node.Init() cam.target.Set(0, 0, 0) cam.up.Set(0, 1, 0) cam.SetDirection(0, 0, -1) cam.updateQuaternion() } // WorldDirection updates the specified vector with the // current world direction the camera is pointed func (cam *Camera) WorldDirection(result *math32.Vector3) { var wpos math32.Vector3 cam.WorldPosition(&wpos) *result = cam.target result.Sub(&wpos).Normalize() } // LookAt sets the camera target position func (cam *Camera) LookAt(target *math32.Vector3) { cam.target = *target cam.updateQuaternion() } // GetCamera satisfies the ICamera interface func (cam *Camera) GetCamera() *Camera { return cam } // Target get the current target position func (cam *Camera) Target() math32.Vector3 { return cam.target } // Up get the current up position func (cam *Camera) Up() math32.Vector3 { return cam.up } // SetUp sets the camera up vector func (cam *Camera) SetUp(up *math32.Vector3) { cam.up = *up } // SetPosition sets this camera world position // This method overrides the Node method to update // the camera quaternion, because changing the camera position // may change its rotation func (cam *Camera) SetPosition(x, y, z float32) { cam.Node.SetPosition(x, y, z) cam.updateQuaternion() } // SetPositionVec sets this node position from the specified vector pointer // This method overrides the Node method to update // the camera quaternion, because changing the camera position // may change its rotation func (cam *Camera) SetPositionVec(vpos *math32.Vector3) { cam.Node.SetPositionVec(vpos) cam.updateQuaternion() } // ViewMatrix returns the current view matrix of this camera func (cam *Camera) ViewMatrix(m *math32.Matrix4) { var wpos math32.Vector3 cam.WorldPosition(&wpos) cam.viewMatrix.LookAt(&wpos, &cam.target, &cam.up) *m = cam.viewMatrix } // updateQuaternion must be called when the camera position or target // is changed to update its quaternion. // This is important if the camera has children, such as an audio listener func (cam *Camera) updateQuaternion() { var wdir math32.Vector3 cam.WorldDirection(&wdir) var q math32.Quaternion q.SetFromUnitVectors(&math32.Vector3{0, 0, -1}, &wdir) cam.SetQuaternionQuat(&q) } // Project satisfies the ICamera interface and must // be implemented for specific camera types. func (cam *Camera) Project(v *math32.Vector3) *math32.Vector3 { panic("Not implemented") } // Unproject satisfies the ICamera interface and must // be implemented for specific camera types. func (cam *Camera) Unproject(v *math32.Vector3) *math32.Vector3 { panic("Not implemented") } // SetRaycaster satisfies the ICamera interface and must // be implemented for specific camera types. func (cam *Camera) SetRaycaster(rc *core.Raycaster, x, y float32) { panic("Not implemented") }