Merge branch 'master' of github.com:mozillareality/hubs-editor

This commit is contained in:
Brian Peiris 2018-07-09 17:14:21 -07:00
Родитель 1c965cd4d0 73c2f384b1
Коммит 2d6049cab0
12 изменённых файлов: 55 добавлений и 337 удалений

Просмотреть файл

@ -6,8 +6,7 @@ module.exports = {
node: true
},
globals: {
THREE: true,
Components: true
THREE: true
},
plugins: ["prettier", "react"],
rules: {

Просмотреть файл

@ -1,33 +0,0 @@
os: osx
language: node_js
node_js: '9'
cache: yarn
branches:
only: master
before_install:
- curl -o- -L https://yarnpkg.com/install.sh | bash -s -- --version 1.7.0
- export PATH="$HOME/.yarn/bin:$PATH"
install: yarn
script:
- yarn build
- npx qbrt package desktop
- cp hubs-editor.dmg hubs-editor.macos.dmg
- npx qbrt package --win desktop
- cp hubs-editor.zip hubs-editor.win.zip
- npx qbrt package --linux desktop
- cp hubs-editor.tgz hubs-editor.linux.tgz
before_deploy:
- git config --local user.name "hubs-editor bot"
- git config --local user.email "hubs-editor-bot@mozilla.com"
- git tag "$(date +'%Y-%m-%d_%H-%M-%S')_$(git log --format=%h -1)"
deploy:
provider: releases
api_key:
secure: fD8SwrudoCqMkignWFKkjnX9rPAKwy2F71MnbPOKeaTY0qcrcabtFp0DUbmypt4POawNEzhRiykwcHTEo86jjhayfb26wXgflSKIS+ZHKxmAAYBuTCQgwwWfOmNGbJYGBEJs3IBETUfr8GKxK2gzJ0F/MJuk9oL+zOckcPSLTAc00biGRcE9WZ9NEeBjckofrUenUHDpjQUnG1jiRfYAkMVUXJKFsGH3shBkAEJ4+2cGpkj32DtRZ96FrkPxHQghZGUDiIysKVllggS2PEiMgYcgcGj00hduUbZ4eXLvDQDu7t7kJuNsCvq+O183eBuYkmTJMwUgpuo7EoBoMMK0Z33pM7GcstT1ceZVn6nSM2qEDYgzKvJya8wLYOprYruzF7fUBPwkMynCDPNJg7USXibZ/90nxrVOoaor1Mgxb1zHwbKx/7HdhBabrNVdQaxxcig/4B6+K9jGLcO9GhIibacobWYXJKdtJDjvB3r8W2sOX+tELwXhvumHf7PcycQbmDVT46UIOMjWk1a+Jyxm3gX+2KWq0KdhKS8NjEP1l0Ws8LWC2qJHtW5fQ69rhNnSRyUQT8XLd51DlJ0dCy7+fiih4stKkF3jgs8cqqceijh+jqGnZkkEhukvSX/+h2hwBc6y55FZv+VoioR8Laoh8++zXtqqA5zmc912cmcrQbs=
file:
- "hubs-editor.macos.dmg"
- "hubs-editor.win.zip"
- "hubs-editor.linux.tgz"
skip_cleanup: true
on:
repo: MozillaReality/hubs-editor

Просмотреть файл

Просмотреть файл

@ -1,16 +0,0 @@
const { Runtime } = Components.utils.import("resource://qbrt/modules/Runtime.jsm", {});
const { Services } = Components.utils.import("resource://gre/modules/Services.jsm", {});
const WINDOW_URL = "chrome://app/content/index.xul";
const WINDOW_FEATURES = ["chrome", "centerscreen", "dialog=no", "all", "width=1280", "height=768", "resizable"].join(
","
);
if (Services.appinfo.OS === "Darwin") {
Components.classes["@mozilla.org/widget/macdocksupport;1"]
.getService(Components.interfaces.nsIMacDockSupport)
.activateApplication(true);
}
Services.ww.openWindow(null, WINDOW_URL, "Hubs Editor", WINDOW_FEATURES, null);

19
desktop/app/package-lock.json сгенерированный
Просмотреть файл

@ -1,19 +0,0 @@
{
"requires": true,
"lockfileVersion": 1,
"dependencies": {
"node": {
"version": "10.4.1",
"resolved": "https://registry.npmjs.org/node/-/node-10.4.1.tgz",
"integrity": "sha512-mr65ue1CjMUGr8jmpQSC1bpzs8FU0abFUByBYTMovTIrrBXjH7uISt67/cxqIXl5A7U1lEb0jmQiwRc3LKwa5g==",
"requires": {
"node-bin-setup": "^1.0.0"
}
},
"node-bin-setup": {
"version": "1.0.6",
"resolved": "https://registry.npmjs.org/node-bin-setup/-/node-bin-setup-1.0.6.tgz",
"integrity": "sha512-uPIxXNis1CRbv1DwqAxkgBk5NFV3s7cMN/Gf556jSw6jBvV7ca4F9lRL/8cALcZecRibeqU+5dFYqFFmzv5a0Q=="
}
}
}

Просмотреть файл

@ -1,10 +0,0 @@
{
"name": "hubs-editor-desktop",
"version": "0.1.0",
"license": "MPL-2.0",
"private": true,
"dependencies": {
"node": "^10.4.1",
"hubs-editor-cli": "0.1.0"
}
}

Просмотреть файл

@ -17,23 +17,36 @@ class PropertiesPanelContainer extends Component {
node: null,
components: []
};
this.props.editor.signals.objectSelected.add(node =>
this.setState({
node,
components: (node && node.userData._components) || []
})
);
this.props.editor.signals.objectChanged.add(object => {
if (this.state.node === object) {
this.setState({
components: object.userData._components || []
});
}
});
}
componentDidMount() {
this.props.editor.signals.objectSelected.add(this.onObjectSelected);
this.props.editor.signals.transformChanged.add(this.onNodeChanged);
this.props.editor.signals.objectChanged.add(this.onNodeChanged);
}
componentWillUnmount() {
this.props.editor.signals.objectSelected.remove(this.onObjectSelected);
this.props.editor.signals.transformChanged.remove(this.onNodeChanged);
this.props.editor.signals.objectChanged.remove(this.onNodeChanged);
}
onObjectSelected = object => {
this.setState({
node: object,
components: (object && object.userData._components) || []
});
};
onNodeChanged = object => {
if (this.state.node === object) {
this.setState({
node: object,
components: object.userData._components || []
});
}
};
render() {
const { node } = this.state;

Просмотреть файл

@ -29,7 +29,7 @@ class ViewportPanelContainer extends Component {
}
componentDidMount() {
this.props.editor.createRenderer(this.canvasRef.current);
this.props.editor.createViewport(this.canvasRef.current);
}
onDropFile = file => {

Просмотреть файл

@ -2,7 +2,6 @@ import signals from "signals";
import THREE from "../vendor/three";
import History from "./History";
import Storage from "./Storage";
import Viewport from "./Viewport";
import RemoveObjectCommand from "./commands/RemoveObjectCommand";
import AddObjectCommand from "./commands/AddObjectCommand";
@ -25,38 +24,21 @@ export default class Editor {
const Signal = signals.Signal;
this.signals = {
// script
editScript: new Signal(),
// player
startPlayer: new Signal(),
stopPlayer: new Signal(),
// actions
showModal: new Signal(),
openScene: new Signal(),
popScene: new Signal(),
// notifications
editorCleared: new Signal(),
savingStarted: new Signal(),
savingFinished: new Signal(),
themeChanged: new Signal(),
deleteSelectedObject: new Signal(),
transformChanged: new Signal(),
transformModeChanged: new Signal(),
snapToggled: new Signal(),
spaceChanged: new Signal(),
viewportInitialized: new Signal(),
rendererChanged: new Signal(),
sceneBackgroundChanged: new Signal(),
sceneFogChanged: new Signal(),
@ -79,21 +61,15 @@ export default class Editor {
materialChanged: new Signal(),
scriptAdded: new Signal(),
scriptChanged: new Signal(),
scriptRemoved: new Signal(),
windowResize: new Signal(),
showGridChanged: new Signal(),
refreshSidebarObject3D: new Signal(),
historyChanged: new Signal(),
fileChanged: new Signal()
};
this.history = new History(this);
this.storage = new Storage();
this.camera = this.DEFAULT_CAMERA.clone();
@ -118,17 +94,17 @@ export default class Editor {
this.sceneHelpers = new THREE.Scene();
this.object = {};
this.objects = [];
this.geometries = {};
this.materials = {};
this.textures = {};
this.scripts = {};
// TODO: Support multiple viewports
this.viewports = [];
this.selected = null;
this.helpers = {};
this.viewport = null;
this.components = new Map();
for (const componentClass of Components) {
@ -142,6 +118,12 @@ export default class Editor {
this.signals.fileChanged.add(this.onFileChanged);
}
createViewport(canvas) {
const viewport = new Viewport(this, canvas);
this.viewports.push(viewport);
return viewport;
}
onWindowResize = () => {
this.signals.windowResize.dispatch();
};
@ -160,26 +142,6 @@ export default class Editor {
}
};
setTheme(value) {
document.getElementById("theme").href = value;
this.signals.themeChanged.dispatch(value);
}
createRenderer(canvas) {
this.canvas = canvas;
const renderer = new THREE.WebGLRenderer({
canvas
});
renderer.shadowMap.enabled = true;
this.viewport = new Viewport(this);
this.signals.viewportInitialized.dispatch(this.viewport);
this.signals.rendererChanged.dispatch(renderer);
}
//
popScene() {
@ -441,30 +403,6 @@ export default class Editor {
//
addScript(object, script) {
if (this.scripts[object.uuid] === undefined) {
this.scripts[object.uuid] = [];
}
this.scripts[object.uuid].push(script);
this.signals.scriptAdded.dispatch(script);
}
removeScript(object, script) {
if (this.scripts[object.uuid] === undefined) return;
const index = this.scripts[object.uuid].indexOf(script);
if (index !== -1) {
this.scripts[object.uuid].splice(index, 1);
}
this.signals.scriptRemoved.dispatch(script);
}
//
registerComponent(componentClass) {
const { componentName } = componentClass;
@ -657,7 +595,6 @@ export default class Editor {
clear() {
this.history.clear();
this.storage.clear();
this.camera.copy(this.DEFAULT_CAMERA);
this.scene.fog = null;
@ -673,68 +610,12 @@ export default class Editor {
this.geometries = {};
this.materials = {};
this.textures = {};
this.scripts = {};
this.deselect();
this.signals.editorCleared.dispatch();
}
//
fromJSON(json) {
const loader = new THREE.ObjectLoader();
// backwards
if (json.scene === undefined) {
this.setScene(loader.parse(json));
return;
}
const camera = loader.parse(json.camera);
this.camera.copy(camera);
this.camera.aspect = this.DEFAULT_CAMERA.aspect;
this.camera.updateProjectionMatrix();
this.history.fromJSON(json.history);
this.scripts = json.scripts;
this.setScene(loader.parse(json.scene));
}
toJSON() {
// scripts clean up
const scene = this.scene;
const scripts = this.scripts;
for (const key in scripts) {
const script = scripts[key];
if (script.length === 0 || scene.getObjectByProperty("uuid", key) === undefined) {
delete scripts[key];
}
}
//
return {
metadata: {},
project: {
gammaInput: this.config.getKey("project/renderer/gammaInput"),
gammaOutput: this.config.getKey("project/renderer/gammaOutput"),
shadows: this.config.getKey("project/renderer/shadows"),
vr: this.config.getKey("project/vr")
},
camera: this.camera.toJSON(),
scene: this.scene.toJSON(),
scripts: this.scripts,
history: this.history.toJSON()
};
}
objectByUuid(uuid) {
return this.scene.getObjectByProperty("uuid", uuid, true);
}

Просмотреть файл

@ -18,18 +18,6 @@ export default class History {
//Set editor-reference in Command
Command.editor = editor;
// signals
const scope = this;
this.editor.signals.startPlayer.add(function() {
scope.historyDisabled = true;
});
this.editor.signals.stopPlayer.add(function() {
scope.historyDisabled = false;
});
}
execute(cmd, optionalName) {
@ -42,15 +30,9 @@ export default class History {
cmd.updatable &&
lastCmd.object === cmd.object &&
lastCmd.type === cmd.type &&
lastCmd.script === cmd.script &&
lastCmd.attributeName === cmd.attributeName;
if (isUpdatableCmd && cmd.type === "SetScriptValueCommand") {
// When the cmd.type is "SetScriptValueCommand" the timeDifference is ignored
lastCmd.update(cmd);
cmd = lastCmd;
} else if (isUpdatableCmd && timeDifference < 500) {
if (isUpdatableCmd && timeDifference < 500) {
lastCmd.update(cmd);
cmd = lastCmd;
} else {

Просмотреть файл

@ -1,74 +0,0 @@
/**
* @author mrdoob / http://mrdoob.com/
*/
const Storage = function() {
const indexedDB = window.indexedDB || window.mozIndexedDB || window.webkitIndexedDB || window.msIndexedDB;
if (indexedDB === undefined) {
console.warn("Storage: IndexedDB not available.");
return { init: function() {}, get: function() {}, set: function() {}, clear: function() {} };
}
const name = "threejs-editor";
const version = 1;
let database;
return {
init: function(callback) {
const request = indexedDB.open(name, version);
request.onupgradeneeded = function(event) {
const db = event.target.result;
if (db.objectStoreNames.contains("states") === false) {
db.createObjectStore("states");
}
};
request.onsuccess = function(event) {
database = event.target.result;
callback();
};
request.onerror = function(event) {
console.error("IndexedDB", event);
};
},
get: function(callback) {
const transaction = database.transaction(["states"], "readwrite");
const objectStore = transaction.objectStore("states");
const request = objectStore.get(0);
request.onsuccess = function(event) {
callback(event.target.result);
};
},
set: function(data) {
const start = performance.now();
const transaction = database.transaction(["states"], "readwrite");
const objectStore = transaction.objectStore("states");
const request = objectStore.put(data, 0);
request.onsuccess = function() {
console.log(
"[" + new Date() + "]",
"Saved state to IndexedDB. " + (performance.now() - start).toFixed(2) + "ms"
);
};
},
clear: function() {
if (database === undefined) return;
const transaction = database.transaction(["states"], "readwrite");
const objectStore = transaction.objectStore("states");
const request = objectStore.clear();
request.onsuccess = function() {
console.log("[" + new Date() + "]", "Cleared IndexedDB.");
};
}
};
};
export default Storage;

Просмотреть файл

@ -8,19 +8,23 @@ import SetScaleCommand from "./commands/SetScaleCommand";
*/
export default class Viewport {
constructor(editor) {
constructor(editor, canvas) {
const signals = editor.signals;
//
const renderer = new THREE.WebGLRenderer({
canvas
});
let renderer = null;
renderer.shadowMap.enabled = true;
renderer.autoClear = false;
renderer.autoUpdateScene = false;
renderer.setPixelRatio(window.devicePixelRatio);
renderer.setSize(canvas.parentElement.offsetWidth, canvas.parentElement.offsetHeight);
const canvas = editor.canvas;
const camera = editor.camera;
const scene = editor.scene;
const sceneHelpers = editor.sceneHelpers;
const objects = [];
const objects = editor.objects;
// helpers
@ -68,7 +72,7 @@ export default class Viewport {
editor.helpers[object.id].update();
}
signals.refreshSidebarObject3D.dispatch(object);
signals.transformChanged.dispatch(object);
}
render();
@ -247,17 +251,6 @@ export default class Viewport {
this._transformControls.setSpace(space);
});
signals.rendererChanged.add(function(newRenderer) {
renderer = newRenderer;
renderer.autoClear = false;
renderer.autoUpdateScene = false;
renderer.setPixelRatio(window.devicePixelRatio);
renderer.setSize(canvas.parentElement.offsetWidth, canvas.parentElement.offsetHeight);
render();
});
signals.sceneSet.add(function() {
render();
});
@ -400,6 +393,8 @@ export default class Viewport {
grid.visible = showGrid;
render();
});
signals.viewportInitialized.dispatch(this);
}
toggleSnap = enabled => {