Merge branch 'master' of github.com:highfidelity/hifi into polyvox-again

This commit is contained in:
Seth Alves 2015-09-01 21:08:23 -07:00
commit 3963035599
13 changed files with 91 additions and 40 deletions

View file

@ -295,7 +295,7 @@ void AvatarMixer::broadcastAvatarData() {
avatarPacketList.startSegment(); avatarPacketList.startSegment();
numAvatarDataBytes += avatarPacketList.write(otherNode->getUUID().toRfc4122()); numAvatarDataBytes += avatarPacketList.write(otherNode->getUUID().toRfc4122());
numAvatarDataBytes += avatarPacketList.write(otherAvatar.toByteArray()); numAvatarDataBytes += avatarPacketList.write(otherAvatar.toByteArray(false));
avatarPacketList.endSegment(); avatarPacketList.endSegment();

View file

@ -77,10 +77,7 @@ void ScriptableAvatar::update(float deltatime) {
int mapping = animationJoints.indexOf(modelJoints[i]); int mapping = animationJoints.indexOf(modelJoints[i]);
if (mapping != -1 && !_maskedJoints.contains(modelJoints[i])) { if (mapping != -1 && !_maskedJoints.contains(modelJoints[i])) {
JointData& data = _jointData[i]; JointData& data = _jointData[i];
data.valid = true;
data.rotation = safeMix(floorFrame.rotations.at(i), ceilFrame.rotations.at(i), frameFraction); data.rotation = safeMix(floorFrame.rotations.at(i), ceilFrame.rotations.at(i), frameFraction);
} else {
_jointData[i].valid = false;
} }
} }
} else { } else {

View file

@ -20,7 +20,9 @@
elRefresh = document.getElementById("refresh"); elRefresh = document.getElementById("refresh");
elDelete = document.getElementById("delete"); elDelete = document.getElementById("delete");
elTeleport = document.getElementById("teleport"); elTeleport = document.getElementById("teleport");
elRadius = document.getElementById("radius");
elNoEntitiesMessage = document.getElementById("no-entities"); elNoEntitiesMessage = document.getElementById("no-entities");
elNoEntitiesRadius = document.getElementById("no-entities-radius");
document.getElementById("entity-name").onclick = function() { document.getElementById("entity-name").onclick = function() {
setSortColumn('name'); setSortColumn('name');
@ -186,6 +188,13 @@
} }
}, false); }, false);
elRadius.onchange = function () {
elRadius.value = Math.max(elRadius.value, 0);
EventBridge.emitWebEvent(JSON.stringify({ type: 'radius', radius: elRadius.value }));
refreshEntities();
elNoEntitiesRadius.firstChild.nodeValue = elRadius.value;
}
if (window.EventBridge !== undefined) { if (window.EventBridge !== undefined) {
EventBridge.scriptEventReceived.connect(function(data) { EventBridge.scriptEventReceived.connect(function(data) {
data = JSON.parse(data); data = JSON.parse(data);
@ -218,14 +227,15 @@
</head> </head>
<body onload='loaded();'> <body onload='loaded();'>
<div id="entity-list-header"> <div id="entity-list-header">
<input type="button" id="refresh" value="Refresh"></button> <input type="button" id="refresh" value="Refresh" />
<input type="button" id="teleport" value="Teleport"></button> <input type="button" id="teleport" value="Teleport" />
<input type="button" id="delete" style="background-color: rgb(244, 64, 64); float: right" value="Delete"></button> <input type="button" id="delete" style="background-color: rgb(244, 64, 64); float: right" value="Delete" />
</div> </div>
<div id="entity-list"> <div id="entity-list">
<div id="search-area"> <div id="search-area">
<input type="text" class="search" id="filter" placeholder="Filter" /> <input type="text" class="search" id="filter" placeholder="Filter" />
<span id="radius-and-unit"><input type="number" id="radius" value="100" />&nbsp;m</span>
</div> </div>
<table id="entity-table"> <table id="entity-table">
<thead> <thead>
@ -246,7 +256,7 @@
</table> </table>
</div> </div>
<div id="no-entities"> <div id="no-entities">
No entities found within 50 meter radius. Try moving to a different location and refreshing. No entities found within a <span id="no-entities-radius">100</span> meter radius. Try moving to a different location and refreshing.
</div> </div>
</body> </body>
</html> </html>

View file

@ -102,13 +102,23 @@ input[type=button] {
} }
#search-area { #search-area {
width: 100%;
padding: 0.5em; padding: 0.5em;
box-sizing: border-box; box-sizing: border-box;
padding-right: 6em;
} }
#search-area input { #filter {
width: 100%; width: 99%;
}
#radius-and-unit {
width: 6em;
float: right;
margin-right: -6em;
}
#radius {
width: 4em;
} }
textarea, input { textarea, input {

View file

@ -4,6 +4,8 @@ EntityListTool = function(opts) {
var url = Script.resolvePath('html/entityList.html'); var url = Script.resolvePath('html/entityList.html');
var webView = new WebWindow('Entities', url, 200, 280, true); var webView = new WebWindow('Entities', url, 200, 280, true);
var searchRadius = 100;
var visible = false; var visible = false;
webView.setVisible(visible); webView.setVisible(visible);
@ -33,7 +35,7 @@ EntityListTool = function(opts) {
that.sendUpdate = function() { that.sendUpdate = function() {
var entities = []; var entities = [];
var ids = Entities.findEntities(MyAvatar.position, 100); var ids = Entities.findEntities(MyAvatar.position, searchRadius);
for (var i = 0; i < ids.length; i++) { for (var i = 0; i < ids.length; i++) {
var id = ids[i]; var id = ids[i];
var properties = Entities.getEntityProperties(id); var properties = Entities.getEntityProperties(id);
@ -80,6 +82,9 @@ EntityListTool = function(opts) {
} }
} else if (data.type == "delete") { } else if (data.type == "delete") {
deleteSelectedEntities(); deleteSelectedEntities();
} else if (data.type === "radius") {
searchRadius = data.radius;
that.sendUpdate();
} }
}); });

View file

@ -200,11 +200,9 @@ void Avatar::simulate(float deltaTime) {
if (!_shouldRenderBillboard && inViewFrustum) { if (!_shouldRenderBillboard && inViewFrustum) {
{ {
PerformanceTimer perfTimer("skeleton"); PerformanceTimer perfTimer("skeleton");
if (_hasNewJointRotations) { for (int i = 0; i < _jointData.size(); i++) {
for (int i = 0; i < _jointData.size(); i++) { const JointData& data = _jointData.at(i);
const JointData& data = _jointData.at(i); _skeletonModel.setJointState(i, true, data.rotation);
_skeletonModel.setJointState(i, data.valid, data.rotation);
}
} }
_skeletonModel.simulate(deltaTime, _hasNewJointRotations); _skeletonModel.simulate(deltaTime, _hasNewJointRotations);
simulateAttachments(deltaTime); simulateAttachments(deltaTime);
@ -784,8 +782,10 @@ Transform Avatar::calculateDisplayNameTransform(const ViewFrustum& frustum, floa
void Avatar::renderDisplayName(gpu::Batch& batch, const ViewFrustum& frustum, const glm::ivec4& viewport) const { void Avatar::renderDisplayName(gpu::Batch& batch, const ViewFrustum& frustum, const glm::ivec4& viewport) const {
bool shouldShowReceiveStats = DependencyManager::get<AvatarManager>()->shouldShowReceiveStats() && !isMyAvatar(); bool shouldShowReceiveStats = DependencyManager::get<AvatarManager>()->shouldShowReceiveStats() && !isMyAvatar();
// If we have nothing to draw, or it's tottaly transparent, return // If we have nothing to draw, or it's totally transparent, or it's too close or behind the camera, return
if ((_displayName.isEmpty() && !shouldShowReceiveStats) || _displayNameAlpha == 0.0f) { const float CLIP_DISTANCE = 0.2f;
if ((_displayName.isEmpty() && !shouldShowReceiveStats) || _displayNameAlpha == 0.0f
|| (glm::dot(frustum.getDirection(), getDisplayNamePosition() - frustum.getPosition()) <= CLIP_DISTANCE)) {
return; return;
} }
auto renderer = textRenderer(DISPLAYNAME); auto renderer = textRenderer(DISPLAYNAME);

View file

@ -123,18 +123,18 @@ MyAvatar::~MyAvatar() {
_lookAtTargetAvatar.reset(); _lookAtTargetAvatar.reset();
} }
QByteArray MyAvatar::toByteArray() { QByteArray MyAvatar::toByteArray(bool cullSmallChanges) {
CameraMode mode = Application::getInstance()->getCamera()->getMode(); CameraMode mode = Application::getInstance()->getCamera()->getMode();
if (mode == CAMERA_MODE_THIRD_PERSON || mode == CAMERA_MODE_INDEPENDENT) { if (mode == CAMERA_MODE_THIRD_PERSON || mode == CAMERA_MODE_INDEPENDENT) {
// fake the avatar position that is sent up to the AvatarMixer // fake the avatar position that is sent up to the AvatarMixer
glm::vec3 oldPosition = _position; glm::vec3 oldPosition = _position;
_position = getSkeletonPosition(); _position = getSkeletonPosition();
QByteArray array = AvatarData::toByteArray(); QByteArray array = AvatarData::toByteArray(cullSmallChanges);
// copy the correct position back // copy the correct position back
_position = oldPosition; _position = oldPosition;
return array; return array;
} }
return AvatarData::toByteArray(); return AvatarData::toByteArray(cullSmallChanges);
} }
void MyAvatar::reset() { void MyAvatar::reset() {
@ -220,7 +220,7 @@ void MyAvatar::simulate(float deltaTime) {
_jointData.resize(_rig->getJointStateCount()); _jointData.resize(_rig->getJointStateCount());
for (int i = 0; i < _jointData.size(); i++) { for (int i = 0; i < _jointData.size(); i++) {
JointData& data = _jointData[i]; JointData& data = _jointData[i];
data.valid = _rig->getJointStateRotation(i, data.rotation); _rig->getJointStateRotation(i, data.rotation);
} }
} }

View file

@ -200,7 +200,7 @@ private:
glm::vec3 getWorldBodyPosition() const; glm::vec3 getWorldBodyPosition() const;
glm::quat getWorldBodyOrientation() const; glm::quat getWorldBodyOrientation() const;
QByteArray toByteArray(); QByteArray toByteArray(bool cullSmallChanges);
void simulate(float deltaTime); void simulate(float deltaTime);
void updateFromTrackers(float deltaTime); void updateFromTrackers(float deltaTime);
virtual void render(RenderArgs* renderArgs, const glm::vec3& cameraPositio) override; virtual void render(RenderArgs* renderArgs, const glm::vec3& cameraPositio) override;

View file

@ -31,6 +31,10 @@
quint64 DEFAULT_FILTERED_LOG_EXPIRY = 2 * USECS_PER_SECOND; quint64 DEFAULT_FILTERED_LOG_EXPIRY = 2 * USECS_PER_SECOND;
// this controls how large a change in joint-rotation must be before the interface sends it to the avatar mixer
const float MIN_ROTATION_DOT = 0.9999999f;
using namespace std; using namespace std;
const glm::vec3 DEFAULT_LOCAL_AABOX_CORNER(-0.5f); const glm::vec3 DEFAULT_LOCAL_AABOX_CORNER(-0.5f);
@ -141,7 +145,7 @@ void AvatarData::setHandPosition(const glm::vec3& handPosition) {
_handPosition = glm::inverse(getOrientation()) * (handPosition - _position); _handPosition = glm::inverse(getOrientation()) * (handPosition - _position);
} }
QByteArray AvatarData::toByteArray() { QByteArray AvatarData::toByteArray(bool cullSmallChanges) {
// TODO: DRY this up to a shared method // TODO: DRY this up to a shared method
// that can pack any type given the number of bytes // that can pack any type given the number of bytes
// and return the number of bytes to push the pointer // and return the number of bytes to push the pointer
@ -234,11 +238,19 @@ QByteArray AvatarData::toByteArray() {
// joint data // joint data
*destinationBuffer++ = _jointData.size(); *destinationBuffer++ = _jointData.size();
unsigned char* validityPosition = destinationBuffer;
unsigned char validity = 0; unsigned char validity = 0;
int validityBit = 0; int validityBit = 0;
foreach (const JointData& data, _jointData) {
if (data.valid) { _lastSentJointData.resize(_jointData.size());
validity |= (1 << validityBit);
// foreach (const JointData& data, _jointData) {
for (int i=0; i < _jointData.size(); i++) {
const JointData& data = _jointData.at(i);
if (_lastSentJointData[i].rotation != data.rotation) {
if (!cullSmallChanges || fabsf(glm::dot(data.rotation, _lastSentJointData[i].rotation)) <= MIN_ROTATION_DOT) {
validity |= (1 << validityBit);
}
} }
if (++validityBit == BITS_IN_BYTE) { if (++validityBit == BITS_IN_BYTE) {
*destinationBuffer++ = validity; *destinationBuffer++ = validity;
@ -248,9 +260,18 @@ QByteArray AvatarData::toByteArray() {
if (validityBit != 0) { if (validityBit != 0) {
*destinationBuffer++ = validity; *destinationBuffer++ = validity;
} }
foreach (const JointData& data, _jointData) {
if (data.valid) { validityBit = 0;
validity = *validityPosition++;
for (int i = 0; i < _jointData.size(); i ++) {
const JointData& data = _jointData[ i ];
if (validity & (1 << validityBit)) {
destinationBuffer += packOrientationQuatToBytes(destinationBuffer, data.rotation); destinationBuffer += packOrientationQuatToBytes(destinationBuffer, data.rotation);
_lastSentJointData[i].rotation = data.rotation;
}
if (++validityBit == BITS_IN_BYTE) {
validityBit = 0;
validity = *validityPosition++;
} }
} }
@ -494,6 +515,10 @@ int AvatarData::parseDataFromBuffer(const QByteArray& buffer) {
} }
int numValidJoints = 0; int numValidJoints = 0;
_jointData.resize(numJoints); _jointData.resize(numJoints);
QVector<bool> valids;
valids.resize(numJoints);
{ // validity bits { // validity bits
unsigned char validity = 0; unsigned char validity = 0;
int validityBit = 0; int validityBit = 0;
@ -505,7 +530,7 @@ int AvatarData::parseDataFromBuffer(const QByteArray& buffer) {
if (valid) { if (valid) {
++numValidJoints; ++numValidJoints;
} }
_jointData[i].valid = valid; valids[i] = valid;
validityBit = (validityBit + 1) % BITS_IN_BYTE; validityBit = (validityBit + 1) % BITS_IN_BYTE;
} }
} }
@ -527,7 +552,7 @@ int AvatarData::parseDataFromBuffer(const QByteArray& buffer) {
{ // joint data { // joint data
for (int i = 0; i < numJoints; i++) { for (int i = 0; i < numJoints; i++) {
JointData& data = _jointData[i]; JointData& data = _jointData[i];
if (data.valid) { if (valids[i]) {
_hasNewJointRotations = true; _hasNewJointRotations = true;
sourceBuffer += unpackOrientationQuatFromBytes(sourceBuffer, data.rotation); sourceBuffer += unpackOrientationQuatFromBytes(sourceBuffer, data.rotation);
} }
@ -731,7 +756,6 @@ void AvatarData::setJointData(int index, const glm::quat& rotation) {
_jointData.resize(index + 1); _jointData.resize(index + 1);
} }
JointData& data = _jointData[index]; JointData& data = _jointData[index];
data.valid = true;
data.rotation = rotation; data.rotation = rotation;
} }
@ -746,7 +770,6 @@ void AvatarData::clearJointData(int index) {
if (_jointData.size() <= index) { if (_jointData.size() <= index) {
_jointData.resize(index + 1); _jointData.resize(index + 1);
} }
_jointData[index].valid = false;
} }
bool AvatarData::isJointDataValid(int index) const { bool AvatarData::isJointDataValid(int index) const {
@ -759,7 +782,7 @@ bool AvatarData::isJointDataValid(int index) const {
Q_RETURN_ARG(bool, result), Q_ARG(int, index)); Q_RETURN_ARG(bool, result), Q_ARG(int, index));
return result; return result;
} }
return index < _jointData.size() && _jointData.at(index).valid; return index < _jointData.size();
} }
glm::quat AvatarData::getJointRotation(int index) const { glm::quat AvatarData::getJointRotation(int index) const {
@ -1060,7 +1083,7 @@ void AvatarData::setJointMappingsFromNetworkReply() {
void AvatarData::sendAvatarDataPacket() { void AvatarData::sendAvatarDataPacket() {
auto nodeList = DependencyManager::get<NodeList>(); auto nodeList = DependencyManager::get<NodeList>();
QByteArray avatarByteArray = toByteArray(); QByteArray avatarByteArray = toByteArray(true);
auto avatarPacket = NLPacket::create(PacketType::AvatarData, avatarByteArray.size()); auto avatarPacket = NLPacket::create(PacketType::AvatarData, avatarByteArray.size());
avatarPacket->write(avatarByteArray); avatarPacket->write(avatarByteArray);

View file

@ -171,7 +171,7 @@ public:
glm::vec3 getHandPosition() const; glm::vec3 getHandPosition() const;
void setHandPosition(const glm::vec3& handPosition); void setHandPosition(const glm::vec3& handPosition);
virtual QByteArray toByteArray(); virtual QByteArray toByteArray(bool cullSmallChanges);
/// \return true if an error should be logged /// \return true if an error should be logged
bool shouldLogError(const quint64& now); bool shouldLogError(const quint64& now);
@ -357,6 +357,7 @@ protected:
char _handState; char _handState;
QVector<JointData> _jointData; ///< the state of the skeleton joints QVector<JointData> _jointData; ///< the state of the skeleton joints
QVector<JointData> _lastSentJointData; ///< the state of the skeleton joints last time we transmitted
// key state // key state
KeyState _keyState; KeyState _keyState;
@ -408,7 +409,6 @@ Q_DECLARE_METATYPE(AvatarData*)
class JointData { class JointData {
public: public:
bool valid;
glm::quat rotation; glm::quat rotation;
}; };

View file

@ -34,6 +34,8 @@ Q_LOGGING_CATEGORY(inputplugins, "hifi.inputplugins")
const unsigned int LEFT_MASK = 0; const unsigned int LEFT_MASK = 0;
const unsigned int RIGHT_MASK = 1U << 1; const unsigned int RIGHT_MASK = 1U << 1;
#ifdef HAVE_SIXENSE
const int CALIBRATION_STATE_IDLE = 0; const int CALIBRATION_STATE_IDLE = 0;
const int CALIBRATION_STATE_X = 1; const int CALIBRATION_STATE_X = 1;
const int CALIBRATION_STATE_Y = 2; const int CALIBRATION_STATE_Y = 2;
@ -47,11 +49,15 @@ const float NECK_Z = 0.3f; // meters
const float CONTROLLER_THRESHOLD = 0.35f; const float CONTROLLER_THRESHOLD = 0.35f;
#endif
#ifdef __APPLE__ #ifdef __APPLE__
typedef int (*SixenseBaseFunction)(); typedef int (*SixenseBaseFunction)();
typedef int (*SixenseTakeIntFunction)(int); typedef int (*SixenseTakeIntFunction)(int);
#ifdef HAVE_SIXENSE
typedef int (*SixenseTakeIntAndSixenseControllerData)(int, sixenseControllerData*); typedef int (*SixenseTakeIntAndSixenseControllerData)(int, sixenseControllerData*);
#endif #endif
#endif
const QString SixenseManager::NAME = "Sixense"; const QString SixenseManager::NAME = "Sixense";

View file

@ -69,7 +69,7 @@ PacketVersion versionForPacketType(PacketType::Value packetType) {
case EntityData: case EntityData:
return VERSION_ENTITIES_POLYVOX_NEIGHBORS; return VERSION_ENTITIES_POLYVOX_NEIGHBORS;
case AvatarData: case AvatarData:
return 12; return 13;
default: default:
return 11; return 11;
} }

View file

@ -599,7 +599,7 @@ void ScriptEngine::run() {
/ (1000 * 1000)) + 0.5); / (1000 * 1000)) + 0.5);
const int SCRIPT_AUDIO_BUFFER_BYTES = SCRIPT_AUDIO_BUFFER_SAMPLES * sizeof(int16_t); const int SCRIPT_AUDIO_BUFFER_BYTES = SCRIPT_AUDIO_BUFFER_SAMPLES * sizeof(int16_t);
QByteArray avatarByteArray = _avatarData->toByteArray(); QByteArray avatarByteArray = _avatarData->toByteArray(true);
auto avatarPacket = NLPacket::create(PacketType::AvatarData, avatarByteArray.size()); auto avatarPacket = NLPacket::create(PacketType::AvatarData, avatarByteArray.size());
avatarPacket->write(avatarByteArray); avatarPacket->write(avatarByteArray);