mirror of
https://github.com/overte-org/overte.git
synced 2025-08-04 02:03:36 +02:00
Merge branch 'master' of https://github.com/highfidelity/hifi into controllers
This commit is contained in:
commit
c7b9d7d26e
20 changed files with 241 additions and 122 deletions
|
@ -12,7 +12,6 @@
|
||||||
#include <QThread>
|
#include <QThread>
|
||||||
|
|
||||||
#include <GLMHelpers.h>
|
#include <GLMHelpers.h>
|
||||||
|
|
||||||
#include "ScriptableAvatar.h"
|
#include "ScriptableAvatar.h"
|
||||||
|
|
||||||
// hold and priority unused but kept so that client side JS can run.
|
// hold and priority unused but kept so that client side JS can run.
|
||||||
|
@ -48,14 +47,12 @@ AnimationDetails ScriptableAvatar::getAnimationDetails() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void ScriptableAvatar::update(float deltatime) {
|
void ScriptableAvatar::update(float deltatime) {
|
||||||
|
if (_bind.isNull() && !_skeletonFBXURL.isEmpty()) { // AvatarData will parse the .fst, but not get the .fbx skeleton.
|
||||||
|
_bind = DependencyManager::get<AnimationCache>()->getAnimation(_skeletonFBXURL);
|
||||||
|
}
|
||||||
|
|
||||||
// Run animation
|
// Run animation
|
||||||
if (_animation && _animation->isLoaded() && _animation->getFrames().size() > 0) {
|
if (_animation && _animation->isLoaded() && _animation->getFrames().size() > 0 && _bind->isLoaded()) {
|
||||||
QStringList modelJoints = getJointNames();
|
|
||||||
QStringList animationJoints = _animation->getJointNames();
|
|
||||||
|
|
||||||
if (_jointData.size() != modelJoints.size()) {
|
|
||||||
_jointData.resize(modelJoints.size());
|
|
||||||
}
|
|
||||||
|
|
||||||
float currentFrame = _animationDetails.currentFrame + deltatime * _animationDetails.fps;
|
float currentFrame = _animationDetails.currentFrame + deltatime * _animationDetails.fps;
|
||||||
if (_animationDetails.loop || currentFrame < _animationDetails.lastFrame) {
|
if (_animationDetails.loop || currentFrame < _animationDetails.lastFrame) {
|
||||||
|
@ -63,19 +60,29 @@ void ScriptableAvatar::update(float deltatime) {
|
||||||
currentFrame -= (_animationDetails.lastFrame - _animationDetails.firstFrame);
|
currentFrame -= (_animationDetails.lastFrame - _animationDetails.firstFrame);
|
||||||
}
|
}
|
||||||
_animationDetails.currentFrame = currentFrame;
|
_animationDetails.currentFrame = currentFrame;
|
||||||
|
|
||||||
|
const QVector<FBXJoint>& modelJoints = _bind->getGeometry().joints;
|
||||||
|
QStringList animationJointNames = _animation->getJointNames();
|
||||||
|
|
||||||
|
if (_jointData.size() != modelJoints.size()) {
|
||||||
|
_jointData.resize(modelJoints.size());
|
||||||
|
}
|
||||||
|
|
||||||
const int frameCount = _animation->getFrames().size();
|
const int frameCount = _animation->getFrames().size();
|
||||||
const FBXAnimationFrame& floorFrame = _animation->getFrames().at((int)glm::floor(currentFrame) % frameCount);
|
const FBXAnimationFrame& floorFrame = _animation->getFrames().at((int)glm::floor(currentFrame) % frameCount);
|
||||||
const FBXAnimationFrame& ceilFrame = _animation->getFrames().at((int)glm::ceil(currentFrame) % frameCount);
|
const FBXAnimationFrame& ceilFrame = _animation->getFrames().at((int)glm::ceil(currentFrame) % frameCount);
|
||||||
const float frameFraction = glm::fract(currentFrame);
|
const float frameFraction = glm::fract(currentFrame);
|
||||||
|
|
||||||
for (int i = 0; i < animationJoints.size(); i++) {
|
for (int i = 0; i < animationJointNames.size(); i++) {
|
||||||
const QString& name = animationJoints[i];
|
const QString& name = animationJointNames[i];
|
||||||
int mapping = getJointIndex(name);
|
// As long as we need the model preRotations anyway, let's get the jointIndex from the bind skeleton rather than
|
||||||
|
// trusting the .fst (which is sometimes not updated to match changes to .fbx).
|
||||||
|
int mapping = _bind->getGeometry().getJointIndex(name);
|
||||||
if (mapping != -1 && !_maskedJoints.contains(name)) {
|
if (mapping != -1 && !_maskedJoints.contains(name)) {
|
||||||
JointData& data = _jointData[mapping];
|
JointData& data = _jointData[mapping];
|
||||||
|
|
||||||
auto newRotation = safeMix(floorFrame.rotations.at(i), ceilFrame.rotations.at(i), frameFraction);
|
auto newRotation = modelJoints[mapping].preRotation *
|
||||||
|
safeMix(floorFrame.rotations.at(i), ceilFrame.rotations.at(i), frameFraction);
|
||||||
// We could probably do translations as in interpolation in model space (rather than the parent space that each frame is in),
|
// We could probably do translations as in interpolation in model space (rather than the parent space that each frame is in),
|
||||||
// but we don't do so for MyAvatar yet, so let's not be different here.
|
// but we don't do so for MyAvatar yet, so let's not be different here.
|
||||||
if (data.rotation != newRotation) {
|
if (data.rotation != newRotation) {
|
||||||
|
|
|
@ -33,6 +33,7 @@ private:
|
||||||
AnimationPointer _animation;
|
AnimationPointer _animation;
|
||||||
AnimationDetails _animationDetails;
|
AnimationDetails _animationDetails;
|
||||||
QStringList _maskedJoints;
|
QStringList _maskedJoints;
|
||||||
|
AnimationPointer _bind; // a sleazy way to get the skeleton, given the various library/cmake dependencies
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // hifi_ScriptableAvatar_h
|
#endif // hifi_ScriptableAvatar_h
|
|
@ -43,6 +43,7 @@ void OctreeInboundPacketProcessor::resetStats() {
|
||||||
_totalPackets = 0;
|
_totalPackets = 0;
|
||||||
_lastNackTime = usecTimestampNow();
|
_lastNackTime = usecTimestampNow();
|
||||||
|
|
||||||
|
QWriteLocker locker(&_senderStatsLock);
|
||||||
_singleSenderStats.clear();
|
_singleSenderStats.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -220,6 +221,8 @@ void OctreeInboundPacketProcessor::trackInboundPacket(const QUuid& nodeUUID, uns
|
||||||
_totalElementsInPacket += editsInPacket;
|
_totalElementsInPacket += editsInPacket;
|
||||||
_totalPackets++;
|
_totalPackets++;
|
||||||
|
|
||||||
|
QWriteLocker locker(&_senderStatsLock);
|
||||||
|
|
||||||
// find the individual senders stats and track them there too...
|
// find the individual senders stats and track them there too...
|
||||||
// see if this is the first we've heard of this node...
|
// see if this is the first we've heard of this node...
|
||||||
if (_singleSenderStats.find(nodeUUID) == _singleSenderStats.end()) {
|
if (_singleSenderStats.find(nodeUUID) == _singleSenderStats.end()) {
|
||||||
|
@ -242,6 +245,8 @@ int OctreeInboundPacketProcessor::sendNackPackets() {
|
||||||
int packetsSent = 0;
|
int packetsSent = 0;
|
||||||
int totalBytesSent = 0;
|
int totalBytesSent = 0;
|
||||||
|
|
||||||
|
QWriteLocker locker(&_senderStatsLock);
|
||||||
|
|
||||||
NodeToSenderStatsMapIterator i = _singleSenderStats.begin();
|
NodeToSenderStatsMapIterator i = _singleSenderStats.begin();
|
||||||
while (i != _singleSenderStats.end()) {
|
while (i != _singleSenderStats.end()) {
|
||||||
|
|
||||||
|
@ -262,10 +267,9 @@ int OctreeInboundPacketProcessor::sendNackPackets() {
|
||||||
}
|
}
|
||||||
|
|
||||||
const SharedNodePointer& destinationNode = DependencyManager::get<NodeList>()->nodeWithUUID(nodeUUID);
|
const SharedNodePointer& destinationNode = DependencyManager::get<NodeList>()->nodeWithUUID(nodeUUID);
|
||||||
// If the node no longer exists, wait until the ReceivedPacketProcessor has cleaned up the node
|
// if the node no longer exists, remove its stats
|
||||||
// to remove it from our stats list.
|
|
||||||
// FIXME Is it safe to clean it up here before ReceivedPacketProcess has?
|
|
||||||
if (!destinationNode) {
|
if (!destinationNode) {
|
||||||
|
i = _singleSenderStats.erase(i);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -72,7 +72,7 @@ public:
|
||||||
|
|
||||||
void resetStats();
|
void resetStats();
|
||||||
|
|
||||||
NodeToSenderStatsMap& getSingleSenderStats() { return _singleSenderStats; }
|
NodeToSenderStatsMap getSingleSenderStats() { QReadLocker locker(&_senderStatsLock); return _singleSenderStats; }
|
||||||
|
|
||||||
virtual void terminating() { _shuttingDown = true; ReceivedPacketProcessor::terminating(); }
|
virtual void terminating() { _shuttingDown = true; ReceivedPacketProcessor::terminating(); }
|
||||||
|
|
||||||
|
@ -94,15 +94,16 @@ private:
|
||||||
OctreeServer* _myServer;
|
OctreeServer* _myServer;
|
||||||
int _receivedPacketCount;
|
int _receivedPacketCount;
|
||||||
|
|
||||||
quint64 _totalTransitTime;
|
std::atomic<uint64_t> _totalTransitTime;
|
||||||
quint64 _totalProcessTime;
|
std::atomic<uint64_t> _totalProcessTime;
|
||||||
quint64 _totalLockWaitTime;
|
std::atomic<uint64_t> _totalLockWaitTime;
|
||||||
quint64 _totalElementsInPacket;
|
std::atomic<uint64_t> _totalElementsInPacket;
|
||||||
quint64 _totalPackets;
|
std::atomic<uint64_t> _totalPackets;
|
||||||
|
|
||||||
NodeToSenderStatsMap _singleSenderStats;
|
NodeToSenderStatsMap _singleSenderStats;
|
||||||
|
QReadWriteLock _senderStatsLock;
|
||||||
|
|
||||||
quint64 _lastNackTime;
|
std::atomic<uint64_t> _lastNackTime;
|
||||||
bool _shuttingDown;
|
bool _shuttingDown;
|
||||||
};
|
};
|
||||||
#endif // hifi_OctreeInboundPacketProcessor_h
|
#endif // hifi_OctreeInboundPacketProcessor_h
|
||||||
|
|
|
@ -711,7 +711,7 @@ bool OctreeServer::handleHTTPRequest(HTTPConnection* connection, const QUrl& url
|
||||||
|
|
||||||
|
|
||||||
int senderNumber = 0;
|
int senderNumber = 0;
|
||||||
NodeToSenderStatsMap& allSenderStats = _octreeInboundPacketProcessor->getSingleSenderStats();
|
NodeToSenderStatsMap allSenderStats = _octreeInboundPacketProcessor->getSingleSenderStats();
|
||||||
for (NodeToSenderStatsMapConstIterator i = allSenderStats.begin(); i != allSenderStats.end(); i++) {
|
for (NodeToSenderStatsMapConstIterator i = allSenderStats.begin(); i != allSenderStats.end(); i++) {
|
||||||
senderNumber++;
|
senderNumber++;
|
||||||
QUuid senderID = i.key();
|
QUuid senderID = i.key();
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
"use strict";
|
"use strict";
|
||||||
/*jslint vars: true, plusplus: true*/
|
/*jslint vars: true, plusplus: true*/
|
||||||
/*global Agent, Avatar, Script, Entities, Vec3, print*/
|
/*global Agent, Avatar, Script, Entities, Vec3, Quat, print*/
|
||||||
//
|
//
|
||||||
// animatedAvatar.js
|
// animatedAvatar.js
|
||||||
// examples/acScripts
|
// examples/acScripts
|
||||||
|
@ -16,15 +16,62 @@
|
||||||
|
|
||||||
var origin = {x: 500, y: 500, z: 500};
|
var origin = {x: 500, y: 500, z: 500};
|
||||||
var spread = 20; // meters
|
var spread = 20; // meters
|
||||||
|
var turnSpread = 90; // How many degrees should turn from front range over.
|
||||||
var animationData = {url: "https://hifi-public.s3.amazonaws.com/ozan/anim/standard_anims/walk_fwd.fbx", lastFrame: 35};
|
var animationData = {url: "https://hifi-public.s3.amazonaws.com/ozan/anim/standard_anims/walk_fwd.fbx", lastFrame: 35};
|
||||||
Avatar.skeletonModelURL = "https://hifi-public.s3.amazonaws.com/marketplace/contents/dd03b8e3-52fb-4ab3-9ac9-3b17e00cd85d/98baa90b3b66803c5d7bd4537fca6993.fst"; //lovejoy
|
var models = [ // Commented-out avatars do not animate properly on AC's. Presumably because ScriptableAvatar doesn't use model pre-rotations.
|
||||||
Avatar.displayName = "'Bot";
|
"https://hifi-public.s3.amazonaws.com/ozan/avatars/hifi_team/alan/alan.fst",
|
||||||
|
"https://hifi-public.s3.amazonaws.com/ozan/avatars/hifi_team/andrew/andrew.fst",
|
||||||
|
"https://hifi-public.s3.amazonaws.com/ozan/avatars/hifi_team/austin/austin.fst",
|
||||||
|
"https://hifi-public.s3.amazonaws.com/ozan/avatars/hifi_team/birarda/birarda.fst",
|
||||||
|
"https://hifi-public.s3.amazonaws.com/ozan/avatars/hifi_team/brad/brad.fst",
|
||||||
|
"https://hifi-public.s3.amazonaws.com/ozan/avatars/hifi_team/chris/chris2.fst",
|
||||||
|
"https://hifi-public.s3.amazonaws.com/ozan/avatars/hifi_team/clement/clement.fst",
|
||||||
|
"https://hifi-public.s3.amazonaws.com/ozan/avatars/hifi_team/emily/emily.fst",
|
||||||
|
"https://hifi-public.s3.amazonaws.com/ozan/avatars/hifi_team/ewing/ewing.fst",
|
||||||
|
"https://hifi-public.s3.amazonaws.com/ozan/avatars/hifi_team/howard/howard.fst",
|
||||||
|
"https://hifi-public.s3.amazonaws.com/ozan/avatars/hifi_team/huffman/huffman.fst",
|
||||||
|
"https://hifi-public.s3.amazonaws.com/ozan/avatars/hifi_team/james/james.fst",
|
||||||
|
"https://hifi-public.s3.amazonaws.com/ozan/avatars/hifi_team/philip/philip.fst",
|
||||||
|
"https://hifi-public.s3.amazonaws.com/ozan/avatars/hifi_team/ryan/ryan.fst",
|
||||||
|
"https://hifi-public.s3.amazonaws.com/ozan/avatars/hifi_team/sam/sam.fst",
|
||||||
|
"https://hifi-public.s3.amazonaws.com/ozan/avatars/hifi_team/tony/tony.fst",
|
||||||
|
|
||||||
|
"https://hifi-metaverse.s3-us-west-1.amazonaws.com/marketplace/contents/1e57c395-612e-4acd-9561-e79dbda0bc49/faafb83c63a3e5e265884d270fc29f8b.fst",
|
||||||
|
"https://hifi-metaverse.s3-us-west-1.amazonaws.com/marketplace/contents/615ca447-06ee-4215-8dd1-a609c2fcd0cd/c7af6d4224c501fdd9cb54e0101ff281.fst",
|
||||||
|
"https://hifi-metaverse.s3-us-west-1.amazonaws.com/marketplace/contents/731c39d7-559a-4ce2-947c-3e2768f5471c/8d5eba2fd5bf068259556aec1861c5dd.fst",
|
||||||
|
"https://hifi-metaverse.s3-us-west-1.amazonaws.com/marketplace/contents/8bdaa1ec-99df-4a29-a249-6941c7fd1930/37351a18a3dea468088fc3d822aaf29c.fst",
|
||||||
|
"https://hifi-metaverse.s3-us-west-1.amazonaws.com/marketplace/contents/0909d7b7-c67e-45fb-acd9-a07380dc6b9c/da76b8c59dbc680bdda90df4b9a46faa.fst",
|
||||||
|
"https://hifi-metaverse.s3-us-west-1.amazonaws.com/marketplace/contents/ad0dffd7-f811-487b-a20a-2509235491ef/29106da1f7e6a42c7907603421fd7df5.fst",
|
||||||
|
"https://hifi-metaverse.s3-us-west-1.amazonaws.com/marketplace/contents/3ebe5c84-8b88-4d91-86ac-f104f3620fe3/3534b032d079514aa8960a316500ce13.fst",
|
||||||
|
"https://hifi-metaverse.s3-us-west-1.amazonaws.com/marketplace/contents/dd03b8e3-52fb-4ab3-9ac9-3b17e00cd85d/98baa90b3b66803c5d7bd4537fca6993.fst",
|
||||||
|
"https://hifi-metaverse.s3-us-west-1.amazonaws.com/marketplace/contents/ff060580-2fc7-4b6c-8e12-f023d05363cf/dadef29b1e60f23b413d1850d7e0dd4a.fst",
|
||||||
|
"https://hifi-metaverse.s3-us-west-1.amazonaws.com/marketplace/contents/b55d3baf-4eb3-4cac-af4c-0fb66d0c907b/ad2c9157f3924ab1f7f6ea87a8cce6cc.fst",
|
||||||
|
"https://hifi-metaverse.s3-us-west-1.amazonaws.com/marketplace/contents/d029ae8d-2905-4eb7-ba46-4bd1b8cb9d73/4618d52e711fbb34df442b414da767bb.fst"
|
||||||
|
];
|
||||||
|
var nameMap = {
|
||||||
|
faafb83c63a3e5e265884d270fc29f8b: 'albert',
|
||||||
|
c7af6d4224c501fdd9cb54e0101ff281: 'boss',
|
||||||
|
'8d5eba2fd5bf068259556aec1861c5dd': 'dougland',
|
||||||
|
'37351a18a3dea468088fc3d822aaf29c': 'fightbot blue',
|
||||||
|
da76b8c59dbc680bdda90df4b9a46faa: 'judd',
|
||||||
|
'29106da1f7e6a42c7907603421fd7df5': 'kate',
|
||||||
|
'3534b032d079514aa8960a316500ce13': 'lenny',
|
||||||
|
'98baa90b3b66803c5d7bd4537fca6993': 'lovejoy',
|
||||||
|
dadef29b1e60f23b413d1850d7e0dd4a: 'mery', // eyes no good
|
||||||
|
ad2c9157f3924ab1f7f6ea87a8cce6cc: 'owen',
|
||||||
|
'4618d52e711fbb34df442b414da767bb': 'will'
|
||||||
|
};
|
||||||
|
|
||||||
|
Avatar.skeletonModelURL = models[Math.round(Math.random() * (models.length - 1))]; // pick one
|
||||||
|
Avatar.displayName = Avatar.skeletonModelURL.match(/\/(\w*).fst/)[1]; // grab the file basename
|
||||||
|
Avatar.displayName = nameMap[Avatar.displayName] || Avatar.displayName;
|
||||||
var millisecondsToWaitBeforeStarting = 10 * 1000; // To give the various servers a chance to start.
|
var millisecondsToWaitBeforeStarting = 10 * 1000; // To give the various servers a chance to start.
|
||||||
|
|
||||||
Agent.isAvatar = true;
|
Agent.isAvatar = true;
|
||||||
function coord() { return (Math.random() * spread) - (spread / 2); } // randomly distribute a coordinate zero += spread/2.
|
function coord() { return (Math.random() * spread) - (spread / 2); } // randomly distribute a coordinate zero += spread/2.
|
||||||
Script.setTimeout(function () {
|
Script.setTimeout(function () {
|
||||||
Avatar.position = Vec3.sum(origin, {x: coord(), y: 0, z: coord()});
|
Avatar.position = Vec3.sum(origin, {x: coord(), y: 0, z: coord()});
|
||||||
|
Avatar.orientation = Quat.fromPitchYawRollDegrees(0, turnSpread * (Math.random() - 0.5), 0);
|
||||||
print("Starting at", JSON.stringify(Avatar.position));
|
print("Starting at", JSON.stringify(Avatar.position));
|
||||||
Avatar.startAnimation(animationData.url, animationData.fps || 30, 1, true, false, animationData.firstFrame || 0, animationData.lastFrame);
|
Avatar.startAnimation(animationData.url, animationData.fps || 30, 1, true, false, animationData.firstFrame || 0, animationData.lastFrame);
|
||||||
}, millisecondsToWaitBeforeStarting);
|
}, millisecondsToWaitBeforeStarting);
|
||||||
|
|
|
@ -200,6 +200,7 @@ function entityIsGrabbedByOther(entityID) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
function MyController(hand) {
|
function MyController(hand) {
|
||||||
this.hand = hand;
|
this.hand = hand;
|
||||||
if (this.hand === RIGHT_HAND) {
|
if (this.hand === RIGHT_HAND) {
|
||||||
|
@ -223,6 +224,8 @@ function MyController(hand) {
|
||||||
this.rawTriggerValue = 0;
|
this.rawTriggerValue = 0;
|
||||||
this.rawBumperValue = 0;
|
this.rawBumperValue = 0;
|
||||||
|
|
||||||
|
this.overlayLine = null;
|
||||||
|
|
||||||
this.offsetPosition = {
|
this.offsetPosition = {
|
||||||
x: 0.0,
|
x: 0.0,
|
||||||
y: 0.0,
|
y: 0.0,
|
||||||
|
@ -318,6 +321,33 @@ function MyController(hand) {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
this.overlayLineOn = function(closePoint, farPoint, color) {
|
||||||
|
if (this.overlayLine === null) {
|
||||||
|
var lineProperties = {
|
||||||
|
lineWidth: 5,
|
||||||
|
start: closePoint,
|
||||||
|
end: farPoint,
|
||||||
|
color: color,
|
||||||
|
ignoreRayIntersection: true, // always ignore this
|
||||||
|
visible: true,
|
||||||
|
alpha: 1
|
||||||
|
};
|
||||||
|
|
||||||
|
this.overlayLine = Overlays.addOverlay("line3d", lineProperties);
|
||||||
|
|
||||||
|
} else {
|
||||||
|
var success = Overlays.editOverlay(this.overlayLine, {
|
||||||
|
lineWidth: 5,
|
||||||
|
start: closePoint,
|
||||||
|
end: farPoint,
|
||||||
|
color: color,
|
||||||
|
visible: true,
|
||||||
|
ignoreRayIntersection: true, // always ignore this
|
||||||
|
alpha: 1
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
this.lineOn = function(closePoint, farPoint, color) {
|
this.lineOn = function(closePoint, farPoint, color) {
|
||||||
// draw a line
|
// draw a line
|
||||||
if (this.pointer === null) {
|
if (this.pointer === null) {
|
||||||
|
@ -356,6 +386,13 @@ function MyController(hand) {
|
||||||
this.pointer = null;
|
this.pointer = null;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
this.overlayLineOff = function() {
|
||||||
|
if (this.overlayLine !== null) {
|
||||||
|
Overlays.deleteOverlay(this.overlayLine);
|
||||||
|
}
|
||||||
|
this.overlayLine = null;
|
||||||
|
};
|
||||||
|
|
||||||
this.triggerPress = function(value) {
|
this.triggerPress = function(value) {
|
||||||
_this.rawTriggerValue = value;
|
_this.rawTriggerValue = value;
|
||||||
};
|
};
|
||||||
|
@ -604,7 +641,8 @@ function MyController(hand) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
this.lineOn(distantPickRay.origin, Vec3.multiply(distantPickRay.direction, LINE_LENGTH), NO_INTERSECT_COLOR);
|
//this.lineOn(distantPickRay.origin, Vec3.multiply(distantPickRay.direction, LINE_LENGTH), NO_INTERSECT_COLOR);
|
||||||
|
this.overlayLineOn(distantPickRay.origin, Vec3.sum(distantPickRay.origin, Vec3.multiply(distantPickRay.direction, LINE_LENGTH)), NO_INTERSECT_COLOR);
|
||||||
};
|
};
|
||||||
|
|
||||||
this.distanceHolding = function() {
|
this.distanceHolding = function() {
|
||||||
|
@ -650,6 +688,9 @@ function MyController(hand) {
|
||||||
this.currentAvatarPosition = MyAvatar.position;
|
this.currentAvatarPosition = MyAvatar.position;
|
||||||
this.currentAvatarOrientation = MyAvatar.orientation;
|
this.currentAvatarOrientation = MyAvatar.orientation;
|
||||||
|
|
||||||
|
this.overlayLineOff();
|
||||||
|
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
this.continueDistanceHolding = function() {
|
this.continueDistanceHolding = function() {
|
||||||
|
@ -757,6 +798,7 @@ function MyController(hand) {
|
||||||
}
|
}
|
||||||
|
|
||||||
this.lineOff();
|
this.lineOff();
|
||||||
|
this.overlayLineOff();
|
||||||
|
|
||||||
var grabbedProperties = Entities.getEntityProperties(this.grabbedEntity, GRABBABLE_PROPERTIES);
|
var grabbedProperties = Entities.getEntityProperties(this.grabbedEntity, GRABBABLE_PROPERTIES);
|
||||||
this.activateEntity(this.grabbedEntity, grabbedProperties);
|
this.activateEntity(this.grabbedEntity, grabbedProperties);
|
||||||
|
@ -898,6 +940,7 @@ function MyController(hand) {
|
||||||
|
|
||||||
this.pullTowardEquipPosition = function() {
|
this.pullTowardEquipPosition = function() {
|
||||||
this.lineOff();
|
this.lineOff();
|
||||||
|
this.overlayLineOff();
|
||||||
|
|
||||||
var grabbedProperties = Entities.getEntityProperties(this.grabbedEntity, GRABBABLE_PROPERTIES);
|
var grabbedProperties = Entities.getEntityProperties(this.grabbedEntity, GRABBABLE_PROPERTIES);
|
||||||
var grabbableData = getEntityCustomData(GRABBABLE_DATA_KEY, this.grabbedEntity, DEFAULT_GRABBABLE_DATA);
|
var grabbableData = getEntityCustomData(GRABBABLE_DATA_KEY, this.grabbedEntity, DEFAULT_GRABBABLE_DATA);
|
||||||
|
@ -1101,7 +1144,7 @@ function MyController(hand) {
|
||||||
this.release = function() {
|
this.release = function() {
|
||||||
|
|
||||||
this.lineOff();
|
this.lineOff();
|
||||||
|
this.overlayLineOff();
|
||||||
if (this.grabbedEntity !== null) {
|
if (this.grabbedEntity !== null) {
|
||||||
if (this.actionID !== null) {
|
if (this.actionID !== null) {
|
||||||
Entities.deleteAction(this.grabbedEntity, this.actionID);
|
Entities.deleteAction(this.grabbedEntity, this.actionID);
|
||||||
|
@ -1223,10 +1266,10 @@ Controller.enableMapping(MAPPING_NAME);
|
||||||
var handToDisable = 'none';
|
var handToDisable = 'none';
|
||||||
|
|
||||||
function update() {
|
function update() {
|
||||||
if (handToDisable !== LEFT_HAND) {
|
if (handToDisable !== LEFT_HAND && handToDisable!=='both') {
|
||||||
leftController.update();
|
leftController.update();
|
||||||
}
|
}
|
||||||
if (handToDisable !== RIGHT_HAND) {
|
if (handToDisable !== RIGHT_HAND && handToDisable!=='both') {
|
||||||
rightController.update();
|
rightController.update();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1234,15 +1277,20 @@ function update() {
|
||||||
Messages.subscribe('Hifi-Hand-Disabler');
|
Messages.subscribe('Hifi-Hand-Disabler');
|
||||||
|
|
||||||
handleHandDisablerMessages = function(channel, message, sender) {
|
handleHandDisablerMessages = function(channel, message, sender) {
|
||||||
|
|
||||||
if (sender === MyAvatar.sessionUUID) {
|
if (sender === MyAvatar.sessionUUID) {
|
||||||
handToDisable = message;
|
|
||||||
if (message === 'left') {
|
if (message === 'left') {
|
||||||
handToDisable = LEFT_HAND;
|
handToDisable = LEFT_HAND;
|
||||||
}
|
}
|
||||||
if (message === 'right') {
|
if (message === 'right') {
|
||||||
handToDisable = RIGHT_HAND;
|
handToDisable = RIGHT_HAND;
|
||||||
}
|
}
|
||||||
|
if(message==='both'){
|
||||||
|
handToDisable='both';
|
||||||
|
}
|
||||||
|
if(message==='none'){
|
||||||
|
handToDisable='none';
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,8 +22,10 @@ var laserPointer = (function () {
|
||||||
];
|
];
|
||||||
|
|
||||||
function isHandPointing(hand) {
|
function isHandPointing(hand) {
|
||||||
var MINIMUM_TRIGGER_PULL = 0.9;
|
var MINIMUM_TRIGGER_PULL = 0.9,
|
||||||
return Controller.getTriggerValue(hand) > MINIMUM_TRIGGER_PULL;
|
controller;
|
||||||
|
controller = hand === 0 ? Controller.Standard.LT : Controller.Standard.RT;
|
||||||
|
return Controller.getValue(controller) > MINIMUM_TRIGGER_PULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
function isFingerPointing(hand) {
|
function isFingerPointing(hand) {
|
||||||
|
|
|
@ -193,13 +193,12 @@ var leapHands = (function () {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set avatar arms vertical, forearms horizontal, as "zero" position for calibration
|
// Set avatar arms vertical, forearms horizontal, as "zero" position for calibration
|
||||||
MyAvatar.setJointData("LeftArm", Quat.fromPitchYawRollDegrees(90.0, 0.0, -90.0));
|
MyAvatar.setJointRotation("LeftArm", Quat.fromPitchYawRollDegrees(90.0, 0.0, 0.0));
|
||||||
MyAvatar.setJointData("LeftForeArm", Quat.fromPitchYawRollDegrees(90.0, 0.0, 180.0));
|
MyAvatar.setJointRotation("LeftForeArm", Quat.fromPitchYawRollDegrees(0.0, 90.0, 90.0));
|
||||||
MyAvatar.setJointData("LeftHand", Quat.fromPitchYawRollRadians(0.0, 0.0, 0.0));
|
MyAvatar.setJointRotation("LeftHand", Quat.fromPitchYawRollRadians(0.0, 0.0, 0.0));
|
||||||
MyAvatar.setJointData("RightArm", Quat.fromPitchYawRollDegrees(90.0, 0.0, 90.0));
|
MyAvatar.setJointRotation("RightArm", Quat.fromPitchYawRollDegrees(90.0, 0.0, 0.0));
|
||||||
MyAvatar.setJointData("RightForeArm", Quat.fromPitchYawRollDegrees(90.0, 0.0, 180.0));
|
MyAvatar.setJointRotation("RightForeArm", Quat.fromPitchYawRollDegrees(0.0, -90.0, -90.0));
|
||||||
MyAvatar.setJointData("RightHand", Quat.fromPitchYawRollRadians(0.0, 0.0, 0.0));
|
MyAvatar.setJointRotation("RightHand", Quat.fromPitchYawRollRadians(0.0, 0.0, 0.0));
|
||||||
|
|
||||||
|
|
||||||
// Wait for arms to assume their positions before calculating
|
// Wait for arms to assume their positions before calculating
|
||||||
Script.setTimeout(finishCalibration, CALIBRATION_TIME);
|
Script.setTimeout(finishCalibration, CALIBRATION_TIME);
|
||||||
|
@ -382,23 +381,14 @@ var leapHands = (function () {
|
||||||
|
|
||||||
// Hand rotation in camera coordinates ...
|
// Hand rotation in camera coordinates ...
|
||||||
handRotation = {
|
handRotation = {
|
||||||
x: handRotation.z,
|
x: -handRotation.x,
|
||||||
y: handRotation.y,
|
y: -handRotation.z,
|
||||||
z: handRotation.x,
|
z: -handRotation.y,
|
||||||
w: handRotation.w
|
w: handRotation.w
|
||||||
};
|
};
|
||||||
|
|
||||||
// Hand rotation in avatar coordinates ...
|
// Hand rotation in avatar coordinates ...
|
||||||
if (h === 0) {
|
handRotation = Quat.multiply(Quat.angleAxis(180.0, { x: 0, y: 1, z: 0 }), handRotation);
|
||||||
handRotation.x = -handRotation.x;
|
|
||||||
handRotation = Quat.multiply(Quat.angleAxis(90.0, { x: 1, y: 0, z: 0 }), handRotation);
|
|
||||||
handRotation = Quat.multiply(Quat.angleAxis(90.0, { x: 0, y: 0, z: 1 }), handRotation);
|
|
||||||
} else {
|
|
||||||
handRotation.z = -handRotation.z;
|
|
||||||
handRotation = Quat.multiply(Quat.angleAxis(90.0, { x: 1, y: 0, z: 0 }), handRotation);
|
|
||||||
handRotation = Quat.multiply(Quat.angleAxis(-90.0, { x: 0, y: 0, z: 1 }), handRotation);
|
|
||||||
}
|
|
||||||
|
|
||||||
cameraOrientation.x = -cameraOrientation.x;
|
cameraOrientation.x = -cameraOrientation.x;
|
||||||
cameraOrientation.z = -cameraOrientation.z;
|
cameraOrientation.z = -cameraOrientation.z;
|
||||||
handRotation = Quat.multiply(cameraOrientation, handRotation);
|
handRotation = Quat.multiply(cameraOrientation, handRotation);
|
||||||
|
@ -421,22 +411,14 @@ var leapHands = (function () {
|
||||||
|
|
||||||
// Hand rotation in camera coordinates ...
|
// Hand rotation in camera coordinates ...
|
||||||
handRotation = {
|
handRotation = {
|
||||||
x: handRotation.z,
|
x: -handRotation.x,
|
||||||
y: handRotation.y,
|
y: -handRotation.z,
|
||||||
z: handRotation.x,
|
z: -handRotation.y,
|
||||||
w: handRotation.w
|
w: handRotation.w
|
||||||
};
|
};
|
||||||
|
|
||||||
// Hand rotation in avatar coordinates ...
|
// Hand rotation in avatar coordinates ...
|
||||||
if (h === 0) {
|
handRotation = Quat.multiply(Quat.angleAxis(90.0, { x: 1, y: 0, z: 0 }), handRotation);
|
||||||
handRotation.x = -handRotation.x;
|
|
||||||
handRotation = Quat.multiply(Quat.angleAxis(-90.0, { x: 0, y: 1, z: 0 }),
|
|
||||||
handRotation);
|
|
||||||
} else {
|
|
||||||
handRotation.z = -handRotation.z;
|
|
||||||
handRotation = Quat.multiply(Quat.angleAxis(90.0, { x: 0, y: 1, z: 0 }),
|
|
||||||
handRotation);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set hand position and orientation ...
|
// Set hand position and orientation ...
|
||||||
|
@ -462,7 +444,7 @@ var leapHands = (function () {
|
||||||
w: locRotation.w
|
w: locRotation.w
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
MyAvatar.setJointData(fingers[h][i][j].jointName, locRotation);
|
MyAvatar.setJointRotation(fingers[h][i][j].jointName, locRotation);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,6 +18,7 @@ Script.include("../../../libraries/constants.js");
|
||||||
|
|
||||||
var GUN_FORCE =20;
|
var GUN_FORCE =20;
|
||||||
|
|
||||||
|
Messages.sendMessage('Hifi-Hand-Disabler', "both");
|
||||||
|
|
||||||
var gameName = "Kill All The Rats!"
|
var gameName = "Kill All The Rats!"
|
||||||
// var HOST = "localhost:5000"
|
// var HOST = "localhost:5000"
|
||||||
|
@ -194,6 +195,7 @@ function fire(side, value) {
|
||||||
|
|
||||||
|
|
||||||
function scriptEnding() {
|
function scriptEnding() {
|
||||||
|
Messages.sendMessage('Hifi-Hand-Disabler', 'none');
|
||||||
mapping.disable();
|
mapping.disable();
|
||||||
for (var i = 0; i < pointers.length; ++i) {
|
for (var i = 0; i < pointers.length; ++i) {
|
||||||
Overlays.deleteOverlay(pointers[i]);
|
Overlays.deleteOverlay(pointers[i]);
|
||||||
|
|
|
@ -36,14 +36,10 @@
|
||||||
Entities.editEntity(this.entityID, {
|
Entities.editEntity(this.entityID, {
|
||||||
animation: {
|
animation: {
|
||||||
url: "https://hifi-public.s3.amazonaws.com/models/Bboys/zombie_scream.fbx",
|
url: "https://hifi-public.s3.amazonaws.com/models/Bboys/zombie_scream.fbx",
|
||||||
currentFrame: 0
|
running: true
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
Entities.editEntity(_this.entityID, {
|
|
||||||
animationIsPlaying: true
|
|
||||||
});
|
|
||||||
|
|
||||||
var position = Entities.getEntityProperties(this.entityID, "position").position;
|
var position = Entities.getEntityProperties(this.entityID, "position").position;
|
||||||
this.audioInjector = Audio.playSound(this.screamSounds[randInt(0, this.screamSounds.length)], {
|
this.audioInjector = Audio.playSound(this.screamSounds[randInt(0, this.screamSounds.length)], {
|
||||||
position: position,
|
position: position,
|
||||||
|
@ -67,8 +63,10 @@
|
||||||
this.audioInjector.stop();
|
this.audioInjector.stop();
|
||||||
Entities.editEntity(this.entityID, {
|
Entities.editEntity(this.entityID, {
|
||||||
animation: {
|
animation: {
|
||||||
url: "http://hifi-public.s3.amazonaws.com/models/Bboys/bboy2/bboy2.fbx",
|
// Providing actual model fbx for animation used to work, now contorts doll into a weird ball
|
||||||
currentFrame: 0
|
// See bug: https://app.asana.com/0/26225263936266/70097355490098
|
||||||
|
// url: "http://hifi-public.s3.amazonaws.com/models/Bboys/bboy2/bboy2.fbx",
|
||||||
|
running: false,
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -22,6 +22,8 @@
|
||||||
Controller.Standard.LT,
|
Controller.Standard.LT,
|
||||||
Controller.Standard.RT,
|
Controller.Standard.RT,
|
||||||
];
|
];
|
||||||
|
var RELOAD_THRESHOLD = 0.95;
|
||||||
|
|
||||||
Pistol = function() {
|
Pistol = function() {
|
||||||
_this = this;
|
_this = this;
|
||||||
this.equipped = false;
|
this.equipped = false;
|
||||||
|
@ -36,7 +38,7 @@
|
||||||
this.fireSound = SoundCache.getSound("https://s3.amazonaws.com/hifi-public/sounds/Guns/GUN-SHOT2.raw");
|
this.fireSound = SoundCache.getSound("https://s3.amazonaws.com/hifi-public/sounds/Guns/GUN-SHOT2.raw");
|
||||||
this.ricochetSound = SoundCache.getSound("https://s3.amazonaws.com/hifi-public/sounds/Guns/Ricochet.L.wav");
|
this.ricochetSound = SoundCache.getSound("https://s3.amazonaws.com/hifi-public/sounds/Guns/Ricochet.L.wav");
|
||||||
this.playRichochetSoundChance = 0.1;
|
this.playRichochetSoundChance = 0.1;
|
||||||
this.fireVolume = 0.5;
|
this.fireVolume = 0.2;
|
||||||
this.bulletForce = 10;
|
this.bulletForce = 10;
|
||||||
|
|
||||||
|
|
||||||
|
@ -45,6 +47,7 @@
|
||||||
};
|
};
|
||||||
|
|
||||||
Pistol.prototype = {
|
Pistol.prototype = {
|
||||||
|
canShoot: false,
|
||||||
|
|
||||||
startEquip: function(id, params) {
|
startEquip: function(id, params) {
|
||||||
this.equipped = true;
|
this.equipped = true;
|
||||||
|
@ -62,6 +65,17 @@
|
||||||
},
|
},
|
||||||
toggleWithTriggerPressure: function() {
|
toggleWithTriggerPressure: function() {
|
||||||
this.triggerValue = Controller.getValue(TRIGGER_CONTROLS[this.hand]);
|
this.triggerValue = Controller.getValue(TRIGGER_CONTROLS[this.hand]);
|
||||||
|
|
||||||
|
if (this.triggerValue < RELOAD_THRESHOLD) {
|
||||||
|
// print('RELOAD');
|
||||||
|
this.canShoot = true;
|
||||||
|
}
|
||||||
|
if (this.canShoot === true && this.triggerValue === 1) {
|
||||||
|
// print('SHOOT');
|
||||||
|
this.fire();
|
||||||
|
this.canShoot = false;
|
||||||
|
}
|
||||||
|
|
||||||
if (this.triggerValue < DISABLE_LASER_THRESHOLD && this.showLaser === true) {
|
if (this.triggerValue < DISABLE_LASER_THRESHOLD && this.showLaser === true) {
|
||||||
this.showLaser = false;
|
this.showLaser = false;
|
||||||
Overlays.editOverlay(this.laser, {
|
Overlays.editOverlay(this.laser, {
|
||||||
|
@ -74,6 +88,7 @@
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
},
|
},
|
||||||
updateLaser: function() {
|
updateLaser: function() {
|
||||||
var gunProps = Entities.getEntityProperties(this.entityID, ['position', 'rotation']);
|
var gunProps = Entities.getEntityProperties(this.entityID, ['position', 'rotation']);
|
||||||
|
@ -101,7 +116,7 @@
|
||||||
|
|
||||||
preload: function(entityID) {
|
preload: function(entityID) {
|
||||||
this.entityID = entityID;
|
this.entityID = entityID;
|
||||||
this.initControllerMapping();
|
// this.initControllerMapping();
|
||||||
this.laser = Overlays.addOverlay("line3d", {
|
this.laser = Overlays.addOverlay("line3d", {
|
||||||
start: ZERO_VECTOR,
|
start: ZERO_VECTOR,
|
||||||
end: ZERO_VECTOR,
|
end: ZERO_VECTOR,
|
||||||
|
@ -150,22 +165,7 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
initControllerMapping: function() {
|
|
||||||
this.mapping = Controller.newMapping();
|
|
||||||
this.mapping.from(Controller.Standard.LT).hysteresis(0.0, 0.75).to(function(value) {
|
|
||||||
_this.triggerPress(0, value);
|
|
||||||
});
|
|
||||||
|
|
||||||
|
|
||||||
this.mapping.from(Controller.Standard.RT).hysteresis(0.0, 0.75).to(function(value) {
|
|
||||||
_this.triggerPress(1, value);
|
|
||||||
});
|
|
||||||
this.mapping.enable();
|
|
||||||
|
|
||||||
},
|
|
||||||
|
|
||||||
unload: function() {
|
unload: function() {
|
||||||
this.mapping.disable();
|
|
||||||
Overlays.deleteOverlay(this.laser);
|
Overlays.deleteOverlay(this.laser);
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
|
@ -2856,6 +2856,8 @@ void Application::update(float deltaTime) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_controllerScriptingInterface->updateInputControllers();
|
||||||
|
|
||||||
// Transfer the user inputs to the driveKeys
|
// Transfer the user inputs to the driveKeys
|
||||||
// FIXME can we drop drive keys and just have the avatar read the action states directly?
|
// FIXME can we drop drive keys and just have the avatar read the action states directly?
|
||||||
myAvatar->clearDriveKeys();
|
myAvatar->clearDriveKeys();
|
||||||
|
|
|
@ -84,13 +84,12 @@ glm::vec2 ControllerScriptingInterface::getViewportDimensions() const {
|
||||||
return qApp->getUiSize();
|
return qApp->getUiSize();
|
||||||
}
|
}
|
||||||
|
|
||||||
controller::InputController::Pointer ControllerScriptingInterface::createInputController(const QString& deviceName, const QString& tracker) {
|
controller::InputController* ControllerScriptingInterface::createInputController(const QString& deviceName, const QString& tracker) {
|
||||||
// This is where we retreive the Device Tracker category and then the sub tracker within it
|
// This is where we retrieve the Device Tracker category and then the sub tracker within it
|
||||||
auto icIt = _inputControllers.find(0);
|
auto icIt = _inputControllers.find(0);
|
||||||
if (icIt != _inputControllers.end()) {
|
if (icIt != _inputControllers.end()) {
|
||||||
return (*icIt).second;
|
return (*icIt).second.get();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Look for device
|
// Look for device
|
||||||
DeviceTracker::ID deviceID = DeviceTracker::getDeviceID(deviceName.toStdString());
|
DeviceTracker::ID deviceID = DeviceTracker::getDeviceID(deviceName.toStdString());
|
||||||
|
@ -110,18 +109,24 @@ controller::InputController::Pointer ControllerScriptingInterface::createInputCo
|
||||||
controller::InputController::Pointer inputController = std::make_shared<InputController>(deviceID, trackerID, this);
|
controller::InputController::Pointer inputController = std::make_shared<InputController>(deviceID, trackerID, this);
|
||||||
controller::InputController::Key key = inputController->getKey();
|
controller::InputController::Key key = inputController->getKey();
|
||||||
_inputControllers.insert(InputControllerMap::value_type(key, inputController));
|
_inputControllers.insert(InputControllerMap::value_type(key, inputController));
|
||||||
return inputController;
|
return inputController.get();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return controller::InputController::Pointer();
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ControllerScriptingInterface::releaseInputController(controller::InputController::Pointer input) {
|
void ControllerScriptingInterface::releaseInputController(controller::InputController* input) {
|
||||||
_inputControllers.erase(input->getKey());
|
_inputControllers.erase(input->getKey());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ControllerScriptingInterface::updateInputControllers() {
|
||||||
|
for (auto it = _inputControllers.begin(); it != _inputControllers.end(); it++) {
|
||||||
|
(*it).second->update();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
InputController::InputController(int deviceTrackerId, int subTrackerId, QObject* parent) :
|
InputController::InputController(int deviceTrackerId, int subTrackerId, QObject* parent) :
|
||||||
_deviceTrackerId(deviceTrackerId),
|
_deviceTrackerId(deviceTrackerId),
|
||||||
_subTrackerId(subTrackerId),
|
_subTrackerId(subTrackerId),
|
||||||
|
|
|
@ -85,6 +85,8 @@ public:
|
||||||
bool isKeyCaptured(const KeyEvent& event) const;
|
bool isKeyCaptured(const KeyEvent& event) const;
|
||||||
bool isJoystickCaptured(int joystickIndex) const;
|
bool isJoystickCaptured(int joystickIndex) const;
|
||||||
|
|
||||||
|
void updateInputControllers();
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
|
|
||||||
virtual void captureKeyEvents(const KeyEvent& event);
|
virtual void captureKeyEvents(const KeyEvent& event);
|
||||||
|
@ -96,8 +98,8 @@ public slots:
|
||||||
virtual glm::vec2 getViewportDimensions() const;
|
virtual glm::vec2 getViewportDimensions() const;
|
||||||
|
|
||||||
/// Factory to create an InputController
|
/// Factory to create an InputController
|
||||||
virtual controller::InputController::Pointer createInputController(const QString& deviceName, const QString& tracker);
|
virtual controller::InputController* createInputController(const QString& deviceName, const QString& tracker);
|
||||||
virtual void releaseInputController(controller::InputController::Pointer input);
|
virtual void releaseInputController(controller::InputController* input);
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void keyPressEvent(const KeyEvent& event);
|
void keyPressEvent(const KeyEvent& event);
|
||||||
|
|
|
@ -116,7 +116,7 @@ void AvatarData::setOrientation(const glm::quat& orientation, bool overideRefere
|
||||||
glm::vec3 eulerAngles = glm::degrees(safeEulerAngles(orientation));
|
glm::vec3 eulerAngles = glm::degrees(safeEulerAngles(orientation));
|
||||||
_bodyPitch = eulerAngles.x;
|
_bodyPitch = eulerAngles.x;
|
||||||
_bodyYaw = eulerAngles.y;
|
_bodyYaw = eulerAngles.y;
|
||||||
_bodyRoll = eulerAngles.z;
|
_bodyRoll = eulerAngles.z;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1212,7 +1212,14 @@ void AvatarData::setJointMappingsFromNetworkReply() {
|
||||||
|
|
||||||
QByteArray line;
|
QByteArray line;
|
||||||
while (!(line = networkReply->readLine()).isEmpty()) {
|
while (!(line = networkReply->readLine()).isEmpty()) {
|
||||||
if (!(line = line.trimmed()).startsWith("jointIndex")) {
|
line = line.trimmed();
|
||||||
|
if (line.startsWith("filename")) {
|
||||||
|
int filenameIndex = line.indexOf('=') + 1;
|
||||||
|
if (filenameIndex > 0) {
|
||||||
|
_skeletonFBXURL = _skeletonModelURL.resolved(QString(line.mid(filenameIndex).trimmed()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!line.startsWith("jointIndex")) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
int jointNameIndex = line.indexOf('=') + 1;
|
int jointNameIndex = line.indexOf('=') + 1;
|
||||||
|
@ -1522,6 +1529,17 @@ QJsonObject AvatarData::toJson() const {
|
||||||
}
|
}
|
||||||
|
|
||||||
void AvatarData::fromJson(const QJsonObject& json) {
|
void AvatarData::fromJson(const QJsonObject& json) {
|
||||||
|
// The head setOrientation likes to overwrite the avatar orientation,
|
||||||
|
// so lets do the head first
|
||||||
|
// Most head data is relative to the avatar, and needs no basis correction,
|
||||||
|
// but the lookat vector does need correction
|
||||||
|
if (json.contains(JSON_AVATAR_HEAD)) {
|
||||||
|
if (!_headData) {
|
||||||
|
_headData = new HeadData(this);
|
||||||
|
}
|
||||||
|
_headData->fromJson(json[JSON_AVATAR_HEAD].toObject());
|
||||||
|
}
|
||||||
|
|
||||||
if (json.contains(JSON_AVATAR_HEAD_MODEL)) {
|
if (json.contains(JSON_AVATAR_HEAD_MODEL)) {
|
||||||
auto faceModelURL = json[JSON_AVATAR_HEAD_MODEL].toString();
|
auto faceModelURL = json[JSON_AVATAR_HEAD_MODEL].toString();
|
||||||
if (faceModelURL != getFaceModelURL().toString()) {
|
if (faceModelURL != getFaceModelURL().toString()) {
|
||||||
|
@ -1593,15 +1611,6 @@ void AvatarData::fromJson(const QJsonObject& json) {
|
||||||
}
|
}
|
||||||
setRawJointData(jointArray);
|
setRawJointData(jointArray);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Most head data is relative to the avatar, and needs no basis correction,
|
|
||||||
// but the lookat vector does need correction
|
|
||||||
if (json.contains(JSON_AVATAR_HEAD)) {
|
|
||||||
if (!_headData) {
|
|
||||||
_headData = new HeadData(this);
|
|
||||||
}
|
|
||||||
_headData->fromJson(json[JSON_AVATAR_HEAD].toObject());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Every frame will store both a basis for the recording and a relative transform
|
// Every frame will store both a basis for the recording and a relative transform
|
||||||
|
|
|
@ -392,6 +392,7 @@ protected:
|
||||||
|
|
||||||
QUrl _faceModelURL; // These need to be empty so that on first time setting them they will not short circuit
|
QUrl _faceModelURL; // These need to be empty so that on first time setting them they will not short circuit
|
||||||
QUrl _skeletonModelURL; // These need to be empty so that on first time setting them they will not short circuit
|
QUrl _skeletonModelURL; // These need to be empty so that on first time setting them they will not short circuit
|
||||||
|
QUrl _skeletonFBXURL;
|
||||||
QVector<AttachmentData> _attachmentData;
|
QVector<AttachmentData> _attachmentData;
|
||||||
QString _displayName;
|
QString _displayName;
|
||||||
|
|
||||||
|
|
|
@ -81,6 +81,9 @@ void avatarDataFromScriptValue(const QScriptValue &object, AvatarData* &out) {
|
||||||
out = qobject_cast<AvatarData*>(object.toQObject());
|
out = qobject_cast<AvatarData*>(object.toQObject());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Q_DECLARE_METATYPE(controller::InputController*)
|
||||||
|
static int inputControllerPointerId = qRegisterMetaType<controller::InputController*>();
|
||||||
|
|
||||||
QScriptValue inputControllerToScriptValue(QScriptEngine *engine, controller::InputController* const &in) {
|
QScriptValue inputControllerToScriptValue(QScriptEngine *engine, controller::InputController* const &in) {
|
||||||
return engine->newQObject(in);
|
return engine->newQObject(in);
|
||||||
}
|
}
|
||||||
|
@ -89,8 +92,6 @@ void inputControllerFromScriptValue(const QScriptValue &object, controller::Inpu
|
||||||
out = qobject_cast<controller::InputController*>(object.toQObject());
|
out = qobject_cast<controller::InputController*>(object.toQObject());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
static bool hasCorrectSyntax(const QScriptProgram& program) {
|
static bool hasCorrectSyntax(const QScriptProgram& program) {
|
||||||
const auto syntaxCheck = QScriptEngine::checkSyntax(program.sourceCode());
|
const auto syntaxCheck = QScriptEngine::checkSyntax(program.sourceCode());
|
||||||
if (syntaxCheck.state() != QScriptSyntaxCheckResult::Valid) {
|
if (syntaxCheck.state() != QScriptSyntaxCheckResult::Valid) {
|
||||||
|
|
|
@ -132,11 +132,12 @@
|
||||||
createLights();
|
createLights();
|
||||||
|
|
||||||
createCat({
|
createCat({
|
||||||
x: 551.09,
|
x: 551.0,
|
||||||
y: 494.98,
|
y: 495.3,
|
||||||
z: 503.49
|
z: 503.3
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
createSprayCan({
|
createSprayCan({
|
||||||
x: 549.7,
|
x: 549.7,
|
||||||
y: 495.6,
|
y: 495.6,
|
||||||
|
@ -240,6 +241,7 @@
|
||||||
gravity: BOW_GRAVITY,
|
gravity: BOW_GRAVITY,
|
||||||
shapeType: 'compound',
|
shapeType: 'compound',
|
||||||
compoundShapeURL: COLLISION_HULL_URL,
|
compoundShapeURL: COLLISION_HULL_URL,
|
||||||
|
collisionSoundURL: "http://hifi-public.s3.amazonaws.com/sounds/bow_fall.L.wav",
|
||||||
script: bowScriptURL,
|
script: bowScriptURL,
|
||||||
userData: JSON.stringify({
|
userData: JSON.stringify({
|
||||||
resetMe: {
|
resetMe: {
|
||||||
|
@ -648,6 +650,7 @@
|
||||||
z: 0.08
|
z: 0.08
|
||||||
},
|
},
|
||||||
collisionsWillMove: true,
|
collisionsWillMove: true,
|
||||||
|
collisionSoundURL: "http://hifi-public.s3.amazonaws.com/sounds/flashlight_drop.L.wav",
|
||||||
gravity: {
|
gravity: {
|
||||||
x: 0,
|
x: 0,
|
||||||
y: -3.5,
|
y: -3.5,
|
||||||
|
@ -1184,10 +1187,11 @@
|
||||||
z: 0.07
|
z: 0.07
|
||||||
},
|
},
|
||||||
collisionsWillMove: true,
|
collisionsWillMove: true,
|
||||||
|
collisionSoundURL: "http://hifi-public.s3.amazonaws.com/sounds/SpryPntCnDrp1.L.wav",
|
||||||
shapeType: 'box',
|
shapeType: 'box',
|
||||||
gravity: {
|
gravity: {
|
||||||
x: 0,
|
x: 0,
|
||||||
y: -0.5,
|
y: -3.0,
|
||||||
z: 0
|
z: 0
|
||||||
},
|
},
|
||||||
velocity: {
|
velocity: {
|
||||||
|
|
|
@ -110,9 +110,9 @@ MasterReset = function() {
|
||||||
|
|
||||||
|
|
||||||
createCat({
|
createCat({
|
||||||
x: 551.09,
|
x: 551.0,
|
||||||
y: 494.98,
|
y: 495.3,
|
||||||
z: 503.49
|
z: 503.3
|
||||||
});
|
});
|
||||||
|
|
||||||
createSprayCan({
|
createSprayCan({
|
||||||
|
@ -220,6 +220,7 @@ MasterReset = function() {
|
||||||
gravity: BOW_GRAVITY,
|
gravity: BOW_GRAVITY,
|
||||||
shapeType: 'compound',
|
shapeType: 'compound',
|
||||||
compoundShapeURL: COLLISION_HULL_URL,
|
compoundShapeURL: COLLISION_HULL_URL,
|
||||||
|
collisionSoundURL: "http://hifi-public.s3.amazonaws.com/sounds/bow_fall.L.wav",
|
||||||
script: bowScriptURL,
|
script: bowScriptURL,
|
||||||
userData: JSON.stringify({
|
userData: JSON.stringify({
|
||||||
resetMe: {
|
resetMe: {
|
||||||
|
@ -629,6 +630,7 @@ MasterReset = function() {
|
||||||
z: 0.08
|
z: 0.08
|
||||||
},
|
},
|
||||||
collisionsWillMove: true,
|
collisionsWillMove: true,
|
||||||
|
collisionSoundURL: "http://hifi-public.s3.amazonaws.com/sounds/flashlight_drop.L.wav",
|
||||||
gravity: {
|
gravity: {
|
||||||
x: 0,
|
x: 0,
|
||||||
y: -3.5,
|
y: -3.5,
|
||||||
|
@ -1165,10 +1167,11 @@ MasterReset = function() {
|
||||||
z: 0.07
|
z: 0.07
|
||||||
},
|
},
|
||||||
collisionsWillMove: true,
|
collisionsWillMove: true,
|
||||||
|
collisionSoundURL: "http://hifi-public.s3.amazonaws.com/sounds/SpryPntCnDrp1.L.wav",
|
||||||
shapeType: 'box',
|
shapeType: 'box',
|
||||||
gravity: {
|
gravity: {
|
||||||
x: 0,
|
x: 0,
|
||||||
y: -0.5,
|
y: -3.0,
|
||||||
z: 0
|
z: 0
|
||||||
},
|
},
|
||||||
velocity: {
|
velocity: {
|
||||||
|
|
Loading…
Reference in a new issue