repo: janusweb action: commit revision: path_from: revision_from: 3412e67b67eef7de47ff881da21eb6da63833d7b: path_to: revision_to:
commit 3412e67b67eef7de47ff881da21eb6da63833d7b Author: James BaicoianuDate: Mon Aug 15 04:42:55 2016 -0700 Experimental code dump. Massive refactoring for scripting support diff --git a/scripts/config.js b/scripts/config.js
--- a/scripts/config.js
+++ b/scripts/config.js
@@ -1,18 +1,28 @@
+/*
elation.config.set('dependencies.protocol', 'https:'); // "http:" or "https:"
elation.config.set('dependencies.host', 'janusweb.metacade.com'); // Hostname this release will live on
elation.config.set('dependencies.rootdir', '/'); // Directory this release will live in
elation.config.set('dependencies.main', 'janusweb.js'); // The main script file for this release
+*/
elation.config.set('janusweb.network.host', 'wss://janusweb.lnq.to:5567'); // Default presence server
elation.config.set('engine.assets.corsproxy', 'https://janusweb.lnq.to:8089/'); // CORS proxy URL
+elation.config.set('engine.assets.workers', 2); // CORS proxy URL
-elation.config.set('janusweb.tracking.enabled', false);
-elation.config.set('janusweb.tracking.clientid', '');
+elation.config.set('janusweb.tracking.enabled', true);
+elation.config.set('janusweb.tracking.clientid', 'UA-49582649-2');
+
+elation.config.set('dependencies.protocol', 'http:'); // "http:" or "https:"
+elation.config.set('dependencies.host', 'bai.dev.supcrit.com'); // Hostname this release will live on
+elation.config.set('dependencies.rootdir', '/'); // Directory this release will live in
+elation.config.set('dependencies.main', 'scripts/utils/elation.js'); // The main script file for this release
+
+elation.config.set('demohack.vive', false);
// You probably don't want to edit past this line unless you know what you're doing
// --------------------------------------------------------------------------------
// These settings can be changed if you want to host your .js and media in non-standard locations
elation.config.set('dependencies.path', elation.config.get('dependencies.protocol') + '//' + elation.config.get('dependencies.host') + elation.config.get('dependencies.rootdir'));
-elation.config.set('janusweb.datapath', elation.config.get('dependencies.path') + 'media/');
+elation.config.set('janusweb.datapath', elation.config.get('dependencies.path') + 'media/janusweb/');
elation.config.set('engine.assets.font.path', elation.config.get('janusweb.datapath') + 'fonts/');
diff --git a/scripts/external/JanusClientConnection.js b/scripts/external/JanusClientConnection.js
--- a/scripts/external/JanusClientConnection.js
+++ b/scripts/external/JanusClientConnection.js
@@ -303,9 +303,19 @@ var JanusClientConnection = function(opts)
this._userId = opts.userId;
this._roomUrl = opts.roomUrl;
this._version = opts.version;
+ this._host = opts.host;
+ this.lastattempt = 0;
+ this.reconnectdelay = 10000;
+ this.connect();
+}
+
+EventDispatcher.prototype.apply(JanusClientConnection.prototype);
+
+JanusClientConnection.prototype.connect = function() {
+ this.lastattempt = new Date().getTime();
this.status = 0;
this.error = '';
- this._websocket = new WebSocket(opts.host, 'binary');
+ this._websocket = new WebSocket(this._host, 'binary');
this.status = 1;
this.msgQueue = [];
this._websocket.onopen = function() {
@@ -318,8 +328,13 @@ var JanusClientConnection = function(opts)
}.bind(this)
this._websocket.onmessage = this.onMessage.bind(this)
};
-
-EventDispatcher.prototype.apply(JanusClientConnection.prototype);
+JanusClientConnection.prototype.reconnect = function() {
+ var now = new Date().getTime();
+ if (this.lastattempt + this.reconnectdelay <= now) {
+ console.log('Reconnecting...');
+ this.connect();
+ }
+}
JanusClientConnection.prototype.sendLogon = function() {
var msgData = {
@@ -342,6 +357,8 @@ JanusClientConnection.prototype.send = function(msg) {
this.msgQueue.push(msg);
} else if (this._websocket.readyState == 1) {
this._websocket.send(JSON.stringify(msg) + '\r\n');
+ } else {
+ this.reconnect();
}
};
diff --git a/scripts/image.js b/scripts/image.js
--- a/scripts/image.js
+++ b/scripts/image.js
@@ -41,26 +41,26 @@ elation.require(['janusweb.janusbase'], function() {
this.postinit = function() {
elation.engine.things.janusimage.extendclass.postinit.call(this);
this.defineProperties({
- image_id: { type: 'string' },
- color: { type: 'color', default: 0xffffff },
- sbs3d: { type: 'boolean', default: false },
- ou3d: { type: 'boolean', default: false },
- reverse3d: { type: 'boolean', default: false },
- lighting: { type: 'boolean', default: true },
+ image_id: { type: 'string', set: this.updateMaterial },
+ sbs3d: { type: 'boolean', default: false, set: this.updateMaterial },
+ ou3d: { type: 'boolean', default: false, set: this.updateMaterial },
+ reverse3d: { type: 'boolean', default: false, set: this.updateMaterial },
});
}
this.createObject3D = function() {
- this.texture = elation.engine.assets.find('image', this.properties.image_id);
- if (this.texture) {
- elation.events.add(this.texture, 'asset_load', elation.bind(this, this.imageloaded));
- elation.events.add(this.texture, 'update', elation.bind(this, this.refresh));
+ var geo = this.createGeometry();
+ var mat = this.createMaterial();
+ return new THREE.Mesh(geo, mat);
+
+/*
var geo = this.createGeometry();
var mat = this.createMaterial();
return new THREE.Mesh(geo, mat);
} else {
console.log('ERROR - could not find image ' + this.properties.image_id);
}
+*/
}
this.createGeometry = function() {
var aspect = this.getAspect(),
@@ -70,16 +70,25 @@ elation.require(['janusweb.janusbase'], function() {
return box;
}
this.createMaterial = function() {
+ this.asset = elation.engine.assets.find('image', this.image_id, true);
+ if (this.asset) {
+ this.texture = this.asset.getInstance();
+ if (this.texture) {
+ elation.events.add(this.texture, 'asset_load', elation.bind(this, this.imageloaded));
+ elation.events.add(this.texture, 'update', elation.bind(this, this.refresh));
+ }
+ }
var matargs = {
- map: this.texture,
- color: this.properties.color,
+ color: this.color,
transparent: true,
alphaTest: 0.2
};
- var sidemattex = this.texture.clone();
- this.sidetex = sidemattex;
- sidemattex.repeat.x = .0001;
+ if (this.texture) {
+ var sidemattex = this.texture.clone();
+ this.sidetex = sidemattex;
+ sidemattex.repeat.x = .0001;
+ }
var sidematargs = {
map: sidemattex,
color: this.properties.color,
@@ -91,17 +100,30 @@ elation.require(['janusweb.janusbase'], function() {
var sidemat = (this.properties.lighting ? new THREE.MeshPhongMaterial(sidematargs) : new THREE.MeshBasicMaterial(sidematargs));
var facemat = new THREE.MeshFaceMaterial([sidemat,sidemat,sidemat,sidemat,mat,mat]);
this.facematerial = mat;
+ this.frontmaterial = mat;
this.sidematerial = sidemat;
return facemat;
}
+ this.updateMaterial = function() {
+ var newtexture = elation.engine.assets.find('image', this.image_id);
+ if (newtexture && newtexture !== this.texture) {
+ this.texture = newtexture;
+ if (newtexture.image) {
+ this.imageloaded();
+ } else {
+ elation.events.add(this.texture, 'asset_load', elation.bind(this, this.imageloaded));
+ }
+ elation.events.add(this.texture, 'update', elation.bind(this, this.refresh));
+ }
+ }
this.getAspect = function() {
var aspect = 1;
if (this.texture && this.texture.image) {
var size = this.getSize(this.texture.image);
aspect = size.height / size.width;
}
- if (this.properties.sbs3d || (this.asset && this.asset.sbs3d)) aspect *= 2;
- if (this.properties.ou3d || (this.asset && this.asset.ou3d)) aspect /= 2;
+ if (this.sbs3d || (this.asset && this.asset.sbs3d)) aspect *= 2;
+ if (this.ou3d || (this.asset && this.asset.ou3d)) aspect /= 2;
return aspect;
}
this.getSize = function(image) {
@@ -113,6 +135,10 @@ elation.require(['janusweb.janusbase'], function() {
this.objects['3d'].geometry = geo;
}
this.imageloaded = function(ev) {
+ if (!this.frontmaterial) return;
+
+ this.frontmaterial.map = this.texture;
+ this.frontmaterial.needsUpdate = true;
this.adjustAspectRatio();
this.sidetex.image = this.texture.image;
this.sidetex.needsUpdate = true;
@@ -123,7 +149,7 @@ elation.require(['janusweb.janusbase'], function() {
texture.reverse = this.properties.reverse3d;
texture.needsUpdate = true;
this.texture = texture;
- this.facematerial.map = texture;
+ this.frontmaterial.map = texture;
/*
this.sidematerial.map = texture.clone();
this.sidematerial.map.needsUpdate = true;
@@ -133,5 +159,12 @@ elation.require(['janusweb.janusbase'], function() {
this.refresh();
}
+ this.getProxyObject = function() {
+ var proxy = elation.engine.things.janusimage.extendclass.getProxyObject.call(this);
+ proxy._proxydefs = {
+ id: [ 'property', 'image_id'],
+ };
+ return proxy;
+ }
}, elation.engine.things.janusbase);
});
diff --git a/scripts/janusbase.js b/scripts/janusbase.js
--- a/scripts/janusbase.js
+++ b/scripts/janusbase.js
@@ -5,10 +5,38 @@ elation.require(['engine.things.generic', 'utils.template'], function() {
elation.component.add('engine.things.janusbase', function() {
this.postinit = function() {
elation.engine.things.janusbase.extendclass.postinit.call(this);
+ this.frameupdates = [];
this.defineProperties({
- js_id: { type: 'string' },
- room: { type: 'object' },
+ room: { type: 'object' },
+ janus: { type: 'object' },
+ js_id: { type: 'string' },
+ color: { type: 'color', default: new THREE.Color(0xffffff), set: this.updateMaterial },
+ fwd: { type: 'vector3', default: new THREE.Vector3(0,0,1), set: this.pushFrameUpdate },
+ xdir: { type: 'vector3', default: new THREE.Vector3(1,0,0), set: this.pushFrameUpdate },
+ ydir: { type: 'vector3', default: new THREE.Vector3(0,1,0), set: this.pushFrameUpdate },
+ zdir: { type: 'vector3', default: new THREE.Vector3(0,0,1), set: this.pushFrameUpdate },
+ lighting: { type: 'boolean', default: true },
+ sync: { type: 'boolean', default: false },
+ rotate_axis: { type: 'string', default: '0 1 0' },
+ rotate_deg_per_sec: { type: 'string' },
});
+ //if (this.col) this.color = this.col;
+ this.jschildren = [];
+ elation.events.add(this.room, 'janusweb_script_frame_end', elation.bind(this, this.handleFrameUpdates));
+ }
+ this.createForces = function() {
+ elation.events.add(this.objects.dynamics, 'physics_collide', elation.bind(this, this.handleCollision));
+
+ var rotate_axis = this.properties.rotate_axis,
+ rotate_speed = this.properties.rotate_deg_per_sec;
+ if (rotate_axis && rotate_speed) {
+ var speed = (rotate_speed * Math.PI/180);
+ var axisparts = rotate_axis.split(' ');
+ var axis = new THREE.Vector3().set(axisparts[0], axisparts[1], axisparts[2]);
+ axis.multiplyScalar(speed);
+ this.objects.dynamics.setAngularVelocity(axis);
+ }
+
}
this.setProperties = function(props) {
var n = this.properties.room.parseNode(props);
@@ -22,13 +50,13 @@ elation.require(['engine.things.generic', 'utils.template'], function() {
this.properties.render.model = n.id;
rebuild = true;
}
- var curcol = this.properties.col;
+ var curcol = this.properties.col || [1,1,1];
if (n.col && (n.col[0] != curcol[0] || n.col[1] != curcol[1] || n.col[2] != curcol[2])) {
this.properties.col = n.col;
rebuild = true;
}
if (rebuild) {
- this.set('visible', true, true);
+ //this.set('visible', true, true);
}
if (n.accel) this.properties.acceleration.fromArray(n.accel.split(' ').map(parseFloat));
if (n.vel) this.objects.dynamics.setVelocity(this.properties.velocity.fromArray(n.vel.split(' ').map(parseFloat)));
@@ -53,7 +81,7 @@ elation.require(['engine.things.generic', 'utils.template'], function() {
xdir: xdir.toArray().join(' '),
ydir: ydir.toArray().join(' '),
zdir: zdir.toArray().join(' '),
- col: this.properties.col,
+ col: this.properties.color,
lighting: this.properties.lighting,
visible: this.properties.visible,
};
@@ -62,18 +90,161 @@ elation.require(['engine.things.generic', 'utils.template'], function() {
return xml;
}
this.getProxyObject = function() {
- return new elation.proxy(this, {
- id: ['property', 'properties.id'],
- js_id: ['property', 'properties.js_id'],
- pos: ['property', 'properties.position'],
- vel: ['property', 'properties.velocity'],
- scale: ['property', 'properties.scale'],
- col: ['property', 'properties.col'],
- });
+ if (!this._proxyobject) {
+ this._proxyobject = new elation.proxy(this, {
+ js_id: ['property', 'properties.js_id'],
+ pos: ['property', 'position'],
+ vel: ['property', 'velocity'],
+ accel: ['property', 'acceleration'],
+ mass: ['property', 'mass'],
+ scale: ['property', 'scale'],
+ col: ['property', 'color'],
+ fwd: [ 'property', 'zdir'],
+ xdir: [ 'property', 'xdir'],
+ ydir: [ 'property', 'ydir'],
+ zdir: [ 'property', 'zdir'],
+ sync: [ 'property', 'sync'],
+ children: ['property', 'jschildren'],
+
+ oncollision: ['callback', 'collision'],
+ appendChild: ['function', 'appendChild']
+ });
+ }
+ return this._proxyobject;
}
this.start = function() {
}
this.stop = function() {
}
+ this.pushFrameUpdate = function(key, value) {
+//console.log('frame update!', key, value);
+ this.frameupdates[key] = value;
+ }
+ this.handleFrameUpdates = function() {
+ var updatenames = Object.keys(this.frameupdates);
+ if (updatenames.length > 0) {
+ var updates = this.frameupdates;
+ if ('fwd' in updates) {
+ this.properties.zdir.copy(this.fwd);
+ updates.zdir = this.properties.zdir;
+ }
+ var xdir = this.properties.xdir,
+ ydir = this.properties.ydir,
+ zdir = this.properties.zdir;
+
+ if ( ('xdir' in updates) &&
+ !('ydir' in updates) &&
+ !('zdir' in updates)) {
+ zdir.crossVectors(xdir, ydir);
+ this.updateVectors(true);
+ }
+ if (!('xdir' in updates) &&
+ !('ydir' in updates) &&
+ ('zdir' in updates)) {
+ xdir.crossVectors(ydir, zdir);
+ this.updateVectors(true);
+ }
+ if (!('xdir' in updates) &&
+ ('ydir' in updates) &&
+ ('zdir' in updates)) {
+ xdir.crossVectors(zdir, ydir);
+ this.updateVectors(true);
+ }
+ if ( ('xdir' in updates) &&
+ !('ydir' in updates) &&
+ ('zdir' in updates)) {
+ ydir.crossVectors(xdir, zdir).multiplyScalar(-1);
+ this.updateVectors(true);
+ }
+ if ( ('xdir' in updates) &&
+ ('ydir' in updates) &&
+ !('zdir' in updates)) {
+ zdir.crossVectors(xdir, ydir);
+ this.updateVectors(true);
+ }
+
+ if (!('xdir' in updates) &&
+ !('ydir' in updates) &&
+ !('zdir' in updates)) {
+ // None specified, so update the vectors from the orientation quaternion
+ this.updateVectors(false);
+ }
+ this.frameupdates = {};
+ } else {
+ this.updateVectors(false);
+ }
+ }
+ this.updateVectors = function(updateOrientation) {
+ if (updateOrientation) {
+ //var quat = this.room.getOrientation(this.properties.xdir.toArray().join(' '), this.properties.ydir.toArray().join(' '), this.properties.zdir.toArray().join(' '));
+ this.xdir.normalize();
+ this.ydir.normalize();
+ this.zdir.normalize();
+ var mat4 = new THREE.Matrix4().makeBasis(this.xdir, this.ydir, this.properties.zdir.clone().negate());
+ var quat = new THREE.Quaternion();
+ var pos = new THREE.Vector3();
+ var scale = new THREE.Vector3();
+ quat.setFromRotationMatrix(mat4);
+ //mat4.decompose(pos, this.orientation, scale);
+ //this.orientation.normalize();
+//console.log(mat4.elements);
+ this.properties.orientation.copy(quat);
+//console.log(this.xdir.toArray(), this.ydir.toArray(), this.zdir.toArray(), this.orientation.toArray());
+//console.log(this.properties.orientation, this.properties.orientation.toArray());
+ } else if (this.objects['3d']) {
+ //this.objects['3d'].matrix.extractBasis(this.properties.xdir, this.properties.ydir, this.properties.zdir);
+ }
+ }
+ this.appendChild = function(obj) {
+ var proxyobj = obj
+ if (elation.utils.isString(obj)) {
+ proxyobj = this.room.jsobjects[obj];
+ }
+ if (proxyobj) {
+ //var realobj = this.room.getObjectFromProxy(proxyobj);
+ var realobj = proxyobj._target;
+ if (realobj) {
+ this.add(realobj);
+ this.updateScriptChildren();
+ }
+ }
+ }
+ this.removeChild = function(obj) {
+ var proxyobj = obj
+ if (elation.utils.isString(obj)) {
+ proxyobj = this.room.jsobjects[obj];
+ }
+ if (proxyobj) {
+ //var realobj = this.room.getObjectFromProxy(proxyobj);
+ var realobj = proxyobj._target;
+ if (realobj) {
+ this.remove(realobj);
+ this.updateScriptChildren();
+ }
+ }
+ }
+ this.updateScriptChildren = function() {
+ this.jschildren = [];
+ var keys = Object.keys(this.children);
+ for (var i = 0; i < keys.length; i++) {
+ this.jschildren.push(this.children[keys[i]].getProxyObject());
+ }
+ }
+ this.handleCollision = function(ev) {
+ var obj1 = ev.data.bodies[0],
+ obj2 = ev.data.bodies[1];
+ //var proxy1 = obj1.getProxy(),
+ // proxy2 = obj2.getProxy();
+ var other = (obj1.object == this ? obj2.object : obj1.object);
+ if (other) {
+ if (other.getProxyObject) {
+ var proxy = other.getProxyObject();
+ //console.log('I collided', proxy, this);
+ elation.events.fire({type: 'collision', element: this, data: proxy});
+ } else {
+console.error('dunno what this is', other);
+ }
+ }
+ }
}, elation.engine.things.generic);
});
diff --git a/scripts/janusplayer.js b/scripts/janusplayer.js
--- a/scripts/janusplayer.js
+++ b/scripts/janusplayer.js
@@ -4,6 +4,9 @@ elation.require(['engine.things.player', 'janusweb.external.JanusVOIP', 'ui.butt
elation.component.add('engine.things.janusplayer', function() {
this.postinit = function() {
elation.engine.things.janusplayer.extendclass.postinit.call(this);
+ this.defineProperties({
+ cursor_visible: {type: 'boolean', default: true, set: this.toggleCursorVisibility}
+ });
this.controlstate2 = this.engine.systems.controls.addContext('janusplayer', {
'voip_active': ['keyboard_v,keyboard_shift_v', elation.bind(this, this.activateVOIP)],
'browse_back': ['gamepad_0_button_4', elation.bind(this, this.browseBack)],
@@ -13,17 +16,35 @@ elation.require(['engine.things.player', 'janusweb.external.JanusVOIP', 'ui.butt
xdir: new THREE.Vector3(1, 0, 0),
ydir: new THREE.Vector3(0, 1, 0),
zdir: new THREE.Vector3(0, 0, 1),
+ eye_pos: new THREE.Vector3(0, 1.6, 0),
view_xdir: new THREE.Vector3(1, 0, 0),
view_ydir: new THREE.Vector3(0, 1, 0),
view_zdir: new THREE.Vector3(0, 0, 1),
- hand0_xdir: new THREE.Vector3(1, 0, 0),
- hand0_ydir: new THREE.Vector3(0, 1, 0),
- hand0_zdir: new THREE.Vector3(0, 0, 1),
- hand1_xdir: new THREE.Vector3(1, 0, 0),
- hand1_ydir: new THREE.Vector3(0, 1, 0),
- hand1_zdir: new THREE.Vector3(0, 0, 1),
+ cursor_xdir: new THREE.Vector3(1, 0, 0),
+ cursor_ydir: new THREE.Vector3(0, 1, 0),
+ cursor_zdir: new THREE.Vector3(0, 0, 1),
cursor_pos: new THREE.Vector3(0, 0, 0),
+ lookat_pos: new THREE.Vector3(0, 0, 0),
+ };
+ this.hands = {
+ left: {
+ active: false,
+ position: new THREE.Vector3(0, 0, 0),
+ xdir: new THREE.Vector3(1, 0, 0),
+ ydir: new THREE.Vector3(0, 1, 0),
+ zdir: new THREE.Vector3(0, 0, 1),
+ },
+ right: {
+ active: false,
+ position: new THREE.Vector3(0, 0, 0),
+ xdir: new THREE.Vector3(1, 0, 0),
+ ydir: new THREE.Vector3(0, 1, 0),
+ zdir: new THREE.Vector3(0, 0, 1),
+ }
};
+ this.cursor_active = false;
+ this.cursor_object = '';
+ this.lookat_object = '';
this.voip = new JanusVOIPRecorder({audioScale: 1024});
this.voipqueue = [];
this.voipbutton = elation.ui.button({append: document.body, classname: 'janusweb_voip', label: 'VOIP'});
@@ -34,6 +55,27 @@ elation.require(['engine.things.player', 'janusweb.external.JanusVOIP', 'ui.butt
elation.events.add(this.voip, 'voip_data', elation.bind(this, this.handleVOIPData));
elation.events.add(this.voip, 'voip_error', elation.bind(this, this.handleVOIPError));
elation.events.add(this.engine, 'engine_frame', elation.bind(this, this.updateVectors));
+ elation.events.add(null, 'mouseover', elation.bind(this, this.updateFocusObject));
+ elation.events.add(null, 'mousemove', elation.bind(this, this.updateFocusObject));
+ elation.events.add(null, 'mouseout', elation.bind(this, this.updateFocusObject));
+ elation.events.add(this.engine.client.container, 'mousedown', elation.bind(this, this.updateMouseStatus));
+ elation.events.add(this.engine.client.container, 'mouseup', elation.bind(this, this.updateMouseStatus));
+ }
+ this.createChildren = function() {
+ elation.engine.things.janusplayer.extendclass.createChildren.call(this);
+/*
+setTimeout(elation.bind(this, function() {
+ this.cursor = this.spawn('janusobject', 'playercursor', {
+ js_id: 'player_cursor',
+ position: this.vectors.cursor_pos,
+ janusid: 'cursor_crosshair',
+ pickable: false,
+ collidable: false,
+ visible: this.cursor_visible
+ }, true);
+ this.vectors.cursor_pos = this.cursor.position;
+}), 1000);
+*/
}
this.enable = function() {
elation.engine.things.janusplayer.extendclass.enable.call(this);
@@ -77,10 +119,129 @@ elation.require(['engine.things.player', 'janusweb.external.JanusVOIP', 'ui.butt
history.go(1);
}
}
+ this.engine_frame = function(ev) {
+ elation.engine.things.janusplayer.extendclass.engine_frame.call(this, ev);
+ if (this.tracker.hasHands()) {
+ var hands = this.tracker.getHands();
+ if (hands.left) {
+ var pos = hands.left.position,
+ orient = hands.left.orientation;
+ this.hands.left.active = true;
+ this.localToWorld(this.hands.left.position.fromArray(pos));
+ }
+ if (hands.right) {
+ var pos = hands.right.position,
+ orient = hands.right.orientation;
+ this.hands.right.active = true;
+ this.localToWorld(this.hands.right.position.fromArray(pos));
+ }
+ }
+ }
this.updateVectors = function() {
var v = this.vectors;
- this.objects['3d'].matrixWorld.extractBasis(v.xdir, v.ydir, v.zdir)
- this.head.objects['3d'].matrixWorld.extractBasis(v.view_xdir, v.view_ydir, v.view_zdir)
+ if (this.objects['3d']) {
+ this.objects['3d'].matrixWorld.extractBasis(v.xdir, v.ydir, v.zdir)
+ }
+ if (this.head) {
+ this.head.objects['3d'].matrixWorld.extractBasis(v.view_xdir, v.view_ydir, v.view_zdir)
+ v.view_zdir.negate();
+ }
+ }
+ this.updateMouseStatus = function(ev) {
+ if (ev.type == 'mousedown' && ev.button === 0) {
+ this.cursor_active = true;
+ } else if (ev.type == 'mouseup' && ev.button === 0) {
+ this.cursor_active = false;
+ }
+ }
+ this.updateFocusObject = function(ev) {
+ var obj = ev.element;
+ if ((ev.type == 'mouseover' || ev.type == 'mousemove') && obj && obj.js_id) {
+ this.cursor_object = obj.js_id;
+ this.vectors.cursor_pos.copy(ev.data.point);
+ var face = ev.data.face;
+ if (face) {
+ this.vectors.cursor_zdir.copy(face.normal);
+ var worldpos = this.localToWorld(new THREE.Vector3(0,0,0));
+
+ this.vectors.cursor_xdir.subVectors(worldpos, this.vectors.cursor_pos).normalize();
+ //this.vectors.cursor_ydir.crossVectors(this.vectors.cursor_xdir, this.vectors.cursor_zdir).normalize();
+ this.vectors.cursor_ydir.set(0,1,0);
+ var dot = this.vectors.cursor_ydir.dot(face.normal);
+ if (Math.abs(dot) > 0.9) {
+ this.vectors.cursor_ydir.crossVectors(this.vectors.cursor_xdir, this.vectors.cursor_zdir).normalize();
+ this.vectors.cursor_xdir.crossVectors(this.vectors.cursor_ydir, this.vectors.cursor_zdir).normalize();
+ if (dot / Math.abs(dot) > 0) {
+ this.vectors.cursor_zdir.negate();
+ }
+ } else {
+ //this.vectors.cursor_zdir.negate();
+ this.vectors.cursor_ydir.set(0,1,0);
+ this.vectors.cursor_xdir.crossVectors(this.vectors.cursor_zdir, this.vectors.cursor_ydir).normalize().negate();
+ }
+
+ //console.log(this.vectors.cursor_xdir.toArray(), this.vectors.cursor_ydir.toArray(), this.vectors.cursor_zdir.toArray());
+ if (this.cursor) {
+ var mat = new THREE.Matrix4().makeBasis(this.vectors.cursor_xdir, this.vectors.cursor_ydir, this.vectors.cursor_zdir);
+ mat.decompose(new THREE.Vector3(), this.cursor.properties.orientation, new THREE.Vector3());
+ var invscale = ev.data.distance / 10;
+ this.cursor.scale.set(invscale,invscale,invscale);
+ }
+ }
+//console.log(ev.data);
+
+ this.lookat_object = obj.js_id;
+ this.vectors.lookat_pos.copy(ev.data.point);
+ } else {
+ this.cursor_object = '';
+ this.lookat_object = '';
+ }
+ }
+ this.toggleCursorVisibility = function() {
+ if (this.cursor) {
+ this.cursor.visible = this.cursor_visible;
+ }
+ }
+ this.getProxyObject = function() {
+ var proxy = new elation.proxy(this, {
+ pos: ['property', 'position'],
+ vel: ['property', 'velocity'],
+ accel: ['property', 'acceleration'],
+ eye_pos: ['property', 'vectors.eye_pos'],
+ head_pos: ['property', 'head.properties.position'],
+ cursor_pos: ['property', 'vectors.cursor_pos'],
+ cursor_xdir: ['property', 'vectors.cursor_xdir'],
+ cursor_ydir: ['property', 'vectors.cursor_ydir'],
+ cursor_zdir: ['property', 'vectors.cursor_zdir'],
+ view_dir: ['property', 'vectors.view_zdir'],
+ dir: ['property', 'vectors.view_zdir'],
+ up_dir: ['property', 'vectors.ydir'],
+ userid: ['property', 'properties.player_id'],
+ flying: ['property', 'flying'],
+ walking: ['property', 'walking'],
+ running: ['property', 'running'],
+ //url: ['property', 'currenturl'],
+ //hmd_enabled: ['property', 'hmd_enabled'],
+ cursor_active: ['property', 'cursor_active'],
+ cursor_object: ['property', 'cursor_object'],
+ lookat_object: ['property', 'lookat_object'],
+ lookat_pos: ['property', 'vectors.lookat_pos'],
+ //lookat_xdir: ['property', 'properties.lookat_xdir'],
+ //lookat_ydir: ['property', 'properties.lookat_ydir'],
+ //lookat_zdir: ['property', 'properties.lookat_zdir'],
+ hand0_active: ['property', 'hands.left.active'],
+ hand0_pos: ['property', 'hands.left.position'],
+ hand0_xdir: ['property', 'hands.left.xdir'],
+ hand0_ydir: ['property', 'hands.left.ydir'],
+ hand0_zdir: ['property', 'hands.left.zdir'],
+ hand1_active: ['property', 'hands.right.active'],
+ hand1_pos: ['property', 'hands.right.position'],
+ hand1_xdir: ['property', 'hands.right.xdir'],
+ hand1_ydir: ['property', 'hands.right.ydir'],
+ hand1_zdir: ['property', 'hands.right.zdir'],
+ url: ['property', 'parent.currentroom.url'],
+ });
+ return proxy;
}
}, elation.engine.things.player);
});
diff --git a/scripts/janusweb.js b/scripts/janusweb.js
--- a/scripts/janusweb.js
+++ b/scripts/janusweb.js
@@ -49,6 +49,9 @@ elation.require(['janusweb.config', 'engine.things.generic','janusweb.remoteplay
elation.engine.assets.setCORSProxy(this.properties.corsproxy);
}
elation.engine.assets.loadAssetPack(this.properties.datapath + 'assets.json');
+setTimeout(function() {
+ //elation.engine.assets.setPlaceholder('model', 'loading');
+}, 200);
this.engine.systems.controls.addContext('janus', {
'load_url': [ 'keyboard_tab', elation.bind(this, this.showLoadURL) ],
@@ -59,6 +62,7 @@ elation.require(['janusweb.config', 'engine.things.generic','janusweb.remoteplay
this.engine.systems.controls.activateContext('janus');
this.remotePlayers = {};
this.remotePlayerCount = 0;
+ this.playerCount = this.remotePlayerCount + 1;
this.lastUpdate = Date.now();
this.tmpMat = new THREE.Matrix4();
this.tmpVecX = new THREE.Vector3();
@@ -66,13 +70,9 @@ elation.require(['janusweb.config', 'engine.things.generic','janusweb.remoteplay
this.tmpVecZ = new THREE.Vector3();
this.sentUpdates = 0;
this.updateRate = 15;
- this.changes = {};
-
- if (this.engine.systems.admin) {
- elation.events.add(this.engine.systems.admin, 'admin_edit_change', elation.bind(this, this.handleRoomEditSelf));
- }
}
this.initScripting = function() {
+ window.delta_time = 1000/60;
window.janus = new elation.proxy(this, {
version: ['property', 'version', { readonly: true}],
versiononline: ['property', 'versiononline', {readonly: true}],
@@ -81,7 +81,7 @@ elation.require(['janusweb.config', 'engine.things.generic','janusweb.remoteplay
networkstatus: ['property', 'network.status', {readonly: true}],
networkerror: ['property', 'network.error', {readonly: true}],
roomserver: ['property', 'network.server'],
- playercount: ['property', 'remotePlayerCount'],
+ playercount: ['property', 'playerCount'],
bookmarkurl: ['property', 'bookmarks.items'],
bookmarkthumb: ['property', 'bookmarks.items'], // FIXME - need to filter?
playerlist: ['property', ''],
@@ -118,45 +118,52 @@ elation.require(['janusweb.config', 'engine.things.generic','janusweb.remoteplay
var player = this.engine.client.player;
player.properties.player_id = this.userId; // FIXME - player spawns without an id, so we fix it up here
- window.player = new elation.proxy(player, {
- pos: ['property', 'properties.position'],
- //eye_pos: ['property', 'eyes.properties.position'],
- head_pos: ['property', 'head.properties.position'],
- cursor_pos: ['property', 'vectors.cursor_pos'],
- //cursor_xdir: ['property', 'properties.cursor_xdir'],
- //cursor_ydir: ['property', 'properties.cursor_ydir'],
- //cursor_zdir: ['property', 'properties.cursor_zdir'],
- view_dir: ['property', 'vectors.view_zdir'],
- dir: ['property', 'vectors.zdir'],
- userid: ['property', 'properties.player_id'],
- //url: ['property', 'currenturl'],
- //hmd_enabled: ['property', 'hmd_enabled'],
- //cursor_active: ['property', 'cursor_active'],
- //cursor_object: ['property', 'cursor_object'],
- //lookat_object: ['property', 'lookat_object'],
- //lookat_pos: ['property', 'properties.lookat_position'],
- //lookat_xdir: ['property', 'properties.lookat_xdir'],
- //lookat_ydir: ['property', 'properties.lookat_ydir'],
- //lookat_zdir: ['property', 'properties.lookat_zdir'],
- hand0_xdir: ['property', 'vectors.hand0_xdir'],
- hand0_ydir: ['property', 'vectors.hand0_ydir'],
- hand0_zdir: ['property', 'vectors.hand0_zdir'],
- hand1_xdir: ['property', 'vectors.hand1_xdir'],
- hand1_ydir: ['property', 'vectors.hand1_ydir'],
- hand1_zdir: ['property', 'vectors.hand1_zdir'],
- });
+ window.player = player.getProxyObject();
+
window.Vector = function(x, y, z) {
+ if (y === undefined) y = x;
+ if (z === undefined) z = y;
return new THREE.Vector3(x, y, z);
}
+ window.translate = function(v1, v2) {
+ return new THREE.Vector3().addVectors(v1, v2);
+ }
window.distance = function(v1, v2) {
return v1.distanceTo(v2);
}
+ window.scalarMultiply = function(v, s) {
+ var ret = new THREE.Vector3().copy(v);
+ if (s instanceof THREE.Vector3) {
+ ret.x *= s.x;
+ ret.y *= s.y;
+ ret.z *= s.z;
+ } else {
+ ret.multiplyScalar(s);
+ }
+ return ret;
+ }
+ window.cross = function(v1, v2) {
+ return new THREE.Vector3().crossVectors(v1, v2);
+ }
+ window.normalized = function(v) {
+ return new THREE.Vector3().copy(v).normalize();
+ }
+ window.equals = function(v1, v2) {
+ return v1.equals(v2);
+ }
window.print = function() {
console.log.apply(console, arguments);
}
window.debug = function() {
console.log.apply(console, arguments);
}
+ window.removeKey = function(dict, key) {
+ delete dict[key];
+ }
+ var uniqueId = 1;
+ window.uniqueId = function() {
+ return uniqueId++;
+ }
}
this.createChildren = function() {
var hashargs = elation.url();
@@ -260,27 +267,37 @@ elation.require(['janusweb.config', 'engine.things.generic','janusweb.remoteplay
}
this.currentroom.enable();
+ this.scriptframeargs = [
+ 1000/60
+ ];
window.room = new elation.proxy(this.currentroom, {
- url: ['property', 'properties.url', { readonly: true}],
+ url: ['property', 'url', { readonly: true}],
objects: ['property', 'jsobjects'],
cookies: ['property', 'cookies'],
- walk_speed: ['property', 'properties.walk_speed'],
- run_speed: ['property', 'properties.run_speed'],
- jump_velocity: ['property', 'properties.jump_velocity'],
- gravity: ['property', 'properties.gravity'],
-
+ walk_speed: ['property', 'walk_speed'],
+ run_speed: ['property', 'run_speed'],
+ jump_velocity: ['property', 'jump_velocity'],
+ gravity: ['property', 'gravity'],
+ fog: ['property', 'fog'],
+ fog_mode: ['property', 'fog_mode'],
+ fog_density: ['property', 'fog_density'],
+ fog_start: ['property', 'fog_start'],
+ fog_end: ['property', 'fog_end'],
+ fog_col: ['property', 'fog_col'],
+
createObject: ['function', 'createObject'],
- removeObject: ['function', 'remove'],
+ removeObject: ['function', 'removeObject'],
addCookie: ['function', 'addCookie'],
playSound: ['function', 'playSound'],
+ stopSound: ['function', 'stopSound'],
getObjectById: ['function', 'getObjectById'],
onLoad: ['callback', 'janus_room_scriptload'],
- update: ['callback', 'engine_frame', 'engine'],
- onCollision: ['callback', 'physics_collide'],
+ update: ['callback', 'janusweb_script_frame', null, this.scriptframeargs],
+ onCollision: ['callback', 'physics_collide', 'objects.dynamics'],
onClick: ['callback', 'click', 'engine.client.container'],
- onMouseDown: ['callback', 'mousedown', 'engine.client.container'],
- onMouseUp: ['callback', 'mouseup', 'engine.client.container'],
+ onMouseDown: ['callback', 'janus_room_mousedown'],
+ onMouseUp: ['callback', 'janus_room_mouseup'],
onKeyDown: ['callback', 'janus_room_keydown'],
onKeyUp: ['callback', 'janus_room_keyup']
});
@@ -355,6 +372,7 @@ elation.require(['janusweb.config', 'engine.things.generic','janusweb.remoteplay
}
delete this.remotePlayers[msg.data.data.userId];
this.remotePlayerCount = Object.keys(this.remotePlayers).length;
+ this.playerCount = this.remotePlayerCount + 1;
} else if (method == 'user_portal') {
var data = msg.data.data;
var portalname = 'portal_' + data.userId + '_' + md5(data.url);
@@ -403,7 +421,7 @@ elation.require(['janusweb.config', 'engine.things.generic','janusweb.remoteplay
this.spawnRemotePlayer = function(data) {
var userId = data.position._userId;
var spawnpos = (data.position.pos ? data.position.pos.split(" ").map(parseFloat) : [0,0,0]);
- this.remotePlayers[userId] = this.currentroom.spawn('remoteplayer', userId, { position: spawnpos, player_id: userId, player_name: userId});
+ this.remotePlayers[userId] = this.currentroom.spawn('remoteplayer', userId, { position: spawnpos, player_id: userId, player_name: userId, pickable: false, collidable: false});
var remote = this.remotePlayers[userId];
remote.janusDirs = {
tmpVec1: new THREE.Vector3(),
@@ -412,6 +430,7 @@ elation.require(['janusweb.config', 'engine.things.generic','janusweb.remoteplay
tmpMat4: new THREE.Matrix4()
}
this.remotePlayerCount = Object.keys(this.remotePlayers).length;
+ this.playerCount = this.remotePlayerCount + 1;
return remote;
}
this.moveRemotePlayer = function(data) {
@@ -487,13 +506,52 @@ elation.require(['janusweb.config', 'engine.things.generic','janusweb.remoteplay
moveData.audio = window.btoa(binary);
moveData.anim_id = "speak";
}
- var changeids = Object.keys(this.changes);
+ var changeids = Object.keys(this.currentroom.changes);
var changestr = '';
- changeids.forEach(elation.bind(this, function(id) {
- changestr += this.changes[id];
- delete this.changes[id];
- }));
+ if (changeids.length > 0) {
+ var xmldoc = document.implementation.createDocument(null, 'edit', null);
+ var editroot = xmldoc.documentElement;
+
+ var typemap = {
+ janustext: 'Text',
+ janusobject: 'Object',
+ };
+
+ changeids.forEach(elation.bind(this, function(id) {
+ //changestr += this.currentroom.changes[id];
+ var change = this.currentroom.changes[id];
+ var real = this.currentroom.getObjectFromProxy(change);
+ if (real) {
+ var xmltype = typemap[real.type] || 'Object';
+ xmlnode = xmldoc.createElement(xmltype); // FIXME - determine object's type
+
+ var attrs = Object.keys(change);
+ for (var i = 0; i < attrs.length; i++) {
+ var k = attrs[i];
+ var val = change[k];
+ if (val instanceof THREE.Vector2 ||
+ val instanceof THREE.Vector3) {
+ val = val.toArray().join(',');
+ } else if (val instanceof THREE.Color) {
+ val = val.toArray().join(',');
+ }
+ if (val !== null && val !== undefined && typeof val != 'function') {
+ xmlnode.setAttribute(k, val);
+ }
+ }
+ editroot.appendChild(xmlnode);
+ }
+ delete this.currentroom.changes[id];
+ }));
+ this.currentroom.appliedchanges = {};
+ var serializer = new XMLSerializer();
+ changestr = serializer.serializeToString(xmldoc);
+ changestr = changestr.replace(/"/g, '^');
+ changestr = changestr.replace(/^/, '');
+ changestr = changestr.replace(/<\/edit>\s*$/, '');
+ }
if (changestr != '') {
+ //console.log('SEND', changestr);
moveData.room_edit = changestr;
}
if (document.activeElement && document.activeElement === this.chat.input.inputelement) {
@@ -552,6 +610,7 @@ elation.require(['janusweb.config', 'engine.things.generic','janusweb.remoteplay
if (room) {
if (edit) {
var editxml = edit.replace(/\^/g, '"');
+//console.log('RECV', editxml);
room.applyEditXML(editxml);
}
if (del) {
@@ -560,13 +619,6 @@ elation.require(['janusweb.config', 'engine.things.generic','janusweb.remoteplay
}
}
}
- this.handleRoomEditSelf = function(ev) {
- var thing = ev.data;
- var change = thing.summarizeXML();
- if (thing.properties.js_id) {
- this.changes[thing.properties.js_id] = change;
- }
- }
this.getCurrentURL = function() {
return this.properties.url;
}
@@ -617,5 +669,15 @@ elation.require(['janusweb.config', 'engine.things.generic','janusweb.remoteplay
this.hasFocus = function() {
return true;
}
+ this.sendScriptFrame = function(ev) {
+/*
+ this.engine.systems.world.scene['world-3d'].updateMatrixWorld(true);
+ this.scriptframeargs[0] = ev.data.delta * 1000;
+ //elation.events.fire({element: this.currentroom, type: 'janusweb_script_frame'});
+ if (this.currentroom.update) {
+ this.currentroom.update(1000/60);
+ }
+*/
+ }
}, elation.engine.things.generic);
});
diff --git a/scripts/object.js b/scripts/object.js
--- a/scripts/object.js
+++ b/scripts/object.js
@@ -8,49 +8,83 @@ elation.require(['janusweb.janusbase'], function() {
this.postinit = function() {
elation.engine.things.janusobject.extendclass.postinit.call(this);
this.defineProperties({
- room: { type: 'object' },
- image_id: { type: 'string' },
- video_id: { type: 'string' },
+ janusid: { type: 'string', refreshGeometry: true },
+ image_id: { type: 'string', set: this.updateMaterial },
+ video_id: { type: 'string', set: this.updateMaterial },
loop: { type: 'boolean' },
collision_id: { type: 'string' },
- websurface_id: { type: 'string' },
- lighting: { type: 'boolean', default: true },
- col: { type: 'string' },
- cull_face: { type: 'string', default: 'back' },
- blend_src: { type: 'string', default: 'src_alpha' },
- blend_dest: { type: 'string', default: 'one_minus_src_alpha' },
- rotate_axis: { type: 'string', default: '0 1 0' },
- rotate_deg_per_sec: { type: 'string' },
- props: { type: 'object' },
+ websurface_id: { type: 'string', set: this.updateMaterial },
+ lighting: { type: 'boolean', default: true, set: this.updateMaterial },
+ cull_face: { type: 'string', default: 'back', set: this.updateMaterial },
+ blend_src: { type: 'string', default: 'src_alpha', set: this.updateMaterial },
+ blend_dest: { type: 'string', default: 'one_minus_src_alpha', set: this.updateMaterial },
});
- elation.events.add(this, 'thing_init3d', elation.bind(this, this.assignTextures));
+ //elation.events.add(this, 'thing_init3d', elation.bind(this, this.assignTextures));
}
- this.createChildren = function() {
- if (this.objects['3d'].userData.loaded) {
- //this.assignTextures();
+ this.createObject3D = function() {
+ if (this.properties.exists === false) return;
+
+ var object = null, geometry = null, material = null;
+ if (this.janusid) {
+ object = elation.engine.assets.find('model', this.janusid);
+ if (object.userData.loaded) {
+ this.assignTextures();
+ } else {
+ elation.events.add(object, 'asset_load', elation.bind(this, this.assignTextures));
+ }
} else {
- elation.events.add(this.objects['3d'], 'asset_load', elation.bind(this, this.assignTextures));
+ object = new THREE.Object3D();
}
+
+ return object;
+ }
+ this.createChildren = function() {
+ //this.properties.collidable = false;
+ //this.updateColliderFromGeometry(new THREE.BoxGeometry(1,1,1));
}
this.createForces = function() {
- var rotate_axis = this.properties.rotate_axis,
- rotate_speed = this.properties.rotate_deg_per_sec;
- if (rotate_axis && rotate_speed) {
- var speed = (rotate_speed * Math.PI/180);
- var axisparts = rotate_axis.split(' ');
- var axis = new THREE.Vector3().set(axisparts[0], axisparts[1], axisparts[2]);
- axis.multiplyScalar(speed);
- this.objects.dynamics.setAngularVelocity(axis);
- }
+ elation.engine.things.janusobject.extendclass.createForces.call(this);
- if (this.properties.collision_id) {
- var collider = elation.engine.assets.find('model', this.properties.collision_id);
- if (collider.userData.loaded) {
- this.extractColliders(collider, true);
+ if (this.collision_id) {
+ this.collidable = true;
+ if (this.collision_id == 'sphere') {
+ this.setCollider('sphere', {radius: Math.max(this.scale.x, this.scale.y, this.scale.z)});
+ } else if (this.collision_id == 'cube') {
+ var halfsize = this.properties.scale.clone().multiplyScalar(.5);
+ this.setCollider('box', {min: halfsize.clone().negate(), max: halfsize});
+ } else if (this.collision_id == 'plane') {
+ var halfsize = this.properties.scale.clone().multiplyScalar(.5);
+ this.setCollider('box', {min: halfsize.clone().negate(), max: halfsize});
+ } else if (this.collision_id == 'cylinder') {
+ this.setCollider('cylinder', {height: this.scale.y, radius: Math.max(this.scale.x, this.scale.z) / 2, offset: new THREE.Vector3(0, 0.5 * this.scale.y, 0)});
} else {
- elation.events.add(collider, 'asset_load', elation.bind(this, function(ev) { this.extractColliders(collider, true); }) );
+ var collider = elation.engine.assets.find('model', this.collision_id);
+ this.collidermesh = collider;
+ if (collider.userData.loaded) {
+ //this.extractColliders(collider, true);
+ collider.userData.thing = this;
+ this.colliders.add(collider);
+ } else {
+ elation.events.add(collider, 'asset_load', elation.bind(this, function(ev) {
+ collider.userData.thing = this;
+ this.extractColliders(collider, true);
+/*
+ //collider.bindPosition(this.position);
+ //collider.bindQuaternion(this.orientation);
+ //collider.bindScale(this.properties.scale);
+
+ collider.traverse(elation.bind(this, function(n) {
+ if (n.geometry) {
+ n.geometry.computeVertexNormals();
+ }
+ if (n.material) n.material = new THREE.MeshLambertMaterial({color: 0x999900, opacity: .2, transparent: true, emissive: 0x444400, alphaTest: .01, depthTest: false, depthWrite: false});
+ n.userData.thing = this;
+ }));
+ this.colliders.add(collider);
+*/
+ }) );
+ }
}
-
}
}
this.createObjectDOM = function() {
@@ -79,8 +113,12 @@ elation.require(['janusweb.janusbase'], function() {
}
}
}
+ this.updateMaterial = function() {
+ this.assignTextures();
+ }
this.assignTextures = function() {
- //console.log('assign textures', this.name, this);
+ //console.log('assign textures', this.name, this.objects['3d']);
+ if (!this.objects['3d']) return;
var modelasset = false,
texture = false,
color = false,
@@ -88,18 +126,23 @@ elation.require(['janusweb.janusbase'], function() {
blend_dest = false,
side = this.sidemap[this.properties.cull_face];
- if (this.properties.render.model) {
- modelasset = elation.engine.assets.find('model', this.properties.render.model, true);
+ if (this.janusid) {
+ modelasset = elation.engine.assets.find('model', this.janusid, true);
}
if (this.properties.image_id) {
- texture = elation.engine.assets.find('image', this.properties.image_id);
+ texture = elation.engine.assets.find('image', this.image_id);
+ if (!texture) {
+ var asset = { assettype:'image', name:this.image_id, src: this.image_id, baseurl: this.baseurl };
+ elation.engine.assets.loadJSON([asset], this.baseurl);
+ texture = elation.engine.assets.find('image', this.image_id);
+ }
elation.events.add(texture, 'asset_load', elation.bind(this, this.assignTextures));
elation.events.add(texture, 'update', elation.bind(this, this.refresh));
}
if (this.properties.video_id) {
var videoasset = elation.engine.assets.find('video', this.properties.video_id, true);
if (videoasset) {
- texture = videoasset.getAsset();
+ texture = videoasset.getInstance();
if (videoasset.sbs3d) {
texture.repeat.x = 0.5;
}
@@ -116,14 +159,16 @@ elation.require(['janusweb.janusbase'], function() {
this.videotexture = texture;
}
}
+ color = this.properties.color;
+/*
if (this.properties.col) {
- color = new THREE.Color();
var col = this.properties.col;
if (!col && modelasset && modelasset.col) {
col = modelasset.col;
}
- color.setRGB(col[0], col[1], col[2]);
+ //color.setRGB(col.x, col.y, col.z);
}
+*/
var srcfactors = {
'src_alpha': THREE.SrcAlphaFactor,
'zero': THREE.ZeroFactor,
@@ -141,36 +186,48 @@ elation.require(['janusweb.janusbase'], function() {
if (srcfactors[this.properties.blend_dest]) {
blend_dest = srcfactors[this.properties.blend_dest];
}
-
- var hasalpha = {};
+ var scene = this.engine.systems.world.scene['world-3d'];
+ if (!this.hasalpha) this.hasalpha = {};
+ var hasalpha = this.hasalpha;
+ var remove = [];
+ var cloneMaterial = false;
this.objects['3d'].traverse(elation.bind(this, function(n) {
if (n.material) {
var materials = [];
if (n.material instanceof THREE.MeshFaceMaterial) {
//materials = [n.material.materials[1]];
for (var i = 0; i < n.material.materials.length; i++) {
- var m = this.copyMaterial(n.material.materials[i]);
- materials.push(m);
+ if (cloneMaterial) {
+ var m = this.copyMaterial(n.material.materials[i]);
+ materials.push(m);
+ } else {
+ materials.push(n.material.materials[i]);
+ }
}
n.material.materials = materials;
} else {
+/*
var m = this.copyMaterial(n.material);
materials.push(m);
n.material = m;
+*/
+ materials.push(n.material);
}
for (var i = 0; i < materials.length; i++) {
var m = materials[i];
- if (texture) {
+ //m.envMap = scene.background;
+ if (texture && texture.image) {
m.map = texture;
}
if (m.map && m.map.image) {
+/*
if (m.map.image instanceof HTMLCanvasElement) {
// FIXME - don't think this works
- hasalpha[m.map.image.src] = this.canvasHasAlpha(m.map.image);
+ //hasalpha[m.map.image.src] = this.canvasHasAlpha(m.map.image);
if (hasalpha[m.map.image.src]) {
m.transparent = true;
- m.alphaTest = 0.1;
+ m.alphaTest = 0.01;
m.needsUpdate = true;
}
} else if (m.map.image.src && m.map.image.src.match(/\.(png|tga)$/)) {
@@ -184,53 +241,52 @@ elation.require(['janusweb.janusbase'], function() {
var ctx = canvas.getContext('2d');
ctx.drawImage(m.map.image, 0, 0);
- hasalpha[ev.target.src] = this.canvasHasAlpha(canvas);
+ //hasalpha[ev.target.src] = this.canvasHasAlpha(canvas);
m.map.image = canvas;
}
if (hasalpha[ev.target.src]) {
m.transparent = true;
- m.alphaTest = 0.1;
+ m.alphaTest = 0.01;
m.needsUpdate = true;
}
}));
}
+*/
}
- m.roughness = 0.75;
- if (color && m.color) {
- m.color.copy(color);
+ //m.roughness = 0.75;
+ if (color) {
+ m.color = color;
}
if (side) {
m.side = side;
}
if (blend_src) m.blendSrc = blend_src;
if (blend_dest) m.blendDst = blend_dest;
- //m.needsUpdate = true;
+ m.needsUpdate = true;
}
- };
+ } else if (n instanceof THREE.Light) {
+ remove.push(n);
+ }
}));
+ for (var i = 0; i < remove.length; i++) {
+ remove[i].parent.remove(remove[i]);
+ }
this.refresh();
}
this.copyMaterial = function(oldmat) {
- var m = (this.properties.lighting != false || oldmat.lightMap ? new THREE.MeshPhongMaterial() : new THREE.MeshBasicMaterial());
+ //var m = (this.properties.lighting != false || oldmat.lightMap ? new THREE.MeshPhongMaterial() : new THREE.MeshBasicMaterial());
+ var m = new THREE.MeshPhongMaterial();
+ m.anisotropy = 16;
+ m.name = oldmat.name;
m.map = oldmat.map;
m.normalMap = oldmat.normalMap;
m.lightMap = oldmat.lightMap;
m.color.copy(oldmat.color);
m.transparent = oldmat.transparent;
+ m.alphaTest = oldmat.alphaTest;
return m;
}
- this.canvasHasAlpha = function(canvas) {
- var ctx = canvas.getContext('2d');
- var pixeldata = ctx.getImageData(0, 0, canvas.width, canvas.height);
- var hasalpha = false;
- for (var i = 3; i < pixeldata.data.length; i+=4) {
- if (pixeldata.data[i] != 255) {
- return true;
- }
- }
- return false;
- }
this.pauseVideo = function() {
if (this.videotexture) {
var video = this.videotexture.image;
@@ -241,6 +297,19 @@ elation.require(['janusweb.janusbase'], function() {
}
}
}
+ this.start = function() {
+ if (this.properties.image_id) {
+ var texture = elation.engine.assets.find('image', this.properties.image_id);
+ console.log('start the image!', texture);
+ }
+ if (this.properties.video_id) {
+ var texture = elation.engine.assets.find('video', this.properties.video_id);
+ if (!texture.image.playing) {
+ texture.image.play();
+ console.log('start the video!', texture);
+ }
+ }
+ }
this.stop = function() {
if (this.properties.image_id) {
var texture = elation.engine.assets.find('image', this.properties.image_id);
@@ -248,8 +317,17 @@ elation.require(['janusweb.janusbase'], function() {
}
if (this.properties.video_id) {
var texture = elation.engine.assets.find('video', this.properties.video_id);
+ texture.image.pause();
console.log('stop the video!', texture);
}
}
+ this.getProxyObject = function() {
+ var proxy = elation.engine.things.janusobject.extendclass.getProxyObject.call(this);
+ proxy._proxydefs = {
+ id: [ 'property', 'janusid'],
+ collision_id: [ 'property', 'collision_id'],
+ };
+ return proxy;
+ }
}, elation.engine.things.janusbase);
});
diff --git a/scripts/portal.js b/scripts/portal.js
--- a/scripts/portal.js
+++ b/scripts/portal.js
@@ -1,11 +1,14 @@
-elation.require(['engine.things.portal'], function() {
+elation.require(['janusweb.janusbase'], function() {
elation.component.add('engine.things.janusportal', function() {
this.postinit = function() {
this.defineProperties({
'janus': { type: 'object' },
- 'url': { type: 'string' },
- 'title': { type: 'string' },
- 'thumbnail': { type: 'texture' }
+ //'color': { type: 'color', default: new THREE.Color(0xffffff), set: this.updateMaterial },
+ 'url': { type: 'string', set: this.updateTitle },
+ 'title': { type: 'string', set: this.updateTitle },
+ 'draw_text': { type: 'boolean', default: true, set: this.updateTitle },
+ 'draw_glow': { type: 'boolean', default: true, refreshGeometry: true},
+ 'thumb_id': { type: 'string', set: this.updateMaterial }
});
this.addTag('usable');
elation.engine.things.janusportal.extendclass.postinit.call(this);
@@ -17,75 +20,109 @@ elation.require(['engine.things.portal'], function() {
var offset = ((thickness / 2) / this.properties.scale.z) * 2;
var box = new THREE.BoxGeometry(1,1,thickness);
box.applyMatrix(new THREE.Matrix4().makeTranslation(0,0.5,offset/2));
- var matargs = { color: 0xdddddd };
- if (this.properties.thumbnail) matargs.map = this.properties.thumbnail;
- var mat = new THREE.MeshBasicMaterial(matargs);
+
+ var mat = this.createMaterial();
+
var mesh = new THREE.Mesh(box, mat);
- var framewidth = .05 / this.properties.scale.x,
- frameheight = .05 / this.properties.scale.y,
- framedepth = .01 / this.properties.scale.z;
- var framegeo = new THREE.Geometry();
- var framepart = new THREE.BoxGeometry(1,frameheight,framedepth);
- var framemat4 = new THREE.Matrix4();
+ if (this.draw_glow) {
+ var framewidth = .05 / this.properties.scale.x,
+ frameheight = .05 / this.properties.scale.y,
+ framedepth = .01 / this.properties.scale.z;
+ var framegeo = new THREE.Geometry();
+ var framepart = new THREE.BoxGeometry(1,frameheight,framedepth);
+ var framemat4 = new THREE.Matrix4();
- framemat4.makeTranslation(0,1 - frameheight/2,framedepth/2 + offset);
- framegeo.merge(framepart, framemat4);
- framemat4.makeTranslation(0,frameheight/2,framedepth/2 + offset);
- framegeo.merge(framepart, framemat4);
-
- framepart = new THREE.BoxGeometry(framewidth,1,framedepth);
+ framemat4.makeTranslation(0,1 - frameheight/2,framedepth/2 + offset);
+ framegeo.merge(framepart, framemat4);
+ framemat4.makeTranslation(0,frameheight/2,framedepth/2 + offset);
+ framegeo.merge(framepart, framemat4);
+
+ framepart = new THREE.BoxGeometry(framewidth,1,framedepth);
- framemat4.makeTranslation(.5 - framewidth/2,.5,framedepth/2 + offset);
- framegeo.merge(framepart, framemat4);
- framemat4.makeTranslation(-.5 + framewidth/2,.5,framedepth/2 + offset);
- framegeo.merge(framepart, framemat4);
+ framemat4.makeTranslation(.5 - framewidth/2,.5,framedepth/2 + offset);
+ framegeo.merge(framepart, framemat4);
+ framemat4.makeTranslation(-.5 + framewidth/2,.5,framedepth/2 + offset);
+ framegeo.merge(framepart, framemat4);
- var framemat = new THREE.MeshPhongMaterial({color: 0x0000cc, emissive: 0x222222});
- var frame = new THREE.Mesh(framegeo, framemat);
- this.frame = frame;
+ var framemat = new THREE.MeshPhongMaterial({color: 0x0000cc, emissive: 0x222222});
+ var frame = new THREE.Mesh(framegeo, framemat);
+ this.frame = frame;
+ mesh.add(frame);
+ }
this.material = mat;
- mesh.add(frame);
+
+ this.objects['3d'] = mesh;
+
+ this.updateTitle();
+
return mesh;
}
+ this.updateTitle = function() {
+ if (this.draw_text) {
+ var title = this.title || this.url;
+ if (title) {
+ if (this.flatlabel) {
+ this.flatlabel.setText(title);
+ this.flatlabel.scale = [1/this.properties.scale.x, 1/this.properties.scale.y, 1/this.properties.scale.z];
+ } else {
+ this.flatlabel = this.spawn('label2d', this.id + '_label', {
+ text: title,
+ position: [0, .75, .15],
+ persist: false,
+ color: 0x0000ee,
+ emissive: 0x222266,
+ scale: [1/this.scale.x, 1/this.scale.y, 1/this.scale.z],
+ thickness: 0.5,
+ collidable: false
+ });
+ }
+ }
+ } else if (this.flatlabel) {
+ this.flatlabel.setText('');
+ }
+ }
this.createChildren = function() {
this.updateColliderFromGeometry();
- if (this.properties.render.collada || this.properties.render.meshname) {
- this.child = this.spawn('generic', this.id + '_model', {
- 'render.collada': this.properties.render.collada,
- 'render.meshname': this.properties.render.meshname,
- 'position': this.properties.childposition,
- 'orientation': this.properties.childorientation.clone(),
- 'scale': this.properties.childscale.clone(),
- persist: false,
- });
- elation.events.add(this.child, 'mouseover,mouseout,click', this);
- }
- if (this.properties.title) {
- this.flatlabel = this.spawn('label2d', this.id + '_label', {
- text: this.properties.title,
- position: [0, .75, .15],
- persist: false,
- color: 0x0000ee,
- emissive: 0x222266,
- scale: [1/this.properties.scale.x, 1/this.properties.scale.y, 1/this.properties.scale.z],
- thickness: 0.5,
-/*
- 'bevel.enabled': true,
- 'bevel.thickness': 0.025,
- 'bevel.size': 0.025,
-*/
- collidable: false
- });
//elation.events.add(this.label, 'mouseover,mousemove,mouseout,click', this);
+ }
+ this.createMaterial = function() {
+ var matargs = { color: this.properties.color };
+ var mat;
+ if (this.thumb_id) {
+ var asset = elation.engine.assets.find('image', this.thumb_id, true);
+ if (!asset) {
+ var asset = elation.engine.assets.get({ assettype:'image', id: this.thumb_id, src: this.thumb_id, baseurl: this.room.baseurl });
+ }
+ if (asset) var thumb = asset.getInstance();
+ if (thumb) {
+ matargs.map = thumb;
+ if (asset.loaded) {
+ if (asset.hasalpha) {
+ matargs.transparent = true;
+ matargs.alphaTest = 0.1;
+ }
+ } else {
+ elation.events.add(thumb, 'asset_load', function() {
+ if (mat && asset.hasalpha) {
+ mat.transparent = true;
+ mat.alphaTest = 0.1;
+ }
+ });
+ }
+ }
}
+ mat = new THREE.MeshBasicMaterial(matargs);
+ mat.color = this.properties.color;
+ return mat;
}
- this.hover = function() {
- if (this.child) {
- this.child.objects.dynamics.setAngularVelocity(new THREE.Vector3(0,Math.PI/4,0));
- this.child.refresh();
+ this.updateMaterial = function() {
+ if (this.objects['3d'] && this.objects['3d'].material) {
+ this.material = this.objects['3d'].material = this.createMaterial();
}
+ }
+ this.hover = function() {
if (this.label) {
this.label.setEmissionColor(0x2222aa);
}
@@ -142,9 +179,11 @@ elation.require(['engine.things.portal'], function() {
this.click = function(ev) {
}
this.activate = function() {
- this.frame.material.emissive.setHex(0x662222);
+ if (this.frame) {
+ this.frame.material.emissive.setHex(0x662222);
+ setTimeout(elation.bind(this, function() { this.frame.material.emissive.setHex(0x222222); }), 250);
+ }
this.properties.janus.setActiveRoom(this.properties.url, [0,0,0]);
- setTimeout(elation.bind(this, function() { this.frame.material.emissive.setHex(0x222222); }), 250);
elation.events.fire({element: this, type: 'janusweb_portal_click'});
}
this.canUse = function(object) {
@@ -157,25 +196,19 @@ elation.require(['engine.things.portal'], function() {
}
}
this.useFocus = function(ev) {
- console.log('focus:', this.properties.gamename);
this.hover();
}
this.useBlur = function(ev) {
- console.log('blur:', this.properties.gamename);
this.unhover();
}
this.getProxyObject = function() {
- return new elation.proxy(this, {
- id: ['property', 'properties.id'],
- js_id: ['property', 'properties.js_id'],
- pos: ['property', 'properties.position'],
- vel: ['property', 'properties.velocity'],
- scale: ['property', 'properties.scale'],
- col: ['property', 'properties.col'],
- url: ['property', 'properties.url'],
- title: ['property', 'properties.title'],
- thumbnail: ['property', 'properties.thumbnail'],
- });
+ var proxy = elation.engine.things.janusobject.extendclass.getProxyObject.call(this);
+ proxy._proxydefs = {
+ url: ['property', 'url'],
+ title: ['property', 'title'],
+ thumb_id: ['property', 'thumb_id'],
+ };
+ return proxy;
}
}, elation.engine.things.janusbase);
});
diff --git a/scripts/remoteplayer.js b/scripts/remoteplayer.js
--- a/scripts/remoteplayer.js
+++ b/scripts/remoteplayer.js
@@ -3,6 +3,8 @@ elation.component.add('engine.things.remoteplayer', function() {
this.postinit = function() {
this.defineProperties({
startposition: {type: 'vector3', default: new THREE.Vector3()},
+ pickable: {type: 'boolean', default: false},
+ collidable: {type: 'boolean', default: false},
player_id: {type: 'string', default: 'UnknownPlayer'},
player_name: {type: 'string', default: 'UnknownPlayer'},
});
@@ -32,7 +34,9 @@ elation.component.add('engine.things.remoteplayer', function() {
'position': [0,0,-0.125],
collidable: false,
'tilesize': 0.075,
- 'player_id': this.properties.player_name
+ 'player_id': this.properties.player_name,
+ pickable: false,
+ collidable: false
});
this.label = this.face.spawn('label', this.properties.player_name + '_label', {
size: .1,
@@ -40,7 +44,9 @@ elation.component.add('engine.things.remoteplayer', function() {
collidable: false,
text: this.properties.player_name,
position: [0,0.35,0],
- orientation: [0,1,0,0]
+ orientation: [0,1,0,0],
+ pickable: false,
+ collidable: false
});
this.mouth = this.face.spawn('sound', this.properties.player_name + '_voice', {
//loop: true
@@ -49,7 +55,7 @@ elation.component.add('engine.things.remoteplayer', function() {
var context = this.mouth.audio.context;
this.voip = new JanusVOIPPlayer();
this.voip.start(context);
- this.audiobuffer = new THREE.AudioBuffer(this.mouth.audio.context);
+ this.audiobuffer = {readyCallbacks: []};//new THREE.AudioBuffer(this.mouth.audio.context);
this.audiobuffer.buffer = this.voip.rawbuffer;
//elation.events.add(this.voip, 'voip_player_data', elation.bind(this, this.handleVoipData));
@@ -60,7 +66,7 @@ elation.component.add('engine.things.remoteplayer', function() {
}
- this.mouth.audio.setBuffer(this.audiobuffer);
+ //this.mouth.audio.setBuffer(this.audiobuffer);
};
this.speak = function(noise) {
this.voip.speak(noise);
diff --git a/scripts/room.js b/scripts/room.js
--- a/scripts/room.js
+++ b/scripts/room.js
@@ -1,20 +1,29 @@
elation.require([
'ui.textarea', 'ui.window',
'engine.things.generic', 'engine.things.label', 'engine.things.skybox',
- 'janusweb.object', 'janusweb.portal', 'janusweb.image', 'janusweb.video', 'janusweb.text', 'janusweb.sound',
+ 'janusweb.object', 'janusweb.portal', 'janusweb.image', 'janusweb.video', 'janusweb.text', 'janusweb.sound', 'janusweb.januslight',
'janusweb.translators.bookmarks', 'janusweb.translators.reddit', 'janusweb.translators.error'
], function() {
elation.component.add('engine.things.janusroom', function() {
this.postinit = function() {
+ elation.engine.things.janusroom.extendclass.postinit.call(this);
this.defineProperties({
'janus': { type: 'object' },
'url': { type: 'string', default: false },
+/*
'skybox_left': { type: 'string', default: 'skyrender_left' },
'skybox_right': { type: 'string', default: 'skyrender_right' },
'skybox_up': { type: 'string', default: 'skyrender_up' },
'skybox_down': { type: 'string', default: 'skyrender_down' },
'skybox_front': { type: 'string', default: 'skyrender_front' },
'skybox_back': { type: 'string', default: 'skyrender_back' },
+*/
+ 'skybox_left': { type: 'string' },
+ 'skybox_right': { type: 'string' },
+ 'skybox_up': { type: 'string' },
+ 'skybox_down': { type: 'string' },
+ 'skybox_front': { type: 'string' },
+ 'skybox_back': { type: 'string' },
'fog': { type: 'boolean', default: false },
'fog_mode': { type: 'string', default: 'exp' },
'fog_density': { type: 'float', default: 1.0 },
@@ -26,6 +35,7 @@ elation.require([
'jump_velocity': { type: 'float', default: 5.0 },
'gravity': { type: 'float', default: -9.8 },
'locked': { type: 'bool', default: false },
+ 'cursor_visible': { type: 'bool', default: true },
});
this.translators = {
'^bookmarks$': elation.janusweb.translators.bookmarks({}),
@@ -34,31 +44,44 @@ elation.require([
};
this.playerstartposition = [0,0,0];
this.playerstartorientation = new THREE.Quaternion();
- this.load();
+ this.load(this.properties.url);
this.roomsrc = '';
+ this.changes = {};
+ this.appliedchanges = {};
+ if (this.engine.systems.admin) {
+ elation.events.add(this.engine.systems.admin, 'admin_edit_change', elation.bind(this, this.onRoomEdit));
+ }
//this.showDebug();
- elation.events.add(this.engine.client.container, 'keydown', elation.bind(this, this.onKeyDown));
- elation.events.add(this.engine.client.container, 'keyup', elation.bind(this, this.onKeyUp));
+ elation.events.add(window, 'keydown', elation.bind(this, this.onKeyDown));
+ elation.events.add(window, 'keyup', elation.bind(this, this.onKeyUp));
+
+ elation.events.add(this.engine.client.container, 'mousedown', elation.bind(this, this.onMouseDown));
+ elation.events.add(this.engine.client.container, 'mouseup', elation.bind(this, this.onMouseUp));
}
this.createChildren = function() {
this.spawn('light_ambient', this.id + '_ambient', {
- color: 0x333333
+ color: 0x666666
});
this.spawn('light_directional', this.id + '_sun', {
position: [-20,50,25],
- intensity: 0.2
+ intensity: 0.1
});
this.spawn('light_point', this.id + '_point', {
position: [22,19,-15],
- intensity: 0.2
+ intensity: 0.1
});
+
+ this.lastthink = 0;
+ this.thinktime = 0;
+ elation.events.add(this, 'thing_think', elation.bind(this, this.onScriptTick));
}
this.setActive = function() {
+ this.setSkybox();
this.setFog();
this.setNearFar();
this.setPlayerPosition();
this.active = true;
- elation.events.fire({type: 'room_active', data: this});
+ elation.events.fire({element: this, type: 'room_active', data: this});
}
this.setPlayerPosition = function(pos, orientation) {
if (!pos) {
@@ -73,8 +96,9 @@ elation.require([
// HACK - we actually want the angle opposite to this
this.engine.client.player.properties.orientation.multiply(new THREE.Quaternion().setFromEuler(new THREE.Euler(0,Math.PI,0)));
}
- player.properties.movespeed = this.properties.walk_speed * 100;
- player.properties.runspeed = this.properties.run_speed * 100;
+ player.properties.movespeed = this.properties.walk_speed;
+ player.properties.runspeed = this.properties.run_speed;
+ player.cursor_visible = this.cursor_visible;
}
this.setSkybox = function() {
if (!this.skybox) {
@@ -216,11 +240,17 @@ elation.require([
this.roomsrc = this.parseSource(document.documentElement.outerHTML);
var roomdata = this.parseFireBox(this.roomsrc.source);
this.createRoomObjects(roomdata);
+ this.setActive();
+ elation.events.fire({type: 'janus_room_load', element: this});
}), 0);
} else if (translator) {
setTimeout(elation.bind(this, function() {
translator.exec({url: url, janus: this.properties.janus, room: this})
- .then(elation.bind(this, this.createRoomObjects));
+ .then(elation.bind(this, function(objs) {
+ this.createRoomObjects(objs);
+ this.setActive();
+ elation.events.fire({type: 'janus_room_load', element: this});
+ }));
}), 0);
} else {
elation.net.get(fullurl, null, {
@@ -248,6 +278,8 @@ elation.require([
}
var roomdata = this.parseFireBox(source.source);
this.createRoomObjects(roomdata);
+ this.setActive();
+ elation.events.fire({type: 'janus_room_load', element: this});
} else {
var datapath = elation.config.get('janusweb.datapath', '/media/janusweb');
var transpath = datapath + 'assets/translator/web/';
@@ -314,168 +346,33 @@ elation.require([
images = roomdata.images || [],
image3ds = roomdata.image3ds || [],
texts = roomdata.texts || [],
+ paragraphs = roomdata.paragraphs || [],
+ lights = roomdata.lights || [],
videos = roomdata.videos || [];
- objects.forEach(elation.bind(this, function(n) {
- var thingname = n.id + (n.js_id ? '_' + n.js_id : '_' + Math.round(Math.random() * 1000000));
-setTimeout(elation.bind(this, function() {
- var thing = this.spawn('janusobject', thingname, {
- 'room': this,
- 'js_id': n.js_id,
- 'render.model': n.id,
- 'position': n.pos,
- 'orientation': n.orientation,
- //'scale': n.scale,
- 'image_id': n.image_id,
- 'video_id': n.video_id,
- 'loop': n.loop,
- 'collision_id': n.collision_id,
- 'websurface_id': n.websurface_id,
- 'col': n.col,
- 'cull_face': n.cull_face,
- 'blend_src': n.blend_src,
- 'blend_dest': n.blend_dest,
- 'rotate_axis': n.rotate_axis,
- 'rotate_deg_per_sec': n.rotate_deg_per_sec,
- 'props': n,
- 'visible': n.visible,
- 'lighting': n.lighting
- });
- thing.setProperties(n);
- if (n.js_id) {
- this.jsobjects[n.js_id] = thing.getProxyObject();
- }
-}), Math.random() * 500);
+ if (lights) lights.forEach(elation.bind(this, function(n) {
+ this.createObject('light', n);
+ }));
+ if (objects) objects.forEach(elation.bind(this, function(n) {
+ this.createObject('object', n);
}));
if (links) links.forEach(elation.bind(this, function(n) {
-setTimeout(elation.bind(this, function() {
- var linkurl = (n.url.match(/^https?:/) || n.url.match(/^\/\//) || this.getTranslator(n.url) ? n.url : this.baseurl + n.url);
- var portalargs = {
- 'room': this,
- 'js_id': n.js_id,
- 'janus': this.properties.janus,
- 'position': n.pos,
- 'orientation': n.orientation,
- 'scale':n.scale,
- 'url': linkurl,
- 'title': n.title,
- };
- if (n.thumb_id) {
- portalargs.thumbnail = elation.engine.assets.find('image', n.thumb_id);
- }
- var portal = this.spawn('janusportal', 'portal_' + n.url + '_' + Math.round(Math.random() * 10000), portalargs);
- if (n.js_id) {
- this.jsobjects[n.js_id] = portal.getProxyObject();
- }
-}), Math.random() * 500);
+ this.createObject('link', n);
}));
if (images) images.forEach(elation.bind(this, function(n) {
-setTimeout(elation.bind(this, function() {
- var imageargs = {
- 'room': this,
- 'janus': this.properties.janus,
- 'js_id': n.js_id,
- 'position': n.pos,
- 'orientation': n.orientation,
- 'scale': n.scale,
- 'image_id': n.id,
- 'color': n.col,
- 'lighting': n.lighting
- };
- var asset = false;
- if (assets.image) assets.image.forEach(function(img) {
- if (img.id == n.id) {
- asset = img;
- }
- });
-
- if (asset) {
- imageargs.sbs3d = asset.sbs3d;
- imageargs.ou3d = asset.ou3d;
- imageargs.reverse3d = asset.reverse3d;
- }
- var image = this.spawn('janusimage', n.id + '_' + Math.round(Math.random() * 10000), imageargs);
- if (n.js_id) {
- this.jsobjects[n.js_id] = image.getProxyObject();
- }
-}), Math.random() * 500);
+ this.createObject('image', n);
}));
if (image3ds) image3ds.forEach(elation.bind(this, function(n) {
- var imageargs = {
- 'room': this,
- 'janus': this.properties.janus,
- 'js_id': n.js_id,
- 'position': n.pos,
- 'orientation': n.orientation,
- 'scale': n.scale,
- 'image_id': n.left_id,
- 'color': n.col,
- 'lighting': n.lighting
- };
- var image = this.spawn('janusimage', n.id + '_' + Math.round(Math.random() * 10000), imageargs);
- if (n.js_id) {
- this.jsobjects[n.js_id] = image.getProxyObject();
- }
+ this.createObject('image', n);
}));
if (texts) texts.forEach(elation.bind(this, function(n) {
- var labelargs = {
- 'room': this,
- 'janus': this.properties.janus,
- 'js_id': n.js_id,
- 'position': n.pos,
- 'orientation': n.orientation,
- 'scale': n.scale,
- 'text': n._content || ' ',
- 'color': (n.col ? new THREE.Color().setRGB(n.col[0], n.col[1], n.col[2]) : new THREE.Color(0xffffff)),
- };
- var label = this.spawn('janustext', n.id + '_' + Math.round(Math.random() * 10000), labelargs);
- if (n.js_id) {
- this.jsobjects[n.js_id] = label.getProxyObject();
- }
+ this.createObject('text', n);
}));
- var soundmap = {};
- if (assets.sound) assets.sound.forEach(elation.bind(this, function(n) {
- soundmap[n.id] = n;
- var soundurl = (n.src.match(/^https?:/) || n.src[0] == '/' ? n.src : this.baseurl + n.src);
-
- var proxyurl = this.properties.janus.properties.corsproxy;
- soundurl = proxyurl + soundurl;
- var sound = this.spawn('janussound', n.id + '_' + Math.round(Math.random() * 10000), {
- 'room': this,
- 'js_id': n.js_id,
- 'position': n.pos,
- 'src': soundurl,
- 'distance': parseFloat(n.dist),
- //'volume': n.scale[0],
- 'autoplay': false,
- 'loop': n.loop,
- });
- this.sounds[n.id] = sound;
+ if (paragraphs) lights.forEach(elation.bind(this, function(n) {
+ this.createObject('paragraph', n);
}));
if (sounds) sounds.forEach(elation.bind(this, function(n) {
- var soundargs = soundmap[n.id];
- if (soundargs) {
-/*
- var sound = this.spawn('janussound', n.id + '_' + Math.round(Math.random() * 10000), {
- 'room': this,
- 'js_id': n.js_id,
- 'position': n.pos,
- 'src': soundurl,
- 'distance': parseFloat(n.dist),
- 'volume': n.scale[0],
- 'autoplay': true,
- 'loop': n.loop,
- });
-*/
- var sound = this.sounds[n.id];
- sound.properties.autoplay = true;
- if (n.js_id) {
- this.jsobjects[n.js_id] = sound.getProxyObject();
- }
- this.sounds[n.id] = sound;
- } else {
- console.log("Couldn't find sound: " + n.id);
- }
+ this.createObject('sound', n);
}));
var videoassetmap = {};
@@ -502,13 +399,16 @@ setTimeout(elation.bind(this, function() {
if (room) {
if (room.use_local_asset && room.visible !== false) {
-setTimeout(elation.bind(this, function() {
- var localasset = this.spawn('janusobject', 'local_asset_' + Math.round(Math.random() * 10000), {
- 'room': this,
- 'render.model': room.use_local_asset,
- 'col': room.col,
- });
-}), Math.random() * 500);
+//setTimeout(elation.bind(this, function() {
+ this.createObject('object', {
+ id: room.use_local_asset,
+ col: room.col,
+ fwd: room.fwd,
+ xdir: room.xdir,
+ ydir: room.ydir,
+ zdir: room.zdir
+ });
+//}), Math.random() * 500);
}
// set player position based on room info
this.playerstartposition = room.pos;
@@ -521,7 +421,7 @@ setTimeout(elation.bind(this, function() {
if (room.skybox_front_id) this.properties.skybox_front = room.skybox_front_id;
if (room.skybox_back_id) this.properties.skybox_back = room.skybox_back_id;
- this.setSkybox();
+ //this.setSkybox();
this.properties.near_dist = parseFloat(room.near_dist) || 0.01;
this.properties.far_dist = parseFloat(room.far_dist) || 1000;
@@ -534,11 +434,14 @@ setTimeout(elation.bind(this, function() {
this.properties.walk_speed = room.walk_speed || 1.8;
this.properties.run_speed = room.run_speed || 5.4;
+ this.properties.cursor_visible = room.cursor_visible;
}
if (assets.scripts) {
+ this.pendingScripts = 0;
assets.scripts.forEach(elation.bind(this, function(s) {
var script = elation.engine.assets.find('script', s.src);
+ this.pendingScripts++;
elation.events.add(script, 'asset_load', elation.bind(this, function() {
document.head.appendChild(script);
script.onload = elation.bind(this, this.doScriptOnload);
@@ -547,10 +450,8 @@ setTimeout(elation.bind(this, function() {
}
//if (!this.active) {
- this.setActive();
+ // this.setActive();
//}
-
- elation.events.fire({type: 'janus_room_load', element: this});
//this.showDebug();
}
this.getRoomData = function(xml, room) {
@@ -561,6 +462,8 @@ setTimeout(elation.bind(this, function() {
var images = this.getAsArray(elation.utils.arrayget(room, '_children.image', []));
var image3ds = this.getAsArray(elation.utils.arrayget(room, '_children.image3d', []));
var texts = this.getAsArray(elation.utils.arrayget(room, '_children.text', []));
+ var paragraphs = this.getAsArray(elation.utils.arrayget(room, '_children.paragraph', []));
+ var lights = this.getAsArray(elation.utils.arrayget(room, '_children.light', []));
var videos = this.getAsArray(elation.utils.arrayget(room, '_children.video', []));
var orphanobjects = this.getAsArray(elation.utils.arrayget(xml, 'fireboxroom._children.object'));
@@ -569,6 +472,8 @@ setTimeout(elation.bind(this, function() {
var orphanvideos = this.getAsArray(elation.utils.arrayget(xml, 'fireboxroom._children.video'));
var orphanimages = this.getAsArray(elation.utils.arrayget(xml, 'fireboxroom._children.image'));
var orphantexts = this.getAsArray(elation.utils.arrayget(xml, 'fireboxroom._children.text'));
+ var orphanparagraphs = this.getAsArray(elation.utils.arrayget(xml, 'fireboxroom._children.paragraph'));
+ var orphanlights = this.getAsArray(elation.utils.arrayget(xml, 'fireboxroom._children.light'));
if (orphanobjects && orphanobjects[0]) objects.push.apply(objects, orphanobjects);
if (links && orphanlinks[0]) links.push.apply(links, orphanlinks);
@@ -576,6 +481,8 @@ setTimeout(elation.bind(this, function() {
if (videos && orphanvideos[0]) videos.push.apply(videos, orphanvideos);
if (sounds && orphansounds[0]) sounds.push.apply(sounds, orphansounds);
if (texts && orphantexts[0]) texts.push.apply(texts, orphantexts);
+ if (paragraphs && orphanparagraphs[0]) paragraphs.push.apply(paragraphs, orphanparagraphs);
+ if (lights && orphanlights[0]) lights.push.apply(lights, orphanlights);
return {
assets: assets,
@@ -586,6 +493,8 @@ setTimeout(elation.bind(this, function() {
images: images.map(elation.bind(this, this.parseNode)),
image3ds: image3ds.map(elation.bind(this, this.parseNode)),
texts: texts.map(elation.bind(this, this.parseNode)),
+ paragraphs: paragraphs.map(elation.bind(this, this.parseNode)),
+ lights: lights.map(elation.bind(this, this.parseNode)),
videos: videos.map(elation.bind(this, this.parseNode)),
};
}
@@ -639,10 +548,11 @@ setTimeout(elation.bind(this, function() {
var websurfaceassets = this.getAsArray(elation.utils.arrayget(assetxml, "_children.assetwebsurface", []));
var assetlist = [];
var datapath = elation.config.get('janusweb.datapath', '/media/janusweb');
- imageassets.forEach(function(n) {
+ imageassets.forEach(elation.bind(this, function(n) {
var src = (n.src.match(/^file:/) ? n.src.replace(/^file:/, datapath) : n.src);
- assetlist.push({ assettype:'image', name:n.id, src: src });
- });
+ //src = (src.match(/^(https?:)?\/\//) ? src : this.baseurl + src);
+ assetlist.push({ assettype:'image', name:n.id, src: src, baseurl: this.baseurl });
+ }));
videoassets.forEach(elation.bind(this, function(n) {
var src = (n.src.match(/^file:/) ? n.src.replace(/^file:/, datapath) : n.src);
assetlist.push({
@@ -653,6 +563,16 @@ setTimeout(elation.bind(this, function() {
sbs3d: n.sbs3d == 'true',
ou3d: n.ou3d == 'true',
auto_play: n.auto_play == 'true',
+ baseurl: this.baseurl
+ });
+ }));
+ soundassets.forEach(elation.bind(this, function(n) {
+ var src = (n.src.match(/^file:/) ? n.src.replace(/^file:/, datapath) : n.src);
+ assetlist.push({
+ assettype:'sound',
+ name:n.id,
+ src: src,
+ baseurl: this.baseurl
});
}));
websurfaceassets.forEach(elation.bind(this, function(n) { this.websurfaces[n.id] = n; }));
@@ -661,7 +581,8 @@ setTimeout(elation.bind(this, function() {
assetlist.push({
assettype:'script',
name: src,
- src: src
+ src: src,
+ baseurl: this.baseurl
});
}));
elation.engine.assets.loadJSON(assetlist, this.baseurl);
@@ -695,9 +616,9 @@ setTimeout(elation.bind(this, function() {
}));
nodeinfo.pos = (n.pos ? (elation.utils.isArray(n.pos) ? n.pos : n.pos.split(' ')).map(parseFloat) : [0,0,0]);
- nodeinfo.scale = (n.scale ? (elation.utils.isArray(n.scale) ? n.scale : n.scale.split(' ')).map(parseFloat) : [1,1,1]);
+ nodeinfo.scale = (n.scale ? (elation.utils.isArray(n.scale) ? n.scale : (n.scale instanceof THREE.Vector3 ? n.scale.toArray() : n.scale.split(' '))).map(parseFloat) : [1,1,1]);
nodeinfo.orientation = this.getOrientation(n.xdir, n.ydir || n.up, n.zdir || n.fwd);
- nodeinfo.col = (n.col ? (n.col[0] == '#' ? [parseInt(n.col.substr(1,2), 16)/255, parseInt(n.col.substr(3, 2), 16)/255, parseInt(n.col.substr(5, 2), 16)/255] : (elation.utils.isArray(n.col) ? n.col : n.col.split(' '))) : null);
+ nodeinfo.col = (n.col ? (n.col[0] == '#' ? [parseInt(n.col.substr(1,2), 16)/255, parseInt(n.col.substr(3, 2), 16)/255, parseInt(n.col.substr(5, 2), 16)/255] : n.col) : null);
var minscale = 1e-6;
/*
@@ -723,6 +644,7 @@ setTimeout(elation.bind(this, function() {
return false;
}
this.enable = function() {
+ this.engine.systems.ai.add(this);
var keys = Object.keys(this.children);
for (var i = 0; i < keys.length; i++) {
var obj = this.children[keys[i]];
@@ -733,6 +655,7 @@ setTimeout(elation.bind(this, function() {
elation.events.fire({type: 'room_enable', data: this});
}
this.disable = function() {
+ this.engine.systems.ai.remove(this);
var keys = Object.keys(this.children);
for (var i = 0; i < keys.length; i++) {
var obj = this.children[keys[i]];
@@ -753,6 +676,11 @@ setTimeout(elation.bind(this, function() {
var edit = xml.edit._children;
var keys = Object.keys(edit);
var hasNew = false;
+
+ var waslocked = this.locked;
+ //this.locked = true;
+ this.applyingEdits = true;
+ var skip = ['sync'];
keys.forEach(elation.bind(this, function(k) {
var newobjs = edit[k];
if (!elation.utils.isArray(newobjs)) newobjs = [newobjs];
@@ -772,25 +700,39 @@ setTimeout(elation.bind(this, function() {
sounds: [],
texts: [],
};
+//console.log('GOT EDIT', editxml);
for (var i = 0; i < newobjs.length; i++) {
var newobj = newobjs[i],
existing = this.jsobjects[newobj.js_id];
+ this.appliedchanges[newobj.jsid] = true;
if (existing) {
- existing.setProperties(newobj);
+ //existing.setProperties(newobj);
+ var objkeys = Object.keys(newobj);
+ for (var j = 0; j < objkeys.length; j++) {
+ if (skip.indexOf(objkeys[j]) == -1) {
+ existing[objkeys[j]] = newobj[objkeys[j]];
+ }
+ }
} else {
hasNew = true;
+ newobj.sync = false;
diff[(k.toLowerCase() + 's')].push(newobj);
- if (newobj.id.match(/^https?:/)) {
+ if (newobj.id && newobj.id.match(/^https?:/)) {
diff.assets.objects.push({assettype: 'model', name: newobj.id, src: newobj.id});
}
- console.log('create new!', newobj.js_id, newobj);
+ //console.log('create new!', newobj.js_id, newobj);
}
}
if (hasNew) {
- elation.engine.assets.loadJSON(diff.assets.objects, this.baseurl);
+ //elation.engine.assets.loadJSON(diff.assets.objects, this.baseurl);
this.createRoomObjects(diff);
}
}));
+ this.applyingEdits = false;
+ setTimeout(elation.bind(this, function() {
+ //this.locked = waslocked;
+ //this.appliedchanges = {};
+ }), 0);
}
this.applyDeleteXML = function(deletexml) {
var del = elation.utils.parseXML(deletexml);
@@ -806,50 +748,191 @@ setTimeout(elation.bind(this, function() {
this.createObject = function(type, args) {
var typemap = {
'object': 'janusobject',
- 'link': 'januslink',
+ 'link': 'janusportal',
'text': 'janustext',
'image': 'janusimage',
'image3d': 'janusimage',
'video': 'janusvideo',
+ 'sound': 'janussound',
+ 'light': 'januslight',
};
var realtype = typemap[type.toLowerCase()] || type;
- var nargs = {
- 'room': this,
- 'janus': this.properties.janus,
- 'js_id': args.js_id,
- 'position': args.pos || '0 0 0',
- 'orientation': args.orientation || '0 0 0 1',
- 'scale': args.scale || '1 1 1',
- 'image_id': args.id,
- 'color': args.col,
- 'lighting': args.lighting
- };
+ //var thingname = args.id + (args.js_id ? '_' + args.js_id : '_' + Math.round(Math.random() * 1000000));
+ var thingname = args.js_id;
+ var objectargs = {
+ 'room': this,
+ 'janus': this.properties.janus,
+ 'position': args.pos,
+ 'velocity': args.vel,
+ 'pickable': true,
+ 'collidable': true
+ };
+/*
+ 'js_id': args.js_id,
+ 'scale': args.scale,
+ 'orientation': args.orientation,
+ 'visible': args.visible,
+ 'rotate_axis': args.rotate_axis,
+ 'rotate_deg_per_sec': args.rotate_deg_per_sec,
+ fwd: args.fwd,
+ xdir: args.xdir,
+ ydir: args.ydir,
+ zdir: args.zdir,
+ };
+*/
+ elation.utils.merge(args, objectargs);
+
+ switch (realtype) {
+ case 'janusobject':
+ elation.utils.merge({
+ 'janusid': args.id,
+ }, objectargs);
+ break;
+ case 'janustext':
+ elation.utils.merge({
+ 'text': args.text || args._content || ' ',
+ 'col': args.col, //(args.col ? new THREE.Color().setRGB(args.col[0], args.col[1], args.col[2]) : new THREE.Color(0xffffff)),
+ }, objectargs);
+ break;
+ case 'janusportal':
+ // If it's an absolute URL or we have a translator for this URL type, use the url unmodified. Otherwise, treat it as relative
+ var linkurl = (args.url.match(/^(https?:)?\/\//) || this.getTranslator(args.url) ? args.url : this.baseurl + args.url);
+ objectargs.url = linkurl;
+ break;
+ case 'janusimage':
+ objectargs.image_id = args.id;
+ break;
+ case 'janussound':
+ objectargs.sound_id = args.id;
+ objectargs.distance = parseFloat(args.dist);
+ //objectargs.volume = args.scale[0];
+ break;
+ }
if (elation.engine.things[realtype]) {
-console.log('spawn it', realtype, args, nargs);
- var object = this.spawn(realtype, args.js_id, nargs);
- if (args.js_id) {
- this.jsobjects[args.js_id] = object.getProxyObject();
+ //console.log('spawn it', realtype, args, objectargs);
+ if (!objectargs.js_id) {
+ objectargs.js_id = realtype + '_' + (objectargs.id ? objectargs.id + '_' : '') + window.uniqueId();
+ }
+ if (this.jsobjects[objectargs.js_id]) {
+ objectargs.js_id = objectargs.js_id + '_' + window.uniqueId();
+ }
+ var object = this.spawn(realtype, objectargs.js_id, objectargs);
+ if (objectargs.js_id) {
+ this.jsobjects[objectargs.js_id] = object.getProxyObject();
+ }
+
+ if (realtype == 'janussound') {
+ this.sounds[objectargs.js_id] = object;
}
+
+ elation.events.add(object, 'thing_change_queued', elation.bind(this, this.onThingChange));
+
+ return this.jsobjects[objectargs.js_id];
} else {
console.log('ERROR - unknown type: ', realtype);
}
}
+ this.removeObject = function(obj) {
+ var proxy = obj;
+ if (elation.utils.isString(obj)) {
+ proxy = this.jsobjects[obj];
+ }
+ if (proxy) {
+ var obj = this.getObjectFromProxy(proxy);
+ if (obj && obj.parent) {
+ obj.parent.remove(obj);
+ }
+ }
+ }
this.addCookie = function(name, value) {
this.cookies[name] = value;
}
this.doScriptOnload = function() {
- elation.events.fire({type: 'janus_room_scriptload', element: this});
+ if (--this.pendingScripts <= 0) {
+ elation.events.fire({type: 'janus_room_scriptload', element: this});
+ }
}
this.playSound = function(name) {
if (this.sounds[name]) {
this.sounds[name].play();
}
}
+ this.stopSound = function(name) {
+ if (this.sounds[name]) {
+ this.sounds[name].stop();
+ }
+ }
this.onKeyDown = function(ev) {
elation.events.fire({type: 'janus_room_keydown', element: this, extras: { keyCode: ev.key.toUpperCase() }});
}
this.onKeyUp = function(ev) {
elation.events.fire({type: 'janus_room_keyup', element: this, extras: { keyCode: ev.key.toUpperCase() }});
}
+ this.onMouseDown = function(ev) {
+ elation.events.fire({type: 'janus_room_mousedown', element: this});
+ }
+ this.onMouseUp = function(ev) {
+ elation.events.fire({type: 'janus_room_mouseup', element: this});
+ }
+ this.onThingChange = function(ev) {
+ var thing = ev.target;
+ if (!this.applyingEdits && thing.js_id && this.jsobjects[thing.js_id]) {
+ var proxy = this.jsobjects[thing.js_id];
+ if (proxy.sync) {
+ var k = Object.keys(proxy);
+ if (!this.appliedchanges[thing.js_id]) {
+ this.changes[thing.js_id] = proxy;
+ }
+ }
+ }
+ }
+ this.onRoomEdit = function(ev) {
+ var thing = ev.data;
+ if (thing && !this.applyingEdits && !this.appliedchanges[thing.js_id] && thing.js_id && this.jsobjects[thing.js_id]) {
+ this.changes[thing.js_id] = this.jsobjects[thing.js_id];
+ }
+ }
+ this.onScriptTick = function(ev) {
+ this.engine.systems.world.scene['world-3d'].updateMatrix(true);
+ this.engine.systems.world.scene['world-3d'].updateMatrixWorld(true);
+ for (var k in this.jsobjects) {
+ var realobj = this.getObjectFromProxy(this.jsobjects[k]);
+ if (realobj) {
+ realobj.updateVectors(false);
+ }
+ }
+ this.janus.scriptframeargs[0] = ev.data.delta * 1000;
+ (function(room) {
+ elation.events.fire({element: room, type: 'janusweb_script_frame'});
+ elation.events.fire({element: room, type: 'janusweb_script_frame_end'});
+ })(this);
+ }
+ this.getObjectFromProxy = function(proxy, children) {
+ return proxy._target;
+/*
+ for (var k in this.children) {
+ var realobj = this.children[k];
+
+ if (realobj.js_id == proxy.js_id) {
+ return realobj;
+ }
+ }
+*/
+ if (!children) children = this.children;
+ var obj = children[proxy.js_id];
+ if (obj) {
+ return obj;
+ }
+/*
+ var childids = Object.keys(children);
+ for (var i = 0; i < childids.length; i++) {
+ var childobj = children[childids[i]];
+ var realobj = this.getObjectFromProxy(proxy, childobj.children);
+ if (realobj) {
+ return realobj;
+ }
+ }
+*/
+ }
}, elation.engine.things.generic);
});
diff --git a/scripts/sound.js b/scripts/sound.js
--- a/scripts/sound.js
+++ b/scripts/sound.js
@@ -3,11 +3,10 @@ elation.require(['janusweb.janusbase'], function() {
this.postinit = function() {
elation.engine.things.janussound.extendclass.postinit.call(this);
this.defineProperties({
- id: { type: 'string' },
- src: { type: 'string' },
+ sound_id: { type: 'string' },
rect: { type: 'string', default: "0 0 0 0" },
loop: { type: 'boolean', default: false },
- autoplay: { type: 'boolean', default: true },
+ auto_play: { type: 'boolean', default: true },
play_once: { type: 'boolean', default: false },
dist: { type: 'float', default: 1.0 },
pitch: { type: 'float', default: 1.0 },
@@ -20,10 +19,13 @@ elation.require(['janusweb.janusbase'], function() {
}
this.createChildren = function() {
if (!this.audio) {
- this.createAudio(this.properties.src);
+ var sound = elation.engine.assets.find('sound', this.sound_id);
+ if (sound) {
+ this.createAudio(sound.getProxiedURL());
+ }
}
}
- this.createAudio = function() {
+ this.createAudio = function(src) {
if (this.audio) {
if (this.audio.isPlaying) {
this.audio.stop();
@@ -42,18 +44,18 @@ elation.require(['janusweb.janusbase'], function() {
} else {
this.audio.panner.distanceModel = 'linear';
}
- this.audio.autoplay = this.properties.autoplay;
- this.audio.setLoop(this.properties.loop);
- this.audio.setVolume(this.properties.gain);
- if (this.properties.src) {
- this.audio.load(this.properties.src);
+ this.audio.autoplay = this.auto_play;
+ this.audio.setLoop(this.loop);
+ this.audio.setVolume(this.gain);
+ if (src) {
+ this.audio.load(src);
+ } else {
}
this.objects['3d'].add(this.audio);
-console.log('MADE AUDIO', this.audio);
}
}
this.load = function(url) {
- this.properties.src = url;
+ this.src = url;
if (this.audio.isPlaying) {
this.audio.stop();
}
@@ -61,7 +63,11 @@ console.log('MADE AUDIO', this.audio);
}
this.play = function() {
if (this.audio && this.audio.source.buffer) {
- this.audio.play();
+ if (this.audio.isPlaying) {
+ this.audio.source.currentTime = 0;
+ } else {
+ this.audio.play();
+ }
}
}
this.pause = function() {
diff --git a/scripts/text.js b/scripts/text.js
--- a/scripts/text.js
+++ b/scripts/text.js
@@ -2,46 +2,171 @@ elation.require(['engine.things.label'], function() {
elation.component.add('engine.things.janustext', function() {
this.postinit = function() {
elation.engine.things.janustext.extendclass.postinit.call(this);
+ this.frameupdates = [];
+ this.textcache = [];
this.defineProperties({
- room: { type: 'object' },
- js_id: { type: 'string' },
- color: { type: 'color', default: 0xffffff },
- lighting: { type: 'boolean', default: true },
+ 'text': { type: 'string', default: '', refreshGeometry: true },
+ 'font': { type: 'string', default: 'helvetiker', refreshGeometry: true },
+ 'font_size': { type: 'float', default: 1.0, refreshGeometry: true },
+ 'align': { type: 'string', default: 'left', refreshGeometry: true },
+ 'verticalalign': { type: 'string', default: 'bottom', refreshGeometry: true },
+ 'zalign': { type: 'string', default: 'back', refreshGeometry: true },
+ 'emissive': { type: 'color', default: 0x000000 },
+ 'opacity': { type: 'float', default: 1.0 },
+ 'depthTest': { type: 'bool', default: true },
+ 'thickness': { type: 'float', refreshGeometry: true },
+ 'segments': { type: 'int', default: 6, refreshGeometry: true },
+ 'bevel.enabled': { type: 'bool', default: false, refreshGeometry: true },
+ 'bevel.thickness': { type: 'float', default: 0, refreshGeometry: true },
+ 'bevel.size': { type: 'float', default: 0, refreshGeometry: true },
});
- this.properties.size = 1;
this.properties.thickness = .11;
this.properties.align = 'center';
+ elation.events.add(this.engine, 'engine_frame', elation.bind(this, this.handleFrameUpdates));
}
this.createObject3D = function() {
- var text = this.properties.text || this.name;
- var geometry = this.createTextGeometry(text);
+ var text = this.properties.text || '';//this.name;
+ var geometry = this.textcache[text];
+ if (!geometry) {
+ geometry = this.createTextGeometry(text);
- geometry.computeBoundingBox();
+ geometry.computeBoundingBox();
- var geosize = new THREE.Vector3().subVectors(geometry.boundingBox.max, geometry.boundingBox.min);
- var geoscale = 1 / geosize.x;
- geometry.applyMatrix(new THREE.Matrix4().makeScale(geoscale, geoscale, geoscale));
+ var geosize = new THREE.Vector3().subVectors(geometry.boundingBox.max, geometry.boundingBox.min);
+ var geoscale = 1 / Math.max(1e-6, text.length * this.font_size);
+ geometry.applyMatrix(new THREE.Matrix4().makeScale(geoscale, geoscale, geoscale));
- this.material = new THREE.MeshPhongMaterial({color: this.properties.color, emissive: this.properties.emissive, shading: THREE.SmoothShading, depthTest: this.properties.depthTest});
+ if (this.properties.opacity < 1.0) {
+ this.material.opacity = this.properties.opacity;
+ this.material.transparent = true;
+ }
- if (this.properties.opacity < 1.0) {
- this.material.opacity = this.properties.opacity;
- this.material.transparent = true;
+ this.textcache[text] = geometry;
}
+ var mesh;
+ if (this.objects['3d']) {
+ mesh = this.objects['3d'];
+ mesh.geometry = geometry;
+ } else {
+ this.material = this.createTextMaterial(text);
+ mesh = new THREE.Mesh(geometry, this.material);
- var mesh = new THREE.Mesh(geometry, this.material);
+ }
return mesh;
}
+ this.createTextMaterial = function() {
+ var matargs = {
+ color: this.properties.color || new THREE.Color(0xffffff),
+ emissive: new THREE.Color(0xff0000), //this.properties.emissive,
+ shading: THREE.SmoothShading,
+ depthTest: this.properties.depthTest
+ };
+ var material = new THREE.MeshPhongMaterial(matargs);
+
+ if (this.properties.opacity < 1.0) {
+ material.opacity = this.properties.opacity;
+ material.transparent = true;
+ }
+ return material;
+ }
+ this.createTextGeometry = function(text) {
+ var font = elation.engine.assets.find('font', this.properties.font);
+ if (!font) font = elation.engine.assets.find('font', 'helvetiker');
+if (!window.GEOMCACHE) window.GEOMCACHE = {};
+if (GEOMCACHE[text]) return GEOMCACHE[text];
+
+ var geometry = new THREE.TextGeometry( text, {
+ size: this.font_size,
+ height: this.properties.thickness || this.font_size / 2,
+ curveSegments: this.segments,
+
+ font: font,
+ weight: "normal",
+ style: "normal",
+
+ bevelThickness: this.properties.bevel.thickness,
+ bevelSize: this.properties.bevel.size,
+ bevelEnabled: this.properties.bevel.enabled
+ });
+ geometry.computeBoundingBox();
+ var bbox = geometry.boundingBox;
+ var diff = new THREE.Vector3().subVectors(bbox.max, bbox.min);
+ var geomod = new THREE.Matrix4();
+ // horizontal alignment
+ if (this.properties.align == 'center') {
+ geomod.makeTranslation(-.5 * diff.x, 0, 0);
+ geometry.applyMatrix(geomod);
+ } else if (this.properties.align == 'right') {
+ geomod.makeTranslation(-1 * diff.x, 0, 0);
+ geometry.applyMatrix(geomod);
+ }
+
+ // vertical alignment
+ if (this.properties.verticalalign == 'middle') {
+ geomod.makeTranslation(0, -.5 * diff.y, 0);
+ geometry.applyMatrix(geomod);
+ } else if (this.properties.verticalalign == 'top') {
+ geomod.makeTranslation(0, -1 * diff.y, 0);
+ geometry.applyMatrix(geomod);
+ }
+
+ // z-alignment
+ if (this.properties.zalign == 'middle') {
+ geomod.makeTranslation(0, 0, -.5 * diff.z);
+ geometry.applyMatrix(geomod);
+ } else if (this.properties.zalign == 'front') {
+ geomod.makeTranslation(0, 0, -1 * diff.z);
+ geometry.applyMatrix(geomod);
+ }
+ geometry.computeBoundingBox();
+GEOMCACHE[text] = geometry;
+ return geometry;
+ }
+ this.setText = function(text) {
+ this.properties.text = text;
+ if (text.indexOf && text.indexOf('\n') != -1) {
+ this.setMultilineText(text);
+ } else {
+ this.objects['3d'].geometry = this.createTextGeometry(text);
+ }
+ if (!this.material) {
+ this.material = this.createTextMaterial(text);
+ }
+ this.objects['3d'].material = this.material;
+ this.refresh();
+ }
+ this.setMultilineText = function(text) {
+ var lines = text.split('\n');
+ var geometry = new THREE.Geometry();
+ var linematrix = new THREE.Matrix4();
+ var lineoffset = 0;
+ var lineheight = 0;
+ for (var i = 0; i < lines.length; i++) {
+ var linegeometry = this.createTextGeometry(lines[i]);
+ linematrix.makeTranslation(0, lineoffset, 0);
+ geometry.merge(linegeometry, linematrix);
+ if (!lineheight) {
+ var bboxdiff = new THREE.Vector3().subVectors(linegeometry.boundingBox.max, linegeometry.boundingBox.min);
+ lineheight = bboxdiff.y;
+ }
+ lineoffset -= lineheight * 1.2;
+ }
+ this.objects['3d'].geometry = geometry;
+ }
this.getProxyObject = function() {
- return new elation.proxy(this, {
- id: ['property', 'properties.id'],
- js_id: ['property', 'properties.js_id'],
- pos: ['property', 'properties.position'],
- vel: ['property', 'properties.velocity'],
- col: ['property', 'properties.color'],
- text: ['property', 'properties.text'],
- });
+ var proxy = elation.engine.things.janustext.extendclass.getProxyObject.call(this);
+
+ proxy._proxydefs = {
+ text: [ 'property', 'text'],
+ emissive: [ 'property', 'emissive'],
+ };
+ return proxy;
+ }
+ this.updateMaterial = function() {
+ if (this.material) {
+ this.material.color = this.color;
+ }
}
- }, elation.engine.things.label);
+ }, elation.engine.things.janusbase);
});
diff --git a/scripts/tracking.js b/scripts/tracking.js
--- a/scripts/tracking.js
+++ b/scripts/tracking.js
@@ -45,11 +45,13 @@ elation.require([], function() {
console.log('[tracking] client connected', ev);
ga('send', 'event', 'client', 'connected', ev.data);
});
+/*
elation.events.add(document, 'pointerlockchange,mozpointerlockchange', function(ev) {
var el = document.pointerLockElement || document.mozPointerLockElement
console.log('[tracking] pointer lock!', (el !== null), ev);
ga('send', 'event', 'player', 'pointerlock', (el !== null));
});
+*/
elation.events.add(null, 'janusweb_client_disconnected', function(ev) {
console.log('[tracking] client disconnected', ev);
ga('send', 'event', 'client', 'disconnected', ev.data);
@@ -133,6 +135,7 @@ var el = document.pointerLockElement || document.mozPointerLockElement
}, 1000);
// report FPS every 15 seconds
+/*
var stats = document.getElementById('fpsText');
if (stats) {
setInterval(function() {
@@ -141,6 +144,7 @@ var el = document.pointerLockElement || document.mozPointerLockElement
ga('send', 'event', 'engine', 'fps', fps);
}, 15000);
}
+*/
});
elation.events.add(window, 'error', function(msg) {
diff --git a/scripts/video.js b/scripts/video.js
--- a/scripts/video.js
+++ b/scripts/video.js
@@ -26,7 +26,7 @@ elation.require(['janusweb.janusbase'], function() {
}
this.createMaterial = function() {
if (this.asset) {
- var texture = this.texture = this.asset.getAsset();
+ var texture = this.texture = this.asset.getInstance();
if (this.asset.sbs3d) {
texture.repeat.x = 0.5;
}
@@ -63,7 +63,7 @@ elation.require(['janusweb.janusbase'], function() {
return {width: image.videoWidth, height: image.videoHeight};
}
this.click = function() {
- var texture = this.asset.getAsset();
+ var texture = this.asset.getInstance();
var video = texture.image;
if (video.currentTime > 0 && !video.paused && !video.ended) {
video.pause();
diff --git a/templates/janusweb.tpl b/templates/janusweb.tpl
--- a/templates/janusweb.tpl
+++ b/templates/janusweb.tpl
@@ -1,3 +1,10 @@
{dependency name="janusweb.client"}
-
+
{set var="page.title"}JanusWeb{/set}
+
diff --git a/tests/janusweb.test.js b/tests/janusweb.test.js
--- a/tests/janusweb.test.js
+++ b/tests/janusweb.test.js
@@ -1,3 +1,4 @@
+/*
describe("JanusWeb Init", function() {
jasmine.DEFAULT_TIMEOUT_INTERVAL = 30000;
var client, janusweb, canvas;
@@ -97,3 +98,4 @@ describe("JanusWeb Init", function() {
client.engine.stop();
});
});
+*/
diff --git a/tests/karma.conf.js b/tests/karma.conf.js
--- a/tests/karma.conf.js
+++ b/tests/karma.conf.js
@@ -15,12 +15,14 @@ module.exports = function(config) {
// list of files / patterns to load in the browser
files: [
- {pattern: 'node_modules/jasmine-core/lib/jasmine-core/jasmine-html.js', watched: false, included: true, served: true},
- {pattern: 'tests/boot.js', watched: true, included: true, served: true},
+ //{pattern: 'node_modules/jasmine-core/lib/jasmine-core/jasmine-html.js', watched: false, included: true, served: true},
+ //{pattern: 'tests/boot.js', watched: true, included: true, served: true},
{pattern: 'build/*', watched: true, included: true, served: true},
+ {pattern: 'build/media/*', watched: false, included: false, served: true},
{pattern: 'build/media/**', watched: false, included: false, served: true},
'tests/imagediff.js',
- {pattern: 'tests/*.test.js', watched: true, included: false, served: true},
+ //{pattern: 'tests/*.test.js', watched: true, included: true, served: true},
+ {pattern: 'tests/assets/*.test.js', watched: true, included: true, served: true},
],
-----END OF PAGE-----