Beispiel #1
0
func (this *Camera) RotateX(angle Double) {
	const limitAngle = 0.05
	upAngle := this.Up.Angle(this.Dir)
	if upAngle < limitAngle && angle < 0.0 {
		return
	}
	if (math.Pi-upAngle) < limitAngle && angle > 0.0 {
		return
	}
	xaxis := this.Dir.Cross(this.Up)
	mrot := mat4.RotationAxis(xaxis, angle)
	this.Dir = mrot.Mulv(this.Dir)
}
Beispiel #2
0
func RenderArrow(pos, dir *Vec3) {
	const tolerance = 0.0001
	arrow := Get("arrow")
	l := dir.Length()
	d0 := dir.Unit()
	zaxis := V3(0, 0, 1)
	arrow.Mat = mat4.Scaling(V3(.1*l, .1*l, .5*l))
	angle := zaxis.Angle(d0)
	if angle > tolerance && math.Pi-angle > tolerance {
		arrow.Mat = arrow.Mat.Mul(mat4.RotationAxis(zaxis.Add(d0).Unit(), math.Pi))
	} else if math.Pi-angle <= tolerance {
		arrow.Mat = arrow.Mat.Mul(mat4.Scaling(V3(1, 1, -1)))
	}
	arrow.Mat = arrow.Mat.Mul(mat4.Translation(pos.Add(dir.Muls(.5))))
	arrow.Render()
}
Beispiel #3
0
func (this *Camera) RotateY(angle Double) {
	yaxis := this.Up
	mrot := mat4.RotationAxis(yaxis, angle)
	this.Dir = mrot.Mulv(this.Dir)
}
Beispiel #4
0
func (s *Spline) CreateVbo_(nsteps, ncorners int, radius Double,
	usetex bool, tex1, tex2 *Vec2) {
	if ncorners < 3 {
		panic("too few corners")
	}
	nump := (ncorners + 1) * (nsteps + 1)
	numn := nump
	numt := nump
	p := make([]*Vec3, 0, nump)
	n := make([]*Vec3, 0, numn)
	var t, tcircle []*Vec2
	if usetex {
		t = make([]*Vec2, 0, numt)
		tcircle = make([]*Vec2, 0, ncorners)
	}
	fixedaxis := V3(0.00001, 1.0, -.00002).Unit()
	angle := -2.0 * math.Pi / Double(ncorners)
	lastDir0, lastPos := V3(1, 0, 0), V3(0, 0, 0)
	processCircle := func(pos, normal *Vec3, step int) {
		dir0 := normal.Perp(fixedaxis)
		//correct axis swift: shortest distance between this circle's dir0 and the last circle's
		if step > 0 {
			dir0 = plane.ByPointAndNormal(pos, normal).NearestPoint(lastPos.Add(lastDir0)).Sub(pos).Unit()
		}
		lastDir0 = dir0
		lastPos = pos
		texy := (tex2.Y-tex1.Y)*Double(step)/Double(nsteps) + tex1.Y
		for i := 0; i < ncorners+1; i++ {
			mrot := mat4.RotationAxis(normal, Double(i)*angle)
			dir := mrot.Mulv(dir0)
			p = append(p, pos.Add(dir.Muls(radius)))
			n = append(n, dir)
			if usetex {
				texx := (tex2.X-tex1.X)*Double(i)/Double(ncorners) + tex1.X
				t = append(t, V2(texx, texy))
			}
		}
	}
	t1, t2 := s.StartTime(), s.EndTime()
	dt := t2 - t1
	part := dt / Double(nsteps)
	time := t1
	for i := 0; i < nsteps+1; i++ {
		pos := s.At(time)
		vel := s.AtD1(time)
		processCircle(pos, vel.Unit(), i)
		time += part
	}
	//front/back texCoords:
	if usetex {
		clockhand := V3(0, 1, 0)
		for i := 0; i < ncorners; i++ {
			mrot := mat4.RotationAxis(V3(0, 0, -1), Double(i)*angle)
			dir := mrot.Mulv(clockhand)
			tcircle = append(tcircle, V2(dir.X, dir.Y).Add(V2(1, 1)).Muls(0.5))
		}
	}
	//filling vbo:
	s.vbo = vbo.New()
	v := s.vbo
	numi := (2 * 3 * nsteps * (ncorners + 1)) + 2*(ncorners-2)
	v.P = make([]*Vec3, 0, numi)
	v.N = make([]*Vec3, 0, numi)
	if usetex {
		v.T = make([]*Vec2, 0, numi)
	}
	//front + back
	fillVboWithCircle := func(index int, ccw bool) {
		normal := s.AtD1(t1).Muls(-1.0) //front face normal
		if !ccw {
			normal = s.AtD1(t2).Muls(1.0) //back face normal
		}
		doIndex := func(i1, i2 int) {
			v.P = append(v.P, p[index], p[index+i1], p[index+i2])
			v.N = append(v.N, normal, normal, normal)
			if usetex {
				v.T = append(v.T, tcircle[0], tcircle[i1], tcircle[i2])
			}
		}
		for i := 1; i < ncorners-1; i++ {
			if ccw {
				doIndex(i+1, i)
			} else {
				doIndex(i, i+1)
			}
		}
	}
	fillVboWithCircle(0, true)
	fillVboWithCircle(len(p)-(ncorners+1), false)

	appendVertexTriangle := func(a, b, c int) {
		v.P = append(v.P, p[a], p[b], p[c])
		v.N = append(v.N, n[a], n[b], n[c])
		if usetex {
			v.T = append(v.T, t[a], t[b], t[c])
		}
	}
	fillVboWithCylinder := func(index int) {
		for i := 0; i < ncorners-1; i++ {
			appendVertexTriangle(index+i+0, index+i+1, index+i+0+ncorners+1)
			appendVertexTriangle(index+i+1+ncorners+1, index+i+0+ncorners+1, index+i+1)
		}
		//last, closing rectangle
		appendVertexTriangle(index+ncorners-1, index+ncorners+0, index+2*ncorners+0)
		appendVertexTriangle(index+2*ncorners+1, index+2*ncorners+0, index+ncorners+0)
	}
	for i := 0; i < nsteps; i++ {
		fillVboWithCylinder(i * (ncorners + 1))
	}
	s.vbo.Create(gl.STATIC_DRAW)
}