func NewModelData(path string) *ModelData { md := &ModelData{path: path, vbo: nil} md.stdMat = mat4.New() md.vbo = vbo.New() md.LoadFile() return md }
func (t *Nurbs) CreateVbo(nusteps, nvsteps int, usetex bool) { //getting vertex data nump := (nusteps + 1) * (nvsteps + 1) p := make([]*Vec3, 0, nump) n := make([]*Vec3, 0, nump) var tc []*Vec2 if usetex { tc = make([]*Vec2, 0, nump) } ustep := 1.0 / Double(nusteps) vstep := 1.0 / Double(nvsteps) for u := 0; u <= nusteps; u++ { for v := 0; v <= nvsteps; v++ { fu, fv := Double(u)*ustep, Double(v)*vstep node := t.Interpolate_(fu, fv) pos, normal := node.P.Copy(), node.Normal() p = append(p, pos) n = append(n, normal) if usetex { tc = append(tc, node.Tc) } } } //filling vbo t.vbo = vbo.New() v := t.vbo numi := (2 * 3 * nusteps * nvsteps) v.P = make([]*Vec3, 0, numi) v.N = make([]*Vec3, 0, numi) if usetex { v.T = make([]*Vec2, 0, numi) } appendVertex := func(index int) { v.P = append(v.P, p[index]) v.N = append(v.N, n[index]) if usetex { v.T = append(v.T, tc[index]) } } appendQuad := func(x, y int) { a := x*(nvsteps+1) + y b, c, d := a+nusteps+1, a+1, a+nusteps+2 appendVertex(a) appendVertex(b) appendVertex(d) appendVertex(a) appendVertex(d) appendVertex(c) } for x := 0; x < nusteps; x++ { for y := 0; y < nvsteps; y++ { appendQuad(x, y) } } t.vbo.Create(gl.STATIC_DRAW) }
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) }