コード例 #1
0
ファイル: kc.go プロジェクト: toophy/vu
// Create is the startup asset creation.
func (kc *kctag) Create(eng vu.Eng, s *vu.State) {
	top := eng.Root().NewPov()
	view := top.NewView()
	view.SetUI()
	kc.ui = view.Cam()
	kc.positions = kc.keyPositions()

	// Create the keyboard image.
	kc.kb = top.NewPov().SetScale(900, 255, 0).SetLocation(450, 100+85, 0)
	kc.kb.NewModel("uv").LoadMesh("icon").AddTex("keyboard")

	// Pressed key focus
	kc.focus = top.NewPov().SetScale(50, 50, 0)
	kc.focus.NewModel("uv").LoadMesh("icon").AddTex("particle")

	// Place the key symbols over the keys.
	font := "lucidiaSu18"
	fontColour := "lucidiaSu18Black"
	for code, key := range kc.positions { // map key is key code, map value is key struct
		if char := vu.Keysym(code); char > 0 {
			cx, cy := key.location()
			letter := top.NewPov().SetLocation(cx, cy, 0)
			model := letter.NewModel("uv")
			model.AddTex(fontColour).LoadFont(font).SetPhrase(string(char))
		}
	}

	// Have a lighter default background.
	eng.SetColor(0.45, 0.45, 0.45, 1)
	kc.resize(s.W, s.H)
}
コード例 #2
0
ファイル: sg.go プロジェクト: skyview059/vu
// Create is the engine callback for initial asset creation.
func (sg *sgtag) Create(eng vu.Eng, s *vu.State) {
	sg.run = 10   // move so many cubes worth in one second.
	sg.spin = 270 // spin so many degrees in one second.
	sg.cam = eng.Root().NewCam()
	sg.cam.SetPerspective(60, float64(800)/float64(600), 0.1, 50)
	sg.cam.SetLocation(0, 0, 6)
	sg.tr = newTrooper(eng, 1)

	// initialize the reactions
	sg.reacts = map[int]inputHandler{
		vu.K_W:     sg.forward,
		vu.K_A:     sg.left,
		vu.K_S:     sg.back,
		vu.K_D:     sg.right,
		vu.K_Equal: sg.attach,
		vu.K_Minus: sg.detach,
		vu.K_0:     func(i *vu.Input, down int) { sg.setTr(down, 0) },
		vu.K_1:     func(i *vu.Input, down int) { sg.setTr(down, 1) },
		vu.K_2:     func(i *vu.Input, down int) { sg.setTr(down, 2) },
		vu.K_3:     func(i *vu.Input, down int) { sg.setTr(down, 3) },
		vu.K_4:     func(i *vu.Input, down int) { sg.setTr(down, 4) },
		vu.K_5:     func(i *vu.Input, down int) { sg.setTr(down, 5) },
		vu.K_P:     sg.stats,
	}
	eng.SetColor(0.1, 0.1, 0.1, 1.0)
}
コード例 #3
0
ファイル: rl.go プロジェクト: skyview059/vu
// Create is the engine callback for initial asset creation.
func (rl *rltag) Create(eng vu.Eng, s *vu.State) {
	rl.ww, rl.wh = 800, 600
	rl.floors = make(map[int]*floor)
	rl.setLevel(eng, vu.K_1)
	eng.SetColor(0.15, 0.15, 0.15, 1)
	return
}
コード例 #4
0
ファイル: sm.go プロジェクト: skyview059/vu
// Create is the startup asset creation.
func (sm *smtag) Create(eng vu.Eng, s *vu.State) {
	scene := eng.Root().NewPov()
	sm.cam = scene.NewCam()

	// need a light for shadows.
	sm.sun = scene.NewPov().SetLocation(0, 0, 0)
	sm.sun.NewLight().SetColour(0.8, 0.8, 0.8)

	// create a scene that will render a shadow map.
	sm.cam = scene.NewCam()
	sm.cam.SetLocation(0, 0, 10)
	sm.cam.SetPerspective(60, float64(s.W)/float64(s.H), 0.1, 50)

	// create a few objects that cast shadows.
	sm.cube = scene.NewPov().SetLocation(-1, -1, -4)
	sm.cube.NewModel("gouraud").LoadMesh("box").LoadMat("gray").CastShadow()
	sm.cube.Spin(45, 45, 0)
	sm.sphere = scene.NewPov().SetLocation(1, 1, -4)
	sm.sphere.NewModel("gouraud").LoadMesh("sphere").LoadMat("red").CastShadow()

	// create a ground block to show shadows.
	ground := scene.NewPov().SetLocation(0, 0, -20).SetScale(50, 50, 5)
	model := ground.NewModel("shadow").LoadMesh("box").LoadMat("gray").HasShadows()
	model.AddTex("tile")
}
コード例 #5
0
ファイル: bb.go プロジェクト: skyview059/vu
// Update is the regular engine callback.
func (bb *bbtag) Update(eng vu.Eng, in *vu.Input, s *vu.State) {
	run := 10.0   // move so many cubes worth in one second.
	spin := 270.0 // spin so many degrees in one second.
	if in.Resized {
		bb.resize(s.W, s.H)
	}
	dt := in.Dt
	for press, _ := range in.Down {
		switch press {
		case vu.K_W:
			bb.cam.Move(0, 0, dt*-run, bb.cam.Lookxz())
		case vu.K_S:
			bb.cam.Move(0, 0, dt*run, bb.cam.Lookxz())
		case vu.K_Q:
			bb.cam.Move(dt*-run, 0, 0, bb.cam.Lookxz())
		case vu.K_E:
			bb.cam.Move(dt*run, 0, 0, bb.cam.Lookxz())
		case vu.K_A:
			bb.cam.AdjustYaw(dt * spin)
		case vu.K_D:
			bb.cam.AdjustYaw(dt * -spin)
		case vu.K_T:
			eng.Shutdown()
		}
	}

	// Use screen coordinates from world coordinates.
	if sx, sy := bb.cam.Screen(5, 2, -15, s.W, s.H); sx == -1 {
		bb.screenText.SetVisible(false)
	} else {
		bb.screenText.SetVisible(true)
		bb.screenText.SetLocation(float64(sx), float64(sy), 0)
	}
}
コード例 #6
0
ファイル: rl.go プロジェクト: toophy/vu
// Create is the engine callback for initial asset creation.
func (rl *rltag) Create(eng vu.Eng, s *vu.State) {
	rl.run = 5    // move so many cubes worth in one second.
	rl.spin = 270 // spin so many degrees in one second.
	rl.ww, rl.wh = 800, 600
	rl.floors = make(map[int]*floor)
	rl.setLevel(eng, vu.K_1)
	eng.SetColor(0.15, 0.15, 0.15, 1)
	return
}
コード例 #7
0
ファイル: tm.go プロジェクト: toophy/vu
// Create is the engine callback for initial asset creation.
func (tm *tmtag) Create(eng vu.Eng, s *vu.State) {
	tm.ww, tm.wh = s.W, s.H
	view := eng.Root().NewView()
	tm.cam = view.Cam()
	tm.cam.SetOrthographic(0, float64(tm.ww), 0, float64(tm.wh), 0, 50)
	sun := eng.Root().NewPov().SetLocation(0, 5, 0)
	sun.NewLight().SetColour(0.4, 0.7, 0.9)

	// create the world surface.
	seed := int64(123)
	patchSize := 128
	tm.world = land.New(1, patchSize, seed)
	worldTile := tm.world.NewTile(1, 0, 0)
	textureRatio := 256.0 / 1024.0
	tm.surface = vu.NewSurface(patchSize, patchSize, 16, float32(textureRatio), 10)

	// create a separate surface for generating initial land textures.
	emap := land.New(1, patchSize, seed-1)
	etile := emap.NewTile(1, 0, 0)
	etopo := etile.Topo()

	// merge the land height and land texture information into a single surface.
	tm.evo = make([][]float64, patchSize)
	for x := range tm.evo {
		tm.evo[x] = make([]float64, patchSize)
	}
	numTextures := 3.0
	pts := tm.surface.Pts()
	topo := worldTile.Topo()
	for x := range topo {
		for y := range topo[x] {
			pts[x][y].Height = float32(topo[x][y])
			evolution := (etopo[x][y] + 1) * 0.5 * numTextures // (-1,1 map to 0-2), map to 0-3
			pts[x][y].Tindex = int(evolution)
			pts[x][y].Blend = float32(evolution) - float32(int(evolution))
			tm.evo[x][y] = evolution // remember for later.
		}
	}

	// Add a rendering component for the surface data.
	scale := 10.0
	tm.ground = eng.Root().NewPov().SetLocation(0, -300, -10).SetScale(scale, scale, 1)
	tm.gm = tm.ground.NewModel("land").AddTex("land")
	tm.gm.LoadMat("land").SetUniform("ratio", textureRatio)
	tm.gm.NewMesh("land")
	tm.surface.Update(tm.gm, 0, 0)

	// Add water planes.
	tm.ocean = eng.Root().NewPov()
	tm.ocean.SetLocation(256, 0, -10.5)
	tm.ocean.SetScale(float64(tm.ww), float64(tm.wh), 1)
	tm.ocean.NewModel("alpha").LoadMesh("plane").LoadMat("blue2")
	tm.coast = eng.Root().NewPov().SetLocation(256, 0, -10)
	tm.coast.SetScale(float64(tm.ww), float64(tm.wh), 1)
	tm.coast.NewModel("alpha").LoadMesh("plane").LoadMat("blue")
	return
}
コード例 #8
0
ファイル: cr.go プロジェクト: toophy/vu
// Create is the engine callback for initial asset creation.
func (cr *crtag) Create(eng vu.Eng, s *vu.State) {
	cr.run = 10   // move so many cubes worth in one second.
	cr.spin = 270 // spin so many degrees in one second.
	cr.top = eng.Root().NewPov()
	sun := cr.top.NewPov().SetLocation(0, 10, 10)
	sun.NewLight().SetColour(0.8, 0.8, 0.8)
	cr.view = cr.top.NewView()
	cr.cam = cr.view.Cam()
	cr.cam.SetPerspective(60, float64(800)/float64(600), 0.1, 500)
	cr.cam.SetLocation(0, 10, 25)

	// load the static slab.
	slab := cr.top.NewPov().SetScale(50, 50, 50).SetLocation(0, -25, 0)
	slab.NewBody(vu.NewBox(25, 25, 25))
	slab.SetSolid(0, 0.4)
	slab.NewModel("gouraud").LoadMesh("cube").LoadMat("floor")

	// create a single moving body.
	useBalls := true // Flip to use boxes instead of spheres.
	cr.striker = cr.top.NewPov()
	cr.striker.SetLocation(15, 15, 0) // -5, 15, -3
	if useBalls {
		cr.getBall(cr.striker)
	} else {
		cr.getBox(cr.striker)
		cr.striker.SetRotation(&lin.Q{X: 0.1825742, Y: 0.3651484, Z: 0.5477226, W: 0.7302967})
	}
	cr.striker.Model().SetColour(rand.Float64(), rand.Float64(), rand.Float64())

	// create a block of physics bodies.
	cubeSize := 3
	startX := -5 - cubeSize/2
	startY := -5
	startZ := -3 - cubeSize/2
	for k := 0; k < cubeSize; k++ {
		for i := 0; i < cubeSize; i++ {
			for j := 0; j < cubeSize; j++ {
				bod := cr.top.NewPov()
				lx := float64(2*i + startX)
				ly := float64(20 + 2*k + startY)
				lz := float64(2*j + startZ)
				bod.SetLocation(lx, ly, lz)
				if useBalls {
					cr.getBall(bod)
				} else {
					cr.getBox(bod)
				}
			}
		}
	}

	// set non default engine state.
	eng.SetColor(0.15, 0.15, 0.15, 1)
	rand.Seed(time.Now().UTC().UnixNano())
}
コード例 #9
0
ファイル: bampf.go プロジェクト: kissthink/bampf
// create the game screens before the main action/update loop is started.
func (mp *bampf) Create(eng vu.Eng, s *vu.State) {
	rand.Seed(time.Now().UnixNano())
	mp.eng = eng
	mp.ani = &animator{}
	mp.setMute(mp.mute)
	mp.eventq = list.New()
	mp.createScreens(s.W, s.H)
	mp.state = mp.choosing
	mp.active = mp.launch
	mp.active.activate(screenActive)
	eng.SetColor(1, 1, 1, 1) // White as default background.
}
コード例 #10
0
ファイル: fm.go プロジェクト: toophy/vu
// Create is the engine callback for initial asset creation.
func (fm *fmtag) Create(eng vu.Eng, s *vu.State) {
	fm.view = eng.Root().NewView()
	fm.view.SetUI()
	eng.SetColor(0.95, 0.95, 0.95, 1)

	// create the panel layout examples.
	fm.layouts = append(fm.layouts, fm.simpleLayout(eng, s.W, s.H))
	fm.layouts = append(fm.layouts, fm.spanLayout(eng, s.W, s.H))
	fm.layouts = append(fm.layouts, fm.grabLayout(eng))
	fm.layouts = append(fm.layouts, fm.largeLayout(eng, s.W, s.H))
	fm.layouts = append(fm.layouts, fm.doubleLayout(eng))
	fm.layouts[fm.example].setVisible(true)

	// set non default engine state.
	fm.resize(s.W, s.H)
}
コード例 #11
0
ファイル: hud.go プロジェクト: kissthink/bampf
// newHud creates all the various parts of the heads up display.
func newHud(eng vu.Eng, sentryCount, wx, wy, ww, wh int) *hud {
	hd := &hud{}
	hd.root = eng.Root().NewPov()
	hd.view = hd.root.NewView()
	hd.view.SetUI()
	hd.cam = hd.view.Cam()
	hd.setSize(wx, wy, ww, wh)

	// create the HUD parts.
	hd.pl = newPlayer(hd.root, hd.w, hd.h)
	hd.xp = newXpbar(hd.root, hd.w, hd.h)
	hd.mm = newMinimap(eng.Root().NewPov(), sentryCount)
	hd.ce = hd.cloakingEffect(hd.root)
	hd.te = hd.teleportEffect(hd.root)
	hd.ee = hd.energyLossEffect(hd.root)
	hd.resize(hd.w, hd.h)
	return hd
}
コード例 #12
0
ファイル: bb.go プロジェクト: toophy/vu
// Create is the startup asset creation.
func (bb *bbtag) Create(eng vu.Eng, s *vu.State) {
	bb.run = 10   // move so many cubes worth in one second.
	bb.spin = 270 // spin so many degrees in one second.
	top := eng.Root().NewPov()
	view := top.NewView()
	bb.cam = view.Cam()
	bb.cam.SetLocation(0.5, 2, 2.5)
	sun := top.NewPov().SetLocation(0, 3, -3)
	sun.NewLight().SetColour(0.4, 0.7, 0.9)

	// Load the floor model.
	floor := top.NewPov()
	floor.NewModel("gouraud").LoadMesh("floor").LoadMat("floor")

	// Create a single image from multiple textures using a shader.
	c4 := top.NewPov().SetLocation(0.5, 2, -1).SetScale(0.25, 0.25, 0.25)
	model := c4.NewModel("spinball").LoadMesh("billboard")
	model.AddTex("core").AddTex("core").AddTex("halo").AddTex("halo")
	model.SetAlpha(0.4)

	// Try banner text with the 3D scene perspective camera.
	font := "lucidiaSu22"
	banner := top.NewPov().SetScale(0.1, 0.1, 0.1).SetLocation(-10, 3, -15)
	banner.NewModel("uv").AddTex(font + "White").LoadFont(font).SetPhrase("Floating Text")

	// Try billboard banner text with the 3D scene perspective camera.
	banner = top.NewPov().SetScale(0.025, 0.025, 0.025).SetLocation(-10, 2, -15)
	banner.NewModel("bb").AddTex(font + "White").LoadFont(font).SetPhrase("Billboard Text")

	// Banner text with an ortho overlay.
	v2D := eng.Root().NewPov()
	view2D := v2D.NewView()
	view2D.SetUI()
	bb.ui = view2D.Cam()

	// 2D static location.
	banner = v2D.NewPov().SetLocation(100, 100, 0)
	banner.NewModel("uv").AddTex(font + "White").LoadFont(font).SetPhrase("Overlay Text")

	// 3D world to 2D screen location.
	bb.screenText = v2D.NewPov()
	bb.screenText.NewModel("uv").AddTex(font + "White").LoadFont(font).SetPhrase("Screen Text")
	bb.resize(s.W, s.H)
}
コード例 #13
0
ファイル: ff.go プロジェクト: toophy/vu
// Create is the engine callback for initial asset creation.
func (ff *fftag) Create(eng vu.Eng, s *vu.State) {
	rand.Seed(time.Now().UTC().UnixNano())

	// create the overlay
	ff.top = eng.Root().NewPov()
	view := ff.top.NewView()
	view.SetUI()
	ff.cam = view.Cam()
	ff.mmap = ff.top.NewPov().SetScale(10, 10, 0)
	ff.mmap.SetLocation(30, 30, 0)

	// populate the map
	ff.msize = 69
	ff.plan = grid.New(grid.ROOMS_SKIRMISH)
	ff.plan.Generate(ff.msize, ff.msize)
	width, height := ff.plan.Size()
	for x := 0; x < width; x++ {
		for y := 0; y < height; y++ {
			if ff.plan.IsOpen(x, y) {
				block := ff.mmap.NewPov()
				block.SetLocation(float64(x), float64(y), 0)
				block.NewModel("uv").LoadMesh("icon").AddTex("wall")
				ff.spots = append(ff.spots, ff.id(x, y))
			}
		}
	}

	// populate chasers and a goal.
	numChasers := 30
	for cnt := 0; cnt < numChasers; cnt++ {
		chaser := ff.mmap.NewPov()
		chaser.NewModel("uv").LoadMesh("icon").AddTex("token")
		ff.chasers = append(ff.chasers, chaser)
	}
	ff.goal = ff.mmap.NewPov()
	ff.goal.NewModel("uv").LoadMesh("icon").AddTex("goal")
	ff.flow = grid.NewFlow(ff.plan) // flow field for the given plan.
	ff.resetLocations()

	// set non default engine state.
	eng.SetColor(0.15, 0.15, 0.15, 1)
	ff.resize(s.W, s.H)
}
コード例 #14
0
ファイル: fm.go プロジェクト: toophy/vu
// Called once to create the visual parts of a panel.
func (lo *layout) visualize(eng vu.Eng) {
	lo.top = eng.Root().NewPov()
	lo.setVisible(false)
	lo.sects = make([]vu.Pov, len(lo.form.Sections()))
	lo.labels = make([]vu.Pov, len(lo.form.Sections()))
	for cnt, sect := range lo.form.Sections() {

		// place a box at the section location.
		lo.sects[cnt] = lo.top.NewPov()
		lo.sects[cnt].NewModel("uv").LoadMesh("icon").AddTex("cell")

		// place the cell name in the middle of the cell.
		lo.labels[cnt] = lo.top.NewPov()
		model := lo.labels[cnt].NewModel("uv").AddTex("lucidiaSu16Black")
		if sect.Label() == "" {
			model.LoadFont("lucidiaSu16").SetPhrase("-")
		} else {
			model.LoadFont("lucidiaSu16").SetPhrase(sect.Label())
		}
	}
}
コード例 #15
0
ファイル: tt.go プロジェクト: skyview059/vu
// Update is the regular engine callback.
func (tt *totex) Update(eng vu.Eng, in *vu.Input, s *vu.State) {
	spin := 270.0 // spin so many degrees in one second.
	if in.Resized {
		tt.resize(s.W, s.H)
	}
	dt := in.Dt
	for press, _ := range in.Down {
		switch press {
		case vu.K_Q:
			tt.frame.Spin(0, dt*-spin, 0)
		case vu.K_E:
			tt.frame.Spin(0, dt*+spin, 0)
		case vu.K_A:
			tt.monkey.Spin(0, dt*-spin, 0)
		case vu.K_D:
			tt.monkey.Spin(0, dt*+spin, 0)
		case vu.K_T:
			eng.Shutdown()
		}
	}
}
コード例 #16
0
ファイル: ps.go プロジェクト: toophy/vu
// Create is the engine callback for initial asset creation.
func (ps *pstag) Create(eng vu.Eng, s *vu.State) {
	ps.run = 10   // move so many cubes worth in one second.
	ps.spin = 270 // spin so many degrees in one second.
	ps.live = []*vu.EffectParticle{}
	ps.random = rand.New(rand.NewSource(time.Now().UTC().UnixNano()))
	view := eng.Root().NewView()
	ps.cam = view.Cam()
	ps.cam.SetPerspective(60, float64(800)/float64(600), 0.1, 50)
	ps.cam.SetLocation(0, 0, 2.5)

	// A GPU/shader based particle example using a particle shader.
	gpu := eng.Root().NewPov()
	gpu.SetVisible(false)
	m := gpu.NewModel("particle").AddTex("particle")
	m.NewMesh("gpu").SetDrawMode(vu.POINTS).SetDepth(false)
	ps.makeParticles(m)
	ps.effects = append(ps.effects, gpu)

	// A CPU/shader based particle example using an effect shader.
	cpu := eng.Root().NewPov()
	cpu.SetVisible(false)
	m = cpu.NewModel("effect").AddTex("particle").SetDrawMode(vu.POINTS)
	m.SetEffect(ps.fall, 250)
	ps.effects = append(ps.effects, cpu)

	// A jet engine exhaust attempt.
	// FUTURE: update textures to look like engine exhaust.
	jet := eng.Root().NewPov().SetLocation(0, -1, 0)
	jet.SetVisible(false)
	m = jet.NewModel("exhaust").AddTex("exhaust").SetDrawMode(vu.POINTS)
	m.SetEffect(ps.vent, 40)
	ps.effects = append(ps.effects, jet)

	// Make the first particle effect visible to kick things off.
	ps.effect = ps.effects[ps.index]
	ps.effect.SetVisible(true)

	// Non default engine state. Have a lighter default background.
	eng.SetColor(0.15, 0.15, 0.15, 1)
}
コード例 #17
0
ファイル: lt.go プロジェクト: toophy/vu
// Create is the engine callback for initial asset creation.
func (lt *lttag) Create(eng vu.Eng, s *vu.State) {
	lt.run = 10   // move so many cubes worth in one second.
	lt.spin = 270 // spin so many degrees in one second.
	top := eng.Root().NewPov()
	view := top.NewView()
	lt.cam3D = view.Cam()
	lt.cam3D.SetLocation(0.5, 2, 0.5)
	lt.sun = top.NewPov().SetLocation(0, 2.5, -1.75).SetScale(0.05, 0.05, 0.05)
	lt.sun.NewLight().SetColour(0.4, 0.7, 0.9)

	// Model at the light position.
	lt.sun.NewModel("solid").LoadMesh("sphere").LoadMat("sphere")

	// Create solid spheres to test the lighting shaders.
	c4 := top.NewPov().SetLocation(-0.5, 2, -2).SetScale(0.25, 0.25, 0.25)
	c4.NewModel("diffuse").LoadMesh("sphere").LoadMat("floor")
	c5 := top.NewPov().SetLocation(0.5, 2, -2).SetScale(0.25, 0.25, 0.25)
	c5.NewModel("gouraud").LoadMesh("sphere").LoadMat("floor")
	c6 := top.NewPov().SetLocation(1.5, 2, -2).SetScale(0.25, 0.25, 0.25)
	c6.NewModel("phong").LoadMesh("sphere").LoadMat("floor")
	lt.resize(s.W, s.H)
}
コード例 #18
0
ファイル: tt.go プロジェクト: skyview059/vu
// Create is the startup asset creation.
func (tt *totex) Create(eng vu.Eng, s *vu.State) {

	// create a scene that will render the blender monkey model to a texture.
	scene0 := eng.Root().NewPov()
	tt.cam0 = scene0.NewCam()
	scene0.NewLayer() // render scene to texture.
	background := scene0.NewPov().SetLocation(0, 0, -10).SetScale(100, 100, 1)
	background.NewModel("uv").LoadMesh("icon").AddTex("wall")
	tt.monkey = scene0.NewPov().SetLocation(0, 0, -5)
	tt.monkey.NewModel("monkey").LoadMesh("monkey").LoadMat("gray")

	// create a scene consisting of a single quad. The quad will display
	// the rendered texture from scene0. The texture image is flipped from
	// normal so reorient it using flipped texture coordinates in flipboard.
	scene1 := eng.Root().NewPov()
	tt.cam1 = scene1.NewCam()
	tt.frame = scene1.NewPov().SetLocation(0, 0, -0.5).SetScale(0.25, 0.25, 0.25)
	model := tt.frame.NewModel("uv").LoadMesh("flipboard")
	model.UseLayer(scene0.Layer()) // use rendered texture from scene0.

	// set camera perspectives and default background colour.
	tt.resize(s.W, s.H)
}
コード例 #19
0
ファイル: lt.go プロジェクト: skyview059/vu
// Create is the engine callback for initial asset creation.
func (lt *lttag) Create(eng vu.Eng, s *vu.State) {
	top := eng.Root().NewPov()
	lt.cam3D = top.NewCam()
	lt.cam3D.SetLocation(0.5, 2, 0.5)
	lt.sun = top.NewPov().SetLocation(0, 2.5, -1.75).SetScale(0.05, 0.05, 0.05)
	lt.sun.NewLight().SetColour(0.4, 0.7, 0.9)

	// Model at the light position.
	lt.sun.NewModel("solid").LoadMesh("sphere").LoadMat("red")

	// Create solid spheres to test the lighting shaders.
	c4 := top.NewPov().SetLocation(-0.5, 2, -2).SetScale(0.25, 0.25, 0.25)
	c4.NewModel("diffuse").LoadMesh("sphere").LoadMat("gray")
	c5 := top.NewPov().SetLocation(0.5, 2, -2).SetScale(0.25, 0.25, 0.25)
	c5.NewModel("gouraud").LoadMesh("sphere").LoadMat("gray")
	c6 := top.NewPov().SetLocation(1.5, 2, -2).SetScale(0.25, 0.25, 0.25)
	c6.NewModel("phong").LoadMesh("sphere").LoadMat("gray")

	// place and angle a large flat box behind the spheres.
	wall := top.NewPov().SetLocation(0, 2, -10).SetScale(5, 5, 5)
	wall.Spin(45, 45, 0)
	wall.NewModel("diffuse").LoadMesh("box").LoadMat("gray")
	lt.resize(s.W, s.H)
}
コード例 #20
0
ファイル: ma.go プロジェクト: toophy/vu
// Create is the engine callback for initial asset creation.
func (ma *matag) Create(eng vu.Eng, s *vu.State) {
	ma.run = 10   // move so many cubes worth in one second.
	ma.spin = 270 // spin so many degrees in one second.
	ma.top = eng.Root().NewPov()
	ma.view = ma.top.NewView()
	ma.cam = ma.view.Cam()
	ma.cam.SetPerspective(60, float64(800)/float64(600), 0.1, 50)
	ma.cam.SetLocation(0, 3, 10)

	// load any available IQM/E models. The loaded model data is fed to
	// the animation capable shader "anim".
	for _, modelFile := range ma.modelFiles() {
		pov := ma.top.NewPov()
		pov.SetScale(-1, 1, 1)
		if modelFile == "runner" {
			pov.SetScale(-3, 3, 3) // Runner is a bit small.
		}
		pov.Spin(-90, 0, 0)   // Have the model face the camera.
		pov.SetVisible(false) // Hide initially.

		// Most IQ* files are expected to be animated.
		// Use a "uv" shader to handle IQ* files without animations.
		pov.NewModel("anim").LoadAnim(modelFile)
		ma.models = append(ma.models, pov)
		ma.names = append(ma.names, modelFile)
	}
	ma.model = ma.models[ma.index] // should always have at least one.
	ma.model.SetVisible(true)

	// Have a lighter default background.
	eng.SetColor(0.15, 0.15, 0.15, 1)

	// Create a banner to show the model name.
	top2D := eng.Root().NewPov()
	view2D := top2D.NewView()
	view2D.SetUI()
	ma.ui = view2D.Cam()
	ma.ui.SetOrthographic(0, float64(s.W), 0, float64(s.H), 0, 10)
	title := top2D.NewPov()
	title.SetLocation(10, 5, 0)
	ma.title = title.NewModel("uv").AddTex("lucidiaSu22White").LoadFont("lucidiaSu22")
	ma.title.SetPhrase(" ")
}
コード例 #21
0
ファイル: rc.go プロジェクト: toophy/vu
// Create is the engine callback for initial asset creation.
func (rc *rctag) Create(eng vu.Eng, s *vu.State) {
	top := eng.Root().NewPov()
	view := top.NewView()
	rc.cam = view.Cam()
	rc.cam.SetPitch(45)            // Tilt the camera and
	rc.cam.SetLocation(0, -14, 14) // ...point directly at 0, 0, 0
	rc.gsize = 32                  // 4x8 ie. image is 4x4 grid, tile.obj is oversampled by 8.

	// The ray cast target is a plane displaying the image of a 32x32 grid.
	rc.fsize = 10.0                               // 2x2 plane to 20x20 plane.
	rc.floor = top.NewPov()                       // create the floor.
	rc.floor.NewBody(vu.NewPlane(0, 0, -1))       // the floors ray intersect shape.
	rc.floor.SetScale(rc.fsize, rc.fsize, 0)      // scale the model to fsize.
	m := rc.floor.NewModel("uv").LoadMesh("tile") // put the image on the floor.
	m.AddTex("tile").SetTexMode(0, vu.TEX_REPEAT)

	// create a selected tile tracker.
	rc.hilite = top.NewPov().SetScale(0.625, 0.625, 0.001) // scale to cover a single tile.
	rc.hilite.NewModel("uv").LoadMesh("icon").AddTex("image")

	// Put spheres at the floor corners.
	rc.s0 = rc.makeSphere(top, 10, 10, 0, 1, 0, 0)
	rc.s1 = rc.makeSphere(top, -10, 10, 0, 0, 1, 0)
	rc.s2 = rc.makeSphere(top, 10, -10, 0, 0, 0, 1)
	rc.s3 = rc.makeSphere(top, -10, -10, 0, 1, 1, 0)

	// Add a banner to show the currently selected grid location.
	top2D := eng.Root().NewPov()
	view2D := top2D.NewView()
	view2D.SetUI()
	rc.ui = view2D.Cam()
	rc.banner = top2D.NewPov()
	rc.banner.SetLocation(100, 100, 0)
	rc.banner.SetVisible(false)
	m = rc.banner.NewModel("uv").AddTex("lucidiaSu22White")
	m.LoadFont("lucidiaSu22").SetPhrase("Overlay Text")

	// set non default engine state.
	eng.SetColor(0.2, 0.2, 0.2, 1.0)
	rc.resize(s.W, s.H)
}
コード例 #22
0
ファイル: rl.go プロジェクト: skyview059/vu
// Update is the regular engine callback.
func (rl *rltag) Update(eng vu.Eng, in *vu.Input, s *vu.State) {
	run := 5.0    // move so many cubes worth in one second.
	spin := 270.0 // spin so many degrees in one second.
	if in.Resized {
		rl.resize(s.W, s.H)
	}

	// pre-process user presses.
	// reduce individual move amounts for multiple move requests.
	dt := in.Dt
	moveDelta := dt * 2
	for press, _ := range in.Down {
		switch press {
		case vu.K_W, vu.K_S, vu.K_Q, vu.K_E:
			moveDelta *= 0.5
		}
	}

	// process user presses.
	for press, down := range in.Down {
		switch press {
		case vu.K_W:
			rl.flr.cam.Move(0, 0, moveDelta*-run, rl.flr.cam.Lookxz())
			rl.arrow.SetLocation(rl.flr.cam.Location())
		case vu.K_S:
			rl.flr.cam.Move(0, 0, moveDelta*run, rl.flr.cam.Lookxz())
			rl.arrow.SetLocation(rl.flr.cam.Location())
		case vu.K_Q:
			rl.flr.cam.Move(moveDelta*-run, 0, 0, rl.flr.cam.Lookxz())
			rl.arrow.SetLocation(rl.flr.cam.Location())
		case vu.K_E:
			rl.flr.cam.Move(moveDelta*run, 0, 0, rl.flr.cam.Lookxz())
			rl.arrow.SetLocation(rl.flr.cam.Location())
		case vu.K_A:
			rl.flr.cam.AdjustYaw(dt * spin)
			rl.arrow.SetRotation(rl.flr.cam.Lookxz())
		case vu.K_D:
			rl.flr.cam.AdjustYaw(dt * -spin)
			rl.arrow.SetRotation(rl.flr.cam.Lookxz())
		case vu.K_1, vu.K_2, vu.K_3, vu.K_4, vu.K_5, vu.K_6, vu.K_7, vu.K_8, vu.K_9, vu.K_0:
			if down == 1 {
				rl.setLevel(eng, press)
			}
		}
	}

	// show some stats to see the effectiveness of culling.
	allModels, allVerts := eng.Modelled()
	renModels, renVerts := eng.Rendered()
	modelStats := fmt.Sprintf("%d  models    culled to %d", allModels, renModels)
	vertexStats := fmt.Sprintf("%d verticies culled to %d", allVerts, renVerts)
	rl.flr.modelStats.SetPhrase(modelStats)
	rl.flr.vertexStats.SetPhrase(vertexStats)

	// http://stackoverflow.com/questions/87304/calculating-frames-per-second-in-a-game
	t := eng.Usage()
	rl.elapsed += t.Elapsed
	rl.update += t.Update
	rl.renders += t.Renders
	if in.Ut%50 == 0 { // average over 50 updates.
		fps := float64(rl.renders) / rl.elapsed.Seconds()
		update := rl.update.Seconds() / 50.0 * 1000
		timings := fmt.Sprintf("FPS %2.2f Update %3.2fms", fps, update)
		rl.flr.times.SetPhrase(timings)
		rl.renders = 0
		rl.elapsed = 0
		rl.update = 0
	}
}
コード例 #23
0
ファイル: rl.go プロジェクト: skyview059/vu
// setLevel switches to the indicated level.
func (rl *rltag) setLevel(eng vu.Eng, keyCode int) {
	if _, ok := rl.floors[keyCode]; !ok {
		var gridSizes = map[int]int{
			vu.K_1: 15,
			vu.K_2: 21,
			vu.K_3: 27,
			vu.K_4: 33,
			vu.K_5: 39,
			vu.K_6: 45,
			vu.K_7: 51,
			vu.K_8: 57,
			vu.K_9: 63,
			vu.K_0: 69,
		}
		var gridType = map[int]grid.Grid{
			vu.K_1: grid.New(grid.DENSE_SKIRMISH),
			vu.K_2: grid.New(grid.DENSE_SKIRMISH),
			vu.K_3: grid.New(grid.SPARSE_SKIRMISH),
			vu.K_4: grid.New(grid.SPARSE_SKIRMISH),
			vu.K_5: grid.New(grid.ROOMS_SKIRMISH),
			vu.K_6: grid.New(grid.ROOMS_SKIRMISH),
			vu.K_7: grid.New(grid.CAVE),
			vu.K_8: grid.New(grid.CAVE),
			vu.K_9: grid.New(grid.DUNGEON),
			vu.K_0: grid.New(grid.DUNGEON),
		}
		flr := &floor{}

		// create the scene
		flr.top = eng.Root().NewPov()
		flr.plan = flr.top.NewPov()
		flr.cam = flr.plan.NewCam()
		flr.cam.SetLocation(1, 0, -1)
		flr.cam.SetPerspective(60, float64(rl.ww)/float64(rl.wh), 0.1, 50)
		flr.cam.SetCull(vu.NewFrontCull(10))

		// create the overlay
		flr.mmap = flr.top.NewPov()
		flr.ui = flr.mmap.NewCam()
		flr.ui.SetUI()
		flr.ui.SetView(vu.XZ_XY)
		flr.ui.SetOrthographic(0, float64(rl.ww), 0, float64(rl.wh), 0, 20)
		flr.mapPart = flr.mmap.NewPov()
		flr.mapPart.SetScale(7.5, 7.5, 7.5)
		flr.mapPart.SetLocation(20, 0, -20)

		// display some rendering statistics.
		flr.modelStats = rl.newText(flr.mmap, 0)
		flr.vertexStats = rl.newText(flr.mmap, 1)
		flr.times = rl.newText(flr.mmap, 2)

		// populate the scenes
		lsize := gridSizes[keyCode]
		flr.layout = gridType[keyCode]
		flr.layout.Generate(lsize, lsize)
		width, height := flr.layout.Size()
		for x := 0; x < width; x++ {
			for y := 0; y < height; y++ {
				if flr.layout.IsOpen(x, y) {
					block := flr.mapPart.NewPov().SetLocation(float64(x), 0, float64(-y))
					block.NewModel("alpha").LoadMesh("cube").LoadMat("transparent_gray")
				} else {
					block := flr.plan.NewPov().SetLocation(float64(x), 0, float64(-y))
					block.NewModel("uv").LoadMesh("box").AddTex("tile")
				}
			}
		}
		flr.arrow = flr.mapPart.NewPov().SetLocation(flr.cam.Location())
		flr.arrow.NewModel("solid").LoadMesh("arrow").LoadMat("transparent_blue")
		rl.floors[keyCode] = flr
	}
	if rl.flr != nil {
		rl.flr.plan.SetVisible(false)
		rl.flr.mmap.SetVisible(false)
	}
	rl.flr = rl.floors[keyCode]
	rl.flr.plan.SetVisible(true)
	rl.flr.mmap.SetVisible(true)
	rl.arrow = rl.flr.arrow
}
コード例 #24
0
ファイル: sg.go プロジェクト: skyview059/vu
// newTrooper creates a trooper at the starting size for the given level.
//    level 0: 1x1x1 :  1 cube
//    level 1: 2x2x2 :  8 edge cubes + 6 panels of 0x0 cubes + 0x0x0 center.
//    level 2: 3x3x3 : 20 edge cubes + 6 panels of 1x1 cubes + 1x1x1 center.
//    level 3: 4x4x4 : 32 edge cubes + 6 panels of 2x2 cubes + 2x2x2 center.
//    ...
func newTrooper(eng vu.Eng, level int) *trooper {
	tr := &trooper{}
	tr.lvl = level
	tr.eng = eng
	tr.bits = []box{}
	tr.mid = tr.lvl*tr.lvl*tr.lvl*8 - (tr.lvl-1)*(tr.lvl-1)*(tr.lvl-1)*8
	tr.top = eng.Root().NewPov()

	//
	if tr.lvl == 0 {
		cube := newCube(tr.top, 0, 0, 0, 1)
		cube.edgeSort(1)
		tr.bits = append(tr.bits, cube)
		return tr
	}

	// create the panels. These are used in each level but the first.
	cubeSize := 1.0 / float64(tr.lvl+1)
	centerOffset := cubeSize * 0.5
	panelCenter := float64(tr.lvl) * centerOffset
	tr.bits = append(tr.bits, newBlock(tr.top, panelCenter, 0.0, 0.0, tr.lvl))
	tr.bits = append(tr.bits, newBlock(tr.top, -panelCenter, 0.0, 0.0, tr.lvl))
	tr.bits = append(tr.bits, newBlock(tr.top, 0.0, panelCenter, 0.0, tr.lvl))
	tr.bits = append(tr.bits, newBlock(tr.top, 0.0, -panelCenter, 0.0, tr.lvl))
	tr.bits = append(tr.bits, newBlock(tr.top, 0.0, 0.0, panelCenter, tr.lvl))
	tr.bits = append(tr.bits, newBlock(tr.top, 0.0, 0.0, -panelCenter, tr.lvl))

	// troopers are made out of cubes and panels.
	mx := float64(-tr.lvl)
	for cx := 0; cx <= tr.lvl; cx++ {
		my := float64(-tr.lvl)
		for cy := 0; cy <= tr.lvl; cy++ {
			mz := float64(-tr.lvl)
			for cz := 0; cz <= tr.lvl; cz++ {

				// create the outer edges.
				newCells := 0
				if (cx == 0 || cx == tr.lvl) && (cy == 0 || cy == tr.lvl) && (cz == 0 || cz == tr.lvl) {

					// corner cube
					newCells = 1
				} else if (cx == 0 || cx == tr.lvl) && (cy == 0 || cy == tr.lvl) ||
					(cx == 0 || cx == tr.lvl) && (cz == 0 || cz == tr.lvl) ||
					(cy == 0 || cy == tr.lvl) && (cz == 0 || cz == tr.lvl) {

					// edge cube
					newCells = 2
				} else if cx == 0 || cx == tr.lvl || cy == 0 || cy == tr.lvl || cz == 0 || cz == tr.lvl {

					// side cubes are added to (controlled by) a panel.
					x, y, z := mx*centerOffset, my*centerOffset, mz*centerOffset
					if cx == tr.lvl && x > y && x > z {
						tr.bits[0].(*block).addCube(x, y, z, float64(cubeSize))
					} else if cx == 0 && x < y && x < z {
						tr.bits[1].(*block).addCube(x, y, z, float64(cubeSize))
					} else if cy == tr.lvl && y > x && y > z {
						tr.bits[2].(*block).addCube(x, y, z, float64(cubeSize))
					} else if cy == 0 && y < x && y < z {
						tr.bits[3].(*block).addCube(x, y, z, float64(cubeSize))
					} else if cz == tr.lvl && z > x && z > y {
						tr.bits[4].(*block).addCube(x, y, z, float64(cubeSize))
					} else if cz == 0 && z < x && z < y {
						tr.bits[5].(*block).addCube(x, y, z, float64(cubeSize))
					}
				}
				if newCells > 0 {
					x, y, z := mx*centerOffset, my*centerOffset, mz*centerOffset
					cube := newCube(tr.top, x, y, z, float64(cubeSize))
					cube.edgeSort(newCells)
					tr.bits = append(tr.bits, cube)
				}
				mz += 2
			}
			my += 2
		}
		mx += 2
	}
	tr.addCenter()
	return tr
}