From e9b694334b96eb3b413a75353e7ecd4289b47038 Mon Sep 17 00:00:00 2001 From: Ivan Danyliuk Date: Wed, 24 Oct 2018 12:19:47 +0200 Subject: [PATCH] Add variadic material for propagation animation --- animate.go | 47 +-------------------- animate_propagation.go | 95 ++++++++++++++++++++++++++++++++++++++++++ material.go | 26 +----------- 3 files changed, 98 insertions(+), 70 deletions(-) create mode 100644 animate_propagation.go diff --git a/animate.go b/animate.go index 8847fe0..cc47ffc 100644 --- a/animate.go +++ b/animate.go @@ -1,19 +1,15 @@ package main import ( - "fmt" "time" "github.com/gopherjs/gopherjs/js" "github.com/gopherjs/vecty" - "github.com/status-im/simulation/propagation" ) // TODO(divan): move this as variables to the frontend const ( - BlinkDecay = 100 * time.Millisecond // time for highlighted node/link to be active - AnimationSlowdown = 1 // slowdown factor for propagation animation - FPS = 60 // default FPS + FPS = 60 // default FPS ) // animate fires up as an requestAnimationFrame handler. @@ -68,47 +64,6 @@ func (w *WebGLScene) ToggleWobbling() { w.wobble = !w.wobble } -// BlinkNode animates a single node blinking. Node specified by its idx. -func (w *WebGLScene) BlinkNode(id int) { - node := w.nodes[id] - node.Set("material", BlinkedNodeMaterial) - restore := func() { node.Object.Set("material", DefaultNodeMaterial) } - time.AfterFunc(BlinkDecay, restore) - -} - -// BlinkEdge animates a single edge blinking. Edge specified by its idx. -func (w *WebGLScene) BlinkEdge(id int) { - edge := w.lines[id] - edge.Set("material", BlinkedEdgeMaterial) - restore := func() { edge.Object.Set("material", DefaultEdgeMaterial) } - time.AfterFunc(BlinkDecay, restore) -} - -// AnimatePropagation visualizes propagation of message based on plog. -func (w *WebGLScene) AnimatePropagation(plog *propagation.Log) { - fmt.Println("Animating plog") - w.rt.Disable() - for i, ts := range plog.Timestamps { - duration := time.Duration(time.Duration(ts) * time.Millisecond) - duration = duration * AnimationSlowdown - - nodes := plog.Nodes[i] - edges := plog.Links[i] - fn := func() { - // blink nodes for this timestamp - for _, idx := range nodes { - w.BlinkNode(idx) - } - // blink links for this timestamp - for _, idx := range edges { - w.BlinkEdge(idx) - } - } - time.AfterFunc(duration, fn) - } -} - // MouseMoveListener implements listener for mousemove events. // We use it for disabling render throttling, as mousemove events // correlates with user moving inside of the WebGL canvas. We diff --git a/animate_propagation.go b/animate_propagation.go new file mode 100644 index 0000000..8987c94 --- /dev/null +++ b/animate_propagation.go @@ -0,0 +1,95 @@ +package main + +import ( + "fmt" + "time" + + "github.com/divan/three" + "github.com/status-im/simulation/propagation" +) + +const ( + BlinkDecay = 200 * time.Millisecond // time for highlighted node/link to be active + AnimationSlowdown = 1 // slowdown factor for propagation animation +) + +var ( + BlinkedEdgeMaterials = NewBlinkedEdgeMaterials() + BlinkedNodeMaterials = NewBlinkedNodeMaterials() +) + +// AnimatePropagation visualizes propagation of message based on plog. +func (w *WebGLScene) AnimatePropagation(plog *propagation.Log) { + fmt.Println("Animating plog") + w.rt.Disable() + + maxTs := plog.Timestamps[len(plog.Timestamps)-1] + for i, ts := range plog.Timestamps { + duration := time.Duration(time.Duration(ts) * time.Millisecond) + duration = duration * AnimationSlowdown + + percentage := (ts * 100) / maxTs // % of plog + if percentage > 99 { + percentage = 99 + } + + nodes := plog.Nodes[i] + edges := plog.Links[i] + fn := func() { + // blink nodes for this timestamp + for _, idx := range nodes { + w.BlinkNode(idx, percentage) + } + // blink links for this timestamp + for _, idx := range edges { + w.BlinkEdge(idx, percentage) + } + } + go time.AfterFunc(duration, fn) + + w.rt.Disable() // prevent thorttler from enabling during long animations + } +} + +// BlinkNode animates a single node blinking. Node specified by its idx. +func (w *WebGLScene) BlinkNode(id, percentage int) { + node := w.nodes[id] + node.Set("material", BlinkedNodeMaterials[percentage/10]) // choose material depending on percentage of propagation + restore := func() { node.Object.Set("material", DefaultNodeMaterial) } + go time.AfterFunc(BlinkDecay, restore) + +} + +// BlinkEdge animates a single edge blinking. Edge specified by its idx. +func (w *WebGLScene) BlinkEdge(id, percentage int) { + edge := w.lines[id] + edge.Set("material", BlinkedEdgeMaterials[percentage/10]) // choose material depending on percentage of propagation + restore := func() { edge.Object.Set("material", DefaultEdgeMaterial) } + go time.AfterFunc(BlinkDecay, restore) +} + +// NewBlinkedEdgeMaterials creates a new default material for the graph blinked edge lines. +func NewBlinkedEdgeMaterials() []three.Material { + params := three.NewMaterialParameters() + params.Color = three.NewColorRGB(255, 0, 0) + params.Transparent = true + ret := make([]three.Material, 0, 10) + for i := 0; i < 10; i++ { + params.Opacity = float64(1 - (float64(i) * 0.05)) // 1, 0.95, 0.90, 0.85... + ret = append(ret, three.NewLineBasicMaterial(params)) + } + return ret +} + +// NewBlinkedNodeMaterials creates a new default material for the graph blinked node. +func NewBlinkedNodeMaterials() []three.Material { + params := three.NewMaterialParameters() + params.Color = three.NewColorRGB(255, 0, 0) // red + params.Transparent = true + ret := make([]three.Material, 0, 10) + for i := 0; i < 10; i++ { + params.Opacity = float64(1 - (float64(i) * 0.05)) // 1, 0.95, 0.90, 0.85... + ret = append(ret, three.NewMeshPhongMaterial(params)) + } + return ret +} diff --git a/material.go b/material.go index 552b796..8fb0b54 100644 --- a/material.go +++ b/material.go @@ -4,15 +4,11 @@ import "github.com/divan/three" var ( DefaultNodeMaterial = NewNodeMaterial() - BlinkedNodeMaterial = NewBlinkedNodeMaterial() TransparentNodeMaterial = NewTransparentNodeMaterial() DefaultEdgeMaterial = NewEdgeMaterial() - BlinkedEdgeMaterial = NewBlinkedEdgeMaterial() ) -const ( - DefaultTransparency = 0.9 -) +const DefaultTransparency = 0.9 // NewNodeMaterial creates a new default material for the graph node. func NewNodeMaterial() three.Material { @@ -23,21 +19,12 @@ func NewNodeMaterial() three.Material { return three.NewMeshPhongMaterial(params) } -// NewBlinkedNodeMaterial creates a new default material for the graph blinked node. -func NewBlinkedNodeMaterial() three.Material { - params := three.NewMaterialParameters() - params.Color = three.NewColorRGB(255, 0, 0) // red - params.Transparent = true - params.Opacity = DefaultTransparency - return three.NewMeshPhongMaterial(params) -} - // NewTransparentNodeMaterial creates a new transparent material for the graph normal node. func NewTransparentNodeMaterial() three.Material { params := three.NewMaterialParameters() params.Color = three.NewColorRGB(0, 255, 0) params.Transparent = true - params.Opacity = 0.5 + params.Opacity = 0.7 return three.NewMeshPhongMaterial(params) } @@ -49,12 +36,3 @@ func NewEdgeMaterial() three.Material { params.Opacity = 0.7 return three.NewLineBasicMaterial(params) } - -// NewBlinkedEdgeMaterial creates a new default material for the graph blinked edge lines. -func NewBlinkedEdgeMaterial() three.Material { - params := three.NewMaterialParameters() - params.Color = three.NewColorRGB(255, 0, 0) - params.Transparent = true - params.Opacity = DefaultTransparency - return three.NewLineBasicMaterial(params) -}