Merge branch 'master' of https://github.com/highfidelity/hifi into desktopEquip

This commit is contained in:
David Back 2018-04-12 10:17:17 -07:00
commit 09f3b845a8
20 changed files with 234 additions and 96 deletions

View file

@ -4,8 +4,8 @@ set(EXTERNAL_NAME serverless-content)
ExternalProject_Add(
${EXTERNAL_NAME}
URL http://cdn.highfidelity.com/content-sets/serverless-tutorial-RC66-v2.zip
URL_MD5 d76bdb3e2bf7ae5d20115bd97b0c44a8
URL http://cdn.highfidelity.com/content-sets/serverless-tutorial-RC66-v3.zip
URL_MD5 ea608c2e4c90539ab3c1d66acf0e005a
CONFIGURE_COMMAND ""
BUILD_COMMAND ""
INSTALL_COMMAND ""

View file

@ -1234,6 +1234,9 @@ Section "Uninstall"
@CPACK_NSIS_EXTRA_UNINSTALL_COMMANDS@
;Remove the installer information file
Delete "$INSTDIR\installer.ini"
;Remove files we installed.
;Keep the list of directories here in sync with the File commands above.
@CPACK_NSIS_DELETE_FILES@

View file

@ -51,7 +51,24 @@ Rectangle {
onCertificateInfoResult: {
if (result.status !== 'success') {
console.log("Failed to get certificate info", result.message);
console.log("Failed to get certificate info", result.data.message);
// We should still tell the user that static cert verification failed
if (root.certificateStatus !== 3) { // CERTIFICATE_STATUS_STATIC_VERIFICATION_FAILED
root.useGoldCert = false;
root.certTitleTextColor = hifi.colors.redHighlight;
root.certTextColor = hifi.colors.redHighlight;
root.infoTextColor = hifi.colors.redHighlight;
titleBarText.text = "Certificate Unavailable";
popText.text = "";
showInMarketplaceButton.visible = false;
root.certInfoReplaceMode = 0;
root.itemName = "";
root.itemEdition = "";
root.itemOwner = "";
root.dateOfPurchase = "";
root.itemCost = "";
errorText.text = "Information about this certificate is currently unavailable. Please try again later.";
}
} else {
root.marketplaceUrl = result.data.marketplace_item_url;
root.isMyCert = result.isMyCert ? result.isMyCert : false;

View file

@ -447,6 +447,9 @@ Menu::Menu() {
textureGroup->addAction(addCheckableActionToQMenuAndActionHash(textureMenu, MenuOption::RenderMaxTexture512MB, 0, false));
textureGroup->addAction(addCheckableActionToQMenuAndActionHash(textureMenu, MenuOption::RenderMaxTexture1024MB, 0, false));
textureGroup->addAction(addCheckableActionToQMenuAndActionHash(textureMenu, MenuOption::RenderMaxTexture2048MB, 0, false));
textureGroup->addAction(addCheckableActionToQMenuAndActionHash(textureMenu, MenuOption::RenderMaxTexture4096MB, 0, false));
textureGroup->addAction(addCheckableActionToQMenuAndActionHash(textureMenu, MenuOption::RenderMaxTexture6144MB, 0, false));
textureGroup->addAction(addCheckableActionToQMenuAndActionHash(textureMenu, MenuOption::RenderMaxTexture8192MB, 0, false));
connect(textureGroup, &QActionGroup::triggered, [textureGroup] {
auto checked = textureGroup->checkedAction();
auto text = checked->text();
@ -463,6 +466,12 @@ Menu::Menu() {
newMaxTextureMemory = MB_TO_BYTES(1024);
} else if (MenuOption::RenderMaxTexture2048MB == text) {
newMaxTextureMemory = MB_TO_BYTES(2048);
} else if (MenuOption::RenderMaxTexture4096MB == text) {
newMaxTextureMemory = MB_TO_BYTES(4096);
} else if (MenuOption::RenderMaxTexture6144MB == text) {
newMaxTextureMemory = MB_TO_BYTES(6144);
} else if (MenuOption::RenderMaxTexture8192MB == text) {
newMaxTextureMemory = MB_TO_BYTES(8192);
}
gpu::Texture::setAllowedGPUMemoryUsage(newMaxTextureMemory);
});

View file

@ -155,6 +155,10 @@ namespace MenuOption {
const QString RenderMaxTexture512MB = "512 MB";
const QString RenderMaxTexture1024MB = "1024 MB";
const QString RenderMaxTexture2048MB = "2048 MB";
const QString RenderMaxTexture3072MB = "3072 MB";
const QString RenderMaxTexture4096MB = "4096 MB";
const QString RenderMaxTexture6144MB = "6144 MB";
const QString RenderMaxTexture8192MB = "8192 MB";
const QString RenderResolution = "Scale Resolution";
const QString RenderResolutionOne = "1";
const QString RenderResolutionTwoThird = "2/3";

View file

@ -35,12 +35,19 @@ QJsonObject Ledger::apiResponse(const QString& label, QNetworkReply& reply) {
QJsonObject Ledger::failResponse(const QString& label, QNetworkReply& reply) {
QString response = reply.readAll();
qWarning(commerce) << "FAILED" << label << response;
QJsonObject result
{
{ "status", "fail" },
{ "message", response }
};
return result;
// tempResult will be NULL if the response isn't valid JSON.
QJsonDocument tempResult = QJsonDocument::fromJson(response.toLocal8Bit());
if (tempResult.isNull()) {
QJsonObject result
{
{ "status", "fail" },
{ "message", response }
};
return result;
} else {
return tempResult.object();
}
}
#define ApiHandler(NAME) void Ledger::NAME##Success(QNetworkReply& reply) { emit NAME##Result(apiResponse(#NAME, reply)); }
#define FailHandler(NAME) void Ledger::NAME##Failure(QNetworkReply& reply) { emit NAME##Result(failResponse(#NAME, reply)); }
@ -337,7 +344,9 @@ void Ledger::certificateInfoSuccess(QNetworkReply& reply) {
qInfo(commerce) << "certificateInfo" << "response" << QJsonDocument(replyObject).toJson(QJsonDocument::Compact);
emit certificateInfoResult(replyObject);
}
void Ledger::certificateInfoFailure(QNetworkReply& reply) { failResponse("certificateInfo", reply); }
void Ledger::certificateInfoFailure(QNetworkReply& reply) {
emit certificateInfoResult(failResponse("certificateInfo", reply));
}
void Ledger::certificateInfo(const QString& certificateId) {
QString endpoint = "proof_of_purchase_status/transfer";
QJsonObject request;

View file

@ -15,6 +15,11 @@
#include <QObject>
#include <QString>
/**jsdoc
* The Settings API provides a facility to store and retrieve values that persist between Interface runs.
* @namespace Settings
*/
class SettingsScriptingInterface : public QObject {
Q_OBJECT
SettingsScriptingInterface() { };
@ -22,8 +27,37 @@ public:
static SettingsScriptingInterface* getInstance();
public slots:
/**jsdoc
* Retrieve the value from a named setting.
* @function Settings.getValue
* @param {string} key - The name of the setting.
* @param {string|number|boolean|object} [defaultValue=""] - The value to return if the setting doesn't exist.
* @returns {string|number|boolean|object} The value stored in the named setting if it exists, otherwise the
* <code>defaultValue</code>.
* @example <caption>Retrieve non-existent setting values.</caption>
* var value1 = Settings.getValue("Script Example/Nonexistent Key");
* print("Value: " + (typeof value1) + " " + JSON.stringify(value1)); // string ""
*
* var value2 = Settings.getValue("Script Example/Nonexistent Key", true);
* print("Value: " + (typeof value2) + " " + JSON.stringify(value2)); // boolean true
*/
QVariant getValue(const QString& setting);
QVariant getValue(const QString& setting, const QVariant& defaultValue);
/**jsdoc
* Store a value in a named setting. If the setting already exists its value is overwritten, otherwise a new setting is
* created. If the value is set to <code>null</code> or <code>undefined</code>, the setting is deleted.
* @function Settings.setValue
* @param {string} key - The name of the setting. Be sure to use a unique name if creating a new setting.
* @param {string|number|boolean|object|undefined} value - The value to store in the setting. If <code>null</code> or
* <code>undefined</code> is specified, the setting is deleted.
* @example <caption>Store and retrieve an object value.</caption>
* Settings.setValue("Script Example/My Key", { x: 0, y: 10, z: 0 });
*
* var value = Settings.getValue("Script Example/My Key");
* print("Value: " + (typeof value) + " " + JSON.stringify(value)); // object {"x":0,"y":10,"z":0}
*/
void setValue(const QString& setting, const QVariant& value);
};

View file

@ -51,7 +51,7 @@ WindowScriptingInterface::WindowScriptingInterface() {
}
});
connect(qApp->getWindow(), &MainWindow::windowGeometryChanged, this, &WindowScriptingInterface::geometryChanged);
connect(qApp->getWindow(), &MainWindow::windowGeometryChanged, this, &WindowScriptingInterface::onWindowGeometryChanged);
}
WindowScriptingInterface::~WindowScriptingInterface() {
@ -390,11 +390,22 @@ glm::vec2 WindowScriptingInterface::getDeviceSize() const {
}
int WindowScriptingInterface::getX() {
return qApp->getWindow()->x();
return qApp->getWindow()->geometry().x();
}
int WindowScriptingInterface::getY() {
return qApp->getWindow()->y();
auto menu = qApp->getPrimaryMenu();
int menuHeight = menu ? menu->geometry().height() : 0;
return qApp->getWindow()->geometry().y() + menuHeight;
}
void WindowScriptingInterface::onWindowGeometryChanged(const QRect& windowGeometry) {
auto geometry = windowGeometry;
auto menu = qApp->getPrimaryMenu();
if (menu) {
geometry.setY(geometry.y() + menu->geometry().height());
}
emit geometryChanged(geometry);
}
void WindowScriptingInterface::copyToClipboard(const QString& text) {

View file

@ -33,8 +33,10 @@
* @property {number} innerHeight - The height of the drawable area of the Interface window (i.e., without borders or other
* chrome), in pixels. <em>Read-only.</em>
* @property {object} location - Provides facilities for working with your current metaverse location. See {@link location}.
* @property {number} x - The x coordinate of the top left corner of the Interface window on the display. <em>Read-only.</em>
* @property {number} y - The y coordinate of the top left corner of the Interface window on the display. <em>Read-only.</em>
* @property {number} x - The x display coordinate of the top left corner of the drawable area of the Interface window.
* <em>Read-only.</em>
* @property {number} y - The y display coordinate of the top left corner of the drawable area of the Interface window.
* <em>Read-only.</em>
*/
class WindowScriptingInterface : public QObject, public Dependency {
@ -522,6 +524,7 @@ public slots:
void closeMessageBox(int id);
private slots:
void onWindowGeometryChanged(const QRect& geometry);
void onMessageBoxSelected(int button);
void disconnectedFromDomain();

View file

@ -20,7 +20,8 @@
#include <AbstractViewStateInterface.h>
const int FIXED_FONT_POINT_SIZE = 40;
const int FIXED_FONT_SCALING_RATIO = FIXED_FONT_POINT_SIZE * 80.0f; // this is a ratio determined through experimentation
const int FIXED_FONT_SCALING_RATIO = FIXED_FONT_POINT_SIZE * 92.0f; // Determined through experimentation to fit font to line
// height.
const float LINE_SCALE_RATIO = 1.2f;
QString const Text3DOverlay::TYPE = "text3d";

View file

@ -128,6 +128,7 @@ namespace controller {
makeButtonPair(Action::TOGGLE_MUTE, "ToggleMute"),
makeButtonPair(Action::CYCLE_CAMERA, "CycleCamera"),
makeButtonPair(Action::TOGGLE_OVERLAY, "ToggleOverlay"),
makeButtonPair(Action::SPRINT, "Sprint"),
makeAxisPair(Action::RETICLE_CLICK, "ReticleClick"),
makeAxisPair(Action::RETICLE_X, "ReticleX"),

View file

@ -62,7 +62,7 @@ EntityItem::EntityItem(const EntityItemID& entityItemID) :
EntityItem::~EntityItem() {
// these pointers MUST be correct at delete, else we probably have a dangling backpointer
// to this EntityItem in the corresponding data structure.
assert(!_simulated);
assert(!_simulated || (!_element && !_physicsInfo));
assert(!_element);
assert(!_physicsInfo);
}

View file

@ -502,6 +502,12 @@ inline QDebug operator<<(QDebug debug, const EntityItemProperties& properties) {
DEBUG_PROPERTY_IF_CHANGED(debug, properties, CertificateID, certificateID, "");
DEBUG_PROPERTY_IF_CHANGED(debug, properties, StaticCertificateVersion, staticCertificateVersion, "");
DEBUG_PROPERTY_IF_CHANGED(debug, properties, LocalPosition, localPosition, "");
DEBUG_PROPERTY_IF_CHANGED(debug, properties, LocalRotation, localRotation, "");
DEBUG_PROPERTY_IF_CHANGED(debug, properties, LocalVelocity, localVelocity, "");
DEBUG_PROPERTY_IF_CHANGED(debug, properties, LocalAngularVelocity, localAngularVelocity, "");
DEBUG_PROPERTY_IF_CHANGED(debug, properties, LocalDimensions, localDimensions, "");
DEBUG_PROPERTY_IF_CHANGED(debug, properties, HazeMode, hazeMode, "");
DEBUG_PROPERTY_IF_CHANGED(debug, properties, KeyLightMode, keyLightMode, "");
DEBUG_PROPERTY_IF_CHANGED(debug, properties, AmbientLightMode, ambientLightMode, "");

View file

@ -477,6 +477,27 @@ QUuid EntityScriptingInterface::editEntity(QUuid id, const EntityItemProperties&
}
}
});
} else {
// Sometimes ESS don't have the entity they are trying to edit in their local tree. In this case,
// convertPropertiesFromScriptSemantics doesn't get called and local* edits will get dropped.
// This is because, on the script side, "position" is in world frame, but in the network
// protocol and in the internal data-structures, "position" is "relative to parent".
// Compensate here. The local* versions will get ignored during the edit-packet encoding.
if (properties.localPositionChanged()) {
properties.setPosition(properties.getLocalPosition());
}
if (properties.localRotationChanged()) {
properties.setRotation(properties.getLocalRotation());
}
if (properties.localVelocityChanged()) {
properties.setVelocity(properties.getLocalVelocity());
}
if (properties.localAngularVelocityChanged()) {
properties.setAngularVelocity(properties.getLocalAngularVelocity());
}
if (properties.localDimensionsChanged()) {
properties.setDimensions(properties.getLocalDimensions());
}
}
});
if (!entityFound) {

View file

@ -158,7 +158,6 @@ void PhysicalEntitySimulation::clearEntitiesInternal() {
EntityMotionState* motionState = static_cast<EntityMotionState*>(&(*stateItr));
assert(motionState);
EntityItemPointer entity = motionState->getEntity();
entity->setPhysicsInfo(nullptr);
// TODO: someday when we invert the entities/physics lib dependencies we can let EntityItem delete its own PhysicsInfo
// until then we must do it here
delete motionState;

View file

@ -79,12 +79,12 @@ void MainWindow::closeEvent(QCloseEvent* event) {
}
void MainWindow::moveEvent(QMoveEvent* event) {
emit windowGeometryChanged(QRect(event->pos(), size()));
emit windowGeometryChanged(QRect(QPoint(geometry().x(), geometry().y()), size())); // Geometry excluding the window frame.
QMainWindow::moveEvent(event);
}
void MainWindow::resizeEvent(QResizeEvent* event) {
emit windowGeometryChanged(QRect(QPoint(x(), y()), event->size()));
emit windowGeometryChanged(QRect(QPoint(geometry().x(), geometry().y()), size())); // Geometry excluding the window frame.
QMainWindow::resizeEvent(event);
}

View file

@ -116,11 +116,19 @@ var MENU_EASE_ON_FOCUS = "Ease Orientation on Focus";
var MENU_SHOW_LIGHTS_AND_PARTICLES_IN_EDIT_MODE = "Show Lights and Particle Systems in Create Mode";
var MENU_SHOW_ZONES_IN_EDIT_MODE = "Show Zones in Create Mode";
var MENU_CREATE_ENTITIES_GRABBABLE = "Create Entities As Grabbable (except Zones, Particles, and Lights)";
var MENU_ALLOW_SELECTION_LARGE = "Allow Selecting of Large Models";
var MENU_ALLOW_SELECTION_SMALL = "Allow Selecting of Small Models";
var MENU_ALLOW_SELECTION_LIGHTS = "Allow Selecting of Lights";
var SETTING_AUTO_FOCUS_ON_SELECT = "autoFocusOnSelect";
var SETTING_EASE_ON_FOCUS = "cameraEaseOnFocus";
var SETTING_SHOW_LIGHTS_AND_PARTICLES_IN_EDIT_MODE = "showLightsAndParticlesInEditMode";
var SETTING_SHOW_ZONES_IN_EDIT_MODE = "showZonesInEditMode";
var SETTING_EDIT_PREFIX = "Edit/";
var CREATE_ENABLED_ICON = "icons/tablet-icons/edit-i.svg";
var CREATE_DISABLED_ICON = "icons/tablet-icons/edit-disabled.svg";
@ -226,7 +234,7 @@ function adjustPositionPerBoundingBox(position, direction, registration, dimensi
var TOOLS_PATH = Script.resolvePath("assets/images/tools/");
var GRABBABLE_ENTITIES_MENU_CATEGORY = "Edit";
var GRABBABLE_ENTITIES_MENU_ITEM = "Create Entities As Grabbable (except Zones, Particles, and Lights)";
var toolBar = (function () {
var EDIT_SETTING = "io.highfidelity.isEditing"; // for communication with other scripts
@ -280,7 +288,7 @@ var toolBar = (function () {
position = grid.snapToSurface(grid.snapToGrid(position, false, dimensions), dimensions);
properties.position = position;
if (Menu.isOptionChecked(GRABBABLE_ENTITIES_MENU_ITEM) &&
if (Menu.isOptionChecked(MENU_CREATE_ENTITIES_GRABBABLE) &&
!(properties.type === "Zone" || properties.type === "Light" || properties.type === "ParticleEffect")) {
properties.userData = JSON.stringify({ grabbableKey: { grabbable: true } });
} else {
@ -338,7 +346,6 @@ var toolBar = (function () {
if (systemToolbar) {
systemToolbar.removeButton(EDIT_TOGGLE_BUTTON);
}
Menu.removeMenuItem(GRABBABLE_ENTITIES_MENU_CATEGORY, GRABBABLE_ENTITIES_MENU_ITEM);
}
var buttonHandlers = {}; // only used to tablet mode
@ -1143,34 +1150,35 @@ function setupModelMenus() {
Menu.addMenuItem({
menuName: GRABBABLE_ENTITIES_MENU_CATEGORY,
menuItemName: GRABBABLE_ENTITIES_MENU_ITEM,
menuItemName: MENU_CREATE_ENTITIES_GRABBABLE,
afterItem: "Unparent Entity",
isCheckable: true,
isChecked: true,
isChecked: Settings.getValue(SETTING_EDIT_PREFIX + MENU_CREATE_ENTITIES_GRABBABLE, true),
grouping: "Advanced"
});
Menu.addMenuItem({
menuName: "Edit",
menuItemName: "Allow Selecting of Large Models",
afterItem: GRABBABLE_ENTITIES_MENU_ITEM,
menuItemName: MENU_ALLOW_SELECTION_LARGE,
afterItem: MENU_CREATE_ENTITIES_GRABBABLE,
isCheckable: true,
isChecked: true,
isChecked: Settings.getValue(SETTING_EDIT_PREFIX + MENU_ALLOW_SELECTION_LARGE, true),
grouping: "Advanced"
});
Menu.addMenuItem({
menuName: "Edit",
menuItemName: "Allow Selecting of Small Models",
afterItem: "Allow Selecting of Large Models",
menuItemName: MENU_ALLOW_SELECTION_SMALL,
afterItem: MENU_ALLOW_SELECTION_LARGE,
isCheckable: true,
isChecked: true,
isChecked: Settings.getValue(SETTING_EDIT_PREFIX + MENU_ALLOW_SELECTION_SMALL, true),
grouping: "Advanced"
});
Menu.addMenuItem({
menuName: "Edit",
menuItemName: "Allow Selecting of Lights",
afterItem: "Allow Selecting of Small Models",
menuItemName: MENU_ALLOW_SELECTION_LIGHTS,
afterItem: MENU_ALLOW_SELECTION_SMALL,
isCheckable: true,
isChecked: Settings.getValue(SETTING_EDIT_PREFIX + MENU_ALLOW_SELECTION_LIGHTS, false),
grouping: "Advanced"
});
Menu.addMenuItem({
@ -1275,6 +1283,12 @@ Script.scriptEnding.connect(function () {
Settings.setValue(SETTING_SHOW_LIGHTS_AND_PARTICLES_IN_EDIT_MODE, Menu.isOptionChecked(MENU_SHOW_LIGHTS_AND_PARTICLES_IN_EDIT_MODE));
Settings.setValue(SETTING_SHOW_ZONES_IN_EDIT_MODE, Menu.isOptionChecked(MENU_SHOW_ZONES_IN_EDIT_MODE));
Settings.setValue(SETTING_EDIT_PREFIX + MENU_CREATE_ENTITIES_GRABBABLE, Menu.isOptionChecked(MENU_CREATE_ENTITIES_GRABBABLE));
Settings.setValue(SETTING_EDIT_PREFIX + MENU_ALLOW_SELECTION_LARGE, Menu.isOptionChecked(MENU_ALLOW_SELECTION_LARGE));
Settings.setValue(SETTING_EDIT_PREFIX + MENU_ALLOW_SELECTION_SMALL, Menu.isOptionChecked(MENU_ALLOW_SELECTION_SMALL));
Settings.setValue(SETTING_EDIT_PREFIX + MENU_ALLOW_SELECTION_LIGHTS, Menu.isOptionChecked(GRABBABLE_ENTITIES_MENU_ITEM));
progressDialog.cleanup();
cleanupModelMenus();
tooltip.cleanup();

View file

@ -2,15 +2,7 @@ var GRID_CONTROLS_HTML_URL = Script.resolvePath('../html/gridControls.html');
Grid = function(opts) {
var that = {};
var colors = [
{ red: 0, green: 0, blue: 0 },
{ red: 255, green: 255, blue: 255 },
{ red: 255, green: 0, blue: 0 },
{ red: 0, green: 255, blue: 0 },
{ red: 0, green: 0, blue: 255 },
];
var colorIndex = 0;
var gridColor = { red: 0, green: 0, blue: 0 };
var gridAlpha = 0.6;
var origin = { x: 0, y: +MyAvatar.getJointPosition('LeftToeBase').y.toFixed(1) + 0.1, z: 0 };
var scale = 500;
@ -28,10 +20,10 @@ Grid = function(opts) {
position: origin,
visible: false,
drawInFront: false,
color: colors[0],
color: gridColor,
alpha: gridAlpha,
minorGridEvery: minorGridEvery,
majorGridEvery: majorGridEvery,
majorGridEvery: majorGridEvery
});
that.visible = false;
@ -39,26 +31,38 @@ Grid = function(opts) {
that.getOrigin = function() {
return origin;
}
};
that.getMinorIncrement = function() {
return minorGridEvery;
};
that.getMinorIncrement = function() { return minorGridEvery; };
that.setMinorIncrement = function(value) {
minorGridEvery = value;
updateGrid();
}
that.getMajorIncrement = function() { return majorGridEvery; };
};
that.getMajorIncrement = function() {
return majorGridEvery;
};
that.setMajorIncrement = function(value) {
majorGridEvery = value;
updateGrid();
};
that.getColorIndex = function() { return colorIndex; };
that.setColorIndex = function(value) {
colorIndex = value;
that.getColor = function() {
return gridColor;
};
that.setColor = function(value) {
gridColor = value;
updateGrid();
};
that.getSnapToGrid = function() { return snapToGrid; };
that.getSnapToGrid = function() {
return snapToGrid;
};
that.setSnapToGrid = function(value) {
snapToGrid = value;
that.emitUpdate();
@ -67,9 +71,11 @@ Grid = function(opts) {
that.setEnabled = function(enabled) {
that.enabled = enabled;
updateGrid();
}
};
that.getVisible = function() { return that.visible; };
that.getVisible = function() {
return that.visible;
};
that.setVisible = function(visible, noUpdate) {
that.visible = visible;
updateGrid();
@ -77,7 +83,7 @@ Grid = function(opts) {
if (!noUpdate) {
that.emitUpdate();
}
}
};
that.snapToSurface = function(position, dimensions, registration) {
if (!snapToGrid) {
@ -97,7 +103,7 @@ Grid = function(opts) {
y: origin.y + (registration.y * dimensions.y),
z: position.z
};
}
};
that.snapToGrid = function(position, majorOnly, dimensions, registration) {
if (!snapToGrid) {
@ -121,7 +127,7 @@ Grid = function(opts) {
position.z = Math.round(position.z / spacing) * spacing;
return Vec3.sum(Vec3.sum(position, Vec3.multiplyVbyV(registration, dimensions)), origin);
}
};
that.snapToSpacing = function(delta, majorOnly) {
if (!snapToGrid) {
@ -133,11 +139,11 @@ Grid = function(opts) {
var snappedDelta = {
x: Math.round(delta.x / spacing) * spacing,
y: Math.round(delta.y / spacing) * spacing,
z: Math.round(delta.z / spacing) * spacing,
z: Math.round(delta.z / spacing) * spacing
};
return snappedDelta;
}
};
that.setPosition = function(newPosition, noUpdate) {
@ -157,7 +163,7 @@ Grid = function(opts) {
majorGridEvery: majorGridEvery,
gridSize: halfSize,
visible: that.visible,
snapToGrid: snapToGrid,
snapToGrid: snapToGrid
});
}
};
@ -183,8 +189,8 @@ Grid = function(opts) {
majorGridEvery = data.majorGridEvery;
}
if (data.colorIndex !== undefined) {
colorIndex = data.colorIndex;
if (data.gridColor) {
gridColor = data.gridColor;
}
if (data.gridSize) {
@ -196,7 +202,7 @@ Grid = function(opts) {
}
updateGrid(true);
}
};
function updateGrid(noUpdate) {
Overlays.editOverlay(gridOverlay, {
@ -204,8 +210,8 @@ Grid = function(opts) {
visible: that.visible && that.enabled,
minorGridEvery: minorGridEvery,
majorGridEvery: majorGridEvery,
color: colors[colorIndex],
alpha: gridAlpha,
color: gridColor,
alpha: gridAlpha
});
if (!noUpdate) {
@ -219,7 +225,7 @@ Grid = function(opts) {
that.addListener = function(callback) {
that.onUpdate = callback;
}
};
Script.scriptEnding.connect(cleanup);
updateGrid();
@ -238,7 +244,7 @@ GridTool = function(opts) {
var webView = null;
webView = Tablet.getTablet("com.highfidelity.interface.tablet.system");
webView.setVisible = function(value) {};
webView.setVisible = function(value) { };
horizontalGrid.addListener(function(data) {
webView.emitScriptEvent(JSON.stringify(data));
@ -250,8 +256,8 @@ GridTool = function(opts) {
webView.webEventReceived.connect(function(data) {
try {
data = JSON.parse(data);
} catch(e) {
print("gridTool.js: Error parsing JSON: " + e.name + " data " + data)
} catch (e) {
print("gridTool.js: Error parsing JSON: " + e.name + " data " + data);
return;
}
@ -280,11 +286,11 @@ GridTool = function(opts) {
that.addListener = function(callback) {
listeners.push(callback);
}
};
that.setVisible = function(visible) {
webView.setVisible(visible);
}
};
return that;
};

View file

@ -12,9 +12,9 @@
Script.include("/~/system/libraries/utils.js");
if (!String.prototype.startsWith) {
String.prototype.startsWith = function(searchString, position){
position = position || 0;
return this.substr(position, searchString.length) === searchString;
};
position = position || 0;
return this.substr(position, searchString.length) === searchString;
};
}
var SETTING_KEY = "com.highfidelity.avatar.isSitting";
@ -122,20 +122,10 @@
this.rolesToOverride = function() {
return MyAvatar.getAnimationRoles().filter(function(role) {
return !(role.startsWith("right") || role.startsWith("left"));
return !(role.startsWith("right") || role.startsWith("left"));
});
}
// Handler for user changing the avatar model while sitting. There's currently an issue with changing avatar models while override role animations are applied,
// so to avoid that problem, re-apply the role overrides once the model has finished changing.
this.modelURLChangeFinished = function () {
print("Sitter's model has FINISHED changing. Reapply anim role overrides.");
var roles = this.rolesToOverride();
for (i in roles) {
MyAvatar.overrideRoleAnimation(roles[i], ANIMATION_URL, ANIMATION_FPS, true, ANIMATION_FIRST_FRAME, ANIMATION_LAST_FRAME);
}
}
this.sitDown = function() {
if (this.checkSeatForAvatar()) {
print("Someone is already sitting in that chair.");
@ -155,11 +145,11 @@
MyAvatar.characterControllerEnabled = false;
MyAvatar.hmdLeanRecenterEnabled = false;
var roles = this.rolesToOverride();
for (i in roles) {
for (var i = 0; i < roles.length; i++) {
MyAvatar.overrideRoleAnimation(roles[i], ANIMATION_URL, ANIMATION_FPS, true, ANIMATION_FIRST_FRAME, ANIMATION_LAST_FRAME);
}
for (var i in OVERRIDEN_DRIVE_KEYS) {
for (i = 0; i < OVERRIDEN_DRIVE_KEYS.length; i++) {
MyAvatar.disableDriveKey(OVERRIDEN_DRIVE_KEYS[i]);
}
@ -174,14 +164,12 @@
return { headType: 0 };
}, ["headType"]);
Script.update.connect(this, this.update);
MyAvatar.onLoadComplete.connect(this, this.modelURLChangeFinished);
}
this.standUp = function() {
print("Standing up (" + this.entityID + ")");
MyAvatar.removeAnimationStateHandler(this.animStateHandlerID);
Script.update.disconnect(this, this.update);
MyAvatar.onLoadComplete.disconnect(this, this.modelURLChangeFinished);
if (MyAvatar.sessionUUID === this.getSeatUser()) {
this.setSeatUser(null);
@ -190,12 +178,12 @@
if (Settings.getValue(SETTING_KEY) === this.entityID) {
Settings.setValue(SETTING_KEY, "");
for (var i in OVERRIDEN_DRIVE_KEYS) {
for (var i = 0; i < OVERRIDEN_DRIVE_KEYS.length; i++) {
MyAvatar.enableDriveKey(OVERRIDEN_DRIVE_KEYS[i]);
}
var roles = this.rolesToOverride();
for (i in roles) {
for (i = 0; i < roles.length; i++) {
MyAvatar.restoreRoleAnimation(roles[i]);
}
MyAvatar.characterControllerEnabled = true;
@ -272,7 +260,7 @@
// Check if a drive key is pressed
var hasActiveDriveKey = false;
for (var i in OVERRIDEN_DRIVE_KEYS) {
if (MyAvatar.getRawDriveKey(OVERRIDEN_DRIVE_KEYS[i]) != 0.0) {
if (MyAvatar.getRawDriveKey(OVERRIDEN_DRIVE_KEYS[i]) !== 0.0) {
hasActiveDriveKey = true;
break;
}
@ -343,7 +331,7 @@
}
this.cleanupOverlay();
}
this.clickDownOnEntity = function (id, event) {
if (isInEditMode()) {
return;
@ -352,4 +340,4 @@
this.sitDown();
}
}
});
});

View file

@ -1,6 +1,16 @@
import os, json, sys, shutil, subprocess, shlex, time
EXE = os.environ['HIFI_OVEN']
def getRelativePath(path1, path2, stop):
parts1 = path1.split('/');
parts2 = path2.split('/');
if len(parts1) <= len(parts2):
for part in parts1:
if part != stop and part != '':
index = parts2.index(part)
parts2.pop(index)
return os.path.join(*parts2)
def listFiles(directory, extension):
items = os.listdir(directory)
fileList = []
@ -44,18 +54,20 @@ def bakeFile(filePath, outputDirectory):
groupKTXFiles(outputDirectory, bakedFile)
def bakeFilesInDirectory(directory, outputDirectory):
rootDirectory = os.path.basename(os.path.normpath(directory))
for root, subFolders, filenames in os.walk(directory):
for filename in filenames:
appendPath = getRelativePath(directory, root, rootDirectory);
if filename.endswith('.fbx'):
filePath = os.sep.join([root, filename])
absFilePath = os.path.abspath(filePath)
outputFolder = os.path.join(outputDirectory, os.path.relpath(root))
outputFolder = os.path.join(outputDirectory, appendPath)
print "Baking file: " + filename
bakeFile(absFilePath, outputFolder)
else:
filePath = os.sep.join([root, filename])
absFilePath = os.path.abspath(filePath)
outputFolder = os.path.join(outputDirectory, os.path.relpath(root))
outputFolder = os.path.join(outputDirectory, appendPath)
newFilePath = os.sep.join([outputFolder, filename])
createDirectory(outputFolder)
print "moving file: " + filename + " to: " + outputFolder