func (c *QuatCamera) Rotate(delta mgl.Vec3) { if delta[0] != 0 { // Pitch (about the X axis) q := mgl.QuatRotate(delta[0], AxisRight).Normalize() c.rotation = c.rotation.Mul(q).Normalize() } if delta[1] != 0 { // Yaw (about the Y axis) q := mgl.QuatRotate(delta[1], AxisUp).Normalize() c.rotation = q.Mul(c.rotation).Normalize() } // TODO: Roll }
func (actor *FreeMoveActor) Update(dt float64) { //orientation vertRot := mgl32.QuatRotate(actor.lookAngle, mgl32.Vec3{0, 1, 0}) axis := vertRot.Rotate(mgl32.Vec3{1, 0, 0}).Cross(mgl32.Vec3{0, 1, 0}) horzRot := mgl32.QuatRotate(actor.lookPitch, axis) orientation := horzRot.Mul(vertRot) velocity := orientation.Rotate(mgl32.Vec3{actor.forwardMove, 0, actor.strafeMove}) actor.Location = actor.Location.Add(velocity.Mul(float32(dt))) //update entity actor.Entity.SetTranslation(actor.Location) actor.Entity.SetOrientation(orientation) }
func (actor *FPSActor) Update(dt float64) { // orientation vertRot := mgl32.QuatRotate(actor.lookAngle, mgl32.Vec3{0, 1, 0}) axis := vertRot.Rotate(mgl32.Vec3{1, 0, 0}).Cross(mgl32.Vec3{0, 1, 0}) horzRot := mgl32.QuatRotate(actor.lookPitch, axis) orientation := horzRot.Mul(vertRot) actor.Entity.SetOrientation(orientation) // walking direction if actor.Character.OnGround() { actor.walkDirection = orientation.Rotate(mgl32.Vec3{actor.forwardMove, 0, actor.strafeMove}) } actor.Character.SetWalkDirection(actor.walkDirection) actor.Entity.SetTranslation(actor.Character.GetPosition()) }
func (ps *ParticleSystem) updateParticle(p *Particle, dt float64) { //set translation p.Translation = p.Translation.Add(p.Velocity.Mul(float32(dt))) p.Velocity = p.Velocity.Add(ps.Settings.Acceleration.Mul(float32(dt))) //set orientation / rotation p.Rotation = p.Rotation + (p.RotationVelocity * float32(dt)) p.LifeRemaining = p.LifeRemaining - float32(dt) // set valuew based on life remaining lifeRatio := p.LifeRemaining / p.Life p.Scale = util.Vec3Lerp(ps.Settings.EndSize, ps.Settings.StartSize, lifeRatio) p.Color = lerpColor(ps.Settings.EndColor, ps.Settings.StartColor, lifeRatio) p.Frame = int((1.0 - lifeRatio) * float32(ps.Settings.TotalFrames)) //face the camera if ps.FaceCamera { p.Orientation = util.FacingOrientation(p.Rotation, ps.cameraPosition.Sub(p.Translation), mgl32.Vec3{0, 0, 1}, mgl32.Vec3{-1, 0, 0}) } else { p.Orientation = mgl32.QuatRotate(p.Rotation, mgl32.Vec3{0, 0, 1}) } //is particle dead if p.LifeRemaining <= 0 { p.active = false } if ps.Settings.OnParticleUpdate != nil && p.active { ps.Settings.OnParticleUpdate(p) } }
func (e *Editor) RotateSelectedNodeModel(x, y float32, axisLock mgl32.Vec3) { selectedModel, _ := e.overviewMenu.getSelectedNode(e.currentMap.Root) if selectedModel != nil { selectedModel.Orientation = mgl32.QuatRotate(x*mouseSpeed, axisLock).Mul(selectedModel.Orientation).Normalize() } updateMap(e.currentMap.Root) }
func (actor *PhysicsActor2D) Update(dt float64) { objPos := actor.Object.GetPosition() var position mgl32.Vec3 var orientation mgl32.Quat if actor.Mask.X() < actor.Mask.Y() && actor.Mask.X() < actor.Mask.Z() { // YZ plane position = mgl32.Vec3{0, actor.Mask.Y() * objPos.X(), actor.Mask.Z() * objPos.Y()} orientation = mgl32.QuatRotate(actor.Object.GetAngle(), mgl32.Vec3{1, 0, 0}) } else if actor.Mask.Y() < actor.Mask.X() && actor.Mask.Y() < actor.Mask.Z() { // XZ plane position = mgl32.Vec3{actor.Mask.X() * objPos.X(), 0, actor.Mask.Z() * objPos.Y()} orientation = mgl32.QuatRotate(actor.Object.GetAngle(), mgl32.Vec3{0, 1, 0}) } else { // XY plane position = mgl32.Vec3{actor.Mask.X() * objPos.X(), actor.Mask.Y() * objPos.Y(), 0} orientation = mgl32.QuatRotate(actor.Object.GetAngle(), mgl32.Vec3{0, 0, 1}) } actor.Entity.SetTranslation(position) actor.Entity.SetOrientation(orientation) }
//FacingOrientation - return an orientation that always faces the given direction with rotation func FacingOrientation(rotation float32, direction, normal, tangent mgl32.Vec3) mgl32.Quat { betweenVectorsQ := mgl32.QuatBetweenVectors(normal, direction) angleQ := mgl32.QuatRotate(rotation, normal) orientation := betweenVectorsQ.Mul(angleQ) return orientation }
func (t *Transform) rotateOnAxis(axis mgl32.Vec3, angle float32) { q1 := mgl32.QuatRotate(angle, axis) t.quaternion = t.quaternion.Mul(q1) t.matrix = t.matrix.Mul4(q1.Mat4()) }
func setupScene(gameEngine engine.Engine, shader *renderer.Shader) { camera := gameEngine.Camera() transparentNode := renderer.NewNode() gameEngine.AddSpatialTransparent(transparentNode) transparentNode.RendererParams = &renderer.RendererParams{ DepthTest: true, Unlit: true, Transparency: renderer.EMISSIVE, } // Sky cubemap skyImg, err := assets.ImportImage("TestAssets/cloudSky.jpg") if err == nil { skyImg = imaging.AdjustBrightness(skyImg, -30) skyImg = imaging.AdjustContrast(skyImg, 30) geom := renderer.CreateSkyBox() geom.Transform(mgl32.Scale3D(10000, 10000, 10000)) skyNode := renderer.NewNode() skyNode.SetOrientation(mgl32.QuatRotate(1.57, mgl32.Vec3{0, 1, 0})) skyNode.Material = renderer.NewMaterial(renderer.NewTexture("diffuseMap", skyImg, false)) skyNode.RendererParams = renderer.NewRendererParams() skyNode.RendererParams.CullBackface = false skyNode.RendererParams.Unlit = true skyNode.Add(geom) gameEngine.AddSpatial(skyNode) // create an environmentMap using the skybox texture envCubeMap := renderer.NewCubemap("environmentMap", skyImg, true) gameEngine.DefaultCubeMap(envCubeMap) } // load scene objs objs := []string{ "TestAssets/wellScene/floor.obj", "TestAssets/wellScene/frame1.obj", "TestAssets/wellScene/frame2.obj", "TestAssets/wellScene/well.obj", "TestAssets/wellScene/torches.obj", } for _, objFile := range objs { if geom, mat, err := assets.ImportObjCached(objFile); err == nil { sceneNode := renderer.NewNode() sceneNode.Add(geom) sceneNode.Material = mat sceneNode.RendererParams = renderer.NewRendererParams() sceneNode.RendererParams.CullBackface = false gameEngine.AddSpatial(sceneNode) } } for i := 0; i < 2; i++ { torchLocation := mgl32.Vec3{0.86, 1.76, 1.05} if i == 1 { torchLocation = mgl32.Vec3{0.86, 1.76, -1.05} } fire := fireParticles() spark := sparkParticles() torchParticles := effects.NewParticleGroup(camera, fire, spark) torchParticles.SetTranslation(torchLocation) transparentNode.Add(torchParticles) gameEngine.AddUpdatable(torchParticles) light := renderer.NewLight(renderer.POINT) light.SetTranslation(torchLocation.Add(mgl32.Vec3{0, 0.05, 0})) gameEngine.AddLight(light) var x float64 gameEngine.AddUpdatable(engine.UpdatableFunc(func(dt float64) { x += dt mag := float32(math.Abs(0.6*math.Sin(3*x)+0.3*math.Sin(4*x)+0.15*math.Sin(7*x)+0.1*math.Sin(15*x))) + 0.5 mag *= 0.05 light.Color = [3]float32{1 * mag, 0.6 * mag, 0.4 * mag} })) } }
func windowLoop(window *sdl.Window, cameraMatrixUniform int32) { var ( yrot float32 xrot float32 buttonDown bool ) numFrame := 0 count := 0 t := time.Now() for { c := time.Now() dt := c.Sub(t) t = c if numFrame > count { fmt.Println("\rDeltaTime:", dt) count += 5 } numFrame++ for event := sdl.PollEvent(); event != nil; event = sdl.PollEvent() { switch t := event.(type) { case *sdl.QuitEvent: return case *sdl.KeyDownEvent: if t.Keysym.Sym == sdl.K_ESCAPE { return } case *sdl.MouseButtonEvent: if t.State == 1 { buttonDown = true } else { buttonDown = false } case *sdl.MouseMotionEvent: if buttonDown { xrot += float32(t.YRel) * 0.001 yrot += float32(t.XRel) * 0.001 } } } gl.Clear(gl.COLOR_BUFFER_BIT) xq := mgl32.QuatRotate(xrot, mgl32.Vec3{1, 0, 0}) yq := mgl32.QuatRotate(yrot, mgl32.Vec3{0, 1, 0}) mat := xq.Mul(yq).Mat4() //mat = mat.Mul4(mgl32.Translate3D(0,0,-0.5)) gl.UniformMatrix4fv(cameraMatrixUniform, 1, false, &mat[0]) gl.DrawArrays(gl.TRIANGLES, 0, 6) sdl.GL_SwapWindow(window) if glErr := gl.GetError(); glErr != gl.NO_ERROR { panic(fmt.Errorf("GL error, swap: %x", glErr)) } } }
func (e *Editor) Start() { glRenderer := opengl.NewOpenglRenderer("GoEngine Editor", 1800, 900, false) e.renderer = glRenderer e.gameEngine = engine.NewEngine(e.renderer) e.gameEngine.Start(func() { shader, err := assets.ImportShader( filepath.Join(e.assetDir, "shaders/build/pbr.vert"), filepath.Join(e.assetDir, "shaders/build/pbr.frag"), ) if err != nil { panic("error importing shader") } e.gameEngine.DefaultShader(shader) // Sky cubemap skyImg, err := assets.ImportImage(filepath.Join(e.assetDir, "resources/cubemap.png")) if err == nil { geom := renderer.CreateSkyBox() geom.Transform(mgl32.Scale3D(10000, 10000, 10000)) skyNode := renderer.NewNode() skyNode.SetOrientation(mgl32.QuatRotate(1.57, mgl32.Vec3{0, 1, 0})) skyNode.Material = renderer.NewMaterial(renderer.NewTexture("diffuseMap", skyImg, false)) skyNode.RendererParams = renderer.NewRendererParams() skyNode.RendererParams.CullBackface = false skyNode.RendererParams.Unlit = true skyNode.Add(geom) e.gameEngine.AddSpatial(skyNode) // create an environmentMap using the skybox texture envCubeMap := renderer.NewCubemap("environmentMap", skyImg, true) e.gameEngine.DefaultCubeMap(envCubeMap) } l := renderer.NewLight(renderer.DIRECTIONAL) l.Color = [3]float32{0.7, 0.7, 0.8} e.gameEngine.AddLight(l) //root node e.gameEngine.AddSpatial(e.rootMapNode) //input/controller manager e.controllerManager = glfwController.NewControllerManager(glRenderer.Window) //camera + player camera := e.gameEngine.Camera() freeMoveActor := actor.NewFreeMoveActor(camera) freeMoveActor.MoveSpeed = 20.0 freeMoveActor.LookSpeed = 0.002 mainController := controller.NewBasicMovementController(freeMoveActor, true) e.controllerManager.AddController(mainController.(glfwController.Controller)) e.gameEngine.AddUpdatable(freeMoveActor) e.initSelectSprite() e.gameEngine.AddUpdatable(engine.UpdatableFunc(e.updateSelectSprite)) //editor controller e.controllerManager.AddController(NewEditorController(e).(glfwController.Controller)) //custom controller e.customController = controller.CreateController() e.controllerManager.AddController(e.customController.(glfwController.Controller)) e.setupUI() }) }
func (node *Node) SetRotation(angle float32, axis mgl32.Vec3) { node.Orientation = mgl32.QuatRotate(angle, axis) node.Transform = util.Mat4From(node.Scale, node.Translation, node.Orientation) }
func main() { glRenderer := opengl.NewOpenglRenderer("Simple", 800, 800, false) gameEngine := engine.NewEngine(glRenderer) gameEngine.InitFpsDial() gameEngine.Start(func() { if shader, err := assets.ImportShader("shaders/build/basic.vert", "shaders/build/basic.frag"); err == nil { gameEngine.DefaultShader(shader) } // sky cube skyImg, err := assets.ImportImage("resources/cubemap.png") if err == nil { geom := renderer.CreateSkyBox() geom.Transform(mgl32.Scale3D(10000, 10000, 10000)) skyNode := renderer.NewNode() skyNode.SetOrientation(mgl32.QuatRotate(1.57, mgl32.Vec3{0, 1, 0})) skyNode.Material = renderer.NewMaterial(renderer.NewTexture("diffuseMap", skyImg, false)) skyNode.RendererParams = renderer.NewRendererParams() skyNode.RendererParams.CullBackface = false skyNode.RendererParams.Unlit = true skyNode.Add(geom) gameEngine.AddSpatial(skyNode) } // Add some light to the scene ambientLight := renderer.NewLight(renderer.AMBIENT) ambientLight.Color = [3]float32{0.3, 0.3, 0.3} gameEngine.AddLight(ambientLight) // Create a red box geometry, attach to a node, add the node to the scenegraph boxGeometry := renderer.CreateBox(10, 10) boxGeometry.SetColor(color.NRGBA{254, 0, 0, 254}) boxNode := renderer.NewNode() boxNode.RendererParams = renderer.NewRendererParams() boxNode.RendererParams.CullBackface = false boxNode.Material = renderer.NewMaterial() boxNode.SetTranslation(mgl32.Vec3{30, 0}) boxNode.Add(boxGeometry) gameEngine.AddSpatial(boxNode) // make the box spin var angle float64 gameEngine.AddUpdatable(engine.UpdatableFunc(func(dt float64) { angle += dt q := mgl32.QuatRotate(float32(angle), mgl32.Vec3{0, 1, 0}) boxNode.SetOrientation(q) })) // input/controller manager controllerManager := glfwController.NewControllerManager(glRenderer.Window) // camera + wasd controls camera := gameEngine.Camera() freeMoveActor := actor.NewFreeMoveActor(camera) freeMoveActor.Location = mgl32.Vec3{} mainController := controller.NewBasicMovementController(freeMoveActor, false) controllerManager.AddController(mainController.(glfwController.Controller)) gameEngine.AddUpdatable(freeMoveActor) //lock the cursor glRenderer.LockCursor(true) // custom key bindings customController := controller.CreateController() controllerManager.AddController(customController.(glfwController.Controller)) // close window and exit on escape customController.BindKeyAction(func() { glRenderer.Window.SetShouldClose(true) }, controller.KeyEscape, controller.Press) }) }