whispervis/scene.go

153 lines
4.0 KiB
Go
Raw Normal View History

2018-09-05 16:53:09 +03:00
package main
2018-09-17 22:11:04 +03:00
import (
"fmt"
2018-10-12 22:34:30 +02:00
"github.com/divan/graphx/layout"
2018-09-20 15:41:24 +03:00
"github.com/divan/three"
2018-09-17 22:11:04 +03:00
"github.com/gopherjs/gopherjs/js"
2018-10-24 22:48:53 +02:00
"github.com/status-im/whispervis/storage"
2018-09-20 15:41:24 +03:00
"github.com/status-im/whispervis/vthree"
2018-09-17 22:11:04 +03:00
)
// WebGLScene represents WebGL part of app.
type WebGLScene struct {
*vthree.WebGLRenderer
scene *three.Scene
camera three.PerspectiveCamera
renderer *three.WebGLRenderer
graphGroup *three.Group
nodesGroup *three.Group
edgesGroup *three.Group
controls TrackBallControl
2018-09-17 22:11:04 +03:00
autoRotate bool
2018-10-12 22:34:30 +02:00
wobble bool
wobbling *Wobbling
2018-10-12 22:34:30 +02:00
positions map[string]*layout.Object
// these slices exist here because we have no good way to access three.Group children for now
// TODO(divan): as soon as three.js wrappers allow us to access children, get rid of it here
nodes []*Mesh
lines []*Line
2018-10-26 16:38:49 +02:00
rt *RenderThrottler // used as a helper to reduce rendering calls when animation is not needed (experimental)
fps int // frames per second
blink int // time in ms for blinking nodes/edges
2018-10-23 08:28:14 +02:00
initFn func() // function to run on initialization
2018-09-17 22:11:04 +03:00
}
// NewWebGLScene inits and returns new WebGL scene and canvas.
2018-10-23 08:28:14 +02:00
func NewWebGLScene(initFn func()) *WebGLScene {
w := &WebGLScene{
2018-10-23 08:28:14 +02:00
rt: NewRenderThrottler(),
initFn: initFn,
2018-10-24 22:48:53 +02:00
fps: storage.FPS(),
2018-10-26 16:38:49 +02:00
blink: storage.BlinkTime(),
}
2018-09-17 22:11:04 +03:00
w.WebGLRenderer = vthree.NewWebGLRenderer(vthree.WebGLOptions{
2018-10-22 14:46:27 +02:00
Init: w.init,
Shutdown: w.shutdown,
Antialias: true,
2018-09-17 22:11:04 +03:00
})
return w
}
func (w *WebGLScene) init(renderer *three.WebGLRenderer) {
fmt.Println("WebGL init")
2018-10-19 22:10:56 +02:00
windowWidth := js.Global.Get("innerWidth").Float() - 300 // TODO(divan): sync this with page layout
2018-09-17 22:11:04 +03:00
windowHeight := js.Global.Get("innerHeight").Float() - 20
w.renderer = renderer
w.renderer.SetSize(windowWidth, windowHeight, true)
devicePixelRatio := js.Global.Get("devicePixelRatio").Float()
w.renderer.SetPixelRatio(devicePixelRatio)
w.InitScene(windowWidth, windowHeight)
2018-10-23 08:28:14 +02:00
if w.initFn != nil {
w.initFn()
}
2018-09-17 22:11:04 +03:00
w.animate()
}
func (w *WebGLScene) shutdown(renderer *three.WebGLRenderer) {
fmt.Println("WebGL shutdown")
w.scene = nil
w.camera = three.PerspectiveCamera{}
w.renderer = nil
w.RemoveObjects()
}
// Reset resets state of WebGLScene.
func (w *WebGLScene) Reset() {
fmt.Println("Resetting WebGL")
w.RemoveObjects()
}
2018-09-05 16:53:09 +03:00
// InitScene inits a new scene, sets up camera, lights and all that.
2018-09-17 22:11:04 +03:00
func (w *WebGLScene) InitScene(width, height float64) {
2018-10-28 12:53:52 +01:00
w.camera = three.NewPerspectiveCamera(70, width/height, 1, 50000)
2018-10-22 14:40:41 +02:00
w.camera.Position.Set(0, 0, 100)
2018-09-05 16:53:09 +03:00
2018-09-17 22:11:04 +03:00
w.scene = three.NewScene()
2018-10-22 14:40:41 +02:00
w.scene.Background = three.NewColorRGB(0, 0, 17)
2018-09-05 16:53:09 +03:00
2018-09-17 22:11:04 +03:00
w.InitLights()
w.InitControls()
w.Reset()
2018-09-05 16:53:09 +03:00
}
// InitLights init lights for the scene.
2018-09-17 22:11:04 +03:00
func (w *WebGLScene) InitLights() {
2018-10-22 14:40:41 +02:00
ambLight := three.NewAmbientLight(three.NewColorHex(0xbbbbbb), 1)
ambLight.MatrixAutoUpdate = false
2018-09-17 22:11:04 +03:00
w.scene.Add(ambLight)
2018-09-05 16:53:09 +03:00
2018-10-22 14:40:41 +02:00
light := three.NewDirectionalLight(three.NewColor("white"), 1)
light.MatrixAutoUpdate = false
2018-09-17 22:11:04 +03:00
w.scene.Add(light)
2018-09-05 16:53:09 +03:00
}
// InitControls init controls for the scene.
2018-09-17 22:11:04 +03:00
func (w *WebGLScene) InitControls() {
w.controls = NewTrackBallControl(w.camera, w.renderer)
2018-09-05 16:53:09 +03:00
}
2018-10-23 17:19:07 +02:00
// WindowSize returns current window's width and height.
func WindowSize() (int, int) {
w := js.Global.Get("innerWidth").Float()
h := js.Global.Get("innerHeight").Float()
return int(w), int(h)
}
// PageViewSize returns current page aread width and height (adjusted for sidebar and margins).
func PageViewSize() (int, int) {
w, h := WindowSize()
w = w - 300 // TODO: remove magic (300 is a width of sidebar)
h = h - 20 // some top margin
return w, h
}
2018-10-24 22:05:23 +02:00
// ToggleRenderThrottler switches render throttling option. Implements SceneConfigurator.
func (w *WebGLScene) ToggleRenderThrottler() {
w.rt.Toggle()
}
// ChangeFPS changes rendering FPS. Implements SceneConfigurator.
func (w *WebGLScene) ChangeFPS(value int) {
fmt.Println("Changing FPS to", value)
w.fps = value
2018-10-24 22:48:53 +02:00
storage.SetFPS(value)
2018-10-24 22:05:23 +02:00
}
2018-10-26 16:38:49 +02:00
// ChangeBlinkTime changes propagation animation blink time. Implements SceneConfigurator.
func (w *WebGLScene) ChangeBlinkTime(value int) {
w.blink = value
storage.SetBlinkTime(value)
}