func CreatePortals() []portal.Portal { a := portal.Quad{ glm.Vec4d{0, 1, -5, 1}, glm.Vec4d{0, 0, 1, 0}, glm.Vec4d{1, 0, 0, 0}, glm.Vec4d{1, 1, 1, 0}, } r := glm.HomogRotate3DYd(90) b := portal.Quad{ glm.Vec4d{-2, 1, 0, 1}, r.Mul4x1(glm.Vec4d{0, 0, 1, 0}), r.Mul4x1(glm.Vec4d{1, 0, 0, 0}), glm.Vec4d{1, 1, 1, 0}, } transform, inverse, pva, pvb := portal.PortalTransform(a, b) pa := portal.Portal{a, inverse, pva} pb := portal.Portal{b, transform, pvb} return []portal.Portal{pa, pb} }
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]) } } }