func gatherBuildingsPositions( rendererPositions map[world.ModelId]Positions, buildings world.Buildings, offsetX, offsetY float64, defaultR *glm.Matrix4, // Can be nil. worldToEye glm.Matrix4, ) { for coords, building := range buildings { position := glm.Vector3{ float64(coords.X) + offsetX, float64(coords.Y) + offsetY, 0, }.Translation() facer, ok := building.(world.Facer) if ok { // We obey the facing of the buildings that have one. r := glm.RotZ(float64(90 * facer.Facing().Value())) position = position.Mult(r) } else { // Buildings without facing receive the provided default facing. // It is given as a precalculated rotation matrix `defaultR`. position = position.Mult(*defaultR) } position = worldToEye.Mult(position) // Shaders work in view space. rendererID := building.Model() positions := rendererPositions[rendererID] positions = append(positions, position) rendererPositions[rendererID] = positions } }
func viewMatrix(pos world.Position) (glm.Matrix4, glm.Matrix4) { const eyeZ = .5 Rd := glm.RotZ(float64(-90 * pos.F.Value())) Td := glm.Vector3{float64(-pos.X), float64(-pos.Y), -eyeZ}.Translation() Ri := glm.RotZ(float64(90 * pos.F.Value())) Ti := glm.Vector3{float64(pos.X), float64(pos.Y), eyeZ}.Translation() Vd := Rd.Mult(Td) // Direct. Vi := Ti.Mult(Ri) // Inverse. return Vd, Vi }