예제 #1
0
파일: main.go 프로젝트: GlenKelley/portal
func NewPlane(name string, q portal.Quad, elements []*gtk.DrawElements) *gtk.Geometry {
	vs, ns := q.Mesh()
	geometry := gtk.NewGeometry(name, vs, ns, elements)
	return geometry
}
예제 #2
0
파일: main.go 프로젝트: GlenKelley/portal
func (r *Receiver) LoadScene(filename string) {
	doc, err := collada.LoadDocument(filename)
	panicOnErr(err)
	index, err := gtk.NewIndex(doc)
	panicOnErr(err)
	r.SceneIndex = index

	model := gtk.EmptyModel("scene")
	switch doc.Asset.UpAxis {
	case collada.Xup:
	case collada.Yup:
	case collada.Zup:
		model.Transform = glm.HomogRotate3DXd(-90).Mul4(glm.HomogRotate3DZd(90))
	}

	portalPattern, _ := regexp.Compile("^Portal_(\\d+)_(\\d+)")

	geometryTemplates := make(map[collada.Id][]*gtk.Geometry)
	for id, mesh := range r.SceneIndex.Mesh {
		geoms := make([]*gtk.Geometry, 0)
		for _, pl := range mesh.Polylist {
			matches := portalPattern.FindStringSubmatch(mesh.VerticesId)
			if matches == nil {
				elements := make([]*gtk.DrawElements, 0)
				drawElements := gtk.NewDrawElements(pl.TriangleElements, gl.TRIANGLES)
				if drawElements != nil {
					elements = append(elements, drawElements)
				}
				geometry := gtk.NewGeometry(string(id), pl.VertexData, pl.NormalData, elements)
				geoms = append(geoms, geometry)
			} else {
				fmt.Println("ignoring Portal")
			}
		}
		if len(geoms) > 0 {
			geometryTemplates[id] = geoms
		}
	}

	portalLink := map[int]int{}
	portals := map[int]portal.Quad{}
	for _, node := range r.SceneIndex.VisualScene.Node {
		matches := portalPattern.FindStringSubmatch(node.Name)
		transform := r.SceneIndex.Transforms[node.Id]
		if matches == nil {
			geoms := make([]*gtk.Geometry, 0)
			for _, geoinstance := range node.InstanceGeometry {
				geoid, _ := geoinstance.Url.Id()
				geoms = append(geoms, geometryTemplates[geoid]...)
			}
			if len(geoms) > 0 {
				child := gtk.NewModel(node.Name, []*gtk.Model{}, geoms, transform)
				model.AddChild(child)
			}
		} else {
			index, err := strconv.Atoi(matches[1])
			if err != nil {
				panic(err)
			}
			exit, err := strconv.Atoi(matches[2])
			if err != nil {
				panic(err)
			}

			mt := model.Transform.Mul4(transform)
			center := mt.Mul4x1(glm.Vec4d{0, 0, 0, 1})
			normal := mt.Mul4x1(glm.Vec4d{0, 0, 1, 0}).Normalize()
			planev := mt.Mul4x1(glm.Vec4d{1, 0, 0, 0}).Normalize()
			scale := glm.Vec4d{}
			n := 0
			for i := 0; i < 3; i++ {
				sum := 0.0
				for j := 0; j < 3; j++ {
					sum += float64(mt[n] * mt[n])
					n++
				}
				n++
				scale[i] = math.Sqrt(sum)
			}

			quad := portal.Quad{
				center,
				normal,
				planev,
				scale,
			}
			portalLink[index] = exit
			portals[index] = quad
			// fmt.Println("portal node", node.Name, quad)
		}
	}
	r.Data.Scene.AddChild(model)

	for id, quad := range portals {
		exit, ok := portals[portalLink[id]]
		if ok {
			up := portal.Cross3D(exit.Normal, exit.PlaneV)
			// fmt.Println("pre ",exit)
			exit = exit.Apply(glm.HomogRotate3Dd(math.Pi, up))
			// fmt.Println("post",exit)
			_, inverse, pva, _ := portal.PortalTransform(quad, exit)
			portal := portal.Portal{quad, inverse, pva}
			r.Portals = append(r.Portals, portal)
		} else {
			fmt.Println("no exit for portal", id, portalLink[id])
		}
	}
}