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

This commit is contained in:
Elisa Lupin-Jimenez 2017-07-27 10:00:17 -07:00
commit 1c640cf37b
17 changed files with 336 additions and 43 deletions

View file

@ -1,42 +1,45 @@
This is a stand-alone guide for creating your first High Fidelity build for Windows 64-bit.
## Building High Fidelity
Note: We are now using Visual Studio 2017 and Qt 5.9.1. If you are upgrading from Visual Studio 2013 and Qt 5.6.2, do a clean uninstall of those versions before going through this guide.
### Step 1. Installing Visual Studio 2013
Note: The prerequisites will require about 10 GB of space on your drive.
If you don't already have the Community or Professional edition of Visual Studio 2013, download and install [Visual Studio Community 2013](https://www.visualstudio.com/en-us/news/releasenotes/vs2013-community-vs). You do not need to install any of the optional components when going through the installer.
### Step 1. Visual Studio 2017
Note: Newer versions of Visual Studio are not yet compatible.
If you dont have Community or Professional edition of Visual Studio 2017, download [Visual Studio Community 2017](https://www.visualstudio.com/downloads/).
When selecting components, check "Desktop development with C++." Also check "Windows 8.1 SDK and UCRT SDK" and "VC++ 2015.3 v140 toolset (x86,x64)" on the Summary toolbar on the right.
### Step 2. Installing CMake
Download and install the [CMake 3.8.0 win64-x64 Installer](https://cmake.org/files/v3.8/cmake-3.8.0-win64-x64.msi). Make sure "Add CMake to system PATH for all users" is checked when going through the installer.
Download and install the latest version of CMake 3.9. Download the file named win64-x64 Installer from the [CMake Website](https://cmake.org/download/). Make sure to check "Add CMake to system PATH for all users" when prompted during installation.
### Step 3. Installing Qt
Download and install the [Qt 5.6.2 for Windows 64-bit (VS 2013)](http://download.qt.io/official_releases/qt/5.6/5.6.2/qt-opensource-windows-x86-msvc2013_64-5.6.2.exe).
Download and install the [Qt Online Installer](https://www.qt.io/download-open-source/?hsCtaTracking=f977210e-de67-475f-a32b-65cec207fd03%7Cd62710cd-e1db-46aa-8d4d-2f1c1ffdacea). While installing, you only need to have the following components checked under Qt 5.9.1: "msvc2017 64-bit", "Qt WebEngine", and "Qt Script (Deprecated)".
Keep the default components checked when going through the installer.
Note: Installing the Sources is optional but recommended if you have room for them (~2GB).
### Step 4. Setting Qt Environment Variable
Go to `Control Panel > System > Advanced System Settings > Environment Variables > New...` (or search “Environment Variables” in Start Search).
* Set "Variable name": `QT_CMAKE_PREFIX_PATH`
* Set "Variable value": `%QT_DIR%\5.6\msvc2013_64\lib\cmake`
* Set "Variable value": `C:\Qt\5.9.1\msvc2017_64\lib\cmake`
### Step 5. Installing OpenSSL
Download and install the [Win64 OpenSSL v1.0.2L Installer](https://slproweb.com/download/Win64OpenSSL-1_0_2L.exe).
Download and install the Win64 OpenSSL v1.0.2 Installer[https://slproweb.com/products/Win32OpenSSL.html].
### Step 6. Running CMake to Generate Build Files
Run Command Prompt from Start and run the following commands:
````
```
cd "%HIFI_DIR%"
mkdir build
cd build
cmake .. -G "Visual Studio 12 Win64"
````
cmake .. -G "Visual Studio 15 Win64"
```
Where `%HIFI_DIR%` is the directory for the highfidelity repository.
@ -72,14 +75,6 @@ For any problems after Step #6, first try this:
Remove `CMakeCache.txt` found in the `%HIFI_DIR%\build` directory.
#### nmake cannot be found
Make sure nmake.exe is located at the following path:
C:\Program Files (x86)\Microsoft Visual Studio 12.0\VC\bin
If not, add the directory where nmake is located to the PATH environment variable.
#### Qt is throwing an error
Make sure you have the correct version (5.6.2) installed and `QT_CMAKE_PREFIX_PATH` environment variable is set correctly.
Make sure you have the correct version (5.9.1) installed and `QT_CMAKE_PREFIX_PATH` environment variable is set correctly.

View file

@ -1,6 +1,15 @@
{
"name": "Vive to Standard",
"channels": [
{ "from": "Vive.LY", "to": "Standard.LeftIndexPoint",
"peek": true,
"filters": [ { "type": "hysteresis", "min": 0.7, "max": 0.75 } ]
},
{ "from": "Vive.RY", "to": "Standard.RightIndexPoint",
"peek": true,
"filters": [ { "type": "hysteresis", "min": 0.7, "max": 0.75 } ]
},
{ "from": "Vive.LY", "when": "Vive.LSY", "filters": ["invert"], "to": "Standard.LY" },
{ "from": "Vive.LX", "when": "Vive.LSX", "to": "Standard.LX" },
{
@ -13,6 +22,10 @@
{ "from": "Vive.LeftGrip", "to": "Standard.LeftGrip" },
{ "from": "Vive.LS", "to": "Standard.LS" },
{ "from": "Vive.LSTouch", "to": "Standard.LeftThumbUp",
"peek": true,
"filters": [ { "type": "logicalNot" } ]
},
{ "from": "Vive.LSTouch", "to": "Standard.LSTouch" },
{ "from": "Vive.RY", "when": "Vive.RSY", "filters": ["invert"], "to": "Standard.RY" },
@ -27,6 +40,10 @@
{ "from": "Vive.RightGrip", "to": "Standard.RightGrip" },
{ "from": "Vive.RS", "to": "Standard.RS" },
{ "from": "Vive.RSTouch", "to": "Standard.RightThumbUp",
"peek": true,
"filters": [ { "type": "logicalNot" } ]
},
{ "from": "Vive.RSTouch", "to": "Standard.RSTouch" },
{ "from": "Vive.LSCenter", "to": "Standard.LeftPrimaryThumb" },
@ -59,7 +76,7 @@
{ "from": "Vive.Head", "to" : "Standard.Head"},
{ "from": "Vive.RightArm", "to" : "Standard.RightArm"},
{ "from": "Vive.LeftArm", "to" : "Standard.LeftArm"}
{ "from": "Vive.RightArm", "to" : "Standard.RightArm" },
{ "from": "Vive.LeftArm", "to" : "Standard.LeftArm" }
]
}

View file

@ -151,13 +151,17 @@ ScrollingWindow {
var SHAPE_TYPE_SIMPLE_HULL = 1;
var SHAPE_TYPE_SIMPLE_COMPOUND = 2;
var SHAPE_TYPE_STATIC_MESH = 3;
var SHAPE_TYPE_BOX = 4;
var SHAPE_TYPE_SPHERE = 5;
var SHAPE_TYPES = [];
SHAPE_TYPES[SHAPE_TYPE_NONE] = "No Collision";
SHAPE_TYPES[SHAPE_TYPE_SIMPLE_HULL] = "Basic - Whole model";
SHAPE_TYPES[SHAPE_TYPE_SIMPLE_COMPOUND] = "Good - Sub-meshes";
SHAPE_TYPES[SHAPE_TYPE_STATIC_MESH] = "Exact - All polygons";
SHAPE_TYPES[SHAPE_TYPE_BOX] = "Box";
SHAPE_TYPES[SHAPE_TYPE_SPHERE] = "Sphere";
var SHAPE_TYPE_DEFAULT = SHAPE_TYPE_STATIC_MESH;
var DYNAMIC_DEFAULT = false;
var prompt = desktop.customInputDialog({
@ -196,6 +200,12 @@ ScrollingWindow {
case SHAPE_TYPE_STATIC_MESH:
shapeType = "static-mesh";
break;
case SHAPE_TYPE_BOX:
shapeType = "box";
break;
case SHAPE_TYPE_SPHERE:
shapeType = "sphere";
break;
default:
shapeType = "none";
}

View file

@ -152,13 +152,17 @@ Rectangle {
var SHAPE_TYPE_SIMPLE_HULL = 1;
var SHAPE_TYPE_SIMPLE_COMPOUND = 2;
var SHAPE_TYPE_STATIC_MESH = 3;
var SHAPE_TYPE_BOX = 4;
var SHAPE_TYPE_SPHERE = 5;
var SHAPE_TYPES = [];
SHAPE_TYPES[SHAPE_TYPE_NONE] = "No Collision";
SHAPE_TYPES[SHAPE_TYPE_SIMPLE_HULL] = "Basic - Whole model";
SHAPE_TYPES[SHAPE_TYPE_SIMPLE_COMPOUND] = "Good - Sub-meshes";
SHAPE_TYPES[SHAPE_TYPE_STATIC_MESH] = "Exact - All polygons";
SHAPE_TYPES[SHAPE_TYPE_BOX] = "Box";
SHAPE_TYPES[SHAPE_TYPE_SPHERE] = "Sphere";
var SHAPE_TYPE_DEFAULT = SHAPE_TYPE_STATIC_MESH;
var DYNAMIC_DEFAULT = false;
var prompt = tabletRoot.customInputDialog({
@ -197,6 +201,12 @@ Rectangle {
case SHAPE_TYPE_STATIC_MESH:
shapeType = "static-mesh";
break;
case SHAPE_TYPE_BOX:
shapeType = "box";
break;
case SHAPE_TYPE_SPHERE:
shapeType = "sphere";
break;
default:
shapeType = "none";
}

View file

@ -145,7 +145,9 @@ Rectangle {
model: ["No Collision",
"Basic - Whole model",
"Good - Sub-meshes",
"Exact - All polygons"]
"Exact - All polygons",
"Box",
"Sphere"]
}
Row {

View file

@ -3034,7 +3034,9 @@ void Application::keyPressEvent(QKeyEvent* event) {
break;
case Qt::Key_F: {
_physicsEngine->dumpNextStats();
if (isOption) {
_physicsEngine->dumpNextStats();
}
break;
}
@ -4474,27 +4476,31 @@ void Application::cameraModeChanged() {
void Application::cameraMenuChanged() {
if (Menu::getInstance()->isOptionChecked(MenuOption::FullscreenMirror)) {
if (_myCamera.getMode() != CAMERA_MODE_MIRROR) {
auto menu = Menu::getInstance();
if (menu->isOptionChecked(MenuOption::FullscreenMirror)) {
if (isHMDMode()) {
menu->setIsOptionChecked(MenuOption::FullscreenMirror, false);
menu->setIsOptionChecked(MenuOption::FirstPerson, true);
} else if (_myCamera.getMode() != CAMERA_MODE_MIRROR) {
_myCamera.setMode(CAMERA_MODE_MIRROR);
}
} else if (Menu::getInstance()->isOptionChecked(MenuOption::FirstPerson)) {
} else if (menu->isOptionChecked(MenuOption::FirstPerson)) {
if (_myCamera.getMode() != CAMERA_MODE_FIRST_PERSON) {
_myCamera.setMode(CAMERA_MODE_FIRST_PERSON);
getMyAvatar()->setBoomLength(MyAvatar::ZOOM_MIN);
}
} else if (Menu::getInstance()->isOptionChecked(MenuOption::ThirdPerson)) {
} else if (menu->isOptionChecked(MenuOption::ThirdPerson)) {
if (_myCamera.getMode() != CAMERA_MODE_THIRD_PERSON) {
_myCamera.setMode(CAMERA_MODE_THIRD_PERSON);
if (getMyAvatar()->getBoomLength() == MyAvatar::ZOOM_MIN) {
getMyAvatar()->setBoomLength(MyAvatar::ZOOM_DEFAULT);
}
}
} else if (Menu::getInstance()->isOptionChecked(MenuOption::IndependentMode)) {
} else if (menu->isOptionChecked(MenuOption::IndependentMode)) {
if (_myCamera.getMode() != CAMERA_MODE_INDEPENDENT) {
_myCamera.setMode(CAMERA_MODE_INDEPENDENT);
}
} else if (Menu::getInstance()->isOptionChecked(MenuOption::CameraEntityMode)) {
} else if (menu->isOptionChecked(MenuOption::CameraEntityMode)) {
if (_myCamera.getMode() != CAMERA_MODE_ENTITY) {
_myCamera.setMode(CAMERA_MODE_ENTITY);
}

View file

@ -222,19 +222,19 @@ Menu::Menu() {
cameraModeGroup->setExclusive(true);
// View > First Person
cameraModeGroup->addAction(addCheckableActionToQMenuAndActionHash(viewMenu,
MenuOption::FirstPerson, 0,
true, qApp, SLOT(cameraMenuChanged())));
cameraModeGroup->addAction(addCheckableActionToQMenuAndActionHash(
viewMenu, MenuOption::FirstPerson, Qt::CTRL | Qt::Key_F,
true, qApp, SLOT(cameraMenuChanged())));
// View > Third Person
cameraModeGroup->addAction(addCheckableActionToQMenuAndActionHash(viewMenu,
MenuOption::ThirdPerson, 0,
false, qApp, SLOT(cameraMenuChanged())));
cameraModeGroup->addAction(addCheckableActionToQMenuAndActionHash(
viewMenu, MenuOption::ThirdPerson, Qt::CTRL | Qt::Key_G,
false, qApp, SLOT(cameraMenuChanged())));
// View > Mirror
cameraModeGroup->addAction(addCheckableActionToQMenuAndActionHash(viewMenu,
MenuOption::FullscreenMirror, 0,
false, qApp, SLOT(cameraMenuChanged())));
cameraModeGroup->addAction(addCheckableActionToQMenuAndActionHash(
viewMenu, MenuOption::FullscreenMirror, Qt::CTRL | Qt::Key_H,
false, qApp, SLOT(cameraMenuChanged())));
// View > Independent [advanced]
cameraModeGroup->addAction(addCheckableActionToQMenuAndActionHash(viewMenu,

View file

@ -22,6 +22,7 @@
#include "filters/DeadZoneFilter.h"
#include "filters/HysteresisFilter.h"
#include "filters/InvertFilter.h"
#include "filters/NotFilter.h"
#include "filters/PulseFilter.h"
#include "filters/ScaleFilter.h"
#include "filters/TranslateFilter.h"
@ -40,6 +41,7 @@ REGISTER_FILTER_CLASS_INSTANCE(ConstrainToPositiveIntegerFilter, "constrainToPos
REGISTER_FILTER_CLASS_INSTANCE(DeadZoneFilter, "deadZone")
REGISTER_FILTER_CLASS_INSTANCE(HysteresisFilter, "hysteresis")
REGISTER_FILTER_CLASS_INSTANCE(InvertFilter, "invert")
REGISTER_FILTER_CLASS_INSTANCE(NotFilter, "logicalNot")
REGISTER_FILTER_CLASS_INSTANCE(ScaleFilter, "scale")
REGISTER_FILTER_CLASS_INSTANCE(PulseFilter, "pulse")
REGISTER_FILTER_CLASS_INSTANCE(TranslateFilter, "translate")

View file

@ -24,6 +24,7 @@
#include "filters/DeadZoneFilter.h"
#include "filters/HysteresisFilter.h"
#include "filters/InvertFilter.h"
#include "filters/NotFilter.h"
#include "filters/PulseFilter.h"
#include "filters/ScaleFilter.h"
#include "filters/TranslateFilter.h"
@ -148,6 +149,11 @@ QObject* RouteBuilderProxy::pulse(float interval) {
return this;
}
QObject* RouteBuilderProxy::logicalNot() {
addFilter(std::make_shared<NotFilter>());
return this;
}
void RouteBuilderProxy::addFilter(Filter::Pointer filter) {
_route->filters.push_back(filter);
}

View file

@ -53,6 +53,7 @@ class RouteBuilderProxy : public QObject {
Q_INVOKABLE QObject* postTransform(glm::mat4 transform);
Q_INVOKABLE QObject* rotate(glm::quat rotation);
Q_INVOKABLE QObject* lowVelocity(float rotationConstant, float translationConstant);
Q_INVOKABLE QObject* logicalNot();
private:
void to(const Endpoint::Pointer& destination);

View file

@ -0,0 +1,10 @@
#include "NotFilter.h"
using namespace controller;
NotFilter::NotFilter() {
}
float NotFilter::apply(float value) const {
return (value == 0.0f) ? 1.0f : 0.0f;
}

View file

@ -0,0 +1,21 @@
#pragma once
#ifndef hifi_Controllers_Filters_Not_h
#define hifi_Controllers_Filters_Not_h
#include "../Filter.h"
namespace controller {
class NotFilter : public Filter {
REGISTER_FILTER_CLASS(NotFilter);
public:
NotFilter();
virtual float apply(float value) const override;
virtual Pose apply(Pose value) const override { return value; }
};
}
#endif

View file

@ -337,6 +337,8 @@ var toolBar = (function () {
var SHAPE_TYPE_SIMPLE_HULL = 1;
var SHAPE_TYPE_SIMPLE_COMPOUND = 2;
var SHAPE_TYPE_STATIC_MESH = 3;
var SHAPE_TYPE_BOX = 4;
var SHAPE_TYPE_SPHERE = 5;
var DYNAMIC_DEFAULT = false;
function handleNewModelDialogResult(result) {
@ -353,6 +355,12 @@ var toolBar = (function () {
case SHAPE_TYPE_STATIC_MESH:
shapeType = "static-mesh";
break;
case SHAPE_TYPE_BOX:
shapeType = "box";
break;
case SHAPE_TYPE_SPHERE:
shapeType = "sphere";
break;
default:
shapeType = "none";
}
@ -450,6 +458,8 @@ var toolBar = (function () {
SHAPE_TYPES[SHAPE_TYPE_SIMPLE_HULL] = "Basic - Whole model";
SHAPE_TYPES[SHAPE_TYPE_SIMPLE_COMPOUND] = "Good - Sub-meshes";
SHAPE_TYPES[SHAPE_TYPE_STATIC_MESH] = "Exact - All polygons";
SHAPE_TYPES[SHAPE_TYPE_BOX] = "Box";
SHAPE_TYPES[SHAPE_TYPE_SPHERE] = "Sphere";
var SHAPE_TYPE_DEFAULT = SHAPE_TYPE_STATIC_MESH;
// tablet version of new-model dialog
@ -654,6 +664,7 @@ var toolBar = (function () {
selectionDisplay.triggerMapping.enable();
print("starting tablet in landscape mode");
tablet.landscape = true;
entityIconOverlayManager.setIconsSelectable(null,false);
// Not sure what the following was meant to accomplish, but it currently causes
// everybody else to think that Interface has lost focus overall. fogbugzid:558
// Window.setFocus();
@ -981,6 +992,7 @@ function mouseClickEvent(event) {
} else {
selectionManager.addEntity(foundEntity, true);
}
if (wantDebug) {
print("Model selected: " + foundEntity);
}

View file

@ -1,6 +1,7 @@
/* globals EntityIconOverlayManager:true */
EntityIconOverlayManager = function(entityTypes, getOverlayPropertiesFunc) {
var visible = false;
// List of all created overlays
@ -69,6 +70,29 @@ EntityIconOverlayManager = function(entityTypes, getOverlayPropertiesFunc) {
}
};
this.setIconsSelectable = function(arrayOfSelectedEntityIDs, isIconsSelectable) {
if (arrayOfSelectedEntityIDs === null) {
for (var id in entityOverlays) {
Overlays.editOverlay(entityOverlays[id], {
ignoreRayIntersection: isIconsSelectable
});
}
} else {
for (var id in entityOverlays) {
if (arrayOfSelectedEntityIDs.indexOf(id) !== -1) { // in the entityOverlays array and selectable
Overlays.editOverlay(entityOverlays[id], {
ignoreRayIntersection: isIconsSelectable
});
} else {
Overlays.editOverlay(entityOverlays[id], {
ignoreRayIntersection: !isIconsSelectable
});
}
}
}
};
// Allocate or get an unused overlay
function getOverlay() {
var overlay;
@ -114,6 +138,9 @@ EntityIconOverlayManager = function(entityTypes, getOverlayPropertiesFunc) {
overlayProperties[key] = customProperties[key];
}
}
if(properties.type === 'ParticleEffect' || properties.type === 'Light'){
overlayProperties.ignoreRayIntersection = true;
}
Overlays.editOverlay(overlay, overlayProperties);
}
}

View file

@ -4060,6 +4060,8 @@ SelectionDisplay = (function() {
return false;
}
entityIconOverlayManager.setIconsSelectable(selectionManager.selections,true);
// ignore ray intersection for our selection box and yaw/pitch/roll
result = Overlays.findRayIntersection(pickRay, true, null, [ yawHandle, pitchHandle, rollHandle, selectionBox ] );
if (result.intersects) {

View file

@ -0,0 +1,91 @@
"use strict";
//
// createDart.js
//
// Created by MrRoboman on 17/05/04
// Copyright 2017 High Fidelity, Inc.
//
// Creates five throwing darts.
//
// Distributed under the Apache License, Version 2.0.
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
var MODEL_URL = "https://hifi-content.s3.amazonaws.com/wadewatts/dart.fbx";
var SCRIPT_URL = Script.resolvePath("./dart.js?v=" + Date.now());
var START_POSITION = Vec3.sum(MyAvatar.position, Vec3.multiply(Quat.getFront(MyAvatar.orientation), 0.75));
var START_ROTATION = MyAvatar.orientation
var SCALE_FACTOR = 1;
var dart = {
type: "Model",
shapeType: "box",
name: "Dart",
description: "Throw it at something!",
script: SCRIPT_URL,
modelURL: MODEL_URL,
position: START_POSITION,
rotation: START_ROTATION,
lifetime: 300,
gravity: {
x: 0,
y: -9.8,
z: 0
},
dimensions: {
x: 0.1,
y: 0.1,
z: 0.3
},
dynamic: true,
owningAvatarID: MyAvatar.sessionUUID,
userData: JSON.stringify({
grabbableKey: {
grabbable: true,
invertSolidWhileHeld: true,
ignoreIK: false
}
})
};
var avatarUp = Quat.getUp(MyAvatar.orientation);
var platformPosition = Vec3.sum(START_POSITION, Vec3.multiply(avatarUp, -0.05));
var platform = {
type: "Box",
name: "Dart Platform",
description: "Holds darts",
position: platformPosition,
rotation: START_ROTATION,
lifetime: 60,
dimensions: {
x: 0.15 * 5,
y: 0.01,
z: 0.3
},
color: {
red: 129,
green: 92,
blue: 11
},
owningAvatarID: MyAvatar.sessionUUID,
userData: JSON.stringify({
grabbableKey: {
grabbable: true,
invertSolidWhileHeld: true,
ignoreIK: false
}
})
};
Entities.addEntity(platform);
var dartCount = 5;
var avatarRight = Quat.getRight(MyAvatar.orientation);
for (var i = 0; i < dartCount; i++) {
var j = i - Math.floor(dartCount / 2);
var position = Vec3.sum(START_POSITION, Vec3.multiply(avatarRight, 0.15 * j));
dart.position = position;
Entities.addEntity(dart);
}
Script.stop();

View file

@ -0,0 +1,81 @@
"use strict";
//
// dart.js
//
// Created by MrRoboman on 17/05/13
// Copyright 2017 High Fidelity, Inc.
//
// Simple throwing dart. Sticks to static objects.
//
// Distributed under the Apache License, Version 2.0.
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
(function() {
var THROW_FACTOR = 3;
var DART_SOUND_URL = Script.resolvePath('https://hifi-content.s3.amazonaws.com/wadewatts/dart.wav?v=' + Date.now());
var Dart = function() {};
Dart.prototype = {
preload: function(entityID) {
this.entityID = entityID;
this.actionID = null;
this.soundHasPlayed = true;
this.dartSound = SoundCache.getSound(DART_SOUND_URL);
},
playDartSound: function(sound) {
if (this.soundHasPlayed) {
return;
}
this.soundHasPlayed = true;
var position = Entities.getEntityProperties(this.entityID, 'position').position;
var audioProperties = {
volume: 0.15,
position: position
};
Audio.playSound(this.dartSound, audioProperties);
},
releaseGrab: function() {
this.soundHasPlayed = false;
var velocity = Entities.getEntityProperties(this.entityID, 'velocity').velocity;
var newVelocity = {};
Object.keys(velocity).forEach(function(key) {
newVelocity[key] = velocity[key] * THROW_FACTOR;
});
Entities.editEntity(this.entityID, {
velocity: newVelocity
});
if (this.actionID) {
Entities.deleteAction(this.entityID, this.actionID);
}
this.actionID = Entities.addAction("travel-oriented", this.entityID, {
forward: { x: 0, y: 0, z: 1 },
angularTimeScale: 0.1,
tag: "throwing dart",
ttl: 3600
});
},
collisionWithEntity: function(myID, otherID, collisionInfo) {
this.playDartSound();
Entities.editEntity(myID, {
velocity: {x: 0, y: 0, z: 0},
angularVelocity: {x: 0, y: 0, z: 0}
});
if (this.actionID) {
Entities.deleteAction(myID, this.actionID);
this.actionID = null;
}
}
};
return new Dart();
});