janusweb 1.5.30 → 1.5.34
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG +39 -0
- package/LICENSE +1 -1
- package/media/assets/janus-avatar-animations.glb +0 -0
- package/media/assets/janus-avatar-base.glb +0 -0
- package/media/assets/webui/apps/avatar/avatar.css +6 -2
- package/media/assets/webui/apps/avatar/avatar.js +99 -11
- package/media/assets/webui/apps/buttons/buttons.html +2 -2
- package/media/assets/webui/apps/buttons/buttons.js +3 -3
- package/media/assets/webui/apps/comms/comms.js +7 -4
- package/media/assets/webui/apps/comms/voip.js +133 -57
- package/media/assets/webui/apps/editor/codemirror/addon/hint/javascript-hint.js +162 -0
- package/media/assets/webui/apps/editor/codemirror/addon/hint/show-hint.css +36 -0
- package/media/assets/webui/apps/editor/codemirror/addon/hint/show-hint.js +529 -0
- package/media/assets/webui/apps/editor/codemirror/addon/hint/xml-hint.js +140 -0
- package/media/assets/webui/apps/editor/codemirror/keymap/vim.js +5734 -0
- package/media/assets/webui/apps/editor/codemirror/lib/codemirror.css +350 -0
- package/media/assets/webui/apps/editor/codemirror/lib/codemirror.js +9800 -0
- package/media/assets/webui/apps/editor/codemirror/lib/jmldark.css +33 -0
- package/media/assets/webui/apps/editor/codemirror/mode/css/css.js +864 -0
- package/media/assets/webui/apps/editor/codemirror/mode/htmlmixed/htmlmixed.js +153 -0
- package/media/assets/webui/apps/editor/codemirror/mode/javascript/javascript.js +942 -0
- package/media/assets/webui/apps/editor/codemirror/mode/xml/xml.js +413 -0
- package/media/assets/webui/apps/editor/editor.css +3 -0
- package/media/assets/webui/apps/editor/editor.js +409 -9
- package/media/assets/webui/apps/editor/editor.json +6 -3
- package/media/assets/webui/apps/inventory/inventory.html +7 -4
- package/media/assets/webui/apps/inventory/inventory.js +2 -2
- package/media/assets/webui/apps/locomotion/teleporter.js +10 -9
- package/media/assets/webui/apps/navigation/navigation.js +12 -12
- package/media/assets/webui/apps/settings/settings.html +1 -1
- package/media/assets/webui/apps/vfs/browserfs/browserfs.js +8 -0
- package/media/assets/webui/apps/vfs/vfs.css +52 -0
- package/media/assets/webui/apps/vfs/vfs.js +452 -0
- package/media/assets/webui/apps/vfs/vfs.json +10 -0
- package/media/assets/webui/apps/virtualgamepad/virtualgamepad.js +9 -7
- package/media/assets/webui/apps/xrmenu/xrmenu.js +13 -4
- package/media/assets/webui/default.json +2 -1
- package/media/assets/webui/none.json +1 -0
- package/media/assets/webui/themes/default.css +29 -2
- package/media/assets.json +2 -1
- package/media/index.html +1 -1
- package/media/lib/draco/README.md +32 -0
- package/media/lib/draco/draco_decoder.js +52 -0
- package/media/lib/draco/draco_decoder.wasm +0 -0
- package/media/lib/draco/draco_encoder.js +33 -0
- package/media/lib/draco/draco_wasm_wrapper.js +104 -0
- package/media/lib/draco/gltf/draco_decoder.js +48 -0
- package/media/lib/draco/gltf/draco_decoder.wasm +0 -0
- package/media/lib/draco/gltf/draco_encoder.js +33 -0
- package/media/lib/draco/gltf/draco_wasm_wrapper.js +104 -0
- package/media/lib/physx/physx.release.js +21 -0
- package/media/lib/physx/physx.release.wasm +0 -0
- package/media/manifest.json +5 -5
- package/media/service-worker.js +7 -0
- package/package.json +2 -9
- package/scripts/client.js +67 -46
- package/scripts/config.js +2 -0
- package/scripts/elements/linesegments.js +10 -3
- package/scripts/external/JanusFireboxParser.js +1 -0
- package/scripts/image.js +7 -1
- package/scripts/janusbase.js +104 -43
- package/scripts/janusghost.js +314 -16
- package/scripts/januslight.js +11 -2
- package/scripts/janusparagraph.js +8 -6
- package/scripts/janusparticle.js +26 -16
- package/scripts/janusplayer.js +126 -37
- package/scripts/janusweb.js +26 -2
- package/scripts/janusxrplayer.js +5 -3
- package/scripts/multiplayermanager.js +6 -4
- package/scripts/object.js +246 -88
- package/scripts/portal.js +23 -14
- package/scripts/remoteplayer.js +1 -25
- package/scripts/room.js +199 -77
- package/scripts/sound.js +8 -6
- package/scripts/text.js +13 -5
- package/scripts/translators/janusvfs.js +20 -0
- package/scripts/video.js +1 -1
- package/scripts/websurface.js +17 -3
- package/utils/build.sh +3 -0
- package/utils/init.sh +2 -2
- package/scripts/chat.js +0 -80
- package/scripts/ui.js +0 -265
- package/scripts/urlbar.js +0 -93
- package/templates/janusweb.tpl +0 -3
package/scripts/janusghost.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
elation.require(['janusweb.janusbase', 'engine.things.leapmotion'], function() {
|
|
2
|
+
|
|
2
3
|
elation.component.add('engine.things.janusghost', function() {
|
|
3
4
|
this.postinit = function() {
|
|
4
5
|
elation.engine.things.janusghost.extendclass.postinit.call(this);
|
|
@@ -16,9 +17,29 @@ elation.require(['janusweb.janusbase', 'engine.things.leapmotion'], function() {
|
|
|
16
17
|
ghostassets: { type: 'object' },
|
|
17
18
|
auto_play: { type: 'boolean', default: true },
|
|
18
19
|
screen_name: { type: 'string' },
|
|
20
|
+
animation_extras: { type: 'string' },
|
|
21
|
+
bone_head: { type: 'string' },
|
|
22
|
+
morphtarget_mouth: { type: 'string' },
|
|
23
|
+
morphtarget_eyes: { type: 'string' },
|
|
19
24
|
});
|
|
20
25
|
|
|
21
26
|
this.frames = false;
|
|
27
|
+
|
|
28
|
+
if (!('project_vertex_discard_close' in THREE.ShaderChunk)) {
|
|
29
|
+
THREE.ShaderChunk['color_fragment_discard_close'] = `
|
|
30
|
+
#if defined( USE_COLOR_ALPHA )
|
|
31
|
+
diffuseColor *= vColor;
|
|
32
|
+
#elif defined( USE_COLOR )
|
|
33
|
+
diffuseColor.rgb *= vColor;
|
|
34
|
+
#endif
|
|
35
|
+
float dist = length(vViewPosition);
|
|
36
|
+
float mindist = .4;
|
|
37
|
+
float maxdist = .6;
|
|
38
|
+
if (dist < maxdist) {
|
|
39
|
+
diffuseColor.a = clamp(((dist - mindist) / (maxdist - mindist)), 0., 1.);
|
|
40
|
+
}
|
|
41
|
+
`;
|
|
42
|
+
}
|
|
22
43
|
}
|
|
23
44
|
this.createObject3D = function() {
|
|
24
45
|
if (this.ghost_src) {
|
|
@@ -76,7 +97,6 @@ elation.require(['janusweb.janusbase', 'engine.things.leapmotion'], function() {
|
|
|
76
97
|
size: .1,
|
|
77
98
|
thickness: .03,
|
|
78
99
|
align: 'center',
|
|
79
|
-
collidable: false,
|
|
80
100
|
text: name,
|
|
81
101
|
pos: this.userid_pos,
|
|
82
102
|
pickable: false,
|
|
@@ -114,6 +134,45 @@ elation.require(['janusweb.janusbase', 'engine.things.leapmotion'], function() {
|
|
|
114
134
|
console.log(this.ghostassets);
|
|
115
135
|
this.assetpack.loadJSON(assets.assetlist);
|
|
116
136
|
}
|
|
137
|
+
|
|
138
|
+
let animnames = []; //'idle', 'walk', 'walk_left', 'walk_right', 'walk_back', 'run', 'jump', 'fly', 'speak', 'type', 'portal'];
|
|
139
|
+
let animassets = assets.assetlist.filter(asset => animnames.indexOf(asset.name) != -1);
|
|
140
|
+
console.log('some ghost animations', animassets, assets);
|
|
141
|
+
|
|
142
|
+
if (!this.animationmixer) {
|
|
143
|
+
// Set up our animation mixer with a simple bone mapper for our head. We'll add more animations to this ass other assets load
|
|
144
|
+
// TODO - this is probably also where we'd map any other tracked objects (hands, hips, etc). and set up IK
|
|
145
|
+
|
|
146
|
+
/*
|
|
147
|
+
let headtrack = new THREE.QuaternionKeyframeTrack('Neck.quaternion', [0], [0, 0, 0, 1]),
|
|
148
|
+
headclip = new THREE.AnimationClip('head_rotation', -1, [headtrack]);
|
|
149
|
+
this.headtrack = headtrack;
|
|
150
|
+
|
|
151
|
+
this.initAnimations([ headclip ]);
|
|
152
|
+
//this.animations['head_rotation'].play();
|
|
153
|
+
*/
|
|
154
|
+
this.initAnimations([]);
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
animassets.forEach(anim => {
|
|
158
|
+
let asset = this.getAsset('model', anim.name);
|
|
159
|
+
console.log('try to load the animation', asset, anim);
|
|
160
|
+
if (asset) {
|
|
161
|
+
if (!asset.loaded) {
|
|
162
|
+
let model = asset.getInstance();
|
|
163
|
+
elation.events.add(asset, 'asset_load', ev => {
|
|
164
|
+
let clip = false;
|
|
165
|
+
model.traverse(n => { if (n.animations && n.animations.length > 0) clip = n.animations[0]; });
|
|
166
|
+
if (clip) {
|
|
167
|
+
if (this.animationmixer && !this.animations[anim.name]) {
|
|
168
|
+
let action = this.animationmixer.clipAction(clip);
|
|
169
|
+
this.animations[anim.name] = action;
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
});
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
});
|
|
117
176
|
}
|
|
118
177
|
this.getGhostObjects = function() {
|
|
119
178
|
var objects = {};
|
|
@@ -186,6 +245,8 @@ elation.require(['janusweb.janusbase', 'engine.things.leapmotion'], function() {
|
|
|
186
245
|
this.head.appendChild(headid);
|
|
187
246
|
this.face.start();
|
|
188
247
|
}
|
|
248
|
+
this.head.pos = headpos.clone().multiplyScalar(this.scale.y);
|
|
249
|
+
this.face.applyPosition(headpos.negate());
|
|
189
250
|
if (this.remotevideo) {
|
|
190
251
|
this.updateVideoScreen();
|
|
191
252
|
this.face.addEventListener('load', (ev) => {
|
|
@@ -217,6 +278,11 @@ elation.require(['janusweb.janusbase', 'engine.things.leapmotion'], function() {
|
|
|
217
278
|
//rotation: V(0, 180, 0),
|
|
218
279
|
lighting: this.lighting,
|
|
219
280
|
//cull_face: 'none'
|
|
281
|
+
opacity: 0.9999,
|
|
282
|
+
renderorder: this.renderorder || 100,
|
|
283
|
+
shader_chunk_replace: (this.lighting ? {
|
|
284
|
+
'color_fragment': 'color_fragment_discard_close',
|
|
285
|
+
} : {}),
|
|
220
286
|
});
|
|
221
287
|
} else {
|
|
222
288
|
this.body = bodyid;
|
|
@@ -225,11 +291,169 @@ elation.require(['janusweb.janusbase', 'engine.things.leapmotion'], function() {
|
|
|
225
291
|
if (pos) this.body.pos = pos;
|
|
226
292
|
this.body.start();
|
|
227
293
|
if (scale && this.body) this.body.scale.fromArray(scale);
|
|
294
|
+
|
|
295
|
+
elation.events.add(this, 'load', ev => {
|
|
296
|
+
if (this.body.modelasset) {
|
|
297
|
+
if (this.body.modelasset.loaded) {
|
|
298
|
+
this.loadAnimations();
|
|
299
|
+
if (this.animation_extras) {
|
|
300
|
+
this.loadAnimationExtras();
|
|
301
|
+
}
|
|
302
|
+
} else {
|
|
303
|
+
elation.events.add(this.body.modelasset, 'asset_load_complete', () => {
|
|
304
|
+
this.loadAnimations();
|
|
305
|
+
if (this.animation_extras) {
|
|
306
|
+
this.loadAnimationExtras();
|
|
307
|
+
}
|
|
308
|
+
});
|
|
309
|
+
}
|
|
310
|
+
}
|
|
311
|
+
// FIXME - this prevents avatars from being culled, which prevents our default mesh from disappearing but also means we lose out on possible performance optimizations in rooms with lots of avatars
|
|
312
|
+
this.objects['3d'].traverse(n => {
|
|
313
|
+
if (n instanceof THREE.Mesh) {
|
|
314
|
+
n.frustumCulled = false;
|
|
315
|
+
}
|
|
316
|
+
});
|
|
317
|
+
});
|
|
318
|
+
}
|
|
319
|
+
}
|
|
320
|
+
this.loadAnimations = function(assetid) {
|
|
321
|
+
if (!assetid) assetid = 'avatar_animations';
|
|
322
|
+
let animasset = this.getAsset('model', assetid);
|
|
323
|
+
if (!animasset.loaded) {
|
|
324
|
+
let animationsLoaded = false;
|
|
325
|
+
elation.events.add(animasset, 'asset_load_complete', ev => {
|
|
326
|
+
if (!animationsLoaded) {
|
|
327
|
+
animationsLoaded = true;
|
|
328
|
+
if (this.body.animationmixer) {
|
|
329
|
+
this.cloneAnimations(animasset);
|
|
330
|
+
}
|
|
331
|
+
this.body.setAnimation('idle');
|
|
332
|
+
}
|
|
333
|
+
});
|
|
334
|
+
animasset.load();
|
|
335
|
+
} else {
|
|
336
|
+
if (this.body.animationmixer) {
|
|
337
|
+
this.cloneAnimations(animasset);
|
|
338
|
+
}
|
|
339
|
+
this.body.setAnimation('idle');
|
|
340
|
+
}
|
|
341
|
+
}
|
|
342
|
+
this.cloneAnimations = function(animasset) {
|
|
343
|
+
let animations = animasset.animations;
|
|
344
|
+
//console.log('clone all the animations', animations, animasset._model);
|
|
345
|
+
if (this.body) {
|
|
346
|
+
if (this.bone_head) {
|
|
347
|
+
this.initHeadAnimation(animasset);
|
|
348
|
+
}
|
|
349
|
+
|
|
350
|
+
animations.forEach(clip => {
|
|
351
|
+
this.body.animations[clip.name] = this.body.animationmixer.clipAction(this.retargetAnimation(clip, animasset._model));
|
|
352
|
+
//console.log('new clip', clip.name, clip, this.body.animations[clip.name]);
|
|
353
|
+
});
|
|
354
|
+
//console.log('head rot', this.body.animations['head_rotation'], headclip, headaction);
|
|
355
|
+
//console.log(this.body.modelasset, this.body.modelasset.vrm);
|
|
356
|
+
if (this.body.modelasset && this.body.modelasset.vrm) {
|
|
357
|
+
let rename = {};
|
|
358
|
+
let bonemap = this.body.modelasset.vrm.humanoid.humanBones;
|
|
359
|
+
for (let k in bonemap) {
|
|
360
|
+
console.log(k, bonemap[k]);
|
|
361
|
+
if (bonemap[k].length > 0) {
|
|
362
|
+
rename[bonemap[k][0].node.name] = k;
|
|
363
|
+
}
|
|
364
|
+
}
|
|
365
|
+
let bones = [];
|
|
366
|
+
let meshes = [];
|
|
367
|
+
this.body.objects['3d'].traverse(n => { if (n instanceof THREE.Bone) bones.push(n); else if (n instanceof THREE.SkinnedMesh) meshes.push(n); });
|
|
368
|
+
/*
|
|
369
|
+
console.log('rename the bones!', rename);
|
|
370
|
+
THREE.SkeletonUtils.renameBones(bones, rename);
|
|
371
|
+
console.log('bones now', bones);
|
|
372
|
+
*/
|
|
373
|
+
|
|
374
|
+
}
|
|
228
375
|
}
|
|
229
376
|
}
|
|
377
|
+
this.retargetAnimation = function(clip, sourcecontainer) {
|
|
378
|
+
let newclip = clip.clone();
|
|
379
|
+
let sourcemesh = null,
|
|
380
|
+
destmesh = null;
|
|
381
|
+
if (sourcecontainer) {
|
|
382
|
+
sourcecontainer.traverse(n => { /*console.log(' - ', n); */ if (n instanceof THREE.SkinnedMesh && n.skeleton) sourcemesh = n; });
|
|
383
|
+
}
|
|
384
|
+
this.objects['3d'].traverse(n => { if (n instanceof THREE.SkinnedMesh && n.skeleton) destmesh = n; });
|
|
385
|
+
//console.log('RETARGET ANI*MATION', clip, sourcemesh, destmesh, sourcecontainer);
|
|
386
|
+
let remove = [];
|
|
387
|
+
if (this.body && this.body.modelasset && this.body.modelasset.vrm) {
|
|
388
|
+
let vrm = this.body.modelasset.vrm;
|
|
389
|
+
//console.log('RETARGET ANI*MATION', clip, this.body.modelasset.vrm, sourcemesh, destmesh);
|
|
390
|
+
newclip.tracks.forEach(track => {
|
|
391
|
+
let parts = track.name.split('.');
|
|
392
|
+
console.log(parts, track.name);
|
|
393
|
+
try {
|
|
394
|
+
let bone = vrm.humanoid.getBone(parts[0]);
|
|
395
|
+
if (bone) {
|
|
396
|
+
track.name = bone.node.name + '.' + parts[1];
|
|
397
|
+
let sourcebone = sourcemesh.skeleton.getBone(bone.node.name);
|
|
398
|
+
//console.log(track, bone);
|
|
399
|
+
} else {
|
|
400
|
+
//console.log('no bone!', parts, track);
|
|
401
|
+
}
|
|
402
|
+
} catch (e) {
|
|
403
|
+
console.log('omgwtf', e.message);
|
|
404
|
+
remove.push(track);
|
|
405
|
+
}
|
|
406
|
+
});
|
|
407
|
+
remove.forEach(track => {
|
|
408
|
+
let idx = newclip.tracks.indexOf(track);
|
|
409
|
+
if (idx != -1) {
|
|
410
|
+
newclip.tracks.splice(idx, 1);
|
|
411
|
+
//console.log('removed track', track);
|
|
412
|
+
}
|
|
413
|
+
});
|
|
414
|
+
} else if (destmesh && sourcemesh) {
|
|
415
|
+
// FIXME - silly hack to store skeleton, we should just be extracting it at load time
|
|
416
|
+
this.body.skeleton = destmesh.skeleton;
|
|
417
|
+
this.body.objects['3d'].skeleton = destmesh.skeleton;
|
|
418
|
+
//newclip = THREE.SkeletonUtils.retargetClip(destmesh, sourcemesh, newclip, {useFirstFramePosition: true});
|
|
419
|
+
//console.log('retarget it!', newclip, destmesh, sourcemesh);
|
|
420
|
+
newclip.tracks.forEach(track => {
|
|
421
|
+
let [name, property] = track.name.split('.');
|
|
422
|
+
let srcbone = sourcemesh.skeleton.getBoneByName(name);
|
|
423
|
+
let dstbone = destmesh.skeleton.getBoneByName(name);
|
|
424
|
+
//console.log(' - fix track', name, property, track, srcbone, dstbone);
|
|
425
|
+
if (dstbone) {
|
|
426
|
+
let scale = srcbone.position.length() / dstbone.position.length();
|
|
427
|
+
if (property == 'position') {
|
|
428
|
+
for (let i = 0; i < track.values.length; i++) {
|
|
429
|
+
track.values[i] /= scale;
|
|
430
|
+
}
|
|
431
|
+
//remove.push(track);
|
|
432
|
+
} else if (property == 'quaternion') {
|
|
433
|
+
}
|
|
434
|
+
} else {
|
|
435
|
+
//console.log('missing bone!', srcbone, track);
|
|
436
|
+
remove.push(track);
|
|
437
|
+
}
|
|
438
|
+
});
|
|
439
|
+
}
|
|
440
|
+
remove.forEach(track => {
|
|
441
|
+
let idx = newclip.tracks.indexOf(track);
|
|
442
|
+
if (idx != -1) {
|
|
443
|
+
newclip.tracks.splice(idx, 1);
|
|
444
|
+
//console.log('removed track', track);
|
|
445
|
+
}
|
|
446
|
+
});
|
|
447
|
+
//console.log('finished clip', newclip);
|
|
448
|
+
return newclip;
|
|
449
|
+
}
|
|
230
450
|
this.rebindAnimations = function() {
|
|
231
451
|
this.body.rebindAnimations();
|
|
232
452
|
}
|
|
453
|
+
this.loadAnimationExtras = function() {
|
|
454
|
+
let animids = this.animation_extras.split(' ');
|
|
455
|
+
animids.forEach(animid => this.loadAnimations(animid));
|
|
456
|
+
}
|
|
233
457
|
|
|
234
458
|
this.start = function() {
|
|
235
459
|
elation.engine.things.janusghost.extendclass.start.call(this);
|
|
@@ -289,13 +513,16 @@ elation.require(['janusweb.janusbase', 'engine.things.leapmotion'], function() {
|
|
|
289
513
|
|
|
290
514
|
matrix.makeBasis(xdir, ydir, zdir);
|
|
291
515
|
q1.setFromRotationMatrix(matrix);
|
|
292
|
-
this.head.properties.orientation.copy(this.orientation).
|
|
516
|
+
this.head.properties.orientation.copy(this.orientation).invert().multiply(q1);
|
|
517
|
+
if (this.body && this.headaction) {
|
|
518
|
+
this.setHeadOrientation(this.head.orientation);
|
|
519
|
+
}
|
|
293
520
|
if (movedata.head_pos && this.face) {
|
|
294
521
|
var headpos = this.head.properties.position;
|
|
295
522
|
var facepos = this.face.properties.position;
|
|
296
523
|
var newpos = parser.getVectorValue(movedata.head_pos);
|
|
297
|
-
headpos.copy(this.head_pos);
|
|
298
|
-
facepos.fromArray(newpos).sub(headpos);
|
|
524
|
+
//headpos.copy(this.head_pos);
|
|
525
|
+
//facepos.fromArray(newpos).sub(headpos);
|
|
299
526
|
if (this.body) {
|
|
300
527
|
if (this.head.parent != this.body) {
|
|
301
528
|
this.body.appendChild(this.head);
|
|
@@ -357,6 +584,20 @@ elation.require(['janusweb.janusbase', 'engine.things.leapmotion'], function() {
|
|
|
357
584
|
if (movedata.userid_pos) {
|
|
358
585
|
this.userid_pos = movedata.userid_pos;
|
|
359
586
|
}
|
|
587
|
+
|
|
588
|
+
// FIXME - workaround for null values
|
|
589
|
+
if (isNaN(this.position.x)) this.position.x = 0;
|
|
590
|
+
if (isNaN(this.position.y)) this.position.y = 0;
|
|
591
|
+
if (isNaN(this.position.z)) this.position.z = 0;
|
|
592
|
+
if (isNaN(this.orientation.x) || isNaN(this.orientation.y) || isNaN(this.orientation.z) || isNaN(this.orientation.w)) this.orientation.set(0,0,0,1);
|
|
593
|
+
|
|
594
|
+
if (this.head) {
|
|
595
|
+
if (isNaN(this.head.position.x)) this.head.position.x = 0;
|
|
596
|
+
if (isNaN(this.head.position.y)) this.head.position.y = 0;
|
|
597
|
+
if (isNaN(this.head.position.z)) this.head.position.z = 0;
|
|
598
|
+
if (isNaN(this.head.orientation.x) || isNaN(this.head.orientation.y) || isNaN(this.head.orientation.z) || isNaN(this.head.orientation.w)) this.head.orientation.set(0,0,0,1);
|
|
599
|
+
}
|
|
600
|
+
|
|
360
601
|
this.objects.dynamics.updateState();
|
|
361
602
|
this.refresh();
|
|
362
603
|
}
|
|
@@ -391,6 +632,14 @@ elation.require(['janusweb.janusbase', 'engine.things.leapmotion'], function() {
|
|
|
391
632
|
this.screen_name = ghostdef.screen_name;
|
|
392
633
|
}
|
|
393
634
|
this.setGhostAssets(things.assets);
|
|
635
|
+
this.animation_extras = ghostdef.animation_extras;
|
|
636
|
+
this.bone_head = ghostdef.bone_head;
|
|
637
|
+
this.morphtarget_mouth = ghostdef.morphtarget_mouth;
|
|
638
|
+
this.morphtarget_eyes = ghostdef.morphtarget_eyes;
|
|
639
|
+
this.lighting = elation.utils.any(ghostdef.lighting, true);
|
|
640
|
+
if (ghostdef.morphtarget_eyes) {
|
|
641
|
+
this.blink();
|
|
642
|
+
}
|
|
394
643
|
if (ghostdef.head_id) {
|
|
395
644
|
this.setHead(ghostdef.head_id, headpos, ghostdef.scale);
|
|
396
645
|
}
|
|
@@ -431,7 +680,7 @@ elation.require(['janusweb.janusbase', 'engine.things.leapmotion'], function() {
|
|
|
431
680
|
}
|
|
432
681
|
|
|
433
682
|
var inverse = new THREE.Matrix4();
|
|
434
|
-
inverse.
|
|
683
|
+
inverse.copy(this.objects['3d'].matrixWorld).invert();
|
|
435
684
|
if (hand0 && hand0.state) {
|
|
436
685
|
this.hands.left.show();
|
|
437
686
|
this.hands.left.setState(hand0.state, inverse);
|
|
@@ -460,6 +709,7 @@ elation.require(['janusweb.janusbase', 'engine.things.leapmotion'], function() {
|
|
|
460
709
|
}
|
|
461
710
|
}
|
|
462
711
|
this.updateTransparency = function() {
|
|
712
|
+
return;
|
|
463
713
|
var player = this.engine.client.player;
|
|
464
714
|
|
|
465
715
|
var dist = player.distanceTo(this);
|
|
@@ -478,17 +728,6 @@ elation.require(['janusweb.janusbase', 'engine.things.leapmotion'], function() {
|
|
|
478
728
|
m.visible = (opacity > 0);
|
|
479
729
|
});
|
|
480
730
|
}
|
|
481
|
-
this.setRoom = function(room) {
|
|
482
|
-
if (room !== this.room) {
|
|
483
|
-
if (this.room) {
|
|
484
|
-
this.room.remove(this);
|
|
485
|
-
}
|
|
486
|
-
this.room = room;
|
|
487
|
-
if (room && this.parent != this.room) {
|
|
488
|
-
room.add(this);
|
|
489
|
-
}
|
|
490
|
-
}
|
|
491
|
-
}
|
|
492
731
|
this.setRemoteVideo = function(video) {
|
|
493
732
|
if (video) {
|
|
494
733
|
this.remotevideo = video;
|
|
@@ -540,5 +779,64 @@ elation.require(['janusweb.janusbase', 'engine.things.leapmotion'], function() {
|
|
|
540
779
|
});
|
|
541
780
|
}
|
|
542
781
|
}
|
|
782
|
+
this.setAnimation = function(anim) {
|
|
783
|
+
if (this.body) this.body.anim_id = anim;
|
|
784
|
+
}
|
|
785
|
+
this.initHeadAnimation = function(animasset) {
|
|
786
|
+
let body = this.body || this._target.body,
|
|
787
|
+
head = this.head || this._target.head;
|
|
788
|
+
if (body && this.bone_head && !this.headaction) {
|
|
789
|
+
if (!body.animationmixer) {
|
|
790
|
+
body.initAnimations([]);
|
|
791
|
+
}
|
|
792
|
+
// Set up our animation mixer with a simple bone mapper for our head. We'll add more animations to this as other assets load
|
|
793
|
+
// TODO - this is probably also where we'd map any other tracked objects (hands, hips, etc). and set up IK
|
|
794
|
+
|
|
795
|
+
let headtrack = new THREE.QuaternionKeyframeTrack(this.bone_head + '.quaternion', [0], [0, 0, 0, 1]),
|
|
796
|
+
headclip = new THREE.AnimationClip('head_rotation', -1, [headtrack]);
|
|
797
|
+
let headaction = body.animationmixer.clipAction(this.retargetAnimation(headclip, animasset._model));
|
|
798
|
+
headaction.weight = 5;
|
|
799
|
+
this.headaction = headaction;
|
|
800
|
+
headaction.play();
|
|
801
|
+
}
|
|
802
|
+
}
|
|
803
|
+
this.setHeadOrientation = function(orientation, invert) {
|
|
804
|
+
let headaction = this.headaction || this._target.headaction;
|
|
805
|
+
if (headaction && headaction._clip.tracks[0]) {
|
|
806
|
+
let track = headaction._clip.tracks[0];
|
|
807
|
+
track.values[0] = orientation.x * (invert ? -1 : 1);
|
|
808
|
+
track.values[1] = orientation.y * (invert ? -1 : 1);
|
|
809
|
+
track.values[2] = orientation.z * (invert ? -1 : 1);
|
|
810
|
+
track.values[3] = orientation.w; // * (invert ? -1 : 1);
|
|
811
|
+
}
|
|
812
|
+
}
|
|
813
|
+
this.blink = function() {
|
|
814
|
+
if (!this.blinktimer) {
|
|
815
|
+
if (this.body && this.morphtarget_eyes) {
|
|
816
|
+
this.body.setMorphTargetInfluence(this.morphtarget_eyes, 1);
|
|
817
|
+
setTimeout(() => {
|
|
818
|
+
this.body.setMorphTargetInfluence(this.morphtarget_eyes, 0);
|
|
819
|
+
}, 100);
|
|
820
|
+
}
|
|
821
|
+
this.blinktimer = setTimeout(() => {
|
|
822
|
+
this.blinktimer = false;
|
|
823
|
+
this.blink();
|
|
824
|
+
}, 2500 + Math.random() * 8500);
|
|
825
|
+
}
|
|
826
|
+
}
|
|
827
|
+
this.setSpeakingVolume = function(volume) {
|
|
828
|
+
if (this.body && this.morphtarget_mouth) {
|
|
829
|
+
this.body.setMorphTargetInfluence(this.morphtarget_mouth, volume);
|
|
830
|
+
}
|
|
831
|
+
}
|
|
832
|
+
this.getProxyObject = function(classdef) {
|
|
833
|
+
if (!this._proxyobject) {
|
|
834
|
+
this._proxyobject = elation.engine.things.janusghost.extendclass.getProxyObject.call(this, classdef);
|
|
835
|
+
this._proxyobject._proxydefs = {
|
|
836
|
+
body: [ 'property', 'body'],
|
|
837
|
+
};
|
|
838
|
+
}
|
|
839
|
+
return this._proxyobject;
|
|
840
|
+
}
|
|
543
841
|
}, elation.engine.things.janusbase);
|
|
544
842
|
});
|
package/scripts/januslight.js
CHANGED
|
@@ -18,6 +18,8 @@ elation.require(['janusweb.janusbase'], function() {
|
|
|
18
18
|
light_shadow_bias: { type: 'float', default: .0001, set: this.updateLight },
|
|
19
19
|
light_shadow_radius: { type: 'float', default: 2.5, set: this.updateLight },
|
|
20
20
|
light_helper: { type: 'boolean', default: false, set: this.updateLightHelper },
|
|
21
|
+
light_style: { type: 'string', default: '' },
|
|
22
|
+
light_style_fps: { type: 'float', default: 10 },
|
|
21
23
|
collision_id: { type: 'string', default: 'sphere', set: this.updateCollider },
|
|
22
24
|
collision_trigger: { type: 'boolean', default: true, set: this.updateCollider },
|
|
23
25
|
});
|
|
@@ -98,8 +100,14 @@ elation.require(['janusweb.janusbase'], function() {
|
|
|
98
100
|
this.updateLightTarget();
|
|
99
101
|
}
|
|
100
102
|
if (this.light_directional || this.light_cone_angle == 1) {
|
|
101
|
-
this.light.position.subVectors(this.light.position, this.light.target.position).add(player.pos);
|
|
102
|
-
this.light.target.position.
|
|
103
|
+
//this.light.position.subVectors(this.light.position, this.light.target.position).add(player.pos).sub(this.pos);
|
|
104
|
+
this.light.position.subVectors(this.position, this.light.target.position).normalize().multiplyScalar(this.light_range / 2).add(player.pos).sub(this.pos);
|
|
105
|
+
this.light.target.position.copy(player.pos).sub(this.pos);
|
|
106
|
+
}
|
|
107
|
+
if (this.light_style != '') {
|
|
108
|
+
let idx = Math.floor(Date.now() / (1000 / this.light_style_fps)) % this.light_style.length;
|
|
109
|
+
let brightness = (this.light_style.charCodeAt(idx) - 97) / 13;
|
|
110
|
+
this.light.intensity = .1 * brightness;
|
|
103
111
|
}
|
|
104
112
|
}
|
|
105
113
|
this.createLight = function() {
|
|
@@ -127,6 +135,7 @@ elation.require(['janusweb.janusbase'], function() {
|
|
|
127
135
|
//this.light.intensity = this.light_intensity / 100;
|
|
128
136
|
var avgscale = (this.scale.x + this.scale.y + this.scale.z) / 3;
|
|
129
137
|
//this.light.intensity = this.light_intensity / 100;
|
|
138
|
+
let brightness = 1;
|
|
130
139
|
this.light.intensity = .1;
|
|
131
140
|
this.light.penumbra = this.light_penumbra;
|
|
132
141
|
this.light.decay = this.light_decay;
|
|
@@ -13,7 +13,7 @@ elation.require(['janusweb.janusbase'], function() {
|
|
|
13
13
|
depth_write: { type: 'boolean', default: true },
|
|
14
14
|
depth_test: { type: 'boolean', default: true },
|
|
15
15
|
collision_id: { type: 'string', default: 'cube' },
|
|
16
|
-
collision_scale: { type: 'vector3', default: V(
|
|
16
|
+
collision_scale: { type: 'vector3', default: V(.5, .5, .02) },
|
|
17
17
|
shadow: { type: 'boolean', default: true, set: this.updateMaterial },
|
|
18
18
|
shadow_receive: { type: 'boolean', default: true, set: this.updateMaterial, comment: 'Receive shadows from self and other objects' },
|
|
19
19
|
shadow_cast: { type: 'boolean', default: true, set: this.updateMaterial, comment: 'Cast shadows onto self and other objects' },
|
|
@@ -29,8 +29,10 @@ elation.require(['janusweb.janusbase'], function() {
|
|
|
29
29
|
return mesh;
|
|
30
30
|
}
|
|
31
31
|
this.createForces = function() {
|
|
32
|
-
this.setCollider('box', { min: V(
|
|
32
|
+
this.setCollider('box', { min: V(-.8, -.8, -.01), max: V(.8, .8, .01) });
|
|
33
|
+
//this.collision_id = 'cube';
|
|
33
34
|
}
|
|
35
|
+
this.updateColliderFromGeometry = function() { }
|
|
34
36
|
this.createMaterial = function() {
|
|
35
37
|
var texture = this.createTexture();
|
|
36
38
|
var sidemap = {
|
|
@@ -66,15 +68,15 @@ elation.require(['janusweb.janusbase'], function() {
|
|
|
66
68
|
if (!this.canvas || !this.texture) return;
|
|
67
69
|
var ctx = this.canvas.getContext('2d'),
|
|
68
70
|
texture = this.texture;
|
|
69
|
-
this.canvas.width =
|
|
70
|
-
this.canvas.height =
|
|
71
|
+
this.canvas.width = 1024;
|
|
72
|
+
this.canvas.height = 1024;
|
|
71
73
|
var text_col = '#' + this.text_col.getHexString(),
|
|
72
74
|
back_col = 'rgba(' + (this.back_col.r * 255) + ', ' + (this.back_col.g * 255) + ', ' + (this.back_col.b * 255) + ', ' + this.back_alpha + ')';
|
|
73
75
|
var basestyle = 'font-family: sans-serif;' +
|
|
74
76
|
'font-size: ' + this.font_size + 'px;' +
|
|
75
77
|
'color: ' + text_col + ';' +
|
|
76
78
|
'background: ' + back_col + ';' +
|
|
77
|
-
'max-width:
|
|
79
|
+
'max-width: 1014px;' +
|
|
78
80
|
'padding: 5px;';
|
|
79
81
|
|
|
80
82
|
// We need to sanitize our HTML in case someone provides us with malformed markup.
|
|
@@ -115,7 +117,7 @@ elation.require(['janusweb.janusbase'], function() {
|
|
|
115
117
|
texture.needsUpdate = true;
|
|
116
118
|
this.refresh();
|
|
117
119
|
}
|
|
118
|
-
}
|
|
120
|
+
};
|
|
119
121
|
this.currentImage = img;
|
|
120
122
|
img.src = url;
|
|
121
123
|
this.refresh();
|
package/scripts/janusparticle.js
CHANGED
|
@@ -39,7 +39,6 @@ elation.require(['janusweb.janusbase'], function() {
|
|
|
39
39
|
opacity: { type: 'float', default: 1.0, set: this.updateMaterial },
|
|
40
40
|
fade_in: { type: 'float', default: 1.0 },
|
|
41
41
|
fade_out: { type: 'float', default: 1.0 },
|
|
42
|
-
duration: { type: 'float', default: 1.0 },
|
|
43
42
|
particle_scale: { type: 'vector3', default: [1, 1, 1], set: this.updateMaterial},
|
|
44
43
|
particle_vel: { type: 'vector3', default: [0, 0, 0]},
|
|
45
44
|
particle_accel: { type: 'vector3', default: [0, 0, 0]},
|
|
@@ -52,8 +51,8 @@ elation.require(['janusweb.janusbase'], function() {
|
|
|
52
51
|
refreshrate: { type: 'int', default: 30 },
|
|
53
52
|
blend_src: { type: 'string', default: 'src_alpha', set: this.updateMaterial },
|
|
54
53
|
blend_dest: { type: 'string', default: 'one_minus_src_alpha', set: this.updateMaterial },
|
|
55
|
-
|
|
56
|
-
|
|
54
|
+
depth_write: { type: 'bool', default: false },
|
|
55
|
+
depth_test: { type: 'bool', default: true },
|
|
57
56
|
});
|
|
58
57
|
this.particles = [];
|
|
59
58
|
this.emitted = 0;
|
|
@@ -67,11 +66,12 @@ elation.require(['janusweb.janusbase'], function() {
|
|
|
67
66
|
this.collidable = false;
|
|
68
67
|
this.boundingRadiusSq = 0;
|
|
69
68
|
this.boundingSphereWorld = new THREE.Sphere();
|
|
69
|
+
this.furthestPoint = new THREE.Vector3();
|
|
70
70
|
this.lastrefresh = 0;
|
|
71
71
|
this.updateParticles = elation.bind(this, this.updateParticles); // FIXME - hack, this should happen at the lower level of all components
|
|
72
72
|
}
|
|
73
73
|
this.createObject3D = function() {
|
|
74
|
-
var geo = this.geometry = new THREE.BufferGeometry()
|
|
74
|
+
var geo = this.geometry = new THREE.BufferGeometry();
|
|
75
75
|
|
|
76
76
|
var texture = null,
|
|
77
77
|
textureasset = null;
|
|
@@ -131,8 +131,8 @@ elation.require(['janusweb.janusbase'], function() {
|
|
|
131
131
|
//blending: THREE.AdditiveBlending,
|
|
132
132
|
transparent: true,
|
|
133
133
|
alphaTest: .001,
|
|
134
|
-
depthWrite: this.
|
|
135
|
-
depthTest: this.
|
|
134
|
+
depthWrite: this.depth_write,
|
|
135
|
+
depthTest: this.depth_test,
|
|
136
136
|
} );
|
|
137
137
|
|
|
138
138
|
this.material = mat;
|
|
@@ -289,8 +289,8 @@ elation.require(['janusweb.janusbase'], function() {
|
|
|
289
289
|
elapsed = now - this.lasttime,
|
|
290
290
|
endtime = now + this.duration * 1000,
|
|
291
291
|
emitted = 0,
|
|
292
|
-
startpoint = this.currentpoint
|
|
293
|
-
spawncount = this.rate * elapsed / 1000
|
|
292
|
+
startpoint = this.currentpoint,
|
|
293
|
+
spawncount = this.rate * elapsed / 1000,
|
|
294
294
|
count = this.count,
|
|
295
295
|
loop = this.loop;
|
|
296
296
|
|
|
@@ -324,11 +324,19 @@ elation.require(['janusweb.janusbase'], function() {
|
|
|
324
324
|
// We also rate limit here, so if nothing else in the scene is changing, we
|
|
325
325
|
// render at a lower fps
|
|
326
326
|
this.localToWorld(this.boundingSphereWorld.center.set(0,0,0));
|
|
327
|
-
|
|
328
|
-
|
|
327
|
+
let geo = this.objects['3d'].geometry;
|
|
328
|
+
if (!geo.boundingSphere) {
|
|
329
|
+
geo.computeBoundingSphere();
|
|
330
|
+
} else {
|
|
331
|
+
let currentBoundingRadius = geo.boundingSphere.radius;
|
|
332
|
+
if (this.boundingRadiusSq > currentBoundingRadius * currentBoundingRadius) {
|
|
333
|
+
geo.boundingSphere.radius = Math.sqrt(this.boundingRadiusSq) + .1;
|
|
334
|
+
}
|
|
329
335
|
}
|
|
330
|
-
|
|
336
|
+
|
|
337
|
+
this.boundingSphereWorld.radius = geo.boundingSphere.radius;
|
|
331
338
|
if (player.viewfrustum.intersectsSphere(this.boundingSphereWorld) && now - this.lastrefresh > (1000 / this.refreshrate)) {
|
|
339
|
+
|
|
332
340
|
this.refresh();
|
|
333
341
|
this.lastrefresh = now;
|
|
334
342
|
}
|
|
@@ -341,11 +349,14 @@ elation.require(['janusweb.janusbase'], function() {
|
|
|
341
349
|
var lengthSq = vec.lengthSq();
|
|
342
350
|
if (lengthSq > this.boundingRadiusSq) {
|
|
343
351
|
this.boundingRadiusSq = lengthSq;
|
|
352
|
+
this.furthestPoint.copy(vec);
|
|
353
|
+
/*
|
|
344
354
|
var geo = this.objects['3d'].geometry;
|
|
345
355
|
if (!geo.boundingSphere) {
|
|
346
356
|
geo.boundingSphere = new THREE.Sphere();
|
|
347
357
|
}
|
|
348
358
|
geo.boundingSphere.radius = Math.sqrt(lengthSq);
|
|
359
|
+
*/
|
|
349
360
|
}
|
|
350
361
|
}
|
|
351
362
|
}
|
|
@@ -396,7 +407,7 @@ elation.require(['janusweb.janusbase'], function() {
|
|
|
396
407
|
var randomInRange = function(range) {
|
|
397
408
|
//return (Math.random() - .5) * range;
|
|
398
409
|
return Math.random() * range;
|
|
399
|
-
}
|
|
410
|
+
};
|
|
400
411
|
let pointpos = point.pos;
|
|
401
412
|
pointpos.set(randomInRange(rand_pos.x), randomInRange(rand_pos.y), randomInRange(rand_pos.z));
|
|
402
413
|
if (this.emitpoints) {
|
|
@@ -461,8 +472,7 @@ elation.require(['janusweb.janusbase'], function() {
|
|
|
461
472
|
mesh.traverse(function(n) {
|
|
462
473
|
if (n && n.geometry) {
|
|
463
474
|
var geo = n.geometry;
|
|
464
|
-
if (geo instanceof THREE.
|
|
465
|
-
} else if (geo instanceof THREE.BufferGeometry) {
|
|
475
|
+
if (geo instanceof THREE.BufferGeometry) {
|
|
466
476
|
var positions = geo.attributes.position.array;
|
|
467
477
|
for (var i = 0; i < positions.length; i += 3) {
|
|
468
478
|
vertices.push(new THREE.Vector3(positions[i] * scale.x, positions[i+1] * scale.y, positions[i+2] * scale.z));
|
|
@@ -521,8 +531,8 @@ elation.require(['janusweb.janusbase'], function() {
|
|
|
521
531
|
count: [ 'property', 'count'],
|
|
522
532
|
duration: [ 'property', 'duration'],
|
|
523
533
|
opacity: [ 'property', 'opacity'],
|
|
524
|
-
|
|
525
|
-
|
|
534
|
+
depth_write: [ 'property', 'depth_write'],
|
|
535
|
+
depth_test: [ 'property', 'depth_test'],
|
|
526
536
|
play: [ 'function', 'start'],
|
|
527
537
|
};
|
|
528
538
|
}
|