File tree Expand file tree Collapse file tree 5 files changed +88
-11
lines changed Expand file tree Collapse file tree 5 files changed +88
-11
lines changed Original file line number Diff line number Diff line change @@ -202,26 +202,28 @@ const box = app.create('prim', {
202202
203203## Animation
204204
205- Only when requested, you can make things move or change over time by hooking into the update cycle:
205+ Only when requested, you can make things move or change over time by hooking into the animation cycle:
206206
207207``` jsx
208- app .on (' update ' , delta => {
208+ app .on (' animate ' , delta => {
209209 box .rotation .y += 45 * DEG2RAD * delta // rotate around Y axis each frame 45 degrees per second
210210})
211211```
212212
213- If something needs to happen in response to interaction (eg triggers or actions), subscribe and unsubscribe only as needed for performance:
213+ The ` animate ` rate is dynamic based on how far away the app is from the camera, so be sure to use ` delta ` time to normalize speeds.
214+
215+ If animations start in response to triggers or actions and have an end time, subscribe and unsubscribe for performance:
214216
215217``` jsx
216- const update = delta => {
218+ const animate = delta => {
217219 // do things
218220}
219221
220222// subscribe when something needs to happen
221- app .on (' update ' , update )
223+ app .on (' animate ' , animate )
222224
223- // unsubscribe when idle to save resources
224- app .off (' update ' , update )
225+ // unsubscribe when finsihed to save resources
226+ app .off (' animate ' , animate )
225227```
226228
227229## Bloom
Original file line number Diff line number Diff line change @@ -6,6 +6,7 @@ import { Collections } from './systems/Collections'
66import { Apps } from './systems/Apps'
77import { Anchors } from './systems/Anchors'
88import { Avatars } from './systems/Avatars'
9+ import { Animation } from './systems/Animation'
910import { Events } from './systems/Events'
1011import { Chat } from './systems/Chat'
1112import { Blueprints } from './systems/Blueprints'
@@ -40,6 +41,7 @@ export class World extends EventEmitter {
4041 this . register ( 'apps' , Apps )
4142 this . register ( 'anchors' , Anchors )
4243 this . register ( 'avatars' , Avatars )
44+ this . register ( 'animation' , Animation )
4345 this . register ( 'events' , Events )
4446 this . register ( 'scripts' , Scripts )
4547 this . register ( 'chat' , Chat )
Original file line number Diff line number Diff line change @@ -12,7 +12,7 @@ import { Layers } from '../extras/Layers'
1212import { createPlayerProxy } from '../extras/createPlayerProxy'
1313import { serializeError } from '../extras/serializeError'
1414
15- const hotEventNames = [ 'fixedUpdate' , 'update' , 'lateUpdate' ]
15+ const hotEventNames = [ 'fixedUpdate' , 'update' , 'animate' , ' lateUpdate']
1616
1717const Modes = {
1818 ACTIVE : 'active' ,
@@ -42,6 +42,8 @@ export class App extends Entity {
4242 this . target = null
4343 this . projectLimit = Infinity
4444 this . resetOnMove = false
45+ this . animateDelta = 0
46+ this . animateRate = 0.001
4547 this . playerProxies = new Map ( )
4648 this . hitResultsPool = [ ]
4749 this . hitResults = [ ]
@@ -226,10 +228,17 @@ export class App extends Entity {
226228 this . networkQuat . update ( delta )
227229 this . networkSca . update ( delta )
228230 }
229- // script update()
231+ // script update/animate
230232 if ( this . script ) {
231233 try {
234+ // update
232235 this . emit ( 'update' , delta )
236+ // animate
237+ this . animateDelta += delta
238+ while ( this . animateDelta >= this . animateRate ) {
239+ this . emit ( 'animate' , this . animateDelta )
240+ this . animateDelta = 0
241+ }
233242 } catch ( err ) {
234243 this . scriptError = serializeError ( err )
235244 console . error ( 'script update() crashed' , this )
Original file line number Diff line number Diff line change 1+ import { System } from './System'
2+ import * as THREE from 'three'
3+
4+ const v1 = new THREE . Vector3 ( )
5+
6+ const BATCH_SIZE = 10
7+
8+ /**
9+ * Animation System
10+ *
11+ * - Updates app animation rates based on distance to camera
12+ *
13+ */
14+ export class Animation extends System {
15+ constructor ( world ) {
16+ super ( world )
17+ this . apps = [ ]
18+ this . cursor = 0
19+ }
20+
21+ init ( ) {
22+ this . world . entities . on ( 'added' , this . onAdded )
23+ this . world . entities . on ( 'removed' , this . onRemoved )
24+ }
25+
26+ onAdded = entity => {
27+ if ( ! entity . isApp ) return
28+ this . apps . push ( entity )
29+ }
30+
31+ onRemoved = entity => {
32+ if ( ! entity . isApp ) return
33+ const idx = this . apps . indexOf ( entity )
34+ if ( idx === - 1 ) return
35+ this . apps . splice ( idx , 1 )
36+ }
37+
38+ update ( ) {
39+ if ( ! this . apps . length ) return
40+ const camPos = v1 . setFromMatrixPosition ( this . world . camera . matrixWorld )
41+ const batch = Math . min ( BATCH_SIZE , this . apps . length )
42+ for ( let i = 0 ; i < batch ; i ++ ) {
43+ const app = this . apps [ this . cursor % this . apps . length ]
44+ if ( ! app . root ) {
45+ this . cursor ++
46+ continue
47+ }
48+ const appPos = app . root . position
49+ const distance = camPos . distanceTo ( appPos )
50+ if ( distance < 30 ) {
51+ app . animateRate = 0.001 // max fps
52+ } else if ( distance < 80 ) {
53+ app . animateRate = 1 / 30
54+ } else {
55+ app . animateRate = 1 / 20
56+ }
57+ this . cursor ++
58+ }
59+ }
60+
61+ destroy ( ) {
62+ this . apps = [ ]
63+ }
64+ }
Original file line number Diff line number Diff line change @@ -58,7 +58,7 @@ export class Entities extends System {
5858 this . player = entity
5959 this . world . emit ( 'player' , entity )
6060 }
61- this . emit ( 'added' )
61+ this . emit ( 'added' , entity )
6262 return entity
6363 }
6464
@@ -69,7 +69,7 @@ export class Entities extends System {
6969 entity . destroy ( )
7070 this . items . delete ( id )
7171 this . removed . push ( id )
72- this . emit ( 'removed' )
72+ this . emit ( 'removed' , entity )
7373 }
7474
7575 setHot ( entity , hot ) {
You can’t perform that action at this time.
0 commit comments