mirror of
https://github.com/overte-org/overte.git
synced 2025-04-20 01:24:03 +02:00
Merge branch 'master' of github.com:highfidelity/hifi into assignment-client-exits
This commit is contained in:
commit
3c2894adb3
13 changed files with 287 additions and 26 deletions
4
BUILD.md
4
BUILD.md
|
@ -2,8 +2,8 @@
|
|||
|
||||
* [cmake](http://www.cmake.org/cmake/resources/software.html) ~> 2.8.12.2
|
||||
* [Qt](http://www.qt.io/download-open-source) ~> 5.4.1
|
||||
* [OpenSSL](https://www.openssl.org/related/binaries.html) ~> 1.0.1g
|
||||
* IMPORTANT: OpenSSL 1.0.1g is critical to avoid a security vulnerability.
|
||||
* [OpenSSL](https://www.openssl.org/related/binaries.html) ~> 1.0.1m
|
||||
* IMPORTANT: Using the recommended version of OpenSSL is critical to avoid security vulnerabilities.
|
||||
* [VHACD](https://github.com/virneo/v-hacd)(clone this repository)(Optional)
|
||||
|
||||
####CMake External Project Dependencies
|
||||
|
|
|
@ -71,7 +71,7 @@ Your system may already have several versions of the OpenSSL DLL's (ssleay32.dll
|
|||
|
||||
To prevent these problems, install OpenSSL yourself. Download the following binary packages [from this website](http://slproweb.com/products/Win32OpenSSL.html):
|
||||
* Visual C++ 2008 Redistributables
|
||||
* Win32 OpenSSL v1.0.1L
|
||||
* Win32 OpenSSL v1.0.1m
|
||||
|
||||
Install OpenSSL into the Windows system directory, to make sure that Qt uses the version that you've just installed, and not some other version.
|
||||
|
||||
|
|
|
@ -18,3 +18,4 @@ Script.load("lobby.js");
|
|||
Script.load("notifications.js");
|
||||
Script.load("look.js");
|
||||
Script.load("users.js");
|
||||
Script.load("grab.js");
|
||||
|
|
223
examples/grab.js
Normal file
223
examples/grab.js
Normal file
|
@ -0,0 +1,223 @@
|
|||
var isGrabbing = false;
|
||||
var grabbedEntity = null;
|
||||
var prevMouse = {};
|
||||
var deltaMouse = {
|
||||
z: 0
|
||||
}
|
||||
var entityProps;
|
||||
var box, box2, ground;
|
||||
var baseMoveFactor = .001;
|
||||
var finalMoveMultiplier;
|
||||
var avatarEntityDistance;
|
||||
var camYaw, dv;
|
||||
var prevPosition;
|
||||
var newPosition;
|
||||
var flingVelocity;
|
||||
var flingMultiplier = 10;
|
||||
var moveUpDown = false;
|
||||
var savedGravity;
|
||||
|
||||
var DROP_DISTANCE = 5.0;
|
||||
var DROP_COLOR = {
|
||||
red: 200,
|
||||
green: 200,
|
||||
blue: 200
|
||||
};
|
||||
var DROP_WIDTH = 4;
|
||||
|
||||
|
||||
var autoBox = false;
|
||||
if (autoBox) {
|
||||
setUpTestObjects();
|
||||
}
|
||||
|
||||
var dropLine = Overlays.addOverlay("line3d", {
|
||||
start: {
|
||||
x: 0,
|
||||
y: 0,
|
||||
z: 0
|
||||
},
|
||||
end: {
|
||||
x: 0,
|
||||
y: 0,
|
||||
z: 0
|
||||
},
|
||||
color: DROP_COLOR,
|
||||
alpha: 1,
|
||||
visible: false,
|
||||
lineWidth: DROP_WIDTH
|
||||
});
|
||||
|
||||
|
||||
function mousePressEvent(event) {
|
||||
var pickRay = Camera.computePickRay(event.x, event.y);
|
||||
var intersection = Entities.findRayIntersection(pickRay);
|
||||
if (intersection.intersects && intersection.properties.collisionsWillMove) {
|
||||
grabbedEntity = intersection.entityID;
|
||||
var props = Entities.getEntityProperties(grabbedEntity)
|
||||
prevPosition = props.position;
|
||||
isGrabbing = true;
|
||||
savedGravity = props.gravity;
|
||||
Overlays.editOverlay(dropLine, {
|
||||
visible: true
|
||||
});
|
||||
Entities.editEntity(grabbedEntity, {
|
||||
gravity: {
|
||||
x: 0,
|
||||
y: 0,
|
||||
z: 0
|
||||
}
|
||||
});
|
||||
//We need to store entity's current gravity, and then disable it while we move
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
function mouseReleaseEvent() {
|
||||
if (isGrabbing) {
|
||||
flingObject();
|
||||
Entities.editEntity(grabbedEntity, {
|
||||
gravity: savedGravity
|
||||
});
|
||||
}
|
||||
isGrabbing = false;
|
||||
Overlays.editOverlay(dropLine, {
|
||||
visible: false
|
||||
});
|
||||
}
|
||||
|
||||
function flingObject() {
|
||||
//calculate velocity to give object base on current and previous position
|
||||
entityProps = Entities.getEntityProperties(grabbedEntity);
|
||||
|
||||
flingVelocity = Vec3.subtract(entityProps.position, prevPosition);
|
||||
flingVelocity = Vec3.multiply(flingMultiplier, flingVelocity);
|
||||
flingVelocity.y = 0;
|
||||
Entities.editEntity(grabbedEntity, {
|
||||
velocity: flingVelocity
|
||||
});
|
||||
}
|
||||
|
||||
function mouseMoveEvent(event) {
|
||||
if (isGrabbing) {
|
||||
entityProps = Entities.getEntityProperties(grabbedEntity);
|
||||
prevPosition = entityProps.position;
|
||||
avatarEntityDistance = Vec3.distance(MyAvatar.position, entityProps.position);
|
||||
finalMoveMultiplier = baseMoveFactor * Math.pow(avatarEntityDistance, 1.5);
|
||||
deltaMouse.x = event.x - prevMouse.x;
|
||||
if (!moveUpDown) {
|
||||
deltaMouse.z = event.y - prevMouse.y;
|
||||
} else {
|
||||
deltaMouse.y = (event.y - prevMouse.y) * -1;
|
||||
}
|
||||
finalMoveMultiplier = baseMoveFactor * Math.pow(avatarEntityDistance, 1.5);
|
||||
deltaMouse = Vec3.multiply(deltaMouse, finalMoveMultiplier);
|
||||
camYaw = Quat.safeEulerAngles(Camera.getOrientation()).y;
|
||||
dv = Vec3.multiplyQbyV(Quat.fromPitchYawRollDegrees(0, camYaw, 0), deltaMouse);
|
||||
newPosition = Vec3.sum(entityProps.position, dv);
|
||||
Entities.editEntity(grabbedEntity, {
|
||||
position: newPosition
|
||||
});
|
||||
Overlays.editOverlay(dropLine, {
|
||||
start: newPosition,
|
||||
end: Vec3.sum(newPosition, {
|
||||
x: 0,
|
||||
y: -DROP_DISTANCE,
|
||||
z: 0
|
||||
})
|
||||
});
|
||||
}
|
||||
prevMouse.x = event.x;
|
||||
prevMouse.y = event.y;
|
||||
}
|
||||
|
||||
function keyReleaseEvent(event) {
|
||||
if (event.text === "SHIFT") {
|
||||
moveUpDown = false;
|
||||
}
|
||||
}
|
||||
|
||||
function keyPressEvent(event) {
|
||||
if (event.text === "SHIFT") {
|
||||
moveUpDown = true;
|
||||
}
|
||||
}
|
||||
|
||||
function cleanup() {
|
||||
Entities.deleteEntity(box);
|
||||
Entities.deleteEntity(box2);
|
||||
Entities.deleteEntity(ground);
|
||||
}
|
||||
|
||||
function setUpTestObjects() {
|
||||
var distance = 4;
|
||||
box = Entities.addEntity({
|
||||
type: 'Box',
|
||||
position: Vec3.sum(MyAvatar.position, Vec3.multiply(distance, Quat.getFront(Camera.getOrientation()))),
|
||||
dimensions: {
|
||||
x: .5,
|
||||
y: .5,
|
||||
z: .5
|
||||
},
|
||||
color: {
|
||||
red: 200,
|
||||
green: 50,
|
||||
blue: 192
|
||||
},
|
||||
collisionsWillMove: true,
|
||||
gravity: {
|
||||
x: 0,
|
||||
y: -1,
|
||||
z: 0
|
||||
}
|
||||
});
|
||||
|
||||
box2 = Entities.addEntity({
|
||||
type: 'Box',
|
||||
position: Vec3.sum(MyAvatar.position, Vec3.multiply(distance + 1, Quat.getFront(Camera.getOrientation()))),
|
||||
dimensions: {
|
||||
x: .5,
|
||||
y: .5,
|
||||
z: .5
|
||||
},
|
||||
color: {
|
||||
red: 200,
|
||||
green: 50,
|
||||
blue: 192
|
||||
},
|
||||
collisionsWillMove: true,
|
||||
gravity: {
|
||||
x: 0,
|
||||
y: -1,
|
||||
z: 0
|
||||
}
|
||||
});
|
||||
|
||||
ground = Entities.addEntity({
|
||||
type: 'Box',
|
||||
position: {
|
||||
x: MyAvatar.position.x,
|
||||
y: MyAvatar.position.y - 5,
|
||||
z: MyAvatar.position.z
|
||||
},
|
||||
dimensions: {
|
||||
x: 100,
|
||||
y: 2,
|
||||
z: 100
|
||||
},
|
||||
color: {
|
||||
red: 20,
|
||||
green: 200,
|
||||
blue: 50
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
Controller.mouseMoveEvent.connect(mouseMoveEvent);
|
||||
Controller.mousePressEvent.connect(mousePressEvent);
|
||||
Controller.mouseReleaseEvent.connect(mouseReleaseEvent);
|
||||
Controller.keyPressEvent.connect(keyPressEvent);
|
||||
Controller.keyReleaseEvent.connect(keyReleaseEvent);
|
||||
Script.scriptEnding.connect(cleanup);
|
|
@ -285,9 +285,6 @@ Menu::Menu() {
|
|||
addCheckableActionToQMenuAndActionHash(viewMenu, MenuOption::OffAxisProjection, 0, false);
|
||||
addCheckableActionToQMenuAndActionHash(viewMenu, MenuOption::TurnWithHead, 0, false);
|
||||
|
||||
|
||||
addCheckableActionToQMenuAndActionHash(viewMenu, MenuOption::Stats,
|
||||
0); // QML Qt::Key_Slash);
|
||||
addCheckableActionToQMenuAndActionHash(viewMenu, MenuOption::Stats);
|
||||
addActionToQMenuAndActionHash(viewMenu, MenuOption::Log,
|
||||
Qt::CTRL | Qt::SHIFT | Qt::Key_L,
|
||||
|
@ -397,6 +394,10 @@ Menu::Menu() {
|
|||
QAction* ddeFiltering = addCheckableActionToQMenuAndActionHash(faceTrackingMenu, MenuOption::VelocityFilter, 0, true);
|
||||
ddeFiltering->setVisible(false);
|
||||
#endif
|
||||
|
||||
auto avatarManager = DependencyManager::get<AvatarManager>();
|
||||
addCheckableActionToQMenuAndActionHash(avatarDebugMenu, MenuOption::AvatarReceiveStats, 0, false,
|
||||
avatarManager.data(), SLOT(setShouldShowReceiveStats(bool)));
|
||||
|
||||
addCheckableActionToQMenuAndActionHash(avatarDebugMenu, MenuOption::RenderSkeletonCollisionShapes);
|
||||
addCheckableActionToQMenuAndActionHash(avatarDebugMenu, MenuOption::RenderHeadCollisionShapes);
|
||||
|
|
|
@ -147,6 +147,7 @@ namespace MenuOption {
|
|||
const QString AudioScopeTwentyFrames = "Twenty";
|
||||
const QString AudioStats = "Audio Stats";
|
||||
const QString AudioStatsShowInjectedStreams = "Audio Stats Show Injected Streams";
|
||||
const QString AvatarReceiveStats = "Show Receive Stats";
|
||||
const QString BandwidthDetails = "Bandwidth Details";
|
||||
const QString BlueSpeechSphere = "Blue Sphere While Speaking";
|
||||
const QString BookmarkLocation = "Bookmark Location";
|
||||
|
|
|
@ -581,7 +581,8 @@ void Avatar::renderBillboard() {
|
|||
glm::vec2 texCoordTopLeft(0.0f, 0.0f);
|
||||
glm::vec2 texCoordBottomRight(1.0f, 1.0f);
|
||||
|
||||
DependencyManager::get<GeometryCache>()->renderQuad(topLeft, bottomRight, texCoordTopLeft, texCoordBottomRight, glm::vec4(1.0f, 1.0f, 1.0f, 1.0f));
|
||||
DependencyManager::get<GeometryCache>()->renderQuad(topLeft, bottomRight, texCoordTopLeft, texCoordBottomRight,
|
||||
glm::vec4(1.0f, 1.0f, 1.0f, 1.0f));
|
||||
|
||||
glPopMatrix();
|
||||
|
||||
|
@ -709,11 +710,24 @@ void Avatar::renderDisplayName() {
|
|||
glm::vec4(0.2f, 0.2f, 0.2f, _displayNameAlpha * DISPLAYNAME_BACKGROUND_ALPHA / DISPLAYNAME_ALPHA));
|
||||
|
||||
glm::vec4 color(0.93f, 0.93f, 0.93f, _displayNameAlpha);
|
||||
|
||||
// optionally render timing stats for this avatar with the display name
|
||||
QString renderedDisplayName = _displayName;
|
||||
|
||||
if (DependencyManager::get<AvatarManager>()->shouldShowReceiveStats()) {
|
||||
const float BYTES_PER_KILOBYTE = 1000.0f;
|
||||
float kilobytesPerSecond = getAverageBytesReceivedPerSecond() / BYTES_PER_KILOBYTE;
|
||||
|
||||
renderedDisplayName += QString(" - (%1 KBps, %2 Hz)")
|
||||
.arg(QString::number(kilobytesPerSecond, 'f', 2))
|
||||
.arg(getReceiveRate());
|
||||
}
|
||||
|
||||
QByteArray ba = _displayName.toLocal8Bit();
|
||||
const char* text = ba.data();
|
||||
|
||||
glDisable(GL_POLYGON_OFFSET_FILL);
|
||||
textRenderer(DISPLAYNAME)->draw(text_x, text_y, text, color);
|
||||
textRenderer(DISPLAYNAME)->draw(text_x, text_y, renderedDisplayName, color);
|
||||
|
||||
glPopMatrix();
|
||||
|
||||
|
|
|
@ -40,7 +40,9 @@ public:
|
|||
void renderAvatars(RenderArgs::RenderMode renderMode, bool postLighting = false, bool selfAvatarOnly = false);
|
||||
|
||||
void clearOtherAvatars();
|
||||
|
||||
|
||||
bool shouldShowReceiveStats() const { return _shouldShowReceiveStats; }
|
||||
|
||||
class LocalLight {
|
||||
public:
|
||||
glm::vec3 color;
|
||||
|
@ -49,7 +51,10 @@ public:
|
|||
|
||||
Q_INVOKABLE void setLocalLights(const QVector<AvatarManager::LocalLight>& localLights);
|
||||
Q_INVOKABLE QVector<AvatarManager::LocalLight> getLocalLights() const;
|
||||
|
||||
|
||||
public slots:
|
||||
void setShouldShowReceiveStats(bool shouldShowReceiveStats) { _shouldShowReceiveStats = shouldShowReceiveStats; }
|
||||
|
||||
private:
|
||||
AvatarManager(QObject* parent = 0);
|
||||
AvatarManager(const AvatarManager& other);
|
||||
|
@ -67,6 +72,8 @@ private:
|
|||
quint64 _lastSendAvatarDataTime = 0; // Controls MyAvatar send data rate.
|
||||
|
||||
QVector<AvatarManager::LocalLight> _localLights;
|
||||
|
||||
bool _shouldShowReceiveStats = false;
|
||||
};
|
||||
|
||||
Q_DECLARE_METATYPE(AvatarManager::LocalLight)
|
||||
|
|
|
@ -58,11 +58,11 @@ AvatarData::AvatarData() :
|
|||
_billboard(),
|
||||
_errorLogExpiry(0),
|
||||
_owningAvatarMixer(),
|
||||
_lastUpdateTimer(),
|
||||
_velocity(0.0f),
|
||||
_targetVelocity(0.0f),
|
||||
_localAABox(DEFAULT_LOCAL_AABOX_CORNER, DEFAULT_LOCAL_AABOX_SCALE)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
AvatarData::~AvatarData() {
|
||||
|
@ -268,9 +268,6 @@ bool AvatarData::shouldLogError(const quint64& now) {
|
|||
// read data in packet starting at byte offset and return number of bytes parsed
|
||||
int AvatarData::parseDataAtOffset(const QByteArray& packet, int offset) {
|
||||
|
||||
// reset the last heard timer since we have new data for this AvatarData
|
||||
_lastUpdateTimer.restart();
|
||||
|
||||
// lazily allocate memory for HeadData in case we're not an Avatar instance
|
||||
if (!_headData) {
|
||||
_headData = new HeadData(this);
|
||||
|
@ -555,7 +552,17 @@ int AvatarData::parseDataAtOffset(const QByteArray& packet, int offset) {
|
|||
}
|
||||
} // numJoints * 8 bytes
|
||||
|
||||
return sourceBuffer - startPosition;
|
||||
int numBytesRead = sourceBuffer - startPosition;
|
||||
_averageBytesReceived.updateAverage(numBytesRead);
|
||||
return numBytesRead;
|
||||
}
|
||||
|
||||
int AvatarData::getAverageBytesReceivedPerSecond() const {
|
||||
return lrint(_averageBytesReceived.getAverageSampleValuePerSecond());
|
||||
}
|
||||
|
||||
int AvatarData::getReceiveRate() const {
|
||||
return lrint(1.0f / _averageBytesReceived.getEventDeltaAverage());
|
||||
}
|
||||
|
||||
bool AvatarData::hasReferential() {
|
||||
|
|
|
@ -46,9 +46,9 @@ typedef unsigned long long quint64;
|
|||
#include <QReadWriteLock>
|
||||
|
||||
#include <CollisionInfo.h>
|
||||
#include <RegisteredMetaTypes.h>
|
||||
|
||||
#include <Node.h>
|
||||
#include <RegisteredMetaTypes.h>
|
||||
#include <SimpleMovingAverage.h>
|
||||
|
||||
#include "AABox.h"
|
||||
#include "HandData.h"
|
||||
|
@ -293,11 +293,13 @@ public:
|
|||
Node* getOwningAvatarMixer() { return _owningAvatarMixer.data(); }
|
||||
void setOwningAvatarMixer(const QWeakPointer<Node>& owningAvatarMixer) { _owningAvatarMixer = owningAvatarMixer; }
|
||||
|
||||
QElapsedTimer& getLastUpdateTimer() { return _lastUpdateTimer; }
|
||||
|
||||
const AABox& getLocalAABox() const { return _localAABox; }
|
||||
const Referential* getReferential() const { return _referential; }
|
||||
|
||||
int getUsecsSinceLastUpdate() const { return _averageBytesReceived.getUsecsSinceLastEvent(); }
|
||||
int getAverageBytesReceivedPerSecond() const;
|
||||
int getReceiveRate() const;
|
||||
|
||||
void setVelocity(const glm::vec3 velocity) { _velocity = velocity; }
|
||||
Q_INVOKABLE glm::vec3 getVelocity() const { return _velocity; }
|
||||
glm::vec3 getTargetVelocity() const { return _targetVelocity; }
|
||||
|
@ -382,7 +384,6 @@ protected:
|
|||
quint64 _errorLogExpiry; ///< time in future when to log an error
|
||||
|
||||
QWeakPointer<Node> _owningAvatarMixer;
|
||||
QElapsedTimer _lastUpdateTimer;
|
||||
|
||||
PlayerPointer _player;
|
||||
|
||||
|
@ -395,6 +396,8 @@ protected:
|
|||
|
||||
AABox _localAABox;
|
||||
|
||||
SimpleMovingAverage _averageBytesReceived;
|
||||
|
||||
private:
|
||||
// privatize the copy constructor and assignment operator so they cannot be called
|
||||
AvatarData(const AvatarData&);
|
||||
|
|
|
@ -11,6 +11,7 @@
|
|||
|
||||
#include <NodeList.h>
|
||||
#include <PacketHeaders.h>
|
||||
#include <SharedUtil.h>
|
||||
|
||||
#include "AvatarLogging.h"
|
||||
#include "AvatarHashMap.h"
|
||||
|
@ -25,11 +26,11 @@ AvatarHash::iterator AvatarHashMap::erase(const AvatarHash::iterator& iterator)
|
|||
return _avatarHash.erase(iterator);
|
||||
}
|
||||
|
||||
const qint64 AVATAR_SILENCE_THRESHOLD_MSECS = 5 * 1000;
|
||||
const qint64 AVATAR_SILENCE_THRESHOLD_USECS = 5 * USECS_PER_SECOND;
|
||||
|
||||
bool AvatarHashMap::shouldKillAvatar(const AvatarSharedPointer& sharedAvatar) {
|
||||
return (sharedAvatar->getOwningAvatarMixer() == NULL
|
||||
|| sharedAvatar->getLastUpdateTimer().elapsed() > AVATAR_SILENCE_THRESHOLD_MSECS);
|
||||
|| sharedAvatar->getUsecsSinceLastUpdate() > AVATAR_SILENCE_THRESHOLD_USECS);
|
||||
}
|
||||
|
||||
void AvatarHashMap::processAvatarMixerDatagram(const QByteArray& datagram, const QWeakPointer<Node>& mixerWeakPointer) {
|
||||
|
|
|
@ -55,6 +55,6 @@ float SimpleMovingAverage::getEventDeltaAverage() const {
|
|||
(WEIGHTING * ((usecTimestampNow() - _lastEventTimestamp) / 1000000.0f));
|
||||
}
|
||||
|
||||
float SimpleMovingAverage::getAverageSampleValuePerSecond() const {
|
||||
return _average * (1.0f / getEventDeltaAverage());
|
||||
uint64_t SimpleMovingAverage::getUsecsSinceLastEvent() const {
|
||||
return usecTimestampNow() - _lastEventTimestamp;
|
||||
}
|
||||
|
|
|
@ -25,8 +25,11 @@ public:
|
|||
|
||||
int getSampleCount() const { return _numSamples; };
|
||||
float getAverage() const { return _average; };
|
||||
float getEventDeltaAverage() const;
|
||||
float getAverageSampleValuePerSecond() const;
|
||||
float getEventDeltaAverage() const; // returned in seconds
|
||||
float getAverageSampleValuePerSecond() const { return _average * (1.0f / getEventDeltaAverage()); }
|
||||
|
||||
uint64_t getUsecsSinceLastEvent() const;
|
||||
|
||||
private:
|
||||
int _numSamples;
|
||||
uint64_t _lastEventTimestamp;
|
||||
|
|
Loading…
Reference in a new issue