mirror of
https://github.com/overte-org/overte.git
synced 2025-06-16 03:00:40 +02:00
Merge branch 'master' of https://github.com/highfidelity/hifi into undo_redo_system
This commit is contained in:
commit
174f37f531
24 changed files with 223 additions and 88 deletions
|
@ -12,6 +12,7 @@
|
||||||
<th>Pool</th>
|
<th>Pool</th>
|
||||||
<th>Public</th>
|
<th>Public</th>
|
||||||
<th>Local</th>
|
<th>Local</th>
|
||||||
|
<th>Uptime (s)</th>
|
||||||
<th>Kill?</th>
|
<th>Kill?</th>
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
|
|
|
@ -2,16 +2,47 @@ $(document).ready(function(){
|
||||||
// setup a function to grab the assignments
|
// setup a function to grab the assignments
|
||||||
function getNodesAndAssignments() {
|
function getNodesAndAssignments() {
|
||||||
$.getJSON("nodes.json", function(json){
|
$.getJSON("nodes.json", function(json){
|
||||||
|
|
||||||
|
json.nodes.sort(function(a, b){
|
||||||
|
if (a.type === b.type) {
|
||||||
|
if (a.wake_timestamp < b.wake_timestamp) {
|
||||||
|
return 1;
|
||||||
|
} else if (a.wake_timestamp > b.wake_timestamp) {
|
||||||
|
return -1;
|
||||||
|
} else {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (a.type === "agent" && b.type !== "agent") {
|
||||||
|
return 1;
|
||||||
|
} else if (b.type === "agent" && a.type !== "agent") {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (a.type > b.type) {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (a.type < b.type) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
nodesTableBody = "";
|
nodesTableBody = "";
|
||||||
|
|
||||||
$.each(json.nodes, function (uuid, data) {
|
$.each(json.nodes, function(index, data) {
|
||||||
nodesTableBody += "<tr>";
|
nodesTableBody += "<tr>";
|
||||||
nodesTableBody += "<td>" + data.type + "</td>";
|
nodesTableBody += "<td>" + data.type + "</td>";
|
||||||
nodesTableBody += "<td><a href='stats/?uuid=" + uuid + "'>" + uuid + "</a></td>";
|
nodesTableBody += "<td><a href='stats/?uuid=" + data.uuid + "'>" + data.uuid + "</a></td>";
|
||||||
nodesTableBody += "<td>" + (data.pool ? data.pool : "") + "</td>";
|
nodesTableBody += "<td>" + (data.pool ? data.pool : "") + "</td>";
|
||||||
nodesTableBody += "<td>" + data.public.ip + "<span class='port'>:" + data.public.port + "</span></td>";
|
nodesTableBody += "<td>" + data.public.ip + "<span class='port'>:" + data.public.port + "</span></td>";
|
||||||
nodesTableBody += "<td>" + data.local.ip + "<span class='port'>:" + data.local.port + "</span></td>";
|
nodesTableBody += "<td>" + data.local.ip + "<span class='port'>:" + data.local.port + "</span></td>";
|
||||||
nodesTableBody += "<td><span class='glyphicon glyphicon-remove' data-uuid=" + uuid + "></span></td>";
|
|
||||||
|
var uptimeSeconds = (Date.now() - data.wake_timestamp) / 1000;
|
||||||
|
nodesTableBody += "<td>" + uptimeSeconds.toLocaleString() + "</td>";
|
||||||
|
|
||||||
|
nodesTableBody += "<td><span class='glyphicon glyphicon-remove' data-uuid=" + data.uuid + "></span></td>";
|
||||||
nodesTableBody += "</tr>";
|
nodesTableBody += "</tr>";
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -622,10 +622,12 @@ QJsonObject DomainServer::jsonForSocket(const HifiSockAddr& socket) {
|
||||||
return socketJSON;
|
return socketJSON;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const char JSON_KEY_UUID[] = "uuid";
|
||||||
const char JSON_KEY_TYPE[] = "type";
|
const char JSON_KEY_TYPE[] = "type";
|
||||||
const char JSON_KEY_PUBLIC_SOCKET[] = "public";
|
const char JSON_KEY_PUBLIC_SOCKET[] = "public";
|
||||||
const char JSON_KEY_LOCAL_SOCKET[] = "local";
|
const char JSON_KEY_LOCAL_SOCKET[] = "local";
|
||||||
const char JSON_KEY_POOL[] = "pool";
|
const char JSON_KEY_POOL[] = "pool";
|
||||||
|
const char JSON_KEY_WAKE_TIMESTAMP[] = "wake_timestamp";
|
||||||
|
|
||||||
QJsonObject DomainServer::jsonObjectForNode(const SharedNodePointer& node) {
|
QJsonObject DomainServer::jsonObjectForNode(const SharedNodePointer& node) {
|
||||||
QJsonObject nodeJson;
|
QJsonObject nodeJson;
|
||||||
|
@ -635,6 +637,9 @@ QJsonObject DomainServer::jsonObjectForNode(const SharedNodePointer& node) {
|
||||||
nodeTypeName = nodeTypeName.toLower();
|
nodeTypeName = nodeTypeName.toLower();
|
||||||
nodeTypeName.replace(' ', '-');
|
nodeTypeName.replace(' ', '-');
|
||||||
|
|
||||||
|
// add the node UUID
|
||||||
|
nodeJson[JSON_KEY_UUID] = uuidStringWithoutCurlyBraces(node->getUUID());
|
||||||
|
|
||||||
// add the node type
|
// add the node type
|
||||||
nodeJson[JSON_KEY_TYPE] = nodeTypeName;
|
nodeJson[JSON_KEY_TYPE] = nodeTypeName;
|
||||||
|
|
||||||
|
@ -642,6 +647,9 @@ QJsonObject DomainServer::jsonObjectForNode(const SharedNodePointer& node) {
|
||||||
nodeJson[JSON_KEY_PUBLIC_SOCKET] = jsonForSocket(node->getPublicSocket());
|
nodeJson[JSON_KEY_PUBLIC_SOCKET] = jsonForSocket(node->getPublicSocket());
|
||||||
nodeJson[JSON_KEY_LOCAL_SOCKET] = jsonForSocket(node->getLocalSocket());
|
nodeJson[JSON_KEY_LOCAL_SOCKET] = jsonForSocket(node->getLocalSocket());
|
||||||
|
|
||||||
|
// add the node uptime in our list
|
||||||
|
nodeJson[JSON_KEY_WAKE_TIMESTAMP] = QString::number(node->getWakeTimestamp());
|
||||||
|
|
||||||
// if the node has pool information, add it
|
// if the node has pool information, add it
|
||||||
SharedAssignmentPointer matchingAssignment = _staticAssignmentHash.value(node->getUUID());
|
SharedAssignmentPointer matchingAssignment = _staticAssignmentHash.value(node->getUUID());
|
||||||
if (matchingAssignment) {
|
if (matchingAssignment) {
|
||||||
|
@ -707,18 +715,17 @@ bool DomainServer::handleHTTPRequest(HTTPConnection* connection, const QUrl& url
|
||||||
} else if (url.path() == QString("%1.json").arg(URI_NODES)) {
|
} else if (url.path() == QString("%1.json").arg(URI_NODES)) {
|
||||||
// setup the JSON
|
// setup the JSON
|
||||||
QJsonObject rootJSON;
|
QJsonObject rootJSON;
|
||||||
QJsonObject nodesJSON;
|
QJsonArray nodesJSONArray;
|
||||||
|
|
||||||
// enumerate the NodeList to find the assigned nodes
|
// enumerate the NodeList to find the assigned nodes
|
||||||
NodeList* nodeList = NodeList::getInstance();
|
NodeList* nodeList = NodeList::getInstance();
|
||||||
|
|
||||||
foreach (const SharedNodePointer& node, nodeList->getNodeHash()) {
|
foreach (const SharedNodePointer& node, nodeList->getNodeHash()) {
|
||||||
// add the node using the UUID as the key
|
// add the node using the UUID as the key
|
||||||
QString uuidString = uuidStringWithoutCurlyBraces(node->getUUID());
|
nodesJSONArray.append(jsonObjectForNode(node));
|
||||||
nodesJSON[uuidString] = jsonObjectForNode(node);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
rootJSON["nodes"] = nodesJSON;
|
rootJSON["nodes"] = nodesJSONArray;
|
||||||
|
|
||||||
// print out the created JSON
|
// print out the created JSON
|
||||||
QJsonDocument nodesDocument(rootJSON);
|
QJsonDocument nodesDocument(rootJSON);
|
||||||
|
|
|
@ -30,9 +30,10 @@ var gravity = {
|
||||||
var damping = 0.1;
|
var damping = 0.1;
|
||||||
|
|
||||||
var scriptA = " " +
|
var scriptA = " " +
|
||||||
" function collisionWithParticle(other, penetration) { " +
|
" function collisionWithParticle(other, collision) { " +
|
||||||
" print('collisionWithParticle(other.getID()=' + other.getID() + ')...'); " +
|
" print('collisionWithParticle(other.getID()=' + other.getID() + ')...'); " +
|
||||||
" Vec3.print('penetration=', penetration); " +
|
" Vec3.print('penetration=', collision.penetration); " +
|
||||||
|
" Vec3.print('contactPoint=', collision.contactPoint); " +
|
||||||
" print('myID=' + Particle.getID() + '\\n'); " +
|
" print('myID=' + Particle.getID() + '\\n'); " +
|
||||||
" var colorBlack = { red: 0, green: 0, blue: 0 };" +
|
" var colorBlack = { red: 0, green: 0, blue: 0 };" +
|
||||||
" var otherColor = other.getColor();" +
|
" var otherColor = other.getColor();" +
|
||||||
|
@ -46,9 +47,10 @@ var scriptA = " " +
|
||||||
" ";
|
" ";
|
||||||
|
|
||||||
var scriptB = " " +
|
var scriptB = " " +
|
||||||
" function collisionWithParticle(other, penetration) { " +
|
" function collisionWithParticle(other, collision) { " +
|
||||||
" print('collisionWithParticle(other.getID()=' + other.getID() + ')...'); " +
|
" print('collisionWithParticle(other.getID()=' + other.getID() + ')...'); " +
|
||||||
" Vec3.print('penetration=', penetration); " +
|
" Vec3.print('penetration=', collision.penetration); " +
|
||||||
|
" Vec3.print('contactPoint=', collision.contactPoint); " +
|
||||||
" print('myID=' + Particle.getID() + '\\n'); " +
|
" print('myID=' + Particle.getID() + '\\n'); " +
|
||||||
" Particle.setScript('Particle.setShouldDie(true);'); " +
|
" Particle.setScript('Particle.setShouldDie(true);'); " +
|
||||||
" } " +
|
" } " +
|
||||||
|
|
|
@ -12,9 +12,12 @@ var AMPLITUDE = 45.0;
|
||||||
|
|
||||||
var cumulativeTime = 0.0;
|
var cumulativeTime = 0.0;
|
||||||
|
|
||||||
print("Joint List:");
|
print("# Joint list start");
|
||||||
var jointList = MyAvatar.getJointNames();
|
var jointList = MyAvatar.getJointNames();
|
||||||
print(jointList);
|
for (var i = 0; i < jointList.length; i++) {
|
||||||
|
print("jointIndex = " + jointList[i] + " = " + i);
|
||||||
|
}
|
||||||
|
print("# Joint list end");
|
||||||
|
|
||||||
Script.update.connect(function(deltaTime) {
|
Script.update.connect(function(deltaTime) {
|
||||||
cumulativeTime += deltaTime;
|
cumulativeTime += deltaTime;
|
||||||
|
|
|
@ -12,18 +12,20 @@
|
||||||
|
|
||||||
print("hello...");
|
print("hello...");
|
||||||
|
|
||||||
function particleCollisionWithVoxel(particle, voxel, penetration) {
|
function particleCollisionWithVoxel(particle, voxel, collision) {
|
||||||
print("particleCollisionWithVoxel()..");
|
print("particleCollisionWithVoxel()..");
|
||||||
print(" particle.getID()=" + particle.id);
|
print(" particle.getID()=" + particle.id);
|
||||||
print(" voxel color...=" + voxel.red + ", " + voxel.green + ", " + voxel.blue);
|
print(" voxel color...=" + voxel.red + ", " + voxel.green + ", " + voxel.blue);
|
||||||
Vec3.print('penetration=', penetration);
|
Vec3.print('penetration=', collision.penetration);
|
||||||
|
Vec3.print('contactPoint=', collision.contactPoint);
|
||||||
}
|
}
|
||||||
|
|
||||||
function particleCollisionWithParticle(particleA, particleB, penetration) {
|
function particleCollisionWithParticle(particleA, particleB, collision) {
|
||||||
print("particleCollisionWithParticle()..");
|
print("particleCollisionWithParticle()..");
|
||||||
print(" particleA.getID()=" + particleA.id);
|
print(" particleA.getID()=" + particleA.id);
|
||||||
print(" particleB.getID()=" + particleB.id);
|
print(" particleB.getID()=" + particleB.id);
|
||||||
Vec3.print('penetration=', penetration);
|
Vec3.print('penetration=', collision.penetration);
|
||||||
|
Vec3.print('contactPoint=', collision.contactPoint);
|
||||||
}
|
}
|
||||||
|
|
||||||
Particles.particleCollisionWithVoxel.connect(particleCollisionWithVoxel);
|
Particles.particleCollisionWithVoxel.connect(particleCollisionWithVoxel);
|
||||||
|
|
|
@ -145,24 +145,21 @@ function shootTarget() {
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
function particleCollisionWithVoxel(particle, voxel, penetration) {
|
function particleCollisionWithVoxel(particle, voxel, collision) {
|
||||||
var HOLE_SIZE = 0.125;
|
var HOLE_SIZE = 0.125;
|
||||||
var particleProperties = Particles.getParticleProperties(particle);
|
var particleProperties = Particles.getParticleProperties(particle);
|
||||||
var position = particleProperties.position;
|
var position = particleProperties.position;
|
||||||
Particles.deleteParticle(particle);
|
Particles.deleteParticle(particle);
|
||||||
// Make a hole in this voxel
|
// Make a hole in this voxel
|
||||||
Vec3.print("penetration", penetration);
|
Vec3.print("penetration", collision.penetration);
|
||||||
Vec3.print("position", position);
|
Vec3.print("contactPoint", collision.contactPoint);
|
||||||
var pointOfEntry = Vec3.subtract(position, penetration);
|
Voxels.eraseVoxel(contactPoint.x, contactPoint.y, contactPoint.z, HOLE_SIZE);
|
||||||
Vec3.print("pointOfEntry", pointOfEntry);
|
|
||||||
Voxels.eraseVoxel(pointOfEntry.x, pointOfEntry.y, pointOfEntry.z, HOLE_SIZE);
|
|
||||||
Voxels.eraseVoxel(position.x, position.y, position.z, HOLE_SIZE);
|
Voxels.eraseVoxel(position.x, position.y, position.z, HOLE_SIZE);
|
||||||
//audioOptions.position = position;
|
|
||||||
audioOptions.position = Vec3.sum(Camera.getPosition(), Quat.getFront(Camera.getOrientation()));
|
audioOptions.position = Vec3.sum(Camera.getPosition(), Quat.getFront(Camera.getOrientation()));
|
||||||
Audio.playSound(impactSound, audioOptions);
|
Audio.playSound(impactSound, audioOptions);
|
||||||
}
|
}
|
||||||
|
|
||||||
function particleCollisionWithParticle(particle1, particle2) {
|
function particleCollisionWithParticle(particle1, particle2, collision) {
|
||||||
score++;
|
score++;
|
||||||
if (showScore) {
|
if (showScore) {
|
||||||
Overlays.editOverlay(text, { text: "Score: " + score } );
|
Overlays.editOverlay(text, { text: "Score: " + score } );
|
||||||
|
@ -174,9 +171,11 @@ function particleCollisionWithParticle(particle1, particle2) {
|
||||||
var endTime = new Date();
|
var endTime = new Date();
|
||||||
var msecs = endTime.valueOf() - shotTime.valueOf();
|
var msecs = endTime.valueOf() - shotTime.valueOf();
|
||||||
print("hit, msecs = " + msecs);
|
print("hit, msecs = " + msecs);
|
||||||
|
Vec3.print("penetration = ", collision.penetration);
|
||||||
|
Vec3.print("contactPoint = ", collision.contactPoint);
|
||||||
Particles.deleteParticle(particle1);
|
Particles.deleteParticle(particle1);
|
||||||
Particles.deleteParticle(particle2);
|
Particles.deleteParticle(particle2);
|
||||||
audioOptions.position = newPosition;
|
// play the sound near the camera so the shooter can hear it
|
||||||
audioOptions.position = Vec3.sum(Camera.getPosition(), Quat.getFront(Camera.getOrientation()));
|
audioOptions.position = Vec3.sum(Camera.getPosition(), Quat.getFront(Camera.getOrientation()));
|
||||||
Audio.playSound(targetHitSound, audioOptions);
|
Audio.playSound(targetHitSound, audioOptions);
|
||||||
}
|
}
|
||||||
|
|
|
@ -62,9 +62,10 @@ function checkController(deltaTime) {
|
||||||
|
|
||||||
// This is the script for the particles that this gun shoots.
|
// This is the script for the particles that this gun shoots.
|
||||||
var script =
|
var script =
|
||||||
" function collisionWithVoxel(voxel, penetration) { " +
|
" function collisionWithVoxel(voxel, collision) { " +
|
||||||
" print('collisionWithVoxel(voxel)... '); " +
|
" print('collisionWithVoxel(voxel)... '); " +
|
||||||
" Vec3.print('penetration=', penetration); " +
|
" Vec3.print('penetration=', collision.penetration); " +
|
||||||
|
" Vec3.print('contactPoint=', collision.contactPoint); " +
|
||||||
" print('myID=' + Particle.getID() + '\\n'); " +
|
" print('myID=' + Particle.getID() + '\\n'); " +
|
||||||
" var voxelColor = { red: voxel.red, green: voxel.green, blue: voxel.blue };" +
|
" var voxelColor = { red: voxel.red, green: voxel.green, blue: voxel.blue };" +
|
||||||
" var voxelAt = { x: voxel.x, y: voxel.y, z: voxel.z };" +
|
" var voxelAt = { x: voxel.x, y: voxel.y, z: voxel.z };" +
|
||||||
|
|
|
@ -392,9 +392,10 @@ function deleteIfInvader(possibleInvaderParticle) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function particleCollisionWithParticle(particleA, particleB, penetration) {
|
function particleCollisionWithParticle(particleA, particleB, collision) {
|
||||||
print("particleCollisionWithParticle() a.id="+particleA.id + " b.id=" + particleB.id);
|
print("particleCollisionWithParticle() a.id="+particleA.id + " b.id=" + particleB.id);
|
||||||
Vec3.print('particleCollisionWithParticle() penetration=', penetration);
|
Vec3.print('particleCollisionWithParticle() penetration=', collision.penetration);
|
||||||
|
Vec3.print('particleCollisionWithParticle() contactPoint=', collision.contactPoint);
|
||||||
if (missileFired) {
|
if (missileFired) {
|
||||||
myMissile = Particles.identifyParticle(myMissile);
|
myMissile = Particles.identifyParticle(myMissile);
|
||||||
if (myMissile.id == particleA.id) {
|
if (myMissile.id == particleA.id) {
|
||||||
|
|
|
@ -1572,14 +1572,14 @@ void Application::init() {
|
||||||
|
|
||||||
// connect the _particleCollisionSystem to our script engine's ParticleScriptingInterface
|
// connect the _particleCollisionSystem to our script engine's ParticleScriptingInterface
|
||||||
connect(&_particleCollisionSystem,
|
connect(&_particleCollisionSystem,
|
||||||
SIGNAL(particleCollisionWithVoxel(const ParticleID&, const VoxelDetail&, const glm::vec3&)),
|
SIGNAL(particleCollisionWithVoxel(const ParticleID&, const VoxelDetail&, const CollisionInfo&)),
|
||||||
ScriptEngine::getParticlesScriptingInterface(),
|
ScriptEngine::getParticlesScriptingInterface(),
|
||||||
SLOT(forwardParticleCollisionWithVoxel(const ParticleID&, const VoxelDetail&, const glm::vec3&)));
|
SIGNAL(particleCollisionWithVoxels(const ParticleID&, const VoxelDetail&, const CollisionInfo&)));
|
||||||
|
|
||||||
connect(&_particleCollisionSystem,
|
connect(&_particleCollisionSystem,
|
||||||
SIGNAL(particleCollisionWithParticle(const ParticleID&, const ParticleID&, const glm::vec3&)),
|
SIGNAL(particleCollisionWithParticle(const ParticleID&, const ParticleID&, const CollisionInfo&)),
|
||||||
ScriptEngine::getParticlesScriptingInterface(),
|
ScriptEngine::getParticlesScriptingInterface(),
|
||||||
SLOT(forwardParticleCollisionWithParticle(const ParticleID&, const ParticleID&, const glm::vec3&)));
|
SIGNAL(particleCollisionWithParticle(const ParticleID&, const ParticleID&, const CollisionInfo&)));
|
||||||
|
|
||||||
_audio.init(_glWidget);
|
_audio.init(_glWidget);
|
||||||
|
|
||||||
|
|
|
@ -46,7 +46,6 @@ Avatar::Avatar() :
|
||||||
_mode(AVATAR_MODE_STANDING),
|
_mode(AVATAR_MODE_STANDING),
|
||||||
_velocity(0.0f, 0.0f, 0.0f),
|
_velocity(0.0f, 0.0f, 0.0f),
|
||||||
_thrust(0.0f, 0.0f, 0.0f),
|
_thrust(0.0f, 0.0f, 0.0f),
|
||||||
_speed(0.0f),
|
|
||||||
_leanScale(0.5f),
|
_leanScale(0.5f),
|
||||||
_scale(1.0f),
|
_scale(1.0f),
|
||||||
_worldUpDirection(DEFAULT_UP_DIRECTION),
|
_worldUpDirection(DEFAULT_UP_DIRECTION),
|
||||||
|
@ -137,7 +136,8 @@ void Avatar::simulate(float deltaTime) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// use speed and angular velocity to determine walking vs. standing
|
// use speed and angular velocity to determine walking vs. standing
|
||||||
if (_speed + fabs(_bodyYawDelta) > 0.2) {
|
float speed = glm::length(_velocity);
|
||||||
|
if (speed + fabs(_bodyYawDelta) > 0.2) {
|
||||||
_mode = AVATAR_MODE_WALKING;
|
_mode = AVATAR_MODE_WALKING;
|
||||||
} else {
|
} else {
|
||||||
_mode = AVATAR_MODE_INTERACTING;
|
_mode = AVATAR_MODE_INTERACTING;
|
||||||
|
@ -331,6 +331,10 @@ void Avatar::renderBody(RenderMode renderMode) {
|
||||||
getHand()->render(false);
|
getHand()->render(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Avatar::updateJointMappings() {
|
||||||
|
// no-op; joint mappings come from skeleton model
|
||||||
|
}
|
||||||
|
|
||||||
void Avatar::renderBillboard() {
|
void Avatar::renderBillboard() {
|
||||||
if (_billboard.isEmpty()) {
|
if (_billboard.isEmpty()) {
|
||||||
return;
|
return;
|
||||||
|
|
|
@ -160,7 +160,6 @@ protected:
|
||||||
AvatarMode _mode;
|
AvatarMode _mode;
|
||||||
glm::vec3 _velocity;
|
glm::vec3 _velocity;
|
||||||
glm::vec3 _thrust;
|
glm::vec3 _thrust;
|
||||||
float _speed;
|
|
||||||
float _leanScale;
|
float _leanScale;
|
||||||
float _scale;
|
float _scale;
|
||||||
glm::vec3 _worldUpDirection;
|
glm::vec3 _worldUpDirection;
|
||||||
|
@ -187,6 +186,8 @@ protected:
|
||||||
void renderDisplayName();
|
void renderDisplayName();
|
||||||
virtual void renderBody(RenderMode renderMode);
|
virtual void renderBody(RenderMode renderMode);
|
||||||
|
|
||||||
|
virtual void updateJointMappings();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
bool _initialized;
|
bool _initialized;
|
||||||
|
|
|
@ -169,9 +169,6 @@ void MyAvatar::simulate(float deltaTime) {
|
||||||
// Collect thrust forces from keyboard and devices
|
// Collect thrust forces from keyboard and devices
|
||||||
updateThrust(deltaTime);
|
updateThrust(deltaTime);
|
||||||
|
|
||||||
// calculate speed
|
|
||||||
_speed = glm::length(_velocity);
|
|
||||||
|
|
||||||
// update the movement of the hand and process handshaking with other avatars...
|
// update the movement of the hand and process handshaking with other avatars...
|
||||||
updateHandMovementAndTouching(deltaTime);
|
updateHandMovementAndTouching(deltaTime);
|
||||||
|
|
||||||
|
@ -203,9 +200,9 @@ void MyAvatar::simulate(float deltaTime) {
|
||||||
if (fabs(_bodyRollDelta) < MINIMUM_ROTATION_RATE) { _bodyRollDelta = 0.f; }
|
if (fabs(_bodyRollDelta) < MINIMUM_ROTATION_RATE) { _bodyRollDelta = 0.f; }
|
||||||
if (fabs(_bodyPitchDelta) < MINIMUM_ROTATION_RATE) { _bodyPitchDelta = 0.f; }
|
if (fabs(_bodyPitchDelta) < MINIMUM_ROTATION_RATE) { _bodyPitchDelta = 0.f; }
|
||||||
|
|
||||||
const float MAX_STATIC_FRICTION_VELOCITY = 0.5f;
|
const float MAX_STATIC_FRICTION_SPEED = 0.5f;
|
||||||
const float STATIC_FRICTION_STRENGTH = _scale * 20.f;
|
const float STATIC_FRICTION_STRENGTH = _scale * 20.f;
|
||||||
applyStaticFriction(deltaTime, _velocity, MAX_STATIC_FRICTION_VELOCITY, STATIC_FRICTION_STRENGTH);
|
applyStaticFriction(deltaTime, _velocity, MAX_STATIC_FRICTION_SPEED, STATIC_FRICTION_STRENGTH);
|
||||||
|
|
||||||
// Damp avatar velocity
|
// Damp avatar velocity
|
||||||
const float LINEAR_DAMPING_STRENGTH = 0.5f;
|
const float LINEAR_DAMPING_STRENGTH = 0.5f;
|
||||||
|
@ -230,7 +227,8 @@ void MyAvatar::simulate(float deltaTime) {
|
||||||
|
|
||||||
const float WALKING_SPEED_THRESHOLD = 0.2f;
|
const float WALKING_SPEED_THRESHOLD = 0.2f;
|
||||||
// use speed and angular velocity to determine walking vs. standing
|
// use speed and angular velocity to determine walking vs. standing
|
||||||
if (_speed + fabs(_bodyYawDelta) > WALKING_SPEED_THRESHOLD) {
|
float speed = glm::length(_velocity);
|
||||||
|
if (speed + fabs(_bodyYawDelta) > WALKING_SPEED_THRESHOLD) {
|
||||||
_mode = AVATAR_MODE_WALKING;
|
_mode = AVATAR_MODE_WALKING;
|
||||||
} else {
|
} else {
|
||||||
_mode = AVATAR_MODE_INTERACTING;
|
_mode = AVATAR_MODE_INTERACTING;
|
||||||
|
@ -238,7 +236,7 @@ void MyAvatar::simulate(float deltaTime) {
|
||||||
|
|
||||||
// update moving flag based on speed
|
// update moving flag based on speed
|
||||||
const float MOVING_SPEED_THRESHOLD = 0.01f;
|
const float MOVING_SPEED_THRESHOLD = 0.01f;
|
||||||
_moving = _speed > MOVING_SPEED_THRESHOLD;
|
_moving = speed > MOVING_SPEED_THRESHOLD;
|
||||||
|
|
||||||
// If a move target is set, update position explicitly
|
// If a move target is set, update position explicitly
|
||||||
const float MOVE_FINISHED_TOLERANCE = 0.1f;
|
const float MOVE_FINISHED_TOLERANCE = 0.1f;
|
||||||
|
@ -681,7 +679,6 @@ void MyAvatar::updateThrust(float deltaTime) {
|
||||||
if (_driveKeys[FWD] || _driveKeys[BACK] || _driveKeys[RIGHT] || _driveKeys[LEFT] || _driveKeys[UP] || _driveKeys[DOWN]) {
|
if (_driveKeys[FWD] || _driveKeys[BACK] || _driveKeys[RIGHT] || _driveKeys[LEFT] || _driveKeys[UP] || _driveKeys[DOWN]) {
|
||||||
const float THRUST_INCREASE_RATE = 1.05f;
|
const float THRUST_INCREASE_RATE = 1.05f;
|
||||||
const float MAX_THRUST_MULTIPLIER = 75.0f;
|
const float MAX_THRUST_MULTIPLIER = 75.0f;
|
||||||
//printf("m = %.3f\n", _thrustMultiplier);
|
|
||||||
_thrustMultiplier *= 1.f + deltaTime * THRUST_INCREASE_RATE;
|
_thrustMultiplier *= 1.f + deltaTime * THRUST_INCREASE_RATE;
|
||||||
if (_thrustMultiplier > MAX_THRUST_MULTIPLIER) {
|
if (_thrustMultiplier > MAX_THRUST_MULTIPLIER) {
|
||||||
_thrustMultiplier = MAX_THRUST_MULTIPLIER;
|
_thrustMultiplier = MAX_THRUST_MULTIPLIER;
|
||||||
|
@ -703,11 +700,12 @@ void MyAvatar::updateThrust(float deltaTime) {
|
||||||
if ((glm::length(_thrust) == 0.0f) && _isThrustOn && (glm::length(_velocity) > MIN_SPEED_BRAKE_VELOCITY)) {
|
if ((glm::length(_thrust) == 0.0f) && _isThrustOn && (glm::length(_velocity) > MIN_SPEED_BRAKE_VELOCITY)) {
|
||||||
_speedBrakes = true;
|
_speedBrakes = true;
|
||||||
}
|
}
|
||||||
|
_isThrustOn = (glm::length(_thrust) > EPSILON);
|
||||||
|
|
||||||
if (_speedBrakes && (glm::length(_velocity) < MIN_SPEED_BRAKE_VELOCITY)) {
|
if (_isThrustOn || (_speedBrakes && (glm::length(_velocity) < MIN_SPEED_BRAKE_VELOCITY))) {
|
||||||
_speedBrakes = false;
|
_speedBrakes = false;
|
||||||
}
|
}
|
||||||
_isThrustOn = (glm::length(_thrust) > EPSILON);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void MyAvatar::updateHandMovementAndTouching(float deltaTime) {
|
void MyAvatar::updateHandMovementAndTouching(float deltaTime) {
|
||||||
|
|
|
@ -50,7 +50,6 @@ public:
|
||||||
void setShouldRenderLocally(bool shouldRender) { _shouldRender = shouldRender; }
|
void setShouldRenderLocally(bool shouldRender) { _shouldRender = shouldRender; }
|
||||||
|
|
||||||
// getters
|
// getters
|
||||||
float getSpeed() const { return _speed; }
|
|
||||||
AvatarMode getMode() const { return _mode; }
|
AvatarMode getMode() const { return _mode; }
|
||||||
float getLeanScale() const { return _leanScale; }
|
float getLeanScale() const { return _leanScale; }
|
||||||
float getElapsedTimeStopped() const { return _elapsedTimeStopped; }
|
float getElapsedTimeStopped() const { return _elapsedTimeStopped; }
|
||||||
|
|
|
@ -20,6 +20,8 @@
|
||||||
#include "Menu.h"
|
#include "Menu.h"
|
||||||
#include "Util.h"
|
#include "Util.h"
|
||||||
|
|
||||||
|
using namespace std;
|
||||||
|
|
||||||
const int STATS_PELS_PER_LINE = 20;
|
const int STATS_PELS_PER_LINE = 20;
|
||||||
|
|
||||||
const int STATS_GENERAL_MIN_WIDTH = 165;
|
const int STATS_GENERAL_MIN_WIDTH = 165;
|
||||||
|
@ -287,7 +289,7 @@ void Stats::display(
|
||||||
MyAvatar* myAvatar = Application::getInstance()->getAvatar();
|
MyAvatar* myAvatar = Application::getInstance()->getAvatar();
|
||||||
glm::vec3 avatarPos = myAvatar->getPosition();
|
glm::vec3 avatarPos = myAvatar->getPosition();
|
||||||
|
|
||||||
lines = _expanded ? 4 : 3;
|
lines = _expanded ? 5 : 3;
|
||||||
drawBackground(backgroundColor, horizontalOffset, 0, _geoStatsWidth, lines * STATS_PELS_PER_LINE + 10);
|
drawBackground(backgroundColor, horizontalOffset, 0, _geoStatsWidth, lines * STATS_PELS_PER_LINE + 10);
|
||||||
horizontalOffset += 5;
|
horizontalOffset += 5;
|
||||||
|
|
||||||
|
@ -318,6 +320,16 @@ void Stats::display(
|
||||||
|
|
||||||
verticalOffset += STATS_PELS_PER_LINE;
|
verticalOffset += STATS_PELS_PER_LINE;
|
||||||
drawText(horizontalOffset, verticalOffset, 0.10f, 0.f, 2.f, avatarMixerStats, color);
|
drawText(horizontalOffset, verticalOffset, 0.10f, 0.f, 2.f, avatarMixerStats, color);
|
||||||
|
|
||||||
|
stringstream downloads;
|
||||||
|
downloads << "Downloads: ";
|
||||||
|
foreach (Resource* resource, ResourceCache::getLoadingRequests()) {
|
||||||
|
downloads << (int)(resource->getProgress() * 100.0f) << "% ";
|
||||||
|
}
|
||||||
|
downloads << "(" << ResourceCache::getPendingRequestCount() << " pending)";
|
||||||
|
|
||||||
|
verticalOffset += STATS_PELS_PER_LINE;
|
||||||
|
drawText(horizontalOffset, verticalOffset, 0.10f, 0.f, 2.f, downloads.str().c_str(), color);
|
||||||
}
|
}
|
||||||
|
|
||||||
verticalOffset = 0;
|
verticalOffset = 0;
|
||||||
|
|
|
@ -639,6 +639,8 @@ void AvatarData::setSkeletonModelURL(const QUrl& skeletonModelURL) {
|
||||||
_skeletonModelURL = skeletonModelURL.isEmpty() ? DEFAULT_BODY_MODEL_URL : skeletonModelURL;
|
_skeletonModelURL = skeletonModelURL.isEmpty() ? DEFAULT_BODY_MODEL_URL : skeletonModelURL;
|
||||||
|
|
||||||
qDebug() << "Changing skeleton model for avatar to" << _skeletonModelURL.toString();
|
qDebug() << "Changing skeleton model for avatar to" << _skeletonModelURL.toString();
|
||||||
|
|
||||||
|
updateJointMappings();
|
||||||
}
|
}
|
||||||
|
|
||||||
void AvatarData::setDisplayName(const QString& displayName) {
|
void AvatarData::setDisplayName(const QString& displayName) {
|
||||||
|
@ -673,6 +675,40 @@ void AvatarData::setBillboardFromURL(const QString &billboardURL) {
|
||||||
void AvatarData::setBillboardFromNetworkReply() {
|
void AvatarData::setBillboardFromNetworkReply() {
|
||||||
QNetworkReply* networkReply = reinterpret_cast<QNetworkReply*>(sender());
|
QNetworkReply* networkReply = reinterpret_cast<QNetworkReply*>(sender());
|
||||||
setBillboard(networkReply->readAll());
|
setBillboard(networkReply->readAll());
|
||||||
|
networkReply->deleteLater();
|
||||||
|
}
|
||||||
|
|
||||||
|
void AvatarData::setJointMappingsFromNetworkReply() {
|
||||||
|
QNetworkReply* networkReply = static_cast<QNetworkReply*>(sender());
|
||||||
|
|
||||||
|
QByteArray line;
|
||||||
|
while (!(line = networkReply->readLine()).isEmpty()) {
|
||||||
|
if (!(line = line.trimmed()).startsWith("jointIndex")) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
int jointNameIndex = line.indexOf('=') + 1;
|
||||||
|
if (jointNameIndex == 0) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
int secondSeparatorIndex = line.indexOf('=', jointNameIndex);
|
||||||
|
if (secondSeparatorIndex == -1) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
QString jointName = line.mid(jointNameIndex, secondSeparatorIndex - jointNameIndex).trimmed();
|
||||||
|
bool ok;
|
||||||
|
int jointIndex = line.mid(secondSeparatorIndex + 1).trimmed().toInt(&ok);
|
||||||
|
if (ok) {
|
||||||
|
while (_jointNames.size() < jointIndex + 1) {
|
||||||
|
_jointNames.append(QString());
|
||||||
|
}
|
||||||
|
_jointNames[jointIndex] = jointName;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (int i = 0; i < _jointNames.size(); i++) {
|
||||||
|
_jointIndices.insert(_jointNames.at(i), i + 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
networkReply->deleteLater();
|
||||||
}
|
}
|
||||||
|
|
||||||
void AvatarData::setClampedTargetScale(float targetScale) {
|
void AvatarData::setClampedTargetScale(float targetScale) {
|
||||||
|
@ -705,3 +741,13 @@ void AvatarData::sendBillboardPacket() {
|
||||||
NodeList::getInstance()->broadcastToNodes(billboardPacket, NodeSet() << NodeType::AvatarMixer);
|
NodeList::getInstance()->broadcastToNodes(billboardPacket, NodeSet() << NodeType::AvatarMixer);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void AvatarData::updateJointMappings() {
|
||||||
|
_jointIndices.clear();
|
||||||
|
_jointNames.clear();
|
||||||
|
|
||||||
|
if (networkAccessManager && _skeletonModelURL.fileName().toLower().endsWith(".fst")) {
|
||||||
|
QNetworkReply* networkReply = networkAccessManager->get(QNetworkRequest(_skeletonModelURL));
|
||||||
|
connect(networkReply, SIGNAL(finished()), this, SLOT(setJointMappingsFromNetworkReply()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -30,6 +30,7 @@ typedef unsigned long long quint64;
|
||||||
#include <glm/gtc/quaternion.hpp>
|
#include <glm/gtc/quaternion.hpp>
|
||||||
|
|
||||||
#include <QtCore/QByteArray>
|
#include <QtCore/QByteArray>
|
||||||
|
#include <QtCore/QHash>
|
||||||
#include <QtCore/QObject>
|
#include <QtCore/QObject>
|
||||||
#include <QtCore/QStringList>
|
#include <QtCore/QStringList>
|
||||||
#include <QtCore/QUrl>
|
#include <QtCore/QUrl>
|
||||||
|
@ -160,9 +161,9 @@ public:
|
||||||
Q_INVOKABLE glm::quat getJointRotation(const QString& name) const;
|
Q_INVOKABLE glm::quat getJointRotation(const QString& name) const;
|
||||||
|
|
||||||
/// Returns the index of the joint with the specified name, or -1 if not found/unknown.
|
/// Returns the index of the joint with the specified name, or -1 if not found/unknown.
|
||||||
Q_INVOKABLE virtual int getJointIndex(const QString& name) const { return -1; }
|
Q_INVOKABLE virtual int getJointIndex(const QString& name) const { return _jointIndices.value(name) - 1; }
|
||||||
|
|
||||||
Q_INVOKABLE virtual QStringList getJointNames() const { return QStringList(); }
|
Q_INVOKABLE virtual QStringList getJointNames() const { return _jointNames; }
|
||||||
|
|
||||||
// key state
|
// key state
|
||||||
void setKeyState(KeyState s) { _keyState = s; }
|
void setKeyState(KeyState s) { _keyState = s; }
|
||||||
|
@ -217,6 +218,7 @@ public slots:
|
||||||
void sendIdentityPacket();
|
void sendIdentityPacket();
|
||||||
void sendBillboardPacket();
|
void sendBillboardPacket();
|
||||||
void setBillboardFromNetworkReply();
|
void setBillboardFromNetworkReply();
|
||||||
|
void setJointMappingsFromNetworkReply();
|
||||||
protected:
|
protected:
|
||||||
glm::vec3 _position;
|
glm::vec3 _position;
|
||||||
glm::vec3 _handPosition;
|
glm::vec3 _handPosition;
|
||||||
|
@ -258,10 +260,16 @@ protected:
|
||||||
QByteArray _billboard;
|
QByteArray _billboard;
|
||||||
QString _billboardURL;
|
QString _billboardURL;
|
||||||
|
|
||||||
|
QHash<QString, int> _jointIndices; ///< 1-based, since zero is returned for missing keys
|
||||||
|
QStringList _jointNames; ///< in order of depth-first traversal
|
||||||
|
|
||||||
static QNetworkAccessManager* networkAccessManager;
|
static QNetworkAccessManager* networkAccessManager;
|
||||||
|
|
||||||
quint64 _errorLogExpiry; ///< time in future when to log an error
|
quint64 _errorLogExpiry; ///< time in future when to log an error
|
||||||
|
|
||||||
|
/// Loads the joint indices, names from the FST file (if any)
|
||||||
|
virtual void updateJointMappings();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// privatize the copy constructor and assignment operator so they cannot be called
|
// privatize the copy constructor and assignment operator so they cannot be called
|
||||||
AvatarData(const AvatarData&);
|
AvatarData(const AvatarData&);
|
||||||
|
|
|
@ -72,17 +72,17 @@ void ParticleCollisionSystem::checkParticle(Particle* particle) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void ParticleCollisionSystem::emitGlobalParticleCollisionWithVoxel(Particle* particle,
|
void ParticleCollisionSystem::emitGlobalParticleCollisionWithVoxel(Particle* particle,
|
||||||
VoxelDetail* voxelDetails, const glm::vec3& penetration) {
|
VoxelDetail* voxelDetails, const CollisionInfo& collision) {
|
||||||
ParticleID particleID = particle->getParticleID();
|
ParticleID particleID = particle->getParticleID();
|
||||||
emit particleCollisionWithVoxel(particleID, *voxelDetails, penetration);
|
emit particleCollisionWithVoxel(particleID, *voxelDetails, collision);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ParticleCollisionSystem::emitGlobalParticleCollisionWithParticle(Particle* particleA,
|
void ParticleCollisionSystem::emitGlobalParticleCollisionWithParticle(Particle* particleA,
|
||||||
Particle* particleB, const glm::vec3& penetration) {
|
Particle* particleB, const CollisionInfo& collision) {
|
||||||
|
|
||||||
ParticleID idA = particleA->getParticleID();
|
ParticleID idA = particleA->getParticleID();
|
||||||
ParticleID idB = particleB->getParticleID();
|
ParticleID idB = particleB->getParticleID();
|
||||||
emit particleCollisionWithParticle(idA, idB, penetration);
|
emit particleCollisionWithParticle(idA, idB, collision);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ParticleCollisionSystem::updateCollisionWithVoxels(Particle* particle) {
|
void ParticleCollisionSystem::updateCollisionWithVoxels(Particle* particle) {
|
||||||
|
@ -100,11 +100,17 @@ void ParticleCollisionSystem::updateCollisionWithVoxels(Particle* particle) {
|
||||||
// let the particles run their collision scripts if they have them
|
// let the particles run their collision scripts if they have them
|
||||||
particle->collisionWithVoxel(voxelDetails, collisionInfo._penetration);
|
particle->collisionWithVoxel(voxelDetails, collisionInfo._penetration);
|
||||||
|
|
||||||
// let the global script run their collision scripts for particles if they have them
|
// findSpherePenetration() only computes the penetration but we also want some other collision info
|
||||||
emitGlobalParticleCollisionWithVoxel(particle, voxelDetails, collisionInfo._penetration);
|
// so we compute it ourselves here. Note that we must multiply scale by TREE_SCALE when feeding
|
||||||
|
// the results to systems outside of this octree reference frame.
|
||||||
updateCollisionSound(particle, collisionInfo._penetration, COLLISION_FREQUENCY);
|
updateCollisionSound(particle, collisionInfo._penetration, COLLISION_FREQUENCY);
|
||||||
|
collisionInfo._contactPoint = (float)TREE_SCALE * (particle->getPosition() + particle->getRadius() * glm::normalize(collisionInfo._penetration));
|
||||||
|
// let the global script run their collision scripts for particles if they have them
|
||||||
|
emitGlobalParticleCollisionWithVoxel(particle, voxelDetails, collisionInfo);
|
||||||
|
|
||||||
|
// we must scale back down to the octree reference frame before updating the particle properties
|
||||||
collisionInfo._penetration /= (float)(TREE_SCALE);
|
collisionInfo._penetration /= (float)(TREE_SCALE);
|
||||||
|
collisionInfo._contactPoint /= (float)(TREE_SCALE);
|
||||||
particle->applyHardCollision(collisionInfo);
|
particle->applyHardCollision(collisionInfo);
|
||||||
queueParticlePropertiesUpdate(particle);
|
queueParticlePropertiesUpdate(particle);
|
||||||
|
|
||||||
|
@ -121,8 +127,7 @@ void ParticleCollisionSystem::updateCollisionWithParticles(Particle* particleA)
|
||||||
glm::vec3 penetration;
|
glm::vec3 penetration;
|
||||||
Particle* particleB;
|
Particle* particleB;
|
||||||
if (_particles->findSpherePenetration(center, radius, penetration, (void**)&particleB, Octree::NoLock)) {
|
if (_particles->findSpherePenetration(center, radius, penetration, (void**)&particleB, Octree::NoLock)) {
|
||||||
// NOTE: 'penetration' is the depth that 'particleA' overlaps 'particleB'.
|
// NOTE: 'penetration' is the depth that 'particleA' overlaps 'particleB'. It points from A into B.
|
||||||
// That is, it points from A into B.
|
|
||||||
|
|
||||||
// Even if the particles overlap... when the particles are already moving appart
|
// Even if the particles overlap... when the particles are already moving appart
|
||||||
// we don't want to count this as a collision.
|
// we don't want to count this as a collision.
|
||||||
|
@ -130,7 +135,12 @@ void ParticleCollisionSystem::updateCollisionWithParticles(Particle* particleA)
|
||||||
if (glm::dot(relativeVelocity, penetration) > 0.0f) {
|
if (glm::dot(relativeVelocity, penetration) > 0.0f) {
|
||||||
particleA->collisionWithParticle(particleB, penetration);
|
particleA->collisionWithParticle(particleB, penetration);
|
||||||
particleB->collisionWithParticle(particleA, penetration * -1.0f); // the penetration is reversed
|
particleB->collisionWithParticle(particleA, penetration * -1.0f); // the penetration is reversed
|
||||||
emitGlobalParticleCollisionWithParticle(particleA, particleB, penetration);
|
|
||||||
|
CollisionInfo collision;
|
||||||
|
collision._penetration = penetration;
|
||||||
|
// for now the contactPoint is the average between the the two paricle centers
|
||||||
|
collision._contactPoint = (0.5f * (float)TREE_SCALE) * (particleA->getPosition() + particleB->getPosition());
|
||||||
|
emitGlobalParticleCollisionWithParticle(particleA, particleB, collision);
|
||||||
|
|
||||||
glm::vec3 axis = glm::normalize(penetration);
|
glm::vec3 axis = glm::normalize(penetration);
|
||||||
glm::vec3 axialVelocity = glm::dot(relativeVelocity, axis) * axis;
|
glm::vec3 axialVelocity = glm::dot(relativeVelocity, axis) * axis;
|
||||||
|
@ -142,25 +152,25 @@ void ParticleCollisionSystem::updateCollisionWithParticles(Particle* particleA)
|
||||||
float massB = (particleB->getInHand()) ? MAX_MASS : particleB->getMass();
|
float massB = (particleB->getInHand()) ? MAX_MASS : particleB->getMass();
|
||||||
float totalMass = massA + massB;
|
float totalMass = massA + massB;
|
||||||
|
|
||||||
// handle A particle
|
// handle particle A
|
||||||
particleA->setVelocity(particleA->getVelocity() - axialVelocity * (2.0f * massB / totalMass));
|
particleA->setVelocity(particleA->getVelocity() - axialVelocity * (2.0f * massB / totalMass));
|
||||||
particleA->setPosition(particleA->getPosition() - 0.5f * penetration);
|
particleA->setPosition(particleA->getPosition() - 0.5f * penetration);
|
||||||
ParticleProperties propertiesA;
|
ParticleProperties propertiesA;
|
||||||
ParticleID particleAid(particleA->getID());
|
ParticleID idA(particleA->getID());
|
||||||
propertiesA.copyFromParticle(*particleA);
|
propertiesA.copyFromParticle(*particleA);
|
||||||
propertiesA.setVelocity(particleA->getVelocity() * (float)TREE_SCALE);
|
propertiesA.setVelocity(particleA->getVelocity() * (float)TREE_SCALE);
|
||||||
propertiesA.setPosition(particleA->getPosition() * (float)TREE_SCALE);
|
propertiesA.setPosition(particleA->getPosition() * (float)TREE_SCALE);
|
||||||
_packetSender->queueParticleEditMessage(PacketTypeParticleAddOrEdit, particleAid, propertiesA);
|
_packetSender->queueParticleEditMessage(PacketTypeParticleAddOrEdit, idA, propertiesA);
|
||||||
|
|
||||||
// handle B particle
|
// handle particle B
|
||||||
particleB->setVelocity(particleB->getVelocity() + axialVelocity * (2.0f * massA / totalMass));
|
particleB->setVelocity(particleB->getVelocity() + axialVelocity * (2.0f * massA / totalMass));
|
||||||
particleA->setPosition(particleB->getPosition() + 0.5f * penetration);
|
particleA->setPosition(particleB->getPosition() + 0.5f * penetration);
|
||||||
ParticleProperties propertiesB;
|
ParticleProperties propertiesB;
|
||||||
ParticleID particleBid(particleB->getID());
|
ParticleID idB(particleB->getID());
|
||||||
propertiesB.copyFromParticle(*particleB);
|
propertiesB.copyFromParticle(*particleB);
|
||||||
propertiesB.setVelocity(particleB->getVelocity() * (float)TREE_SCALE);
|
propertiesB.setVelocity(particleB->getVelocity() * (float)TREE_SCALE);
|
||||||
propertiesB.setPosition(particleB->getPosition() * (float)TREE_SCALE);
|
propertiesB.setPosition(particleB->getPosition() * (float)TREE_SCALE);
|
||||||
_packetSender->queueParticleEditMessage(PacketTypeParticleAddOrEdit, particleBid, propertiesB);
|
_packetSender->queueParticleEditMessage(PacketTypeParticleAddOrEdit, idB, propertiesB);
|
||||||
|
|
||||||
_packetSender->releaseQueuedMessages();
|
_packetSender->releaseQueuedMessages();
|
||||||
|
|
||||||
|
|
|
@ -53,13 +53,13 @@ public:
|
||||||
void updateCollisionSound(Particle* particle, const glm::vec3 &penetration, float frequency);
|
void updateCollisionSound(Particle* particle, const glm::vec3 &penetration, float frequency);
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void particleCollisionWithVoxel(const ParticleID& particleID, const VoxelDetail& voxel, const glm::vec3& penetration);
|
void particleCollisionWithVoxel(const ParticleID& particleID, const VoxelDetail& voxel, const CollisionInfo& penetration);
|
||||||
void particleCollisionWithParticle(const ParticleID& idA, const ParticleID& idB, const glm::vec3& penetration);
|
void particleCollisionWithParticle(const ParticleID& idA, const ParticleID& idB, const CollisionInfo& penetration);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static bool updateOperation(OctreeElement* element, void* extraData);
|
static bool updateOperation(OctreeElement* element, void* extraData);
|
||||||
void emitGlobalParticleCollisionWithVoxel(Particle* particle, VoxelDetail* voxelDetails, const glm::vec3& penetration);
|
void emitGlobalParticleCollisionWithVoxel(Particle* particle, VoxelDetail* voxelDetails, const CollisionInfo& penetration);
|
||||||
void emitGlobalParticleCollisionWithParticle(Particle* particleA, Particle* particleB, const glm::vec3& penetration);
|
void emitGlobalParticleCollisionWithParticle(Particle* particleA, Particle* particleB, const CollisionInfo& penetration);
|
||||||
|
|
||||||
ParticleEditPacketSender* _packetSender;
|
ParticleEditPacketSender* _packetSender;
|
||||||
ParticleTree* _particles;
|
ParticleTree* _particles;
|
||||||
|
|
|
@ -11,6 +11,8 @@
|
||||||
|
|
||||||
#include <QtCore/QObject>
|
#include <QtCore/QObject>
|
||||||
|
|
||||||
|
#include <CollisionInfo.h>
|
||||||
|
|
||||||
#include <OctreeScriptingInterface.h>
|
#include <OctreeScriptingInterface.h>
|
||||||
#include "ParticleEditPacketSender.h"
|
#include "ParticleEditPacketSender.h"
|
||||||
|
|
||||||
|
@ -27,17 +29,6 @@ public:
|
||||||
void setParticleTree(ParticleTree* particleTree) { _particleTree = particleTree; }
|
void setParticleTree(ParticleTree* particleTree) { _particleTree = particleTree; }
|
||||||
ParticleTree* getParticleTree(ParticleTree*) { return _particleTree; }
|
ParticleTree* getParticleTree(ParticleTree*) { return _particleTree; }
|
||||||
|
|
||||||
private slots:
|
|
||||||
/// inbound slots for external collision systems
|
|
||||||
void forwardParticleCollisionWithVoxel(const ParticleID& particleID,
|
|
||||||
const VoxelDetail& voxel, const glm::vec3& penetration) {
|
|
||||||
emit particleCollisionWithVoxel(particleID, voxel, penetration);
|
|
||||||
}
|
|
||||||
|
|
||||||
void forwardParticleCollisionWithParticle(const ParticleID& idA, const ParticleID& idB, const glm::vec3& penetration) {
|
|
||||||
emit particleCollisionWithParticle(idA, idB, penetration);
|
|
||||||
}
|
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
/// adds a particle with the specific properties
|
/// adds a particle with the specific properties
|
||||||
ParticleID addParticle(const ParticleProperties& properties);
|
ParticleID addParticle(const ParticleProperties& properties);
|
||||||
|
@ -66,8 +57,8 @@ public slots:
|
||||||
QVector<ParticleID> findParticles(const glm::vec3& center, float radius) const;
|
QVector<ParticleID> findParticles(const glm::vec3& center, float radius) const;
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void particleCollisionWithVoxel(const ParticleID& particleID, const VoxelDetail& voxel, const glm::vec3& penetration);
|
void particleCollisionWithVoxel(const ParticleID& particleID, const VoxelDetail& voxel, const CollisionInfo& collision);
|
||||||
void particleCollisionWithParticle(const ParticleID& idA, const ParticleID& idB, const glm::vec3& penetration);
|
void particleCollisionWithParticle(const ParticleID& idA, const ParticleID& idB, const CollisionInfo& collision);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void queueParticleMessage(PacketType packetType, ParticleID particleID, const ParticleProperties& properties);
|
void queueParticleMessage(PacketType packetType, ParticleID particleID, const ParticleProperties& properties);
|
||||||
|
|
|
@ -19,6 +19,7 @@
|
||||||
#include "SharedUtil.h"
|
#include "SharedUtil.h"
|
||||||
|
|
||||||
#include <QtCore/QDataStream>
|
#include <QtCore/QDataStream>
|
||||||
|
#include <QtCore/QDateTime>
|
||||||
#include <QtCore/QDebug>
|
#include <QtCore/QDebug>
|
||||||
|
|
||||||
const QString UNKNOWN_NodeType_t_NAME = "Unknown";
|
const QString UNKNOWN_NodeType_t_NAME = "Unknown";
|
||||||
|
@ -47,7 +48,7 @@ const QString& NodeType::getNodeTypeName(NodeType_t nodeType) {
|
||||||
Node::Node(const QUuid& uuid, char type, const HifiSockAddr& publicSocket, const HifiSockAddr& localSocket) :
|
Node::Node(const QUuid& uuid, char type, const HifiSockAddr& publicSocket, const HifiSockAddr& localSocket) :
|
||||||
_type(type),
|
_type(type),
|
||||||
_uuid(uuid),
|
_uuid(uuid),
|
||||||
_wakeMicrostamp(usecTimestampNow()),
|
_wakeTimestamp(QDateTime::currentMSecsSinceEpoch()),
|
||||||
_lastHeardMicrostamp(usecTimestampNow()),
|
_lastHeardMicrostamp(usecTimestampNow()),
|
||||||
_publicSocket(publicSocket),
|
_publicSocket(publicSocket),
|
||||||
_localSocket(localSocket),
|
_localSocket(localSocket),
|
||||||
|
|
|
@ -60,8 +60,8 @@ public:
|
||||||
const QUuid& getUUID() const { return _uuid; }
|
const QUuid& getUUID() const { return _uuid; }
|
||||||
void setUUID(const QUuid& uuid) { _uuid = uuid; }
|
void setUUID(const QUuid& uuid) { _uuid = uuid; }
|
||||||
|
|
||||||
quint64 getWakeMicrostamp() const { return _wakeMicrostamp; }
|
quint64 getWakeTimestamp() const { return _wakeTimestamp; }
|
||||||
void setWakeMicrostamp(quint64 wakeMicrostamp) { _wakeMicrostamp = wakeMicrostamp; }
|
void setWakeTimestamp(quint64 wakeTimestamp) { _wakeTimestamp = wakeTimestamp; }
|
||||||
|
|
||||||
quint64 getLastHeardMicrostamp() const { return _lastHeardMicrostamp; }
|
quint64 getLastHeardMicrostamp() const { return _lastHeardMicrostamp; }
|
||||||
void setLastHeardMicrostamp(quint64 lastHeardMicrostamp) { _lastHeardMicrostamp = lastHeardMicrostamp; }
|
void setLastHeardMicrostamp(quint64 lastHeardMicrostamp) { _lastHeardMicrostamp = lastHeardMicrostamp; }
|
||||||
|
@ -109,7 +109,7 @@ private:
|
||||||
|
|
||||||
NodeType_t _type;
|
NodeType_t _type;
|
||||||
QUuid _uuid;
|
QUuid _uuid;
|
||||||
quint64 _wakeMicrostamp;
|
quint64 _wakeTimestamp;
|
||||||
quint64 _lastHeardMicrostamp;
|
quint64 _lastHeardMicrostamp;
|
||||||
HifiSockAddr _publicSocket;
|
HifiSockAddr _publicSocket;
|
||||||
HifiSockAddr _localSocket;
|
HifiSockAddr _localSocket;
|
||||||
|
|
|
@ -16,6 +16,7 @@ static int vec2MetaTypeId = qRegisterMetaType<glm::vec2>();
|
||||||
static int quatMetaTypeId = qRegisterMetaType<glm::quat>();
|
static int quatMetaTypeId = qRegisterMetaType<glm::quat>();
|
||||||
static int xColorMetaTypeId = qRegisterMetaType<xColor>();
|
static int xColorMetaTypeId = qRegisterMetaType<xColor>();
|
||||||
static int pickRayMetaTypeId = qRegisterMetaType<PickRay>();
|
static int pickRayMetaTypeId = qRegisterMetaType<PickRay>();
|
||||||
|
static int collisionMetaTypeId = qRegisterMetaType<CollisionInfo>();
|
||||||
|
|
||||||
void registerMetaTypes(QScriptEngine* engine) {
|
void registerMetaTypes(QScriptEngine* engine) {
|
||||||
qScriptRegisterMetaType(engine, vec4toScriptValue, vec4FromScriptValue);
|
qScriptRegisterMetaType(engine, vec4toScriptValue, vec4FromScriptValue);
|
||||||
|
@ -24,6 +25,7 @@ void registerMetaTypes(QScriptEngine* engine) {
|
||||||
qScriptRegisterMetaType(engine, quatToScriptValue, quatFromScriptValue);
|
qScriptRegisterMetaType(engine, quatToScriptValue, quatFromScriptValue);
|
||||||
qScriptRegisterMetaType(engine, xColorToScriptValue, xColorFromScriptValue);
|
qScriptRegisterMetaType(engine, xColorToScriptValue, xColorFromScriptValue);
|
||||||
qScriptRegisterMetaType(engine, pickRayToScriptValue, pickRayFromScriptValue);
|
qScriptRegisterMetaType(engine, pickRayToScriptValue, pickRayFromScriptValue);
|
||||||
|
qScriptRegisterMetaType(engine, collisionToScriptValue, collisionFromScriptValue);
|
||||||
}
|
}
|
||||||
|
|
||||||
QScriptValue vec4toScriptValue(QScriptEngine* engine, const glm::vec4& vec4) {
|
QScriptValue vec4toScriptValue(QScriptEngine* engine, const glm::vec4& vec4) {
|
||||||
|
@ -122,3 +124,14 @@ void pickRayFromScriptValue(const QScriptValue& object, PickRay& pickRay) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QScriptValue collisionToScriptValue(QScriptEngine* engine, const CollisionInfo& collision) {
|
||||||
|
QScriptValue obj = engine->newObject();
|
||||||
|
obj.setProperty("penetration", vec3toScriptValue(engine, collision._penetration));
|
||||||
|
obj.setProperty("contactPoint", vec3toScriptValue(engine, collision._contactPoint));
|
||||||
|
return obj;
|
||||||
|
}
|
||||||
|
|
||||||
|
void collisionFromScriptValue(const QScriptValue &object, CollisionInfo& collision) {
|
||||||
|
// TODO: implement this when we know what it means to accept collision events from JS
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
@ -15,6 +15,7 @@
|
||||||
|
|
||||||
#include <QtScript/QScriptEngine>
|
#include <QtScript/QScriptEngine>
|
||||||
|
|
||||||
|
#include "CollisionInfo.h"
|
||||||
#include "SharedUtil.h"
|
#include "SharedUtil.h"
|
||||||
|
|
||||||
Q_DECLARE_METATYPE(glm::vec4)
|
Q_DECLARE_METATYPE(glm::vec4)
|
||||||
|
@ -50,4 +51,8 @@ Q_DECLARE_METATYPE(PickRay)
|
||||||
QScriptValue pickRayToScriptValue(QScriptEngine* engine, const PickRay& pickRay);
|
QScriptValue pickRayToScriptValue(QScriptEngine* engine, const PickRay& pickRay);
|
||||||
void pickRayFromScriptValue(const QScriptValue& object, PickRay& pickRay);
|
void pickRayFromScriptValue(const QScriptValue& object, PickRay& pickRay);
|
||||||
|
|
||||||
|
Q_DECLARE_METATYPE(CollisionInfo)
|
||||||
|
QScriptValue collisionToScriptValue(QScriptEngine* engine, const CollisionInfo& collision);
|
||||||
|
void collisionFromScriptValue(const QScriptValue &object, CollisionInfo& collision);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
Loading…
Reference in a new issue