Пример #1
0
// Spin rotates the current direction by the given number degrees around each
// axis.  Generally this is called with one direction change at a time.
func (p *pov) Spin(x, y, z float64) {
	if x != 0 {
		rotation := lin.NewQ().SetAa(1, 0, 0, lin.Rad(x))
		p.dir.Mult(rotation, p.dir)
	}
	if y != 0 {
		rotation := lin.NewQ().SetAa(0, 1, 0, lin.Rad(y))
		p.dir.Mult(p.dir, rotation)
	}
	if z != 0 {
		rotation := lin.NewQ().SetAa(0, 0, 1, lin.Rad(z))
		p.dir.Mult(rotation, p.dir)
	}
}
Пример #2
0
// drawScene renders the 3D models consisting of one VAO
func (tag *trtag) drawScene() {
	gl.Clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT)
	tag.checkError("gl.Clear")
	gl.UseProgram(tag.shaders)
	tag.checkError("gl.UseProgram")
	gl.BindVertexArray(tag.vao)
	tag.checkError("gl.BindVertexArray")

	// Use a modelview matrix and quaternion to rotate the 3D object.
	tag.mvp64.SetQ(lin.NewQ().SetAa(0, 1, 0, lin.Rad(-tag.rotateAngle)))
	tag.mvp64.TranslateMT(0, 0, -4)
	tag.mvp64.Mult(tag.mvp64, tag.persp)
	tag.mvp32 = renderMatrix(tag.mvp64, tag.mvp32)
	gl.UniformMatrix4fv(tag.mvpRef, 1, false, tag.mvp32.Pointer())
	if err := gl.GetError(); err != 0 {
		fmt.Printf("gl.UniformMatrix error %d\n", err)
	}
	gl.DrawElements(gl.TRIANGLES, int32(len(tag.faces)), gl.UNSIGNED_BYTE, gl.Pointer(nil))
	if err := gl.GetError(); err != 0 {
		fmt.Printf("gl.DrawElements error %d\n", err)
	}

	// cleanup
	gl.UseProgram(0)
	tag.checkError("gl.UseProgram-0")
	gl.BindVertexArray(0)
	tag.checkError("gl.BindVertexArray-0")

	// rotate based on time... not on how fast the computer runs.
	if time.Now().Sub(tag.lastTime).Seconds() > 0.01 {
		tag.rotateAngle += 1
		tag.lastTime = time.Now()
	}
}
Пример #3
0
// Update is the regular engine callback.
func (cm *cmtag) Update(input *vu.Input) {
	if input.Resized {
		cm.resize()
	}

	// own the rotation.
	dir := lin.NewQ().SetAa(0, 1, 0, lin.Rad(cm.turn))
	cm.bod.SetRotation(dir.GetS())
	if cm.switchCam {

		// apply physics location to the camera.
		x, y, z := cm.bod.Location()
		cm.scene.SetViewLocation(x, y, z)
		cm.scene.SetViewRotation(dir.GetS())
		cm.scene.SetViewTilt(-cm.look)
	} else {

		// keep camera at a fixed location.
		cm.scene.SetViewLocation(0, 10, 25)
		cm.scene.SetViewRotation(0, 0, 0, 1)
		cm.scene.SetViewTilt(0)
	}

	// handle user requests.
	for press, rel := range input.Down {
		switch press {
		case "W":
			cm.move(zaxis, -1, rel < 0) // back and forth.
		case "S":
			cm.move(zaxis, 1, rel < 0)
		case "A":
			cm.move(xaxis, -1, rel < 0) // left and right
		case "D":
			cm.move(xaxis, 1, rel < 0)

		// switch camera between first and fixed third person.
		case "C":
			if time.Now().After(cm.last.Add(cm.holdoff)) {
				cm.switchCam = !cm.switchCam
				cm.last = time.Now()
			}
		}
	}

	// apply rotation based on mouse changes.
	xdiff := cm.pmx - input.Mx
	ydiff := cm.pmy - input.My
	cm.spin(yaxis, xdiff) // rotate left/right (around y-axis)
	cm.spin(xaxis, ydiff) // rotate up/down (around x-axis)
	cm.pmx, cm.pmy = input.Mx, input.My
}
Пример #4
0
// model transform must be done in rotation, scale, translate order.
func (p *part) mt() *lin.M4 {
	mt := p.model.SetQ(lin.NewQ().Inv(p.dir)) // rotation.
	mt.ScaleSM(p.Scale())                     // scale is applied first (on left of rotation)
	return mt.TranslateMT(p.Location())       // translate is applied last (on right of rotation).
}