mirror of
https://github.com/overte-org/overte.git
synced 2025-04-26 14:56:23 +02:00
entityProperties.js was throwing out: 801 Uncaught TypeError: Cannot read property 'split' of undefined This moves properties.modelURL related checks behind the property.type validation check to avoid calling the function on an undefined member if the object doesn't have that key defined. Changes Committed: modified: scripts/system/html/js/entityProperties.js
1860 lines
89 KiB
JavaScript
1860 lines
89 KiB
JavaScript
// entityProperties.js
|
|
//
|
|
// Created by Ryan Huffman on 13 Nov 2014
|
|
// Copyright 2014 High Fidelity, Inc.
|
|
//
|
|
// Distributed under the Apache License, Version 2.0.
|
|
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
|
|
|
/* global alert, augmentSpinButtons, clearTimeout, console, document, Element, EventBridge,
|
|
HifiEntityUI, JSONEditor, openEventBridge, setUpKeyboardControl, setTimeout, window, _ $ */
|
|
|
|
var PI = 3.14159265358979;
|
|
var DEGREES_TO_RADIANS = PI / 180.0;
|
|
var RADIANS_TO_DEGREES = 180.0 / PI;
|
|
var ICON_FOR_TYPE = {
|
|
Box: "V",
|
|
Sphere: "n",
|
|
Shape: "n",
|
|
ParticleEffect: "",
|
|
Model: "",
|
|
Web: "q",
|
|
Image: "",
|
|
Text: "l",
|
|
Light: "p",
|
|
Zone: "o",
|
|
PolyVox: "",
|
|
Multiple: "",
|
|
PolyLine: ""
|
|
};
|
|
|
|
var EDITOR_TIMEOUT_DURATION = 1500;
|
|
var KEY_P = 80; // Key code for letter p used for Parenting hotkey.
|
|
var colorPickers = [];
|
|
var lastEntityID = null;
|
|
|
|
function debugPrint(message) {
|
|
EventBridge.emitWebEvent(
|
|
JSON.stringify({
|
|
type: "print",
|
|
message: message
|
|
})
|
|
);
|
|
}
|
|
|
|
function enableChildren(el, selector) {
|
|
var elSelectors = el.querySelectorAll(selector);
|
|
for (var selectorIndex = 0; selectorIndex < elSelectors.length; ++selectorIndex) {
|
|
elSelectors[selectorIndex].removeAttribute('disabled');
|
|
}
|
|
}
|
|
|
|
function disableChildren(el, selector) {
|
|
var elSelectors = el.querySelectorAll(selector);
|
|
for (var selectorIndex = 0; selectorIndex < elSelectors.length; ++selectorIndex) {
|
|
elSelectors[selectorIndex].setAttribute('disabled', 'disabled');
|
|
}
|
|
}
|
|
|
|
function enableProperties() {
|
|
enableChildren(document.getElementById("properties-list"), "input, textarea, checkbox, .dropdown dl, .color-picker");
|
|
enableChildren(document, ".colpick");
|
|
var elLocked = document.getElementById("property-locked");
|
|
|
|
if (elLocked.checked === false) {
|
|
removeStaticUserData();
|
|
}
|
|
}
|
|
|
|
|
|
function disableProperties() {
|
|
disableChildren(document.getElementById("properties-list"), "input, textarea, checkbox, .dropdown dl, .color-picker");
|
|
disableChildren(document, ".colpick");
|
|
for (var i = 0; i < colorPickers.length; i++) {
|
|
colorPickers[i].colpickHide();
|
|
}
|
|
var elLocked = document.getElementById("property-locked");
|
|
|
|
if ($('#userdata-editor').css('display') === "block" && elLocked.checked === true) {
|
|
showStaticUserData();
|
|
}
|
|
|
|
}
|
|
|
|
function showElements(els, show) {
|
|
for (var i = 0; i < els.length; i++) {
|
|
els[i].style.display = (show) ? 'table' : 'none';
|
|
|
|
}
|
|
}
|
|
|
|
function updateProperty(propertyName, propertyValue) {
|
|
var properties = {};
|
|
properties[propertyName] = propertyValue;
|
|
updateProperties(properties);
|
|
}
|
|
|
|
function updateProperties(properties) {
|
|
EventBridge.emitWebEvent(JSON.stringify({
|
|
id: lastEntityID,
|
|
type: "update",
|
|
properties: properties
|
|
}));
|
|
}
|
|
|
|
function createEmitCheckedPropertyUpdateFunction(propertyName) {
|
|
return function() {
|
|
updateProperty(propertyName, this.checked);
|
|
};
|
|
}
|
|
|
|
function createEmitGroupCheckedPropertyUpdateFunction(group, propertyName) {
|
|
return function() {
|
|
var properties = {};
|
|
properties[group] = {};
|
|
properties[group][propertyName] = this.checked;
|
|
updateProperties(properties);
|
|
};
|
|
}
|
|
|
|
function createEmitNumberPropertyUpdateFunction(propertyName, decimals) {
|
|
decimals = ((decimals === undefined) ? 4 : decimals);
|
|
return function() {
|
|
var value = parseFloat(this.value).toFixed(decimals);
|
|
updateProperty(propertyName, value);
|
|
};
|
|
}
|
|
|
|
function createEmitGroupNumberPropertyUpdateFunction(group, propertyName) {
|
|
return function() {
|
|
var properties = {};
|
|
properties[group] = {};
|
|
properties[group][propertyName] = this.value;
|
|
updateProperties(properties);
|
|
};
|
|
}
|
|
|
|
function createImageURLUpdateFunction(propertyName) {
|
|
return function () {
|
|
var newTextures = JSON.stringify({ "tex.picture": this.value });
|
|
updateProperty(propertyName, newTextures);
|
|
};
|
|
}
|
|
|
|
function createEmitTextPropertyUpdateFunction(propertyName) {
|
|
return function() {
|
|
updateProperty(propertyName, this.value);
|
|
};
|
|
}
|
|
|
|
function createZoneComponentModeChangedFunction(zoneComponent, zoneComponentModeInherit,
|
|
zoneComponentModeDisabled, zoneComponentModeEnabled) {
|
|
|
|
return function() {
|
|
var zoneComponentMode;
|
|
|
|
if (zoneComponentModeInherit.checked) {
|
|
zoneComponentMode = 'inherit';
|
|
} else if (zoneComponentModeDisabled.checked) {
|
|
zoneComponentMode = 'disabled';
|
|
} else if (zoneComponentModeEnabled.checked) {
|
|
zoneComponentMode = 'enabled';
|
|
}
|
|
|
|
updateProperty(zoneComponent, zoneComponentMode);
|
|
};
|
|
}
|
|
|
|
function createEmitGroupTextPropertyUpdateFunction(group, propertyName) {
|
|
return function() {
|
|
var properties = {};
|
|
properties[group] = {};
|
|
properties[group][propertyName] = this.value;
|
|
updateProperties(properties);
|
|
};
|
|
}
|
|
|
|
function createEmitVec3PropertyUpdateFunction(property, elX, elY, elZ) {
|
|
return function() {
|
|
var properties = {};
|
|
properties[property] = {
|
|
x: elX.value,
|
|
y: elY.value,
|
|
z: elZ.value
|
|
};
|
|
updateProperties(properties);
|
|
};
|
|
}
|
|
|
|
function createEmitGroupVec3PropertyUpdateFunction(group, property, elX, elY, elZ) {
|
|
return function() {
|
|
var properties = {};
|
|
properties[group] = {};
|
|
properties[group][property] = {
|
|
x: elX.value,
|
|
y: elY.value,
|
|
z: elZ ? elZ.value : 0
|
|
};
|
|
updateProperties(properties);
|
|
};
|
|
}
|
|
|
|
function createEmitVec3PropertyUpdateFunctionWithMultiplier(property, elX, elY, elZ, multiplier) {
|
|
return function() {
|
|
var properties = {};
|
|
properties[property] = {
|
|
x: elX.value * multiplier,
|
|
y: elY.value * multiplier,
|
|
z: elZ.value * multiplier
|
|
};
|
|
updateProperties(properties);
|
|
};
|
|
}
|
|
|
|
function createEmitColorPropertyUpdateFunction(property, elRed, elGreen, elBlue) {
|
|
return function() {
|
|
emitColorPropertyUpdate(property, elRed.value, elGreen.value, elBlue.value);
|
|
};
|
|
}
|
|
|
|
function emitColorPropertyUpdate(property, red, green, blue, group) {
|
|
var properties = {};
|
|
if (group) {
|
|
properties[group] = {};
|
|
properties[group][property] = {
|
|
red: red,
|
|
green: green,
|
|
blue: blue
|
|
};
|
|
} else {
|
|
properties[property] = {
|
|
red: red,
|
|
green: green,
|
|
blue: blue
|
|
};
|
|
}
|
|
updateProperties(properties);
|
|
}
|
|
|
|
|
|
function createEmitGroupColorPropertyUpdateFunction(group, property, elRed, elGreen, elBlue) {
|
|
return function() {
|
|
var properties = {};
|
|
properties[group] = {};
|
|
properties[group][property] = {
|
|
red: elRed.value,
|
|
green: elGreen.value,
|
|
blue: elBlue.value
|
|
};
|
|
updateProperties(properties);
|
|
};
|
|
}
|
|
|
|
function updateCheckedSubProperty(propertyName, propertyValue, subPropertyElement, subPropertyString) {
|
|
if (subPropertyElement.checked) {
|
|
if (propertyValue.indexOf(subPropertyString)) {
|
|
propertyValue += subPropertyString + ',';
|
|
}
|
|
} else {
|
|
// We've unchecked, so remove
|
|
propertyValue = propertyValue.replace(subPropertyString + ",", "");
|
|
}
|
|
updateProperty(propertyName, propertyValue);
|
|
}
|
|
|
|
function setUserDataFromEditor(noUpdate) {
|
|
var json = null;
|
|
try {
|
|
json = editor.get();
|
|
} catch (e) {
|
|
alert('Invalid JSON code - look for red X in your code ', +e);
|
|
}
|
|
if (json === null) {
|
|
return;
|
|
} else {
|
|
var text = editor.getText();
|
|
if (noUpdate === true) {
|
|
EventBridge.emitWebEvent(
|
|
JSON.stringify({
|
|
id: lastEntityID,
|
|
type: "saveUserData",
|
|
properties: {
|
|
userData: text
|
|
}
|
|
})
|
|
);
|
|
return;
|
|
} else {
|
|
updateProperty('userData', text);
|
|
}
|
|
}
|
|
}
|
|
|
|
function multiDataUpdater(groupName, updateKeyPair, userDataElement, defaults) {
|
|
var properties = {};
|
|
var parsedData = {};
|
|
try {
|
|
if ($('#userdata-editor').css('height') !== "0px") {
|
|
// if there is an expanded, we want to use its json.
|
|
parsedData = getEditorJSON();
|
|
} else {
|
|
parsedData = JSON.parse(userDataElement.value);
|
|
}
|
|
} catch (e) {
|
|
// TODO: Should an alert go here?
|
|
}
|
|
|
|
if (!(groupName in parsedData)) {
|
|
parsedData[groupName] = {};
|
|
}
|
|
var keys = Object.keys(updateKeyPair);
|
|
keys.forEach(function (key) {
|
|
delete parsedData[groupName][key];
|
|
if (updateKeyPair[key] !== null && updateKeyPair[key] !== "null") {
|
|
if (updateKeyPair[key] instanceof Element) {
|
|
if (updateKeyPair[key].type === "checkbox") {
|
|
if (updateKeyPair[key].checked !== defaults[key]) {
|
|
parsedData[groupName][key] = updateKeyPair[key].checked;
|
|
}
|
|
} else {
|
|
var val = isNaN(updateKeyPair[key].value) ? updateKeyPair[key].value : parseInt(updateKeyPair[key].value);
|
|
if (val !== defaults[key]) {
|
|
parsedData[groupName][key] = val;
|
|
}
|
|
}
|
|
} else {
|
|
parsedData[groupName][key] = updateKeyPair[key];
|
|
}
|
|
}
|
|
});
|
|
if (Object.keys(parsedData[groupName]).length === 0) {
|
|
delete parsedData[groupName];
|
|
}
|
|
if (Object.keys(parsedData).length > 0) {
|
|
properties.userData = JSON.stringify(parsedData);
|
|
} else {
|
|
properties.userData = '';
|
|
}
|
|
|
|
userDataElement.value = properties.userData;
|
|
|
|
updateProperties(properties);
|
|
}
|
|
function userDataChanger(groupName, keyName, values, userDataElement, defaultValue) {
|
|
var val = {}, def = {};
|
|
val[keyName] = values;
|
|
def[keyName] = defaultValue;
|
|
multiDataUpdater(groupName, val, userDataElement, def);
|
|
}
|
|
|
|
function setTextareaScrolling(element) {
|
|
var isScrolling = element.scrollHeight > element.offsetHeight;
|
|
element.setAttribute("scrolling", isScrolling ? "true" : "false");
|
|
}
|
|
|
|
|
|
var editor = null;
|
|
var editorTimeout = null;
|
|
var lastJSONString = null;
|
|
|
|
function createJSONEditor() {
|
|
var container = document.getElementById("userdata-editor");
|
|
var options = {
|
|
search: false,
|
|
mode: 'tree',
|
|
modes: ['code', 'tree'],
|
|
name: 'userData',
|
|
onModeChange: function() {
|
|
$('.jsoneditor-poweredBy').remove();
|
|
},
|
|
onError: function(e) {
|
|
alert('JSON editor:' + e);
|
|
},
|
|
onChange: function() {
|
|
var currentJSONString = editor.getText();
|
|
|
|
if (currentJSONString === '{"":""}') {
|
|
return;
|
|
}
|
|
$('#userdata-save').attr('disabled', false);
|
|
|
|
|
|
}
|
|
};
|
|
editor = new JSONEditor(container, options);
|
|
}
|
|
|
|
function hideNewJSONEditorButton() {
|
|
$('#userdata-new-editor').hide();
|
|
|
|
}
|
|
|
|
function hideClearUserDataButton() {
|
|
$('#userdata-clear').hide();
|
|
}
|
|
|
|
function showSaveUserDataButton() {
|
|
$('#userdata-save').show();
|
|
}
|
|
|
|
function hideSaveUserDataButton() {
|
|
$('#userdata-save').hide();
|
|
|
|
}
|
|
|
|
function showNewJSONEditorButton() {
|
|
$('#userdata-new-editor').show();
|
|
|
|
}
|
|
|
|
function showClearUserDataButton() {
|
|
$('#userdata-clear').show();
|
|
|
|
}
|
|
|
|
function showUserDataTextArea() {
|
|
$('#property-user-data').show();
|
|
}
|
|
|
|
function hideUserDataTextArea() {
|
|
$('#property-user-data').hide();
|
|
}
|
|
|
|
function showStaticUserData() {
|
|
if (editor !== null) {
|
|
$('#static-userdata').show();
|
|
$('#static-userdata').css('height', $('#userdata-editor').height());
|
|
$('#static-userdata').text(editor.getText());
|
|
}
|
|
}
|
|
|
|
function removeStaticUserData() {
|
|
$('#static-userdata').hide();
|
|
}
|
|
|
|
function setEditorJSON(json) {
|
|
editor.set(json);
|
|
if (editor.hasOwnProperty('expandAll')) {
|
|
editor.expandAll();
|
|
}
|
|
|
|
}
|
|
|
|
function getEditorJSON() {
|
|
return editor.get();
|
|
}
|
|
|
|
function deleteJSONEditor() {
|
|
if (editor !== null) {
|
|
editor.destroy();
|
|
editor = null;
|
|
}
|
|
}
|
|
|
|
var savedJSONTimer = null;
|
|
|
|
function saveJSONUserData(noUpdate) {
|
|
setUserDataFromEditor(noUpdate);
|
|
$('#userdata-saved').show();
|
|
$('#userdata-save').attr('disabled', true);
|
|
if (savedJSONTimer !== null) {
|
|
clearTimeout(savedJSONTimer);
|
|
}
|
|
savedJSONTimer = setTimeout(function() {
|
|
$('#userdata-saved').hide();
|
|
|
|
}, EDITOR_TIMEOUT_DURATION);
|
|
}
|
|
|
|
function bindAllNonJSONEditorElements() {
|
|
var inputs = $('input');
|
|
var i;
|
|
for (i = 0; i < inputs.length; i++) {
|
|
var input = inputs[i];
|
|
var field = $(input);
|
|
// TODO FIXME: (JSHint) Functions declared within loops referencing
|
|
// an outer scoped variable may lead to confusing semantics.
|
|
field.on('focus', function(e) {
|
|
if (e.target.id === "userdata-new-editor" || e.target.id === "userdata-clear") {
|
|
return;
|
|
} else {
|
|
if ($('#userdata-editor').css('height') !== "0px") {
|
|
saveJSONUserData(true);
|
|
|
|
}
|
|
}
|
|
});
|
|
}
|
|
}
|
|
|
|
function unbindAllInputs() {
|
|
var inputs = $('input');
|
|
var i;
|
|
for (i = 0; i < inputs.length; i++) {
|
|
var input = inputs[i];
|
|
var field = $(input);
|
|
field.unbind();
|
|
}
|
|
}
|
|
|
|
function clearSelection() {
|
|
if (document.selection && document.selection.empty) {
|
|
document.selection.empty();
|
|
} else if (window.getSelection) {
|
|
var sel = window.getSelection();
|
|
sel.removeAllRanges();
|
|
}
|
|
}
|
|
|
|
function loaded() {
|
|
openEventBridge(function() {
|
|
|
|
var elPropertiesList = document.getElementById("properties-list");
|
|
var elID = document.getElementById("property-id");
|
|
var elType = document.getElementById("property-type");
|
|
var elTypeIcon = document.getElementById("type-icon");
|
|
var elName = document.getElementById("property-name");
|
|
var elLocked = document.getElementById("property-locked");
|
|
var elVisible = document.getElementById("property-visible");
|
|
var elPositionX = document.getElementById("property-pos-x");
|
|
var elPositionY = document.getElementById("property-pos-y");
|
|
var elPositionZ = document.getElementById("property-pos-z");
|
|
var elMoveSelectionToGrid = document.getElementById("move-selection-to-grid");
|
|
var elMoveAllToGrid = document.getElementById("move-all-to-grid");
|
|
|
|
var elDimensionsX = document.getElementById("property-dim-x");
|
|
var elDimensionsY = document.getElementById("property-dim-y");
|
|
var elDimensionsZ = document.getElementById("property-dim-z");
|
|
var elResetToNaturalDimensions = document.getElementById("reset-to-natural-dimensions");
|
|
var elRescaleDimensionsPct = document.getElementById("dimension-rescale-pct");
|
|
var elRescaleDimensionsButton = document.getElementById("dimension-rescale-button");
|
|
|
|
var elParentID = document.getElementById("property-parent-id");
|
|
var elParentJointIndex = document.getElementById("property-parent-joint-index");
|
|
|
|
var elRegistrationX = document.getElementById("property-reg-x");
|
|
var elRegistrationY = document.getElementById("property-reg-y");
|
|
var elRegistrationZ = document.getElementById("property-reg-z");
|
|
|
|
var elRotationX = document.getElementById("property-rot-x");
|
|
var elRotationY = document.getElementById("property-rot-y");
|
|
var elRotationZ = document.getElementById("property-rot-z");
|
|
|
|
var elLinearVelocityX = document.getElementById("property-lvel-x");
|
|
var elLinearVelocityY = document.getElementById("property-lvel-y");
|
|
var elLinearVelocityZ = document.getElementById("property-lvel-z");
|
|
var elLinearDamping = document.getElementById("property-ldamping");
|
|
|
|
var elAngularVelocityX = document.getElementById("property-avel-x");
|
|
var elAngularVelocityY = document.getElementById("property-avel-y");
|
|
var elAngularVelocityZ = document.getElementById("property-avel-z");
|
|
var elAngularDamping = document.getElementById("property-adamping");
|
|
|
|
var elRestitution = document.getElementById("property-restitution");
|
|
var elFriction = document.getElementById("property-friction");
|
|
|
|
var elGravityX = document.getElementById("property-grav-x");
|
|
var elGravityY = document.getElementById("property-grav-y");
|
|
var elGravityZ = document.getElementById("property-grav-z");
|
|
|
|
var elAccelerationX = document.getElementById("property-lacc-x");
|
|
var elAccelerationY = document.getElementById("property-lacc-y");
|
|
var elAccelerationZ = document.getElementById("property-lacc-z");
|
|
|
|
var elDensity = document.getElementById("property-density");
|
|
var elCollisionless = document.getElementById("property-collisionless");
|
|
var elDynamic = document.getElementById("property-dynamic");
|
|
var elCollideStatic = document.getElementById("property-collide-static");
|
|
var elCollideDynamic = document.getElementById("property-collide-dynamic");
|
|
var elCollideKinematic = document.getElementById("property-collide-kinematic");
|
|
var elCollideMyAvatar = document.getElementById("property-collide-myAvatar");
|
|
var elCollideOtherAvatar = document.getElementById("property-collide-otherAvatar");
|
|
var elCollisionSoundURL = document.getElementById("property-collision-sound-url");
|
|
|
|
var elGrabbable = document.getElementById("property-grabbable");
|
|
|
|
var elCloneable = document.getElementById("property-cloneable");
|
|
var elCloneableDynamic = document.getElementById("property-cloneable-dynamic");
|
|
var elCloneableAvatarEntity = document.getElementById("property-cloneable-avatarEntity");
|
|
var elCloneableGroup = document.getElementById("group-cloneable-group");
|
|
var elCloneableLifetime = document.getElementById("property-cloneable-lifetime");
|
|
var elCloneableLimit = document.getElementById("property-cloneable-limit");
|
|
|
|
var elWantsTrigger = document.getElementById("property-wants-trigger");
|
|
var elIgnoreIK = document.getElementById("property-ignore-ik");
|
|
|
|
var elLifetime = document.getElementById("property-lifetime");
|
|
var elScriptURL = document.getElementById("property-script-url");
|
|
var elScriptTimestamp = document.getElementById("property-script-timestamp");
|
|
var elReloadScriptsButton = document.getElementById("reload-script-button");
|
|
var elServerScripts = document.getElementById("property-server-scripts");
|
|
var elReloadServerScriptsButton = document.getElementById("reload-server-scripts-button");
|
|
var elServerScriptStatus = document.getElementById("server-script-status");
|
|
var elServerScriptError = document.getElementById("server-script-error");
|
|
var elUserData = document.getElementById("property-user-data");
|
|
var elClearUserData = document.getElementById("userdata-clear");
|
|
var elSaveUserData = document.getElementById("userdata-save");
|
|
var elNewJSONEditor = document.getElementById('userdata-new-editor');
|
|
var elColorControlVariant2 = document.getElementById("property-color-control2");
|
|
var elColorRed = document.getElementById("property-color-red");
|
|
var elColorGreen = document.getElementById("property-color-green");
|
|
var elColorBlue = document.getElementById("property-color-blue");
|
|
|
|
var elShape = document.getElementById("property-shape");
|
|
|
|
var elLightSpotLight = document.getElementById("property-light-spot-light");
|
|
var elLightColor = document.getElementById("property-light-color");
|
|
var elLightColorRed = document.getElementById("property-light-color-red");
|
|
var elLightColorGreen = document.getElementById("property-light-color-green");
|
|
var elLightColorBlue = document.getElementById("property-light-color-blue");
|
|
|
|
var elLightIntensity = document.getElementById("property-light-intensity");
|
|
var elLightFalloffRadius = document.getElementById("property-light-falloff-radius");
|
|
var elLightExponent = document.getElementById("property-light-exponent");
|
|
var elLightCutoff = document.getElementById("property-light-cutoff");
|
|
|
|
var elModelURL = document.getElementById("property-model-url");
|
|
var elShapeType = document.getElementById("property-shape-type");
|
|
var elCompoundShapeURL = document.getElementById("property-compound-shape-url");
|
|
var elModelAnimationURL = document.getElementById("property-model-animation-url");
|
|
var elModelAnimationPlaying = document.getElementById("property-model-animation-playing");
|
|
var elModelAnimationFPS = document.getElementById("property-model-animation-fps");
|
|
var elModelAnimationFrame = document.getElementById("property-model-animation-frame");
|
|
var elModelAnimationFirstFrame = document.getElementById("property-model-animation-first-frame");
|
|
var elModelAnimationLastFrame = document.getElementById("property-model-animation-last-frame");
|
|
var elModelAnimationLoop = document.getElementById("property-model-animation-loop");
|
|
var elModelAnimationHold = document.getElementById("property-model-animation-hold");
|
|
var elModelAnimationAllowTranslation = document.getElementById("property-model-animation-allow-translation");
|
|
var elModelTextures = document.getElementById("property-model-textures");
|
|
var elModelOriginalTextures = document.getElementById("property-model-original-textures");
|
|
|
|
var elImageURL = document.getElementById("property-image-url");
|
|
|
|
var elWebSourceURL = document.getElementById("property-web-source-url");
|
|
var elWebDPI = document.getElementById("property-web-dpi");
|
|
|
|
var elDescription = document.getElementById("property-description");
|
|
|
|
var elHyperlinkHref = document.getElementById("property-hyperlink-href");
|
|
|
|
var elTextText = document.getElementById("property-text-text");
|
|
var elTextLineHeight = document.getElementById("property-text-line-height");
|
|
var elTextTextColor = document.getElementById("property-text-text-color");
|
|
var elTextFaceCamera = document.getElementById("property-text-face-camera");
|
|
var elTextTextColorRed = document.getElementById("property-text-text-color-red");
|
|
var elTextTextColorGreen = document.getElementById("property-text-text-color-green");
|
|
var elTextTextColorBlue = document.getElementById("property-text-text-color-blue");
|
|
var elTextBackgroundColorRed = document.getElementById("property-text-background-color-red");
|
|
var elTextBackgroundColorGreen = document.getElementById("property-text-background-color-green");
|
|
var elTextBackgroundColorBlue = document.getElementById("property-text-background-color-blue");
|
|
|
|
// Key light
|
|
var elZoneKeyLightModeInherit = document.getElementById("property-zone-key-light-mode-inherit");
|
|
var elZoneKeyLightModeDisabled = document.getElementById("property-zone-key-light-mode-disabled");
|
|
var elZoneKeyLightModeEnabled = document.getElementById("property-zone-key-light-mode-enabled");
|
|
|
|
var elZoneKeyLightColor = document.getElementById("property-zone-key-light-color");
|
|
var elZoneKeyLightColorRed = document.getElementById("property-zone-key-light-color-red");
|
|
var elZoneKeyLightColorGreen = document.getElementById("property-zone-key-light-color-green");
|
|
var elZoneKeyLightColorBlue = document.getElementById("property-zone-key-light-color-blue");
|
|
var elZoneKeyLightIntensity = document.getElementById("property-zone-key-intensity");
|
|
var elZoneKeyLightDirectionX = document.getElementById("property-zone-key-light-direction-x");
|
|
var elZoneKeyLightDirectionY = document.getElementById("property-zone-key-light-direction-y");
|
|
|
|
// Skybox
|
|
var elZoneSkyboxModeInherit = document.getElementById("property-zone-skybox-mode-inherit");
|
|
var elZoneSkyboxModeDisabled = document.getElementById("property-zone-skybox-mode-disabled");
|
|
var elZoneSkyboxModeEnabled = document.getElementById("property-zone-skybox-mode-enabled");
|
|
|
|
// Ambient light
|
|
var elCopySkyboxURLToAmbientURL = document.getElementById("copy-skybox-url-to-ambient-url");
|
|
|
|
var elZoneAmbientLightModeInherit = document.getElementById("property-zone-ambient-light-mode-inherit");
|
|
var elZoneAmbientLightModeDisabled = document.getElementById("property-zone-ambient-light-mode-disabled");
|
|
var elZoneAmbientLightModeEnabled = document.getElementById("property-zone-ambient-light-mode-enabled");
|
|
|
|
var elZoneAmbientLightIntensity = document.getElementById("property-zone-key-ambient-intensity");
|
|
var elZoneAmbientLightURL = document.getElementById("property-zone-key-ambient-url");
|
|
|
|
// Haze
|
|
var elZoneHazeModeInherit = document.getElementById("property-zone-haze-mode-inherit");
|
|
var elZoneHazeModeDisabled = document.getElementById("property-zone-haze-mode-disabled");
|
|
var elZoneHazeModeEnabled = document.getElementById("property-zone-haze-mode-enabled");
|
|
|
|
var elZoneHazeRange = document.getElementById("property-zone-haze-range");
|
|
var elZoneHazeColor = document.getElementById("property-zone-haze-color");
|
|
var elZoneHazeColorRed = document.getElementById("property-zone-haze-color-red");
|
|
var elZoneHazeColorGreen = document.getElementById("property-zone-haze-color-green");
|
|
var elZoneHazeColorBlue = document.getElementById("property-zone-haze-color-blue");
|
|
var elZoneHazeGlareColor = document.getElementById("property-zone-haze-glare-color");
|
|
var elZoneHazeGlareColorRed = document.getElementById("property-zone-haze-glare-color-red");
|
|
var elZoneHazeGlareColorGreen = document.getElementById("property-zone-haze-glare-color-green");
|
|
var elZoneHazeGlareColorBlue = document.getElementById("property-zone-haze-glare-color-blue");
|
|
var elZoneHazeEnableGlare = document.getElementById("property-zone-haze-enable-light-blend");
|
|
var elZonehazeGlareAngle = document.getElementById("property-zone-haze-blend-angle");
|
|
|
|
var elZoneHazeAltitudeEffect = document.getElementById("property-zone-haze-altitude-effect");
|
|
var elZoneHazeBaseRef = document.getElementById("property-zone-haze-base");
|
|
var elZoneHazeCeiling = document.getElementById("property-zone-haze-ceiling");
|
|
|
|
var elZoneHazeBackgroundBlend = document.getElementById("property-zone-haze-background-blend");
|
|
|
|
var elZoneSkyboxColor = document.getElementById("property-zone-skybox-color");
|
|
var elZoneSkyboxColorRed = document.getElementById("property-zone-skybox-color-red");
|
|
var elZoneSkyboxColorGreen = document.getElementById("property-zone-skybox-color-green");
|
|
var elZoneSkyboxColorBlue = document.getElementById("property-zone-skybox-color-blue");
|
|
var elZoneSkyboxURL = document.getElementById("property-zone-skybox-url");
|
|
|
|
var elZoneFlyingAllowed = document.getElementById("property-zone-flying-allowed");
|
|
var elZoneGhostingAllowed = document.getElementById("property-zone-ghosting-allowed");
|
|
var elZoneFilterURL = document.getElementById("property-zone-filter-url");
|
|
|
|
var elVoxelVolumeSizeX = document.getElementById("property-voxel-volume-size-x");
|
|
var elVoxelVolumeSizeY = document.getElementById("property-voxel-volume-size-y");
|
|
var elVoxelVolumeSizeZ = document.getElementById("property-voxel-volume-size-z");
|
|
var elVoxelSurfaceStyle = document.getElementById("property-voxel-surface-style");
|
|
var elXTextureURL = document.getElementById("property-x-texture-url");
|
|
var elYTextureURL = document.getElementById("property-y-texture-url");
|
|
var elZTextureURL = document.getElementById("property-z-texture-url");
|
|
|
|
if (window.EventBridge !== undefined) {
|
|
var properties;
|
|
EventBridge.scriptEventReceived.connect(function(data) {
|
|
data = JSON.parse(data);
|
|
if (data.type === "server_script_status") {
|
|
elServerScriptError.value = data.errorInfo;
|
|
// If we just set elServerScriptError's diplay to block or none, we still end up with
|
|
// it's parent contributing 21px bottom padding even when elServerScriptError is display:none.
|
|
// So set it's parent to block or none
|
|
elServerScriptError.parentElement.style.display = data.errorInfo ? "block" : "none";
|
|
if (data.statusRetrieved === false) {
|
|
elServerScriptStatus.innerText = "Failed to retrieve status";
|
|
} else if (data.isRunning) {
|
|
var ENTITY_SCRIPT_STATUS = {
|
|
pending: "Pending",
|
|
loading: "Loading",
|
|
error_loading_script: "Error loading script", // eslint-disable-line camelcase
|
|
error_running_script: "Error running script", // eslint-disable-line camelcase
|
|
running: "Running",
|
|
unloaded: "Unloaded"
|
|
};
|
|
elServerScriptStatus.innerText = ENTITY_SCRIPT_STATUS[data.status] || data.status;
|
|
} else {
|
|
elServerScriptStatus.innerText = "Not running";
|
|
}
|
|
} else if (data.type === "update") {
|
|
|
|
if (!data.selections || data.selections.length === 0) {
|
|
if (editor !== null && lastEntityID !== null) {
|
|
saveJSONUserData(true);
|
|
deleteJSONEditor();
|
|
}
|
|
elTypeIcon.style.display = "none";
|
|
elType.innerHTML = "<i>No selection</i>";
|
|
elID.value = "";
|
|
elPropertiesList.className = '';
|
|
disableProperties();
|
|
} else if (data.selections && data.selections.length > 1) {
|
|
deleteJSONEditor();
|
|
var selections = data.selections;
|
|
|
|
var ids = [];
|
|
var types = {};
|
|
var numTypes = 0;
|
|
|
|
for (var i = 0; i < selections.length; i++) {
|
|
ids.push(selections[i].id);
|
|
var currentSelectedType = selections[i].properties.type;
|
|
if (types[currentSelectedType] === undefined) {
|
|
types[currentSelectedType] = 0;
|
|
numTypes += 1;
|
|
}
|
|
types[currentSelectedType]++;
|
|
}
|
|
|
|
var type = "Multiple";
|
|
if (numTypes === 1) {
|
|
type = selections[0].properties.type;
|
|
}
|
|
|
|
elType.innerHTML = type + " (" + data.selections.length + ")";
|
|
elTypeIcon.innerHTML = ICON_FOR_TYPE[type];
|
|
elTypeIcon.style.display = "inline-block";
|
|
elPropertiesList.className = '';
|
|
|
|
elID.value = "";
|
|
|
|
disableProperties();
|
|
} else {
|
|
|
|
properties = data.selections[0].properties;
|
|
if (lastEntityID !== '"' + properties.id + '"' && lastEntityID !== null && editor !== null) {
|
|
saveJSONUserData(true);
|
|
}
|
|
// the event bridge and json parsing handle our avatar id string differently.
|
|
|
|
lastEntityID = '"' + properties.id + '"';
|
|
elID.value = properties.id;
|
|
|
|
// HTML workaround since image is not yet a separate entity type
|
|
var IMAGE_MODEL_NAME = 'default-image-model.fbx';
|
|
if (properties.type === "Model") {
|
|
var urlParts = properties.modelURL.split('/');
|
|
var propsFilename = urlParts[urlParts.length - 1];
|
|
|
|
if (propsFilename === IMAGE_MODEL_NAME) {
|
|
properties.type = "Image";
|
|
}
|
|
}
|
|
|
|
// Create class name for css ruleset filtering
|
|
elPropertiesList.className = properties.type + 'Menu';
|
|
|
|
elType.innerHTML = properties.type;
|
|
elTypeIcon.innerHTML = ICON_FOR_TYPE[properties.type];
|
|
elTypeIcon.style.display = "inline-block";
|
|
|
|
elLocked.checked = properties.locked;
|
|
|
|
|
|
elName.value = properties.name;
|
|
|
|
elVisible.checked = properties.visible;
|
|
|
|
elPositionX.value = properties.position.x.toFixed(4);
|
|
elPositionY.value = properties.position.y.toFixed(4);
|
|
elPositionZ.value = properties.position.z.toFixed(4);
|
|
|
|
elDimensionsX.value = properties.dimensions.x.toFixed(4);
|
|
elDimensionsY.value = properties.dimensions.y.toFixed(4);
|
|
elDimensionsZ.value = properties.dimensions.z.toFixed(4);
|
|
|
|
elParentID.value = properties.parentID;
|
|
elParentJointIndex.value = properties.parentJointIndex;
|
|
|
|
elRegistrationX.value = properties.registrationPoint.x.toFixed(4);
|
|
elRegistrationY.value = properties.registrationPoint.y.toFixed(4);
|
|
elRegistrationZ.value = properties.registrationPoint.z.toFixed(4);
|
|
|
|
elRotationX.value = properties.rotation.x.toFixed(4);
|
|
elRotationY.value = properties.rotation.y.toFixed(4);
|
|
elRotationZ.value = properties.rotation.z.toFixed(4);
|
|
|
|
elLinearVelocityX.value = properties.velocity.x.toFixed(4);
|
|
elLinearVelocityY.value = properties.velocity.y.toFixed(4);
|
|
elLinearVelocityZ.value = properties.velocity.z.toFixed(4);
|
|
elLinearDamping.value = properties.damping.toFixed(2);
|
|
|
|
elAngularVelocityX.value = (properties.angularVelocity.x * RADIANS_TO_DEGREES).toFixed(4);
|
|
elAngularVelocityY.value = (properties.angularVelocity.y * RADIANS_TO_DEGREES).toFixed(4);
|
|
elAngularVelocityZ.value = (properties.angularVelocity.z * RADIANS_TO_DEGREES).toFixed(4);
|
|
elAngularDamping.value = properties.angularDamping.toFixed(4);
|
|
|
|
elRestitution.value = properties.restitution.toFixed(4);
|
|
elFriction.value = properties.friction.toFixed(4);
|
|
|
|
elGravityX.value = properties.gravity.x.toFixed(4);
|
|
elGravityY.value = properties.gravity.y.toFixed(4);
|
|
elGravityZ.value = properties.gravity.z.toFixed(4);
|
|
|
|
elAccelerationX.value = properties.acceleration.x.toFixed(4);
|
|
elAccelerationY.value = properties.acceleration.y.toFixed(4);
|
|
elAccelerationZ.value = properties.acceleration.z.toFixed(4);
|
|
|
|
elDensity.value = properties.density.toFixed(4);
|
|
elCollisionless.checked = properties.collisionless;
|
|
elDynamic.checked = properties.dynamic;
|
|
|
|
elCollideStatic.checked = properties.collidesWith.indexOf("static") > -1;
|
|
elCollideKinematic.checked = properties.collidesWith.indexOf("kinematic") > -1;
|
|
elCollideDynamic.checked = properties.collidesWith.indexOf("dynamic") > -1;
|
|
elCollideMyAvatar.checked = properties.collidesWith.indexOf("myAvatar") > -1;
|
|
elCollideOtherAvatar.checked = properties.collidesWith.indexOf("otherAvatar") > -1;
|
|
|
|
elGrabbable.checked = properties.dynamic;
|
|
|
|
elWantsTrigger.checked = false;
|
|
elIgnoreIK.checked = true;
|
|
|
|
elCloneable.checked = false;
|
|
elCloneableDynamic.checked = false;
|
|
elCloneableGroup.style.display = elCloneable.checked ? "block": "none";
|
|
elCloneableLimit.value = 0;
|
|
elCloneableLifetime.value = 300;
|
|
|
|
var grabbablesSet = false;
|
|
var parsedUserData = {};
|
|
try {
|
|
parsedUserData = JSON.parse(properties.userData);
|
|
|
|
if ("grabbableKey" in parsedUserData) {
|
|
grabbablesSet = true;
|
|
var grabbableData = parsedUserData.grabbableKey;
|
|
if ("grabbable" in grabbableData) {
|
|
elGrabbable.checked = grabbableData.grabbable;
|
|
} else {
|
|
elGrabbable.checked = true;
|
|
}
|
|
if ("wantsTrigger" in grabbableData) {
|
|
elWantsTrigger.checked = grabbableData.wantsTrigger;
|
|
} else {
|
|
elWantsTrigger.checked = false;
|
|
}
|
|
if ("ignoreIK" in grabbableData) {
|
|
elIgnoreIK.checked = grabbableData.ignoreIK;
|
|
} else {
|
|
elIgnoreIK.checked = true;
|
|
}
|
|
if ("cloneable" in grabbableData) {
|
|
elCloneable.checked = grabbableData.cloneable;
|
|
elCloneableGroup.style.display = elCloneable.checked ? "block" : "none";
|
|
elCloneableDynamic.checked =
|
|
grabbableData.cloneDynamic ? grabbableData.cloneDynamic : properties.dynamic;
|
|
if (elCloneable.checked) {
|
|
if ("cloneLifetime" in grabbableData) {
|
|
elCloneableLifetime.value =
|
|
grabbableData.cloneLifetime ? grabbableData.cloneLifetime : 300;
|
|
}
|
|
if ("cloneLimit" in grabbableData) {
|
|
elCloneableLimit.value = grabbableData.cloneLimit ? grabbableData.cloneLimit : 0;
|
|
}
|
|
if ("cloneAvatarEntity" in grabbableData) {
|
|
elCloneableAvatarEntity.checked =
|
|
grabbableData.cloneAvatarEntity ? grabbableData.cloneAvatarEntity : false;
|
|
}
|
|
}
|
|
} else {
|
|
elCloneable.checked = false;
|
|
}
|
|
}
|
|
} catch (e) {
|
|
// TODO: What should go here?
|
|
}
|
|
if (!grabbablesSet) {
|
|
elGrabbable.checked = true;
|
|
elWantsTrigger.checked = false;
|
|
elIgnoreIK.checked = true;
|
|
elCloneable.checked = false;
|
|
}
|
|
|
|
elCollisionSoundURL.value = properties.collisionSoundURL;
|
|
elLifetime.value = properties.lifetime;
|
|
elScriptURL.value = properties.script;
|
|
elScriptTimestamp.value = properties.scriptTimestamp;
|
|
elServerScripts.value = properties.serverScripts;
|
|
|
|
var json = null;
|
|
try {
|
|
json = JSON.parse(properties.userData);
|
|
} catch (e) {
|
|
// normal text
|
|
deleteJSONEditor();
|
|
elUserData.value = properties.userData;
|
|
showUserDataTextArea();
|
|
showNewJSONEditorButton();
|
|
hideSaveUserDataButton();
|
|
}
|
|
if (json !== null) {
|
|
if (editor === null) {
|
|
createJSONEditor();
|
|
}
|
|
|
|
setEditorJSON(json);
|
|
showSaveUserDataButton();
|
|
hideUserDataTextArea();
|
|
hideNewJSONEditorButton();
|
|
}
|
|
|
|
elHyperlinkHref.value = properties.href;
|
|
elDescription.value = properties.description;
|
|
|
|
|
|
if (properties.type === "Shape" || properties.type === "Box" || properties.type === "Sphere") {
|
|
elShape.value = properties.shape;
|
|
setDropdownText(elShape);
|
|
}
|
|
|
|
if (properties.type === "Shape" || properties.type === "Box" ||
|
|
properties.type === "Sphere" || properties.type === "ParticleEffect") {
|
|
elColorRed.value = properties.color.red;
|
|
elColorGreen.value = properties.color.green;
|
|
elColorBlue.value = properties.color.blue;
|
|
elColorControlVariant2.style.backgroundColor = "rgb(" + properties.color.red + "," +
|
|
properties.color.green + "," + properties.color.blue + ")";
|
|
}
|
|
|
|
if (properties.type === "Model") {
|
|
elModelURL.value = properties.modelURL;
|
|
elShapeType.value = properties.shapeType;
|
|
setDropdownText(elShapeType);
|
|
elCompoundShapeURL.value = properties.compoundShapeURL;
|
|
elModelAnimationURL.value = properties.animation.url;
|
|
elModelAnimationPlaying.checked = properties.animation.running;
|
|
elModelAnimationFPS.value = properties.animation.fps;
|
|
elModelAnimationFrame.value = properties.animation.currentFrame;
|
|
elModelAnimationFirstFrame.value = properties.animation.firstFrame;
|
|
elModelAnimationLastFrame.value = properties.animation.lastFrame;
|
|
elModelAnimationLoop.checked = properties.animation.loop;
|
|
elModelAnimationHold.checked = properties.animation.hold;
|
|
elModelAnimationAllowTranslation.checked = properties.animation.allowTranslation;
|
|
elModelTextures.value = properties.textures;
|
|
setTextareaScrolling(elModelTextures);
|
|
elModelOriginalTextures.value = properties.originalTextures;
|
|
setTextareaScrolling(elModelOriginalTextures);
|
|
} else if (properties.type === "Web") {
|
|
elWebSourceURL.value = properties.sourceUrl;
|
|
elWebDPI.value = properties.dpi;
|
|
} else if (properties.type === "Image") {
|
|
var imageLink = JSON.parse(properties.textures)["tex.picture"];
|
|
elImageURL.value = imageLink;
|
|
} else if (properties.type === "Text") {
|
|
elTextText.value = properties.text;
|
|
elTextLineHeight.value = properties.lineHeight.toFixed(4);
|
|
elTextFaceCamera.checked = properties.faceCamera;
|
|
elTextTextColor.style.backgroundColor = "rgb(" + properties.textColor.red + "," +
|
|
properties.textColor.green + "," + properties.textColor.blue + ")";
|
|
elTextTextColorRed.value = properties.textColor.red;
|
|
elTextTextColorGreen.value = properties.textColor.green;
|
|
elTextTextColorBlue.value = properties.textColor.blue;
|
|
elTextBackgroundColorRed.value = properties.backgroundColor.red;
|
|
elTextBackgroundColorGreen.value = properties.backgroundColor.green;
|
|
elTextBackgroundColorBlue.value = properties.backgroundColor.blue;
|
|
} else if (properties.type === "Light") {
|
|
elLightSpotLight.checked = properties.isSpotlight;
|
|
|
|
elLightColor.style.backgroundColor = "rgb(" + properties.color.red + "," +
|
|
properties.color.green + "," + properties.color.blue + ")";
|
|
elLightColorRed.value = properties.color.red;
|
|
elLightColorGreen.value = properties.color.green;
|
|
elLightColorBlue.value = properties.color.blue;
|
|
|
|
elLightIntensity.value = properties.intensity.toFixed(1);
|
|
elLightFalloffRadius.value = properties.falloffRadius.toFixed(1);
|
|
elLightExponent.value = properties.exponent.toFixed(2);
|
|
elLightCutoff.value = properties.cutoff.toFixed(2);
|
|
|
|
} else if (properties.type === "Zone") {
|
|
// Key light
|
|
elZoneKeyLightModeInherit.checked = (properties.keyLightMode === 'inherit');
|
|
elZoneKeyLightModeDisabled.checked = (properties.keyLightMode === 'disabled');
|
|
elZoneKeyLightModeEnabled.checked = (properties.keyLightMode === 'enabled');
|
|
|
|
elZoneKeyLightColor.style.backgroundColor = "rgb(" + properties.keyLight.color.red + "," +
|
|
properties.keyLight.color.green + "," + properties.keyLight.color.blue + ")";
|
|
elZoneKeyLightColorRed.value = properties.keyLight.color.red;
|
|
elZoneKeyLightColorGreen.value = properties.keyLight.color.green;
|
|
elZoneKeyLightColorBlue.value = properties.keyLight.color.blue;
|
|
elZoneKeyLightIntensity.value = properties.keyLight.intensity.toFixed(2);
|
|
elZoneKeyLightDirectionX.value = properties.keyLight.direction.x.toFixed(2);
|
|
elZoneKeyLightDirectionY.value = properties.keyLight.direction.y.toFixed(2);
|
|
|
|
// Skybox
|
|
elZoneSkyboxModeInherit.checked = (properties.skyboxMode === 'inherit');
|
|
elZoneSkyboxModeDisabled.checked = (properties.skyboxMode === 'disabled');
|
|
elZoneSkyboxModeEnabled.checked = (properties.skyboxMode === 'enabled');
|
|
|
|
// Ambient light
|
|
elZoneAmbientLightModeInherit.checked = (properties.ambientLightMode === 'inherit');
|
|
elZoneAmbientLightModeDisabled.checked = (properties.ambientLightMode === 'disabled');
|
|
elZoneAmbientLightModeEnabled.checked = (properties.ambientLightMode === 'enabled');
|
|
|
|
elZoneAmbientLightIntensity.value = properties.ambientLight.ambientIntensity.toFixed(2);
|
|
elZoneAmbientLightURL.value = properties.ambientLight.ambientURL;
|
|
|
|
// Haze
|
|
elZoneHazeModeInherit.checked = (properties.hazeMode === 'inherit');
|
|
elZoneHazeModeDisabled.checked = (properties.hazeMode === 'disabled');
|
|
elZoneHazeModeEnabled.checked = (properties.hazeMode === 'enabled');
|
|
|
|
elZoneHazeRange.value = properties.haze.hazeRange.toFixed(0);
|
|
elZoneHazeColor.style.backgroundColor = "rgb(" +
|
|
properties.haze.hazeColor.red + "," +
|
|
properties.haze.hazeColor.green + "," +
|
|
properties.haze.hazeColor.blue + ")";
|
|
|
|
elZoneHazeColorRed.value = properties.haze.hazeColor.red;
|
|
elZoneHazeColorGreen.value = properties.haze.hazeColor.green;
|
|
elZoneHazeColorBlue.value = properties.haze.hazeColor.blue;
|
|
elZoneHazeBackgroundBlend.value = properties.haze.hazeBackgroundBlend.toFixed(2);
|
|
|
|
elZoneHazeGlareColor.style.backgroundColor = "rgb(" +
|
|
properties.haze.hazeGlareColor.red + "," +
|
|
properties.haze.hazeGlareColor.green + "," +
|
|
properties.haze.hazeGlareColor.blue + ")";
|
|
|
|
elZoneHazeGlareColorRed.value = properties.haze.hazeGlareColor.red;
|
|
elZoneHazeGlareColorGreen.value = properties.haze.hazeGlareColor.green;
|
|
elZoneHazeGlareColorBlue.value = properties.haze.hazeGlareColor.blue;
|
|
|
|
elZoneHazeEnableGlare.checked = properties.haze.hazeEnableGlare;
|
|
elZonehazeGlareAngle.value = properties.haze.hazeGlareAngle.toFixed(0);
|
|
|
|
elZoneHazeAltitudeEffect.checked = properties.haze.hazeAltitudeEffect;
|
|
elZoneHazeBaseRef.value = properties.haze.hazeBaseRef.toFixed(0);
|
|
elZoneHazeCeiling.value = properties.haze.hazeCeiling.toFixed(0);
|
|
|
|
elZoneHazeBackgroundBlend.value = properties.haze.hazeBackgroundBlend.toFixed(2);
|
|
elShapeType.value = properties.shapeType;
|
|
elCompoundShapeURL.value = properties.compoundShapeURL;
|
|
|
|
elZoneSkyboxColor.style.backgroundColor = "rgb(" + properties.skybox.color.red + "," +
|
|
properties.skybox.color.green + "," + properties.skybox.color.blue + ")";
|
|
elZoneSkyboxColorRed.value = properties.skybox.color.red;
|
|
elZoneSkyboxColorGreen.value = properties.skybox.color.green;
|
|
elZoneSkyboxColorBlue.value = properties.skybox.color.blue;
|
|
elZoneSkyboxURL.value = properties.skybox.url;
|
|
|
|
elZoneFlyingAllowed.checked = properties.flyingAllowed;
|
|
elZoneGhostingAllowed.checked = properties.ghostingAllowed;
|
|
elZoneFilterURL.value = properties.filterURL;
|
|
|
|
// Show/hide sections as required
|
|
showElements(document.getElementsByClassName('skybox-section'),
|
|
elZoneSkyboxModeEnabled.checked);
|
|
showElements(document.getElementsByClassName('keylight-section'),
|
|
elZoneKeyLightModeEnabled.checked);
|
|
showElements(document.getElementsByClassName('ambient-section'),
|
|
elZoneAmbientLightModeEnabled.checked);
|
|
showElements(document.getElementsByClassName('haze-section'),
|
|
elZoneHazeModeEnabled.checked);
|
|
|
|
} else if (properties.type === "PolyVox") {
|
|
elVoxelVolumeSizeX.value = properties.voxelVolumeSize.x.toFixed(2);
|
|
elVoxelVolumeSizeY.value = properties.voxelVolumeSize.y.toFixed(2);
|
|
elVoxelVolumeSizeZ.value = properties.voxelVolumeSize.z.toFixed(2);
|
|
elVoxelSurfaceStyle.value = properties.voxelSurfaceStyle;
|
|
setDropdownText(elVoxelSurfaceStyle);
|
|
elXTextureURL.value = properties.xTextureURL;
|
|
elYTextureURL.value = properties.yTextureURL;
|
|
elZTextureURL.value = properties.zTextureURL;
|
|
}
|
|
|
|
if (properties.locked) {
|
|
disableProperties();
|
|
elLocked.removeAttribute('disabled');
|
|
} else {
|
|
enableProperties();
|
|
elSaveUserData.disabled = true;
|
|
}
|
|
|
|
var activeElement = document.activeElement;
|
|
|
|
if (typeof activeElement.select !== "undefined") {
|
|
activeElement.select();
|
|
}
|
|
}
|
|
clearSelection();
|
|
}
|
|
});
|
|
}
|
|
|
|
elLocked.addEventListener('change', createEmitCheckedPropertyUpdateFunction('locked'));
|
|
elName.addEventListener('change', createEmitTextPropertyUpdateFunction('name'));
|
|
elHyperlinkHref.addEventListener('change', createEmitTextPropertyUpdateFunction('href'));
|
|
elDescription.addEventListener('change', createEmitTextPropertyUpdateFunction('description'));
|
|
elVisible.addEventListener('change', createEmitCheckedPropertyUpdateFunction('visible'));
|
|
|
|
var positionChangeFunction = createEmitVec3PropertyUpdateFunction(
|
|
'position', elPositionX, elPositionY, elPositionZ);
|
|
elPositionX.addEventListener('change', positionChangeFunction);
|
|
elPositionY.addEventListener('change', positionChangeFunction);
|
|
elPositionZ.addEventListener('change', positionChangeFunction);
|
|
|
|
var dimensionsChangeFunction = createEmitVec3PropertyUpdateFunction(
|
|
'dimensions', elDimensionsX, elDimensionsY, elDimensionsZ);
|
|
elDimensionsX.addEventListener('change', dimensionsChangeFunction);
|
|
elDimensionsY.addEventListener('change', dimensionsChangeFunction);
|
|
elDimensionsZ.addEventListener('change', dimensionsChangeFunction);
|
|
|
|
elParentID.addEventListener('change', createEmitTextPropertyUpdateFunction('parentID'));
|
|
elParentJointIndex.addEventListener('change', createEmitNumberPropertyUpdateFunction('parentJointIndex', 0));
|
|
|
|
var registrationChangeFunction = createEmitVec3PropertyUpdateFunction(
|
|
'registrationPoint', elRegistrationX, elRegistrationY, elRegistrationZ);
|
|
elRegistrationX.addEventListener('change', registrationChangeFunction);
|
|
elRegistrationY.addEventListener('change', registrationChangeFunction);
|
|
elRegistrationZ.addEventListener('change', registrationChangeFunction);
|
|
|
|
var rotationChangeFunction = createEmitVec3PropertyUpdateFunction(
|
|
'rotation', elRotationX, elRotationY, elRotationZ);
|
|
elRotationX.addEventListener('change', rotationChangeFunction);
|
|
elRotationY.addEventListener('change', rotationChangeFunction);
|
|
elRotationZ.addEventListener('change', rotationChangeFunction);
|
|
|
|
var velocityChangeFunction = createEmitVec3PropertyUpdateFunction(
|
|
'velocity', elLinearVelocityX, elLinearVelocityY, elLinearVelocityZ);
|
|
elLinearVelocityX.addEventListener('change', velocityChangeFunction);
|
|
elLinearVelocityY.addEventListener('change', velocityChangeFunction);
|
|
elLinearVelocityZ.addEventListener('change', velocityChangeFunction);
|
|
elLinearDamping.addEventListener('change', createEmitNumberPropertyUpdateFunction('damping'));
|
|
|
|
var angularVelocityChangeFunction = createEmitVec3PropertyUpdateFunctionWithMultiplier(
|
|
'angularVelocity', elAngularVelocityX, elAngularVelocityY, elAngularVelocityZ, DEGREES_TO_RADIANS);
|
|
elAngularVelocityX.addEventListener('change', angularVelocityChangeFunction);
|
|
elAngularVelocityY.addEventListener('change', angularVelocityChangeFunction);
|
|
elAngularVelocityZ.addEventListener('change', angularVelocityChangeFunction);
|
|
elAngularDamping.addEventListener('change', createEmitNumberPropertyUpdateFunction('angularDamping'));
|
|
|
|
elRestitution.addEventListener('change', createEmitNumberPropertyUpdateFunction('restitution'));
|
|
elFriction.addEventListener('change', createEmitNumberPropertyUpdateFunction('friction'));
|
|
|
|
var gravityChangeFunction = createEmitVec3PropertyUpdateFunction(
|
|
'gravity', elGravityX, elGravityY, elGravityZ);
|
|
elGravityX.addEventListener('change', gravityChangeFunction);
|
|
elGravityY.addEventListener('change', gravityChangeFunction);
|
|
elGravityZ.addEventListener('change', gravityChangeFunction);
|
|
|
|
var accelerationChangeFunction = createEmitVec3PropertyUpdateFunction(
|
|
'acceleration', elAccelerationX, elAccelerationY, elAccelerationZ);
|
|
elAccelerationX.addEventListener('change', accelerationChangeFunction);
|
|
elAccelerationY.addEventListener('change', accelerationChangeFunction);
|
|
elAccelerationZ.addEventListener('change', accelerationChangeFunction);
|
|
|
|
elDensity.addEventListener('change', createEmitNumberPropertyUpdateFunction('density'));
|
|
elCollisionless.addEventListener('change', createEmitCheckedPropertyUpdateFunction('collisionless'));
|
|
elDynamic.addEventListener('change', createEmitCheckedPropertyUpdateFunction('dynamic'));
|
|
|
|
elCollideDynamic.addEventListener('change', function() {
|
|
updateCheckedSubProperty("collidesWith", properties.collidesWith, elCollideDynamic, 'dynamic');
|
|
});
|
|
|
|
elCollideKinematic.addEventListener('change', function() {
|
|
updateCheckedSubProperty("collidesWith", properties.collidesWith, elCollideKinematic, 'kinematic');
|
|
});
|
|
|
|
elCollideStatic.addEventListener('change', function() {
|
|
updateCheckedSubProperty("collidesWith", properties.collidesWith, elCollideStatic, 'static');
|
|
});
|
|
elCollideMyAvatar.addEventListener('change', function() {
|
|
updateCheckedSubProperty("collidesWith", properties.collidesWith, elCollideMyAvatar, 'myAvatar');
|
|
});
|
|
elCollideOtherAvatar.addEventListener('change', function() {
|
|
updateCheckedSubProperty("collidesWith", properties.collidesWith, elCollideOtherAvatar, 'otherAvatar');
|
|
});
|
|
|
|
elGrabbable.addEventListener('change', function() {
|
|
if (elCloneable.checked) {
|
|
elGrabbable.checked = false;
|
|
}
|
|
userDataChanger("grabbableKey", "grabbable", elGrabbable, elUserData, properties.dynamic);
|
|
});
|
|
elCloneableDynamic.addEventListener('change', function(event) {
|
|
userDataChanger("grabbableKey", "cloneDynamic", event.target, elUserData, -1);
|
|
});
|
|
|
|
elCloneableAvatarEntity.addEventListener('change', function(event) {
|
|
userDataChanger("grabbableKey", "cloneAvatarEntity", event.target, elUserData, -1);
|
|
});
|
|
|
|
elCloneable.addEventListener('change', function (event) {
|
|
var checked = event.target.checked;
|
|
if (checked) {
|
|
multiDataUpdater("grabbableKey", {
|
|
cloneLifetime: elCloneableLifetime,
|
|
cloneLimit: elCloneableLimit,
|
|
cloneDynamic: elCloneableDynamic,
|
|
cloneAvatarEntity: elCloneableAvatarEntity,
|
|
cloneable: event.target,
|
|
grabbable: null
|
|
}, elUserData, {});
|
|
elCloneableGroup.style.display = "block";
|
|
updateProperty('dynamic', false);
|
|
} else {
|
|
multiDataUpdater("grabbableKey", {
|
|
cloneLifetime: null,
|
|
cloneLimit: null,
|
|
cloneDynamic: null,
|
|
cloneAvatarEntity: null,
|
|
cloneable: false
|
|
}, elUserData, {});
|
|
elCloneableGroup.style.display = "none";
|
|
}
|
|
});
|
|
|
|
var numberListener = function (event) {
|
|
userDataChanger("grabbableKey",
|
|
event.target.getAttribute("data-user-data-type"), parseInt(event.target.value), elUserData, false);
|
|
};
|
|
elCloneableLifetime.addEventListener('change', numberListener);
|
|
elCloneableLimit.addEventListener('change', numberListener);
|
|
|
|
elWantsTrigger.addEventListener('change', function() {
|
|
userDataChanger("grabbableKey", "wantsTrigger", elWantsTrigger, elUserData, false);
|
|
});
|
|
elIgnoreIK.addEventListener('change', function() {
|
|
userDataChanger("grabbableKey", "ignoreIK", elIgnoreIK, elUserData, true);
|
|
});
|
|
|
|
elCollisionSoundURL.addEventListener('change', createEmitTextPropertyUpdateFunction('collisionSoundURL'));
|
|
|
|
elLifetime.addEventListener('change', createEmitNumberPropertyUpdateFunction('lifetime'));
|
|
elScriptURL.addEventListener('change', createEmitTextPropertyUpdateFunction('script'));
|
|
elScriptTimestamp.addEventListener('change', createEmitNumberPropertyUpdateFunction('scriptTimestamp'));
|
|
elServerScripts.addEventListener('change', createEmitTextPropertyUpdateFunction('serverScripts'));
|
|
elServerScripts.addEventListener('change', function() {
|
|
// invalidate the current status (so that same-same updates can still be observed visually)
|
|
elServerScriptStatus.innerText = '[' + elServerScriptStatus.innerText + ']';
|
|
});
|
|
|
|
elClearUserData.addEventListener("click", function() {
|
|
deleteJSONEditor();
|
|
elUserData.value = "";
|
|
showUserDataTextArea();
|
|
showNewJSONEditorButton();
|
|
hideSaveUserDataButton();
|
|
updateProperty('userData', elUserData.value);
|
|
});
|
|
|
|
elSaveUserData.addEventListener("click", function() {
|
|
saveJSONUserData(true);
|
|
});
|
|
|
|
elUserData.addEventListener('change', createEmitTextPropertyUpdateFunction('userData'));
|
|
|
|
elNewJSONEditor.addEventListener('click', function() {
|
|
deleteJSONEditor();
|
|
createJSONEditor();
|
|
var data = {};
|
|
setEditorJSON(data);
|
|
hideUserDataTextArea();
|
|
hideNewJSONEditorButton();
|
|
showSaveUserDataButton();
|
|
});
|
|
|
|
var colorChangeFunction = createEmitColorPropertyUpdateFunction(
|
|
'color', elColorRed, elColorGreen, elColorBlue);
|
|
elColorRed.addEventListener('change', colorChangeFunction);
|
|
elColorGreen.addEventListener('change', colorChangeFunction);
|
|
elColorBlue.addEventListener('change', colorChangeFunction);
|
|
colorPickers.push($('#property-color-control2').colpick({
|
|
colorScheme: 'dark',
|
|
layout: 'hex',
|
|
color: '000000',
|
|
submit: false, // We don't want to have a submission button
|
|
onShow: function(colpick) {
|
|
$('#property-color-control2').attr('active', 'true');
|
|
},
|
|
onHide: function(colpick) {
|
|
$('#property-color-control2').attr('active', 'false');
|
|
},
|
|
onChange: function(hsb, hex, rgb, el) {
|
|
$(el).css('background-color', '#' + hex);
|
|
emitColorPropertyUpdate('color', rgb.r, rgb.g, rgb.b);
|
|
}
|
|
}));
|
|
|
|
elLightSpotLight.addEventListener('change', createEmitCheckedPropertyUpdateFunction('isSpotlight'));
|
|
|
|
var lightColorChangeFunction = createEmitColorPropertyUpdateFunction(
|
|
'color', elLightColorRed, elLightColorGreen, elLightColorBlue);
|
|
elLightColorRed.addEventListener('change', lightColorChangeFunction);
|
|
elLightColorGreen.addEventListener('change', lightColorChangeFunction);
|
|
elLightColorBlue.addEventListener('change', lightColorChangeFunction);
|
|
colorPickers.push($('#property-light-color').colpick({
|
|
colorScheme: 'dark',
|
|
layout: 'hex',
|
|
color: '000000',
|
|
submit: false, // We don't want to have a submission button
|
|
onShow: function(colpick) {
|
|
$('#property-light-color').attr('active', 'true');
|
|
},
|
|
onHide: function(colpick) {
|
|
$('#property-light-color').attr('active', 'false');
|
|
},
|
|
onChange: function(hsb, hex, rgb, el) {
|
|
$(el).css('background-color', '#' + hex);
|
|
emitColorPropertyUpdate('color', rgb.r, rgb.g, rgb.b);
|
|
}
|
|
}));
|
|
|
|
elLightIntensity.addEventListener('change', createEmitNumberPropertyUpdateFunction('intensity', 1));
|
|
elLightFalloffRadius.addEventListener('change', createEmitNumberPropertyUpdateFunction('falloffRadius', 1));
|
|
elLightExponent.addEventListener('change', createEmitNumberPropertyUpdateFunction('exponent', 2));
|
|
elLightCutoff.addEventListener('change', createEmitNumberPropertyUpdateFunction('cutoff', 2));
|
|
|
|
elShape.addEventListener('change', createEmitTextPropertyUpdateFunction('shape'));
|
|
|
|
elImageURL.addEventListener('change', createImageURLUpdateFunction('textures'));
|
|
|
|
elWebSourceURL.addEventListener('change', createEmitTextPropertyUpdateFunction('sourceUrl'));
|
|
elWebDPI.addEventListener('change', createEmitNumberPropertyUpdateFunction('dpi', 0));
|
|
|
|
elModelURL.addEventListener('change', createEmitTextPropertyUpdateFunction('modelURL'));
|
|
elShapeType.addEventListener('change', createEmitTextPropertyUpdateFunction('shapeType'));
|
|
elCompoundShapeURL.addEventListener('change', createEmitTextPropertyUpdateFunction('compoundShapeURL'));
|
|
|
|
elModelAnimationURL.addEventListener('change', createEmitGroupTextPropertyUpdateFunction('animation', 'url'));
|
|
elModelAnimationPlaying.addEventListener('change',createEmitGroupCheckedPropertyUpdateFunction('animation', 'running'));
|
|
elModelAnimationFPS.addEventListener('change', createEmitGroupNumberPropertyUpdateFunction('animation', 'fps'));
|
|
elModelAnimationFrame.addEventListener('change',
|
|
createEmitGroupNumberPropertyUpdateFunction('animation', 'currentFrame'));
|
|
elModelAnimationFirstFrame.addEventListener('change',
|
|
createEmitGroupNumberPropertyUpdateFunction('animation', 'firstFrame'));
|
|
elModelAnimationLastFrame.addEventListener('change',
|
|
createEmitGroupNumberPropertyUpdateFunction('animation', 'lastFrame'));
|
|
elModelAnimationLoop.addEventListener('change', createEmitGroupCheckedPropertyUpdateFunction('animation', 'loop'));
|
|
elModelAnimationHold.addEventListener('change', createEmitGroupCheckedPropertyUpdateFunction('animation', 'hold'));
|
|
elModelAnimationAllowTranslation.addEventListener('change',
|
|
createEmitGroupCheckedPropertyUpdateFunction('animation', 'allowTranslation'));
|
|
|
|
elModelTextures.addEventListener('change', createEmitTextPropertyUpdateFunction('textures'));
|
|
|
|
elTextText.addEventListener('change', createEmitTextPropertyUpdateFunction('text'));
|
|
elTextFaceCamera.addEventListener('change', createEmitCheckedPropertyUpdateFunction('faceCamera'));
|
|
elTextLineHeight.addEventListener('change', createEmitNumberPropertyUpdateFunction('lineHeight'));
|
|
var textTextColorChangeFunction = createEmitColorPropertyUpdateFunction(
|
|
'textColor', elTextTextColorRed, elTextTextColorGreen, elTextTextColorBlue);
|
|
elTextTextColorRed.addEventListener('change', textTextColorChangeFunction);
|
|
elTextTextColorGreen.addEventListener('change', textTextColorChangeFunction);
|
|
elTextTextColorBlue.addEventListener('change', textTextColorChangeFunction);
|
|
colorPickers.push($('#property-text-text-color').colpick({
|
|
colorScheme: 'dark',
|
|
layout: 'hex',
|
|
color: '000000',
|
|
submit: false, // We don't want to have a submission button
|
|
onShow: function(colpick) {
|
|
$('#property-text-text-color').attr('active', 'true');
|
|
},
|
|
onHide: function(colpick) {
|
|
$('#property-text-text-color').attr('active', 'false');
|
|
},
|
|
onChange: function(hsb, hex, rgb, el) {
|
|
$(el).css('background-color', '#' + hex);
|
|
$(el).attr('active', 'false');
|
|
emitColorPropertyUpdate('textColor', rgb.r, rgb.g, rgb.b);
|
|
}
|
|
}));
|
|
|
|
var textBackgroundColorChangeFunction = createEmitColorPropertyUpdateFunction(
|
|
'backgroundColor', elTextBackgroundColorRed, elTextBackgroundColorGreen, elTextBackgroundColorBlue);
|
|
|
|
elTextBackgroundColorRed.addEventListener('change', textBackgroundColorChangeFunction);
|
|
elTextBackgroundColorGreen.addEventListener('change', textBackgroundColorChangeFunction);
|
|
elTextBackgroundColorBlue.addEventListener('change', textBackgroundColorChangeFunction);
|
|
colorPickers.push($('#property-text-background-color').colpick({
|
|
colorScheme: 'dark',
|
|
layout: 'hex',
|
|
color: '000000',
|
|
submit: false, // We don't want to have a submission button
|
|
onShow: function(colpick) {
|
|
$('#property-text-background-color').attr('active', 'true');
|
|
},
|
|
onHide: function(colpick) {
|
|
$('#property-text-background-color').attr('active', 'false');
|
|
},
|
|
onChange: function(hsb, hex, rgb, el) {
|
|
$(el).css('background-color', '#' + hex);
|
|
emitColorPropertyUpdate('backgroundColor', rgb.r, rgb.g, rgb.b);
|
|
}
|
|
}));
|
|
|
|
// Key light
|
|
var keyLightModeChanged = createZoneComponentModeChangedFunction('keyLightMode',
|
|
elZoneKeyLightModeInherit, elZoneKeyLightModeDisabled, elZoneKeyLightModeEnabled);
|
|
|
|
elZoneKeyLightModeInherit.addEventListener('change', keyLightModeChanged);
|
|
elZoneKeyLightModeDisabled.addEventListener('change', keyLightModeChanged);
|
|
elZoneKeyLightModeEnabled.addEventListener('change', keyLightModeChanged);
|
|
|
|
colorPickers.push($('#property-zone-key-light-color').colpick({
|
|
colorScheme: 'dark',
|
|
layout: 'hex',
|
|
color: '000000',
|
|
submit: false, // We don't want to have a submission button
|
|
onShow: function(colpick) {
|
|
$('#property-zone-key-light-color').attr('active', 'true');
|
|
},
|
|
onHide: function(colpick) {
|
|
$('#property-zone-key-light-color').attr('active', 'false');
|
|
},
|
|
onChange: function(hsb, hex, rgb, el) {
|
|
$(el).css('background-color', '#' + hex);
|
|
emitColorPropertyUpdate('color', rgb.r, rgb.g, rgb.b, 'keyLight');
|
|
}
|
|
}));
|
|
var zoneKeyLightColorChangeFunction = createEmitGroupColorPropertyUpdateFunction('keyLight', 'color',
|
|
elZoneKeyLightColorRed, elZoneKeyLightColorGreen, elZoneKeyLightColorBlue);
|
|
|
|
elZoneKeyLightColorRed.addEventListener('change', zoneKeyLightColorChangeFunction);
|
|
elZoneKeyLightColorGreen.addEventListener('change', zoneKeyLightColorChangeFunction);
|
|
elZoneKeyLightColorBlue.addEventListener('change', zoneKeyLightColorChangeFunction);
|
|
elZoneKeyLightIntensity.addEventListener('change',
|
|
createEmitGroupNumberPropertyUpdateFunction('keyLight', 'intensity'));
|
|
|
|
var zoneKeyLightDirectionChangeFunction = createEmitGroupVec3PropertyUpdateFunction('keyLight', 'direction',
|
|
elZoneKeyLightDirectionX, elZoneKeyLightDirectionY);
|
|
|
|
elZoneKeyLightDirectionX.addEventListener('change', zoneKeyLightDirectionChangeFunction);
|
|
elZoneKeyLightDirectionY.addEventListener('change', zoneKeyLightDirectionChangeFunction);
|
|
|
|
// Skybox
|
|
var skyboxModeChanged = createZoneComponentModeChangedFunction('skyboxMode',
|
|
elZoneSkyboxModeInherit, elZoneSkyboxModeDisabled, elZoneSkyboxModeEnabled);
|
|
|
|
elZoneSkyboxModeInherit.addEventListener('change', skyboxModeChanged);
|
|
elZoneSkyboxModeDisabled.addEventListener('change', skyboxModeChanged);
|
|
elZoneSkyboxModeEnabled.addEventListener('change', skyboxModeChanged);
|
|
|
|
// Ambient light
|
|
elCopySkyboxURLToAmbientURL.addEventListener("click", function () {
|
|
document.getElementById("property-zone-key-ambient-url").value = properties.skybox.url;
|
|
properties.ambientLight.ambientURL = properties.skybox.url;
|
|
updateProperties(properties);
|
|
});
|
|
|
|
var ambientLightModeChanged = createZoneComponentModeChangedFunction('ambientLightMode',
|
|
elZoneAmbientLightModeInherit, elZoneAmbientLightModeDisabled, elZoneAmbientLightModeEnabled);
|
|
|
|
elZoneAmbientLightModeInherit.addEventListener('change', ambientLightModeChanged);
|
|
elZoneAmbientLightModeDisabled.addEventListener('change', ambientLightModeChanged);
|
|
elZoneAmbientLightModeEnabled.addEventListener('change', ambientLightModeChanged);
|
|
|
|
elZoneAmbientLightIntensity.addEventListener('change',
|
|
createEmitGroupNumberPropertyUpdateFunction('ambientLight', 'ambientIntensity'));
|
|
|
|
elZoneAmbientLightURL.addEventListener('change',
|
|
createEmitGroupTextPropertyUpdateFunction('ambientLight', 'ambientURL'));
|
|
|
|
// Haze
|
|
var hazeModeChanged = createZoneComponentModeChangedFunction('hazeMode',
|
|
elZoneHazeModeInherit, elZoneHazeModeDisabled, elZoneHazeModeEnabled);
|
|
|
|
elZoneHazeModeInherit.addEventListener('change', hazeModeChanged);
|
|
elZoneHazeModeDisabled.addEventListener('change', hazeModeChanged);
|
|
elZoneHazeModeEnabled.addEventListener('change', hazeModeChanged);
|
|
|
|
elZoneHazeRange.addEventListener('change', createEmitGroupNumberPropertyUpdateFunction('haze', 'hazeRange'));
|
|
|
|
colorPickers.push($('#property-zone-haze-color').colpick({
|
|
colorScheme: 'dark',
|
|
layout: 'hex',
|
|
color: '000000',
|
|
submit: false, // We don't want to have a submission button
|
|
onShow: function(colpick) {
|
|
$('#property-zone-haze-color').attr('active', 'true');
|
|
},
|
|
onHide: function(colpick) {
|
|
$('#property-zone-haze-color').attr('active', 'false');
|
|
},
|
|
onChange: function(hsb, hex, rgb, el) {
|
|
$(el).css('background-color', '#' + hex);
|
|
emitColorPropertyUpdate('hazeColor', rgb.r, rgb.g, rgb.b, 'haze');
|
|
}
|
|
}));
|
|
var zoneHazeColorChangeFunction = createEmitGroupColorPropertyUpdateFunction('haze', 'hazeColor',
|
|
elZoneHazeColorRed,
|
|
elZoneHazeColorGreen,
|
|
elZoneHazeColorBlue);
|
|
|
|
elZoneHazeColorRed.addEventListener('change', zoneHazeColorChangeFunction);
|
|
elZoneHazeColorGreen.addEventListener('change', zoneHazeColorChangeFunction);
|
|
elZoneHazeColorBlue.addEventListener('change', zoneHazeColorChangeFunction);
|
|
|
|
colorPickers.push($('#property-zone-haze-glare-color').colpick({
|
|
colorScheme: 'dark',
|
|
layout: 'hex',
|
|
color: '000000',
|
|
submit: false, // We don't want to have a submission button
|
|
onShow: function(colpick) {
|
|
$('#property-zone-haze-glare-color').attr('active', 'true');
|
|
},
|
|
onHide: function(colpick) {
|
|
$('#property-zone-haze-glare-color').attr('active', 'false');
|
|
},
|
|
onChange: function(hsb, hex, rgb, el) {
|
|
$(el).css('background-color', '#' + hex);
|
|
emitColorPropertyUpdate('hazeGlareColor', rgb.r, rgb.g, rgb.b, 'haze');
|
|
}
|
|
}));
|
|
var zoneHazeGlareColorChangeFunction = createEmitGroupColorPropertyUpdateFunction('haze', 'hazeGlareColor',
|
|
elZoneHazeGlareColorRed,
|
|
elZoneHazeGlareColorGreen,
|
|
elZoneHazeGlareColorBlue);
|
|
|
|
elZoneHazeGlareColorRed.addEventListener('change', zoneHazeGlareColorChangeFunction);
|
|
elZoneHazeGlareColorGreen.addEventListener('change', zoneHazeGlareColorChangeFunction);
|
|
elZoneHazeGlareColorBlue.addEventListener('change', zoneHazeGlareColorChangeFunction);
|
|
|
|
elZoneHazeEnableGlare.addEventListener('change',
|
|
createEmitGroupCheckedPropertyUpdateFunction('haze', 'hazeEnableGlare'));
|
|
elZonehazeGlareAngle.addEventListener('change', createEmitGroupNumberPropertyUpdateFunction('haze', 'hazeGlareAngle'));
|
|
|
|
elZoneHazeAltitudeEffect.addEventListener('change',
|
|
createEmitGroupCheckedPropertyUpdateFunction('haze', 'hazeAltitudeEffect'));
|
|
elZoneHazeCeiling.addEventListener('change', createEmitGroupNumberPropertyUpdateFunction('haze', 'hazeCeiling'));
|
|
elZoneHazeBaseRef.addEventListener('change', createEmitGroupNumberPropertyUpdateFunction('haze', 'hazeBaseRef'));
|
|
|
|
elZoneHazeBackgroundBlend.addEventListener('change',
|
|
createEmitGroupNumberPropertyUpdateFunction('haze', 'hazeBackgroundBlend'));
|
|
|
|
var zoneSkyboxColorChangeFunction = createEmitGroupColorPropertyUpdateFunction('skybox', 'color',
|
|
elZoneSkyboxColorRed, elZoneSkyboxColorGreen, elZoneSkyboxColorBlue);
|
|
elZoneSkyboxColorRed.addEventListener('change', zoneSkyboxColorChangeFunction);
|
|
elZoneSkyboxColorGreen.addEventListener('change', zoneSkyboxColorChangeFunction);
|
|
elZoneSkyboxColorBlue.addEventListener('change', zoneSkyboxColorChangeFunction);
|
|
colorPickers.push($('#property-zone-skybox-color').colpick({
|
|
colorScheme: 'dark',
|
|
layout: 'hex',
|
|
color: '000000',
|
|
submit: false, // We don't want to have a submission button
|
|
onShow: function(colpick) {
|
|
$('#property-zone-skybox-color').attr('active', 'true');
|
|
},
|
|
onHide: function(colpick) {
|
|
$('#property-zone-skybox-color').attr('active', 'false');
|
|
},
|
|
onChange: function(hsb, hex, rgb, el) {
|
|
$(el).css('background-color', '#' + hex);
|
|
emitColorPropertyUpdate('color', rgb.r, rgb.g, rgb.b, 'skybox');
|
|
}
|
|
}));
|
|
|
|
elZoneSkyboxURL.addEventListener('change', createEmitGroupTextPropertyUpdateFunction('skybox', 'url'));
|
|
|
|
elZoneFlyingAllowed.addEventListener('change', createEmitCheckedPropertyUpdateFunction('flyingAllowed'));
|
|
elZoneGhostingAllowed.addEventListener('change', createEmitCheckedPropertyUpdateFunction('ghostingAllowed'));
|
|
elZoneFilterURL.addEventListener('change', createEmitTextPropertyUpdateFunction('filterURL'));
|
|
|
|
var voxelVolumeSizeChangeFunction = createEmitVec3PropertyUpdateFunction(
|
|
'voxelVolumeSize', elVoxelVolumeSizeX, elVoxelVolumeSizeY, elVoxelVolumeSizeZ);
|
|
elVoxelVolumeSizeX.addEventListener('change', voxelVolumeSizeChangeFunction);
|
|
elVoxelVolumeSizeY.addEventListener('change', voxelVolumeSizeChangeFunction);
|
|
elVoxelVolumeSizeZ.addEventListener('change', voxelVolumeSizeChangeFunction);
|
|
elVoxelSurfaceStyle.addEventListener('change', createEmitTextPropertyUpdateFunction('voxelSurfaceStyle'));
|
|
elXTextureURL.addEventListener('change', createEmitTextPropertyUpdateFunction('xTextureURL'));
|
|
elYTextureURL.addEventListener('change', createEmitTextPropertyUpdateFunction('yTextureURL'));
|
|
elZTextureURL.addEventListener('change', createEmitTextPropertyUpdateFunction('zTextureURL'));
|
|
|
|
elMoveSelectionToGrid.addEventListener("click", function() {
|
|
EventBridge.emitWebEvent(JSON.stringify({
|
|
type: "action",
|
|
action: "moveSelectionToGrid"
|
|
}));
|
|
});
|
|
elMoveAllToGrid.addEventListener("click", function() {
|
|
EventBridge.emitWebEvent(JSON.stringify({
|
|
type: "action",
|
|
action: "moveAllToGrid"
|
|
}));
|
|
});
|
|
elResetToNaturalDimensions.addEventListener("click", function() {
|
|
EventBridge.emitWebEvent(JSON.stringify({
|
|
type: "action",
|
|
action: "resetToNaturalDimensions"
|
|
}));
|
|
});
|
|
elRescaleDimensionsButton.addEventListener("click", function() {
|
|
EventBridge.emitWebEvent(JSON.stringify({
|
|
type: "action",
|
|
action: "rescaleDimensions",
|
|
percentage: parseFloat(elRescaleDimensionsPct.value)
|
|
}));
|
|
});
|
|
elReloadScriptsButton.addEventListener("click", function() {
|
|
EventBridge.emitWebEvent(JSON.stringify({
|
|
type: "action",
|
|
action: "reloadClientScripts"
|
|
}));
|
|
});
|
|
elReloadServerScriptsButton.addEventListener("click", function() {
|
|
// invalidate the current status (so that same-same updates can still be observed visually)
|
|
elServerScriptStatus.innerText = '[' + elServerScriptStatus.innerText + ']';
|
|
EventBridge.emitWebEvent(JSON.stringify({
|
|
type: "action",
|
|
action: "reloadServerScripts"
|
|
}));
|
|
});
|
|
|
|
document.addEventListener("keydown", function (keyDown) {
|
|
if (keyDown.keyCode === KEY_P && keyDown.ctrlKey) {
|
|
if (keyDown.shiftKey) {
|
|
EventBridge.emitWebEvent(JSON.stringify({ type: 'unparent' }));
|
|
} else {
|
|
EventBridge.emitWebEvent(JSON.stringify({ type: 'parent' }));
|
|
}
|
|
}
|
|
});
|
|
window.onblur = function() {
|
|
// Fake a change event
|
|
var ev = document.createEvent("HTMLEvents");
|
|
ev.initEvent("change", true, true);
|
|
document.activeElement.dispatchEvent(ev);
|
|
};
|
|
|
|
// For input and textarea elements, select all of the text on focus
|
|
// WebKit-based browsers, such as is used with QWebView, have a quirk
|
|
// where the mouseup event comes after the focus event, causing the
|
|
// text to be deselected immediately after selecting all of the text.
|
|
// To make this work we block the first mouseup event after the elements
|
|
// received focus. If we block all mouseup events the user will not
|
|
// be able to click within the selected text.
|
|
// We also check to see if the value has changed to make sure we aren't
|
|
// blocking a mouse-up event when clicking on an input spinner.
|
|
var els = document.querySelectorAll("input, textarea");
|
|
for (var i = 0; i < els.length; i++) {
|
|
var clicked = false;
|
|
var originalText;
|
|
// TODO FIXME: (JSHint) Functions declared within loops referencing
|
|
// an outer scoped variable may lead to confusing semantics.
|
|
els[i].onfocus = function(e) {
|
|
originalText = this.value;
|
|
this.select();
|
|
clicked = false;
|
|
};
|
|
// TODO FIXME: (JSHint) Functions declared within loops referencing
|
|
// an outer scoped variable may lead to confusing semantics.
|
|
els[i].onmouseup = function(e) {
|
|
if (!clicked && originalText === this.value) {
|
|
e.preventDefault();
|
|
}
|
|
clicked = true;
|
|
};
|
|
}
|
|
bindAllNonJSONEditorElements();
|
|
});
|
|
|
|
// Collapsible sections
|
|
var elCollapsible = document.getElementsByClassName("section-header");
|
|
|
|
var toggleCollapsedEvent = function(event) {
|
|
var element = event.target.parentNode.parentNode;
|
|
var isCollapsed = element.dataset.collapsed !== "true";
|
|
element.dataset.collapsed = isCollapsed ? "true" : false;
|
|
element.setAttribute("collapsed", isCollapsed ? "true" : "false");
|
|
element.getElementsByClassName(".collapse-icon")[0].textContent = isCollapsed ? "L" : "M";
|
|
};
|
|
|
|
for (var collapseIndex = 0, numCollapsibles = elCollapsible.length; collapseIndex < numCollapsibles; ++collapseIndex) {
|
|
var curCollapsibleElement = elCollapsible[collapseIndex];
|
|
curCollapsibleElement.getElementsByTagName('span')[0].addEventListener("click", toggleCollapsedEvent, true);
|
|
}
|
|
|
|
|
|
// Textarea scrollbars
|
|
var elTextareas = document.getElementsByTagName("TEXTAREA");
|
|
|
|
var textareaOnChangeEvent = function(event) {
|
|
setTextareaScrolling(event.target);
|
|
};
|
|
|
|
for (var textAreaIndex = 0, numTextAreas = elTextareas.length; textAreaIndex < numTextAreas; ++textAreaIndex) {
|
|
var curTextAreaElement = elTextareas[textAreaIndex];
|
|
setTextareaScrolling(curTextAreaElement);
|
|
curTextAreaElement.addEventListener("input", textareaOnChangeEvent, false);
|
|
curTextAreaElement.addEventListener("change", textareaOnChangeEvent, false);
|
|
/* FIXME: Detect and update textarea scrolling attribute on resize. Unfortunately textarea doesn't have a resize
|
|
event; mouseup is a partial stand-in but doesn't handle resizing if mouse moves outside textarea rectangle. */
|
|
curTextAreaElement.addEventListener("mouseup", textareaOnChangeEvent, false);
|
|
}
|
|
|
|
// Dropdowns
|
|
// For each dropdown the following replacement is created in place of the original dropdown...
|
|
// Structure created:
|
|
// <dl dropped="true/false">
|
|
// <dt name="?" id="?" value="?"><span>display text</span><span>carat</span></dt>
|
|
// <dd>
|
|
// <ul>
|
|
// <li value="??>display text</li>
|
|
// <li>...</li>
|
|
// </ul>
|
|
// </dd>
|
|
// </dl>
|
|
|
|
function setDropdownText(dropdown) {
|
|
var lis = dropdown.parentNode.getElementsByTagName("li");
|
|
var text = "";
|
|
for (var i = 0; i < lis.length; i++) {
|
|
if (String(lis[i].getAttribute("value")) === String(dropdown.value)) {
|
|
text = lis[i].textContent;
|
|
}
|
|
}
|
|
dropdown.firstChild.textContent = text;
|
|
}
|
|
|
|
function toggleDropdown(event) {
|
|
var element = event.target;
|
|
if (element.nodeName !== "DT") {
|
|
element = element.parentNode;
|
|
}
|
|
element = element.parentNode;
|
|
var isDropped = element.getAttribute("dropped");
|
|
element.setAttribute("dropped", isDropped !== "true" ? "true" : "false");
|
|
}
|
|
|
|
function setDropdownValue(event) {
|
|
var dt = event.target.parentNode.parentNode.previousSibling;
|
|
dt.value = event.target.getAttribute("value");
|
|
dt.firstChild.textContent = event.target.textContent;
|
|
|
|
dt.parentNode.setAttribute("dropped", "false");
|
|
|
|
var evt = document.createEvent("HTMLEvents");
|
|
evt.initEvent("change", true, true);
|
|
dt.dispatchEvent(evt);
|
|
}
|
|
|
|
var elDropdowns = document.getElementsByTagName("select");
|
|
for (var dropDownIndex = 0; dropDownIndex < elDropdowns.length; ++dropDownIndex) {
|
|
var options = elDropdowns[dropDownIndex].getElementsByTagName("option");
|
|
var selectedOption = 0;
|
|
for (var optionIndex = 0; optionIndex < options.length; ++optionIndex) {
|
|
if (options[optionIndex].getAttribute("selected") === "selected") {
|
|
selectedOption = optionIndex;
|
|
// TODO: Shouldn't there be a break here?
|
|
}
|
|
}
|
|
var div = elDropdowns[dropDownIndex].parentNode;
|
|
|
|
var dl = document.createElement("dl");
|
|
div.appendChild(dl);
|
|
|
|
var dt = document.createElement("dt");
|
|
dt.name = elDropdowns[dropDownIndex].name;
|
|
dt.id = elDropdowns[dropDownIndex].id;
|
|
dt.addEventListener("click", toggleDropdown, true);
|
|
dl.appendChild(dt);
|
|
|
|
var span = document.createElement("span");
|
|
span.setAttribute("value", options[selectedOption].value);
|
|
span.textContent = options[selectedOption].firstChild.textContent;
|
|
dt.appendChild(span);
|
|
|
|
var spanCaratDown = document.createElement("span");
|
|
spanCaratDown.textContent = "5"; // caratDn
|
|
dt.appendChild(spanCaratDown);
|
|
|
|
var dd = document.createElement("dd");
|
|
dl.appendChild(dd);
|
|
|
|
var ul = document.createElement("ul");
|
|
dd.appendChild(ul);
|
|
|
|
for (var listOptionIndex = 0; listOptionIndex < options.length; ++listOptionIndex) {
|
|
var li = document.createElement("li");
|
|
li.setAttribute("value", options[listOptionIndex].value);
|
|
li.textContent = options[listOptionIndex].firstChild.textContent;
|
|
li.addEventListener("click", setDropdownValue);
|
|
ul.appendChild(li);
|
|
}
|
|
}
|
|
|
|
elDropdowns = document.getElementsByTagName("select");
|
|
while (elDropdowns.length > 0) {
|
|
var el = elDropdowns[0];
|
|
el.parentNode.removeChild(el);
|
|
elDropdowns = document.getElementsByTagName("select");
|
|
}
|
|
|
|
augmentSpinButtons();
|
|
|
|
setUpKeyboardControl();
|
|
|
|
// Disable right-click context menu which is not visible in the HMD and makes it seem like the app has locked
|
|
document.addEventListener("contextmenu", function(event) {
|
|
event.preventDefault();
|
|
}, false);
|
|
|
|
setTimeout(function() {
|
|
EventBridge.emitWebEvent(JSON.stringify({ type: 'propertiesPageReady' }));
|
|
}, 1000);
|
|
}
|