mirror of
https://github.com/AleziaKurdis/overte.git
synced 2025-04-08 06:32:35 +02:00
merge from master
This commit is contained in:
commit
99300a5bc8
61 changed files with 409 additions and 542 deletions
|
@ -181,4 +181,4 @@ endif ()
|
|||
|
||||
if (ANDROID OR DESKTOP_GVR)
|
||||
add_subdirectory(gvr-interface)
|
||||
endif ()
|
||||
endif ()
|
||||
|
|
|
@ -92,7 +92,6 @@ function checkControllerSide(whichSide) {
|
|||
Vec3.multiply(1.0 - AVERAGE_FACTOR, averageLinearVelocity[0]));
|
||||
linearVelocity = averageLinearVelocity[0];
|
||||
angularVelocity = Vec3.multiplyQbyV(MyAvatar.orientation, Controller.getSpatialControlRawAngularVelocity(LEFT_TIP));
|
||||
angularVelocity = Vec3.multiply(180.0 / Math.PI, angularVelocity);
|
||||
} else {
|
||||
BUTTON_FWD = RIGHT_BUTTON_FWD;
|
||||
BUTTON_3 = RIGHT_BUTTON_3;
|
||||
|
@ -104,7 +103,6 @@ function checkControllerSide(whichSide) {
|
|||
Vec3.multiply(1.0 - AVERAGE_FACTOR, averageLinearVelocity[1]));
|
||||
linearVelocity = averageLinearVelocity[1];
|
||||
angularVelocity = Vec3.multiplyQbyV(MyAvatar.orientation, Controller.getSpatialControlRawAngularVelocity(RIGHT_TIP));
|
||||
angularVelocity = Vec3.multiply(180.0 / Math.PI, angularVelocity);
|
||||
handMessage = "RIGHT";
|
||||
}
|
||||
|
||||
|
|
|
@ -53,7 +53,9 @@ function shootDice(position, velocity) {
|
|||
position: position,
|
||||
velocity: velocity,
|
||||
rotation: Quat.fromPitchYawRollDegrees(Math.random() * 360, Math.random() * 360, Math.random() * 360),
|
||||
angularVelocity: { x: Math.random() * 100, y: Math.random() * 100, z: Math.random() * 100 },
|
||||
// NOTE: angularVelocity is in radians/sec
|
||||
var maxAngularSpeed = Math.PI;
|
||||
angularVelocity: { x: Math.random() * maxAngularSpeed, y: Math.random() * maxAngularSpeed, z: Math.random() * maxAngularSpeed },
|
||||
lifetime: LIFETIME,
|
||||
gravity: { x: 0, y: GRAVITY, z: 0 },
|
||||
shapeType: "box",
|
||||
|
@ -108,4 +110,4 @@ function scriptEnding() {
|
|||
|
||||
Entities.entityCollisionWithEntity.connect(entityCollisionWithEntity);
|
||||
Controller.mousePressEvent.connect(mousePressEvent);
|
||||
Script.scriptEnding.connect(scriptEnding);
|
||||
Script.scriptEnding.connect(scriptEnding);
|
||||
|
|
|
@ -11,11 +11,13 @@
|
|||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
//
|
||||
|
||||
var DEGREES_TO_RADIANS = Math.PI / 180.0;
|
||||
|
||||
var lightProperties = {
|
||||
type: "Light",
|
||||
position: { x: 0, y: 0, z: 0 },
|
||||
dimensions: { x: 1000, y: 1000, z: 1000 },
|
||||
angularVelocity: { x: 0, y: 10, z: 0 },
|
||||
angularVelocity: { x: 0, y: 10 * DEGREES_TO_RADIANS, z: 0 },
|
||||
angularDamping: 0,
|
||||
|
||||
isSpotlight: true,
|
||||
|
|
|
@ -2,6 +2,10 @@
|
|||
<head>
|
||||
<link rel="stylesheet" type="text/css" href="style.css">
|
||||
<script>
|
||||
var PI = 3.14159265358979;
|
||||
var DEGREES_TO_RADIANS = PI / 180.0;
|
||||
var RADIANS_TO_DEGREES = 180.0 / PI;
|
||||
|
||||
function enableChildren(el, selector) {
|
||||
els = el.querySelectorAll(selector);
|
||||
for (var i = 0; i < els.length; i++) {
|
||||
|
@ -58,6 +62,22 @@
|
|||
}
|
||||
};
|
||||
|
||||
function createEmitVec3PropertyUpdateFunctionWithMultiplier(property, elX, elY, elZ, multiplier) {
|
||||
return function() {
|
||||
var data = {
|
||||
type: "update",
|
||||
properties: {
|
||||
}
|
||||
};
|
||||
data.properties[property] = {
|
||||
x: elX.value * multiplier,
|
||||
y: elY.value * multiplier,
|
||||
z: elZ.value * multiplier,
|
||||
};
|
||||
EventBridge.emitWebEvent(JSON.stringify(data));
|
||||
}
|
||||
};
|
||||
|
||||
function createEmitColorPropertyUpdateFunction(property, elRed, elGreen, elBlue) {
|
||||
return function() {
|
||||
var data = {
|
||||
|
@ -228,9 +248,9 @@
|
|||
elLinearVelocityZ.value = properties.velocity.z.toFixed(2);
|
||||
elLinearDamping.value = properties.damping.toFixed(2);
|
||||
|
||||
elAngularVelocityX.value = properties.angularVelocity.x.toFixed(2);
|
||||
elAngularVelocityY.value = properties.angularVelocity.y.toFixed(2);
|
||||
elAngularVelocityZ.value = properties.angularVelocity.z.toFixed(2);
|
||||
elAngularVelocityX.value = (properties.angularVelocity.x * RADIANS_TO_DEGREES).toFixed(2);
|
||||
elAngularVelocityY.value = (properties.angularVelocity.y * RADIANS_TO_DEGREES).toFixed(2);
|
||||
elAngularVelocityZ.value = (properties.angularVelocity.z * RADIANS_TO_DEGREES).toFixed(2);
|
||||
elAngularDamping.value = properties.angularDamping.toFixed(2);
|
||||
|
||||
elGravityX.value = properties.gravity.x.toFixed(2);
|
||||
|
@ -354,8 +374,8 @@
|
|||
elLinearVelocityZ.addEventListener('change', velocityChangeFunction);
|
||||
elLinearDamping.addEventListener('change', createEmitNumberPropertyUpdateFunction('damping'));
|
||||
|
||||
var angularVelocityChangeFunction = createEmitVec3PropertyUpdateFunction(
|
||||
'angularVelocity', elAngularVelocityX, elAngularVelocityY, elAngularVelocityZ);
|
||||
var angularVelocityChangeFunction = createEmitVec3PropertyUpdateFunctionWithMultiplier(
|
||||
'angularVelocity', elAngularVelocityX, elAngularVelocityY, elAngularVelocityZ, DEGREES_TO_RADIANS);
|
||||
elAngularVelocityX.addEventListener('change', angularVelocityChangeFunction);
|
||||
elAngularVelocityY.addEventListener('change', angularVelocityChangeFunction);
|
||||
elAngularVelocityZ.addEventListener('change', angularVelocityChangeFunction);
|
||||
|
|
|
@ -11,6 +11,9 @@
|
|||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
//
|
||||
|
||||
var DEGREES_TO_RADIANS = Math.PI / 180.0;
|
||||
var RADIANS_TO_DEGREES = 180.0 / Math.PI;
|
||||
|
||||
EntityPropertyDialogBox = (function () {
|
||||
var that = {};
|
||||
|
||||
|
@ -148,11 +151,12 @@ EntityPropertyDialogBox = (function () {
|
|||
index++;
|
||||
array.push({ label: "Linear Damping:", value: properties.damping.toFixed(decimals) });
|
||||
index++;
|
||||
array.push({ label: "Angular Pitch:", value: properties.angularVelocity.x.toFixed(decimals) });
|
||||
// NOTE: angular velocity is in radians/sec but we display degrees/sec for users
|
||||
array.push({ label: "Angular Pitch:", value: (properties.angularVelocity.x * RADIANS_TO_DEGREES).toFixed(decimals) });
|
||||
index++;
|
||||
array.push({ label: "Angular Yaw:", value: properties.angularVelocity.y.toFixed(decimals) });
|
||||
array.push({ label: "Angular Yaw:", value: (properties.angularVelocity.y * RADIANS_TO_DEGREES).toFixed(decimals) });
|
||||
index++;
|
||||
array.push({ label: "Angular Roll:", value: properties.angularVelocity.z.toFixed(decimals) });
|
||||
array.push({ label: "Angular Roll:", value: (properties.angularVelocity.z * RADIANS_TO_DEGREES).toFixed(decimals) });
|
||||
index++;
|
||||
array.push({ label: "Angular Damping:", value: properties.angularDamping.toFixed(decimals) });
|
||||
index++;
|
||||
|
@ -346,9 +350,10 @@ EntityPropertyDialogBox = (function () {
|
|||
properties.velocity.z = array[index++].value;
|
||||
properties.damping = array[index++].value;
|
||||
|
||||
properties.angularVelocity.x = array[index++].value;
|
||||
properties.angularVelocity.y = array[index++].value;
|
||||
properties.angularVelocity.z = array[index++].value;
|
||||
// NOTE: angular velocity is in radians/sec but we display degrees/sec for users
|
||||
properties.angularVelocity.x = array[index++].value * DEGREES_TO_RADIANS;
|
||||
properties.angularVelocity.y = array[index++].value * DEGREES_TO_RADIANS;
|
||||
properties.angularVelocity.z = array[index++].value * DEGREES_TO_RADIANS;
|
||||
properties.angularDamping = array[index++].value;
|
||||
|
||||
properties.gravity.x = array[index++].value;
|
||||
|
|
|
@ -35,13 +35,15 @@ var NUM_INITIAL_PARTICLES = 200;
|
|||
var PARTICLE_MIN_SIZE = 0.50;
|
||||
var PARTICLE_MAX_SIZE = 1.50;
|
||||
var INITIAL_VELOCITY = 5.0;
|
||||
var DEGREES_TO_RADIANS = Math.PI / 180.0;
|
||||
|
||||
var planets = [];
|
||||
var particles = [];
|
||||
|
||||
// Create planets that will extert gravity on test particles
|
||||
for (var i = 0; i < planetTypes.length; i++) {
|
||||
var rotationalVelocity = 10 + Math.random() * 60;
|
||||
// NOTE: rotationalVelocity is in radians/sec
|
||||
var rotationalVelocity = (10 + Math.random() * 60) * DEGREES_TO_RADIANS;
|
||||
var position = { x: planetTypes[i].x, y: planetTypes[i].y, z: planetTypes[i].z };
|
||||
position = Vec3.multiply(MAX_RANGE / 2, position);
|
||||
position = Vec3.sum(center, position);
|
||||
|
@ -118,4 +120,4 @@ function update(deltaTime) {
|
|||
}
|
||||
}
|
||||
|
||||
Script.scriptEnding.connect(scriptEnding);
|
||||
Script.scriptEnding.connect(scriptEnding);
|
||||
|
|
|
@ -20,6 +20,8 @@ var GRAVITY = -1.0;
|
|||
var LIFETIME = 600;
|
||||
var DAMPING = 0.50;
|
||||
|
||||
var TWO_PI = 2.0 * Math.PI;
|
||||
|
||||
var center = Vec3.sum(MyAvatar.position, Vec3.multiply(SCALE * 3.0, Quat.getFront(Camera.getOrientation())));
|
||||
|
||||
var floor = Entities.addEntity(
|
||||
|
@ -122,7 +124,8 @@ var spinner = Entities.addEntity(
|
|||
position: center,
|
||||
dimensions: { x: SCALE / 1.5, y: SCALE / 3.0, z: SCALE / 8.0 },
|
||||
color: { red: 255, green: 0, blue: 0 },
|
||||
angularVelocity: { x: 0, y: 360, z: 0 },
|
||||
// NOTE: angularVelocity is in radians/sec
|
||||
angularVelocity: { x: 0, y: TWO_PI, z: 0 },
|
||||
angularDamping: 0.0,
|
||||
gravity: { x: 0, y: 0, z: 0 },
|
||||
ignoreCollisions: false,
|
||||
|
@ -179,4 +182,4 @@ function scriptEnding() {
|
|||
}
|
||||
|
||||
Script.scriptEnding.connect(scriptEnding);
|
||||
Script.update.connect(update);
|
||||
Script.update.connect(update);
|
||||
|
|
|
@ -849,4 +849,4 @@ function animateAvatar(deltaTime, speed) {
|
|||
MyAvatar.setJointData(jointName, Quat.fromVec3Degrees(jointRotations));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -151,7 +151,7 @@ static QTimer* billboardPacketTimer = NULL;
|
|||
static QTimer* checkFPStimer = NULL;
|
||||
static QTimer* idleTimer = NULL;
|
||||
|
||||
const QString CHECK_VERSION_URL = "https://highfidelity.io/latestVersion.xml";
|
||||
const QString CHECK_VERSION_URL = "https://highfidelity.com/latestVersion.xml";
|
||||
const QString SKIP_FILENAME = QStandardPaths::writableLocation(QStandardPaths::DataLocation) + "/hifi.skipversion";
|
||||
|
||||
const QString DEFAULT_SCRIPTS_JS_URL = "http://s3.amazonaws.com/hifi-public/scripts/defaultScripts.js";
|
||||
|
@ -1680,8 +1680,7 @@ bool Application::exportEntities(const QString& filename, const QVector<EntityIt
|
|||
|
||||
bool Application::exportEntities(const QString& filename, float x, float y, float z, float scale) {
|
||||
QVector<EntityItem*> entities;
|
||||
_entities.getTree()->findEntities(AACube(glm::vec3(x / (float)TREE_SCALE,
|
||||
y / (float)TREE_SCALE, z / (float)TREE_SCALE), scale / (float)TREE_SCALE), entities);
|
||||
_entities.getTree()->findEntities(AACube(glm::vec3(x, y, z), scale), entities);
|
||||
|
||||
if (entities.size() > 0) {
|
||||
glm::vec3 root(x, y, z);
|
||||
|
@ -2311,7 +2310,6 @@ void Application::queryOctree(NodeType_t serverType, PacketType packetType, Node
|
|||
VoxelPositionSize rootDetails;
|
||||
voxelDetailsForCode(rootCode, rootDetails);
|
||||
AACube serverBounds(glm::vec3(rootDetails.x, rootDetails.y, rootDetails.z), rootDetails.s);
|
||||
serverBounds.scale(TREE_SCALE);
|
||||
|
||||
ViewFrustum::location serverFrustumLocation = _viewFrustum.cubeInFrustum(serverBounds);
|
||||
|
||||
|
@ -2375,7 +2373,6 @@ void Application::queryOctree(NodeType_t serverType, PacketType packetType, Node
|
|||
VoxelPositionSize rootDetails;
|
||||
voxelDetailsForCode(rootCode, rootDetails);
|
||||
AACube serverBounds(glm::vec3(rootDetails.x, rootDetails.y, rootDetails.z), rootDetails.s);
|
||||
serverBounds.scale(TREE_SCALE);
|
||||
|
||||
ViewFrustum::location serverFrustumLocation = _viewFrustum.cubeInFrustum(serverBounds);
|
||||
if (serverFrustumLocation != ViewFrustum::OUTSIDE) {
|
||||
|
|
|
@ -178,6 +178,7 @@ bool ModelUploader::zip() {
|
|||
QByteArray fbxContents = fbx.readAll();
|
||||
FBXGeometry geometry = readFBX(fbxContents, QVariantHash());
|
||||
|
||||
#if 0 /// Temporarily remove this check until CtrlAltDavid can come up with a fix.
|
||||
// Make sure that a skeleton model has a skeleton
|
||||
if (_modelType == SKELETON_MODEL) {
|
||||
if (geometry.rootJointIndex == -1) {
|
||||
|
@ -193,6 +194,7 @@ bool ModelUploader::zip() {
|
|||
return false;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
// make sure we have some basic mappings
|
||||
populateBasicMapping(mapping, filename, geometry);
|
||||
|
|
|
@ -21,7 +21,6 @@ ModelReferential::ModelReferential(Referential* referential, EntityTree* tree, A
|
|||
{
|
||||
_translation = referential->getTranslation();
|
||||
_rotation = referential->getRotation();
|
||||
_scale = referential->getScale();
|
||||
unpackExtraData(reinterpret_cast<unsigned char*>(referential->getExtraData().data()),
|
||||
referential->getExtraData().size());
|
||||
|
||||
|
@ -32,9 +31,9 @@ ModelReferential::ModelReferential(Referential* referential, EntityTree* tree, A
|
|||
|
||||
const EntityItem* item = _tree->findEntityByID(_entityID);
|
||||
if (item != NULL) {
|
||||
_refScale = item->getLargestDimension();
|
||||
_lastRefDimension = item->getDimensions();
|
||||
_refRotation = item->getRotation();
|
||||
_refPosition = item->getPosition() * (float)TREE_SCALE;
|
||||
_refPosition = item->getPosition();
|
||||
update();
|
||||
}
|
||||
}
|
||||
|
@ -51,14 +50,13 @@ ModelReferential::ModelReferential(const QUuid& entityID, EntityTree* tree, Avat
|
|||
return;
|
||||
}
|
||||
|
||||
_refScale = item->getLargestDimension();
|
||||
_lastRefDimension = item->getDimensions();
|
||||
_refRotation = item->getRotation();
|
||||
_refPosition = item->getPosition() * (float)TREE_SCALE;
|
||||
_refPosition = item->getPosition();
|
||||
|
||||
glm::quat refInvRot = glm::inverse(_refRotation);
|
||||
_scale = _avatar->getTargetScale() / _refScale;
|
||||
_rotation = refInvRot * _avatar->getOrientation();
|
||||
_translation = refInvRot * (avatar->getPosition() - _refPosition) / _refScale;
|
||||
_translation = refInvRot * (avatar->getPosition() - _refPosition);
|
||||
}
|
||||
|
||||
void ModelReferential::update() {
|
||||
|
@ -68,9 +66,10 @@ void ModelReferential::update() {
|
|||
}
|
||||
|
||||
bool somethingChanged = false;
|
||||
if (item->getLargestDimension() != _refScale) {
|
||||
_refScale = item->getLargestDimension();
|
||||
_avatar->setTargetScale(_refScale * _scale, true);
|
||||
if (item->getDimensions() != _lastRefDimension) {
|
||||
glm::vec3 oldDimension = _lastRefDimension;
|
||||
_lastRefDimension = item->getDimensions();
|
||||
_translation *= _lastRefDimension / oldDimension;
|
||||
somethingChanged = true;
|
||||
}
|
||||
if (item->getRotation() != _refRotation) {
|
||||
|
@ -80,7 +79,7 @@ void ModelReferential::update() {
|
|||
}
|
||||
if (item->getPosition() != _refPosition || somethingChanged) {
|
||||
_refPosition = item->getPosition();
|
||||
_avatar->setPosition(_refPosition * (float)TREE_SCALE + _refRotation * (_translation * _refScale), true);
|
||||
_avatar->setPosition(_refPosition + _refRotation * _translation, true);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -108,7 +107,7 @@ JointReferential::JointReferential(Referential* referential, EntityTree* tree, A
|
|||
const EntityItem* item = _tree->findEntityByID(_entityID);
|
||||
const Model* model = getModel(item);
|
||||
if (!isValid() || model == NULL || _jointIndex >= (uint32_t)(model->getJointStateCount())) {
|
||||
_refScale = item->getLargestDimension();
|
||||
_lastRefDimension = item->getDimensions();
|
||||
model->getJointRotationInWorldFrame(_jointIndex, _refRotation);
|
||||
model->getJointPositionInWorldFrame(_jointIndex, _refPosition);
|
||||
}
|
||||
|
@ -128,14 +127,14 @@ JointReferential::JointReferential(uint32_t jointIndex, const QUuid& entityID, E
|
|||
return;
|
||||
}
|
||||
|
||||
_refScale = item->getLargestDimension();
|
||||
_lastRefDimension = item->getDimensions();
|
||||
model->getJointRotationInWorldFrame(_jointIndex, _refRotation);
|
||||
model->getJointPositionInWorldFrame(_jointIndex, _refPosition);
|
||||
|
||||
glm::quat refInvRot = glm::inverse(_refRotation);
|
||||
_scale = _avatar->getTargetScale() / _refScale;
|
||||
_rotation = refInvRot * _avatar->getOrientation();
|
||||
_translation = refInvRot * (avatar->getPosition() - _refPosition) / _refScale;
|
||||
// BUG! _refPosition is in domain units, but avatar is in meters
|
||||
_translation = refInvRot * (avatar->getPosition() - _refPosition);
|
||||
}
|
||||
|
||||
void JointReferential::update() {
|
||||
|
@ -146,9 +145,10 @@ void JointReferential::update() {
|
|||
}
|
||||
|
||||
bool somethingChanged = false;
|
||||
if (item->getLargestDimension() != _refScale) {
|
||||
_refScale = item->getLargestDimension();
|
||||
_avatar->setTargetScale(_refScale * _scale, true);
|
||||
if (item->getDimensions() != _lastRefDimension) {
|
||||
glm::vec3 oldDimension = _lastRefDimension;
|
||||
_lastRefDimension = item->getDimensions();
|
||||
_translation *= _lastRefDimension / oldDimension;
|
||||
somethingChanged = true;
|
||||
}
|
||||
if (item->getRotation() != _refRotation) {
|
||||
|
@ -158,7 +158,7 @@ void JointReferential::update() {
|
|||
}
|
||||
if (item->getPosition() != _refPosition || somethingChanged) {
|
||||
model->getJointPositionInWorldFrame(_jointIndex, _refPosition);
|
||||
_avatar->setPosition(_refPosition + _refRotation * (_translation * _refScale), true);
|
||||
_avatar->setPosition(_refPosition + _refRotation * _translation, true);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -45,4 +45,4 @@ protected:
|
|||
uint32_t _jointIndex;
|
||||
};
|
||||
|
||||
#endif // hifi_ModelReferential_h
|
||||
#endif // hifi_ModelReferential_h
|
||||
|
|
|
@ -42,7 +42,7 @@ void OctreeFade::render() {
|
|||
|
||||
glDisable(GL_LIGHTING);
|
||||
glPushMatrix();
|
||||
glScalef(TREE_SCALE, TREE_SCALE, TREE_SCALE);
|
||||
glScalef(1.0f, 1.0f, 1.0f);
|
||||
glTranslatef(voxelDetails.x + voxelDetails.s * 0.5f,
|
||||
voxelDetails.y + voxelDetails.s * 0.5f,
|
||||
voxelDetails.z + voxelDetails.s * 0.5f);
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
//
|
||||
//Merge branch 'master' of ssh://github.com/highfidelity/hifi into isentropic/
|
||||
// OctreePacketProcessor.cpp
|
||||
// interface/src/octree
|
||||
//
|
||||
|
|
|
@ -62,12 +62,12 @@ void DiskCacheEditor::makeDialog() {
|
|||
path->setAlignment(Qt::AlignRight);
|
||||
layout->addWidget(path, 0, 0);
|
||||
|
||||
QLabel* size = new QLabel("Max Size : ", _dialog);
|
||||
QLabel* size = new QLabel("Current Size : ", _dialog);
|
||||
Q_CHECK_PTR(size);
|
||||
size->setAlignment(Qt::AlignRight);
|
||||
layout->addWidget(size, 1, 0);
|
||||
|
||||
QLabel* maxSize = new QLabel("Current Size : ", _dialog);
|
||||
QLabel* maxSize = new QLabel("Max Size : ", _dialog);
|
||||
Q_CHECK_PTR(maxSize);
|
||||
maxSize->setAlignment(Qt::AlignRight);
|
||||
layout->addWidget(maxSize, 2, 0);
|
||||
|
|
|
@ -71,20 +71,19 @@ void NodeBounds::draw() {
|
|||
voxelDetailsForCode(rootCode, rootDetails);
|
||||
serverJurisdictions->unlock();
|
||||
glm::vec3 location(rootDetails.x, rootDetails.y, rootDetails.z);
|
||||
location *= (float)TREE_SCALE;
|
||||
|
||||
AACube serverBounds(location, rootDetails.s * TREE_SCALE);
|
||||
AACube serverBounds(location, rootDetails.s);
|
||||
|
||||
glm::vec3 center = serverBounds.getVertex(BOTTOM_RIGHT_NEAR)
|
||||
+ ((serverBounds.getVertex(TOP_LEFT_FAR) - serverBounds.getVertex(BOTTOM_RIGHT_NEAR)) / 2.0f);
|
||||
|
||||
const float ENTITY_NODE_SCALE = 0.99f;
|
||||
|
||||
float scaleFactor = rootDetails.s * TREE_SCALE;
|
||||
float scaleFactor = rootDetails.s;
|
||||
|
||||
// Scale by 0.92 - 1.00 depending on the scale of the node. This allows smaller nodes to scale in
|
||||
// a bit and not overlap larger nodes.
|
||||
scaleFactor *= 0.92 + (rootDetails.s * 0.08);
|
||||
scaleFactor *= 0.92f + (rootDetails.s * 0.08f);
|
||||
|
||||
// Scale different node types slightly differently because it's common for them to overlap.
|
||||
if (nodeType == NodeType::EntityServer) {
|
||||
|
|
|
@ -273,7 +273,6 @@ void OctreeStatsDialog::showOctreeServersOfType(int& serverCount, NodeType_t ser
|
|||
VoxelPositionSize rootDetails;
|
||||
voxelDetailsForCode(rootCode, rootDetails);
|
||||
AACube serverBounds(glm::vec3(rootDetails.x, rootDetails.y, rootDetails.z), rootDetails.s);
|
||||
serverBounds.scale(TREE_SCALE);
|
||||
serverDetails << " jurisdiction: "
|
||||
<< qPrintable(rootCodeHex)
|
||||
<< " ["
|
||||
|
|
|
@ -76,7 +76,6 @@ int Referential::pack(unsigned char* destinationBuffer) const {
|
|||
|
||||
destinationBuffer += packFloatVec3ToSignedTwoByteFixed(destinationBuffer, _translation, 0);
|
||||
destinationBuffer += packOrientationQuatToBytes(destinationBuffer, _rotation);
|
||||
destinationBuffer += packFloatScalarToSignedTwoByteFixed(destinationBuffer, _scale, 0);
|
||||
return destinationBuffer - startPosition;
|
||||
}
|
||||
|
||||
|
@ -91,7 +90,6 @@ int Referential::unpack(const unsigned char* sourceBuffer) {
|
|||
|
||||
sourceBuffer += unpackFloatVec3FromSignedTwoByteFixed(sourceBuffer, _translation, 0);
|
||||
sourceBuffer += unpackOrientationQuatFromBytes(sourceBuffer, _rotation);
|
||||
sourceBuffer += unpackFloatScalarFromSignedTwoByteFixed((const int16_t*) sourceBuffer, &_scale, 0);
|
||||
return sourceBuffer - startPosition;
|
||||
}
|
||||
|
||||
|
|
|
@ -39,7 +39,6 @@ public:
|
|||
|
||||
glm::vec3 getTranslation() const { return _translation; }
|
||||
glm::quat getRotation() const { return _rotation; }
|
||||
float getScale() const {return _scale; }
|
||||
QByteArray getExtraData() const { return _extraDataBuffer; }
|
||||
|
||||
virtual void update() {}
|
||||
|
@ -62,14 +61,13 @@ protected:
|
|||
AvatarData* _avatar;
|
||||
QByteArray _extraDataBuffer;
|
||||
|
||||
glm::vec3 _refPosition;
|
||||
glm::quat _refRotation;
|
||||
float _refScale;
|
||||
glm::vec3 _refPosition; // position of object in world-frame
|
||||
glm::quat _refRotation; // rotation of object in world-frame
|
||||
glm::vec3 _lastRefDimension; // dimension of object when _translation was last computed
|
||||
|
||||
glm::vec3 _translation;
|
||||
glm::quat _rotation;
|
||||
float _scale;
|
||||
glm::vec3 _translation; // offset of avatar in object local-frame
|
||||
glm::quat _rotation; // rotation of avatar in object local-frame
|
||||
};
|
||||
|
||||
|
||||
#endif // hifi_Referential_h
|
||||
#endif // hifi_Referential_h
|
||||
|
|
|
@ -98,7 +98,7 @@ void EntityTreeRenderer::init() {
|
|||
|
||||
// make sure our "last avatar position" is something other than our current position, so that on our
|
||||
// first chance, we'll check for enter/leave entity events.
|
||||
_lastAvatarPosition = _viewState->getAvatarPosition() + glm::vec3(1.0f, 1.0f, 1.0f);
|
||||
_lastAvatarPosition = _viewState->getAvatarPosition() + glm::vec3((float)TREE_SCALE);
|
||||
|
||||
connect(entityTree, &EntityTree::deletingEntity, this, &EntityTreeRenderer::deletingEntity);
|
||||
connect(entityTree, &EntityTree::addingEntity, this, &EntityTreeRenderer::checkAndCallPreload);
|
||||
|
@ -278,10 +278,10 @@ void EntityTreeRenderer::update() {
|
|||
void EntityTreeRenderer::checkEnterLeaveEntities() {
|
||||
if (_tree && !_shuttingDown) {
|
||||
_tree->lockForWrite(); // so that our scripts can do edits if they want
|
||||
glm::vec3 avatarPosition = _viewState->getAvatarPosition() / (float) TREE_SCALE;
|
||||
glm::vec3 avatarPosition = _viewState->getAvatarPosition();
|
||||
|
||||
if (avatarPosition != _lastAvatarPosition) {
|
||||
float radius = 1.0f / (float) TREE_SCALE; // for now, assume 1 meter radius
|
||||
float radius = 1.0f; // for now, assume 1 meter radius
|
||||
QVector<const EntityItem*> foundEntities;
|
||||
QVector<EntityItemID> entitiesContainingAvatar;
|
||||
|
||||
|
@ -343,7 +343,7 @@ void EntityTreeRenderer::leaveAllEntities() {
|
|||
|
||||
// make sure our "last avatar position" is something other than our current position, so that on our
|
||||
// first chance, we'll check for enter/leave entity events.
|
||||
_lastAvatarPosition = _viewState->getAvatarPosition() + glm::vec3(1.0f, 1.0f, 1.0f);
|
||||
_lastAvatarPosition = _viewState->getAvatarPosition() + glm::vec3((float)TREE_SCALE);
|
||||
_tree->unlock();
|
||||
}
|
||||
}
|
||||
|
@ -418,8 +418,8 @@ const Model* EntityTreeRenderer::getModelForEntityItem(const EntityItem* entityI
|
|||
}
|
||||
|
||||
void EntityTreeRenderer::renderElementProxy(EntityTreeElement* entityTreeElement) {
|
||||
glm::vec3 elementCenter = entityTreeElement->getAACube().calcCenter() * (float) TREE_SCALE;
|
||||
float elementSize = entityTreeElement->getScale() * (float) TREE_SCALE;
|
||||
glm::vec3 elementCenter = entityTreeElement->getAACube().calcCenter();
|
||||
float elementSize = entityTreeElement->getScale();
|
||||
glPushMatrix();
|
||||
glTranslatef(elementCenter.x, elementCenter.y, elementCenter.z);
|
||||
DependencyManager::get<DeferredLightingEffect>()->renderWireCube(elementSize, glm::vec4(1.0f, 0.0f, 0.0f, 1.0f));
|
||||
|
@ -480,10 +480,6 @@ void EntityTreeRenderer::renderProxies(const EntityItem* entity, RenderArgs* arg
|
|||
AACube minCube = entity->getMinimumAACube();
|
||||
AABox entityBox = entity->getAABox();
|
||||
|
||||
maxCube.scale((float) TREE_SCALE);
|
||||
minCube.scale((float) TREE_SCALE);
|
||||
entityBox.scale((float) TREE_SCALE);
|
||||
|
||||
glm::vec3 maxCenter = maxCube.calcCenter();
|
||||
glm::vec3 minCenter = minCube.calcCenter();
|
||||
glm::vec3 entityBoxCenter = entityBox.calcCenter();
|
||||
|
@ -509,9 +505,9 @@ void EntityTreeRenderer::renderProxies(const EntityItem* entity, RenderArgs* arg
|
|||
glPopMatrix();
|
||||
|
||||
|
||||
glm::vec3 position = entity->getPosition() * (float) TREE_SCALE;
|
||||
glm::vec3 center = entity->getCenter() * (float) TREE_SCALE;
|
||||
glm::vec3 dimensions = entity->getDimensions() * (float) TREE_SCALE;
|
||||
glm::vec3 position = entity->getPosition();
|
||||
glm::vec3 center = entity->getCenter();
|
||||
glm::vec3 dimensions = entity->getDimensions();
|
||||
glm::quat rotation = entity->getRotation();
|
||||
|
||||
glPushMatrix();
|
||||
|
@ -551,8 +547,6 @@ void EntityTreeRenderer::renderElement(OctreeElement* element, RenderArgs* args)
|
|||
if (entityItem->isVisible()) {
|
||||
// render entityItem
|
||||
AABox entityBox = entityItem->getAABox();
|
||||
|
||||
entityBox.scale(TREE_SCALE);
|
||||
|
||||
// TODO: some entity types (like lights) might want to be rendered even
|
||||
// when they are outside of the view frustum...
|
||||
|
|
|
@ -25,9 +25,9 @@ EntityItem* RenderableBoxEntityItem::factory(const EntityItemID& entityID, const
|
|||
void RenderableBoxEntityItem::render(RenderArgs* args) {
|
||||
PerformanceTimer perfTimer("RenderableBoxEntityItem::render");
|
||||
assert(getType() == EntityTypes::Box);
|
||||
glm::vec3 position = getPositionInMeters();
|
||||
glm::vec3 center = getCenter() * (float)TREE_SCALE;
|
||||
glm::vec3 dimensions = getDimensions() * (float)TREE_SCALE;
|
||||
glm::vec3 position = getPosition();
|
||||
glm::vec3 center = getCenter();
|
||||
glm::vec3 dimensions = getDimensions();
|
||||
glm::quat rotation = getRotation();
|
||||
|
||||
const float MAX_COLOR = 255.0f;
|
||||
|
|
|
@ -26,8 +26,8 @@ EntityItem* RenderableLightEntityItem::factory(const EntityItemID& entityID, con
|
|||
void RenderableLightEntityItem::render(RenderArgs* args) {
|
||||
PerformanceTimer perfTimer("RenderableLightEntityItem::render");
|
||||
assert(getType() == EntityTypes::Light);
|
||||
glm::vec3 position = getPositionInMeters();
|
||||
glm::vec3 dimensions = getDimensions() * (float)TREE_SCALE;
|
||||
glm::vec3 position = getPosition();
|
||||
glm::vec3 dimensions = getDimensions();
|
||||
glm::quat rotation = getRotation();
|
||||
float largestDiameter = glm::max(dimensions.x, dimensions.y, dimensions.z);
|
||||
|
||||
|
|
|
@ -114,9 +114,9 @@ void RenderableModelEntityItem::render(RenderArgs* args) {
|
|||
|
||||
bool drawAsModel = hasModel();
|
||||
|
||||
glm::vec3 position = getPosition() * (float)TREE_SCALE;
|
||||
float size = getSize() * (float)TREE_SCALE;
|
||||
glm::vec3 dimensions = getDimensions() * (float)TREE_SCALE;
|
||||
glm::vec3 position = getPosition();
|
||||
glm::vec3 dimensions = getDimensions();
|
||||
float size = glm::length(dimensions);
|
||||
|
||||
if (drawAsModel) {
|
||||
remapTextures();
|
||||
|
@ -260,23 +260,10 @@ bool RenderableModelEntityItem::findDetailedRayIntersection(const glm::vec3& ori
|
|||
if (!_model) {
|
||||
return true;
|
||||
}
|
||||
|
||||
glm::vec3 originInMeters = origin * (float)TREE_SCALE;
|
||||
QString extraInfo;
|
||||
float localDistance;
|
||||
|
||||
//qDebug() << "RenderableModelEntityItem::findDetailedRayIntersection() precisionPicking:" << precisionPicking;
|
||||
|
||||
bool intersectsModel = _model->findRayIntersectionAgainstSubMeshes(originInMeters, direction,
|
||||
localDistance, face, extraInfo, precisionPicking);
|
||||
|
||||
if (intersectsModel) {
|
||||
// NOTE: findRayIntersectionAgainstSubMeshes() does work in meters, but we're expected to return
|
||||
// results in tree scale.
|
||||
distance = localDistance / (float)TREE_SCALE;
|
||||
}
|
||||
|
||||
return intersectsModel; // we only got here if we intersected our non-aabox
|
||||
QString extraInfo;
|
||||
return _model->findRayIntersectionAgainstSubMeshes(origin, direction, distance, face, extraInfo, precisionPicking);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -31,9 +31,6 @@ RenderableParticleEffectEntityItem::RenderableParticleEffectEntityItem(const Ent
|
|||
void RenderableParticleEffectEntityItem::render(RenderArgs* args) {
|
||||
PerformanceTimer perfTimer("RenderableParticleEffectEntityItem::render");
|
||||
assert(getType() == EntityTypes::ParticleEffect);
|
||||
glm::vec3 position = getPositionInMeters();
|
||||
glm::vec3 center = getCenterInMeters();
|
||||
glm::quat rotation = getRotation();
|
||||
float pa_rad = getParticleRadius();
|
||||
|
||||
const float MAX_COLOR = 255.0f;
|
||||
|
@ -75,13 +72,14 @@ void RenderableParticleEffectEntityItem::render(RenderArgs* args) {
|
|||
DependencyManager::get<GeometryCache>()->updateVertices(_cacheID, *pointVec, paColor);
|
||||
|
||||
glPushMatrix();
|
||||
glm::vec3 position = getPosition();
|
||||
glTranslatef(position.x, position.y, position.z);
|
||||
glm::quat rotation = getRotation();
|
||||
glm::vec3 axis = glm::axis(rotation);
|
||||
glRotatef(glm::degrees(glm::angle(rotation)), axis.x, axis.y, axis.z);
|
||||
|
||||
|
||||
glPushMatrix();
|
||||
glm::vec3 positionToCenter = center - position;
|
||||
glm::vec3 positionToCenter = getCenter() - position;
|
||||
glTranslatef(positionToCenter.x, positionToCenter.y, positionToCenter.z);
|
||||
|
||||
DependencyManager::get<GeometryCache>()->renderVertices(gpu::QUADS, _cacheID);
|
||||
|
|
|
@ -26,9 +26,9 @@ EntityItem* RenderableSphereEntityItem::factory(const EntityItemID& entityID, co
|
|||
void RenderableSphereEntityItem::render(RenderArgs* args) {
|
||||
PerformanceTimer perfTimer("RenderableSphereEntityItem::render");
|
||||
assert(getType() == EntityTypes::Sphere);
|
||||
glm::vec3 position = getPositionInMeters();
|
||||
glm::vec3 center = getCenterInMeters();
|
||||
glm::vec3 dimensions = getDimensions() * (float)TREE_SCALE;
|
||||
glm::vec3 position = getPosition();
|
||||
glm::vec3 center = getCenter();
|
||||
glm::vec3 dimensions = getDimensions();
|
||||
glm::quat rotation = getRotation();
|
||||
|
||||
const float MAX_COLOR = 255.0f;
|
||||
|
|
|
@ -30,8 +30,8 @@ EntityItem* RenderableTextEntityItem::factory(const EntityItemID& entityID, cons
|
|||
void RenderableTextEntityItem::render(RenderArgs* args) {
|
||||
PerformanceTimer perfTimer("RenderableTextEntityItem::render");
|
||||
assert(getType() == EntityTypes::Text);
|
||||
glm::vec3 position = getPositionInMeters();
|
||||
glm::vec3 dimensions = getDimensions() * (float)TREE_SCALE;
|
||||
glm::vec3 position = getPosition();
|
||||
glm::vec3 dimensions = getDimensions();
|
||||
glm::vec3 halfDimensions = dimensions / 2.0f;
|
||||
glm::quat rotation = getRotation();
|
||||
float leftMargin = 0.1f;
|
||||
|
|
|
@ -25,7 +25,7 @@ AddEntityOperator::AddEntityOperator(EntityTree* tree,
|
|||
{
|
||||
// caller must have verified existence of newEntity
|
||||
assert(_newEntity);
|
||||
_newEntityBox = _newEntity->getMaximumAACube().clamp(0.0f, 1.0f);
|
||||
_newEntityBox = _newEntity->getMaximumAACube().clamp(0.0f, (float)TREE_SCALE);
|
||||
}
|
||||
|
||||
bool AddEntityOperator::preRecursion(OctreeElement* element) {
|
||||
|
|
|
@ -60,7 +60,7 @@ bool DeleteEntityOperator::subTreeContainsSomeEntitiesToDelete(OctreeElement* el
|
|||
// If we don't have an old entity, then we don't contain the entity, otherwise
|
||||
// check the bounds
|
||||
if (_entitiesToDelete.size() > 0) {
|
||||
AACube elementCube = element->getAACube();
|
||||
const AACube& elementCube = element->getAACube();
|
||||
foreach(const EntityToDeleteDetails& details, _entitiesToDelete) {
|
||||
if (elementCube.contains(details.cube)) {
|
||||
containsEntity = true;
|
||||
|
|
|
@ -501,8 +501,12 @@ int EntityItem::readEntityDataFromBuffer(const unsigned char* data, int bytesLef
|
|||
EntityPropertyFlags propertyFlags = encodedPropertyFlags;
|
||||
dataAt += propertyFlags.getEncodedLength();
|
||||
bytesRead += propertyFlags.getEncodedLength();
|
||||
|
||||
READ_ENTITY_PROPERTY_SETTER(PROP_POSITION, glm::vec3, updatePosition);
|
||||
bool useMeters = (args.bitstreamVersion == VERSION_ENTITIES_USE_METERS_AND_RADIANS);
|
||||
if (useMeters) {
|
||||
READ_ENTITY_PROPERTY_SETTER(PROP_POSITION, glm::vec3, updatePosition);
|
||||
} else {
|
||||
READ_ENTITY_PROPERTY_SETTER(PROP_POSITION, glm::vec3, updatePositionInDomainUnits);
|
||||
}
|
||||
|
||||
// Old bitstreams had PROP_RADIUS, new bitstreams have PROP_DIMENSIONS
|
||||
if (args.bitstreamVersion < VERSION_ENTITIES_SUPPORT_DIMENSIONS) {
|
||||
|
@ -516,18 +520,31 @@ int EntityItem::readEntityDataFromBuffer(const unsigned char* data, int bytesLef
|
|||
}
|
||||
}
|
||||
} else {
|
||||
READ_ENTITY_PROPERTY_SETTER(PROP_DIMENSIONS, glm::vec3, setDimensions);
|
||||
if (useMeters) {
|
||||
READ_ENTITY_PROPERTY_SETTER(PROP_DIMENSIONS, glm::vec3, setDimensions);
|
||||
} else {
|
||||
READ_ENTITY_PROPERTY_SETTER(PROP_DIMENSIONS, glm::vec3, setDimensionsInDomainUnits);
|
||||
}
|
||||
}
|
||||
|
||||
READ_ENTITY_PROPERTY_QUAT_SETTER(PROP_ROTATION, updateRotation);
|
||||
READ_ENTITY_PROPERTY_SETTER(PROP_DENSITY, float, updateDensity);
|
||||
READ_ENTITY_PROPERTY_SETTER(PROP_VELOCITY, glm::vec3, updateVelocity);
|
||||
READ_ENTITY_PROPERTY_SETTER(PROP_GRAVITY, glm::vec3, updateGravity);
|
||||
if (useMeters) {
|
||||
READ_ENTITY_PROPERTY_SETTER(PROP_VELOCITY, glm::vec3, updateVelocity);
|
||||
READ_ENTITY_PROPERTY_SETTER(PROP_GRAVITY, glm::vec3, updateGravity);
|
||||
} else {
|
||||
READ_ENTITY_PROPERTY_SETTER(PROP_VELOCITY, glm::vec3, updateVelocityInDomainUnits);
|
||||
READ_ENTITY_PROPERTY_SETTER(PROP_GRAVITY, glm::vec3, updateGravityInDomainUnits);
|
||||
}
|
||||
READ_ENTITY_PROPERTY(PROP_DAMPING, float, _damping);
|
||||
READ_ENTITY_PROPERTY_SETTER(PROP_LIFETIME, float, updateLifetime);
|
||||
READ_ENTITY_PROPERTY_STRING(PROP_SCRIPT, setScript);
|
||||
READ_ENTITY_PROPERTY(PROP_REGISTRATION_POINT, glm::vec3, _registrationPoint);
|
||||
READ_ENTITY_PROPERTY_SETTER(PROP_ANGULAR_VELOCITY, glm::vec3, updateAngularVelocity);
|
||||
if (useMeters) {
|
||||
READ_ENTITY_PROPERTY_SETTER(PROP_ANGULAR_VELOCITY, glm::vec3, updateAngularVelocity);
|
||||
} else {
|
||||
READ_ENTITY_PROPERTY_SETTER(PROP_ANGULAR_VELOCITY, glm::vec3, updateAngularVelocityInDegrees);
|
||||
}
|
||||
READ_ENTITY_PROPERTY(PROP_ANGULAR_DAMPING, float, _angularDamping);
|
||||
READ_ENTITY_PROPERTY(PROP_VISIBLE, bool, _visible);
|
||||
READ_ENTITY_PROPERTY_SETTER(PROP_IGNORE_FOR_COLLISIONS, bool, updateIgnoreForCollisions);
|
||||
|
@ -587,8 +604,7 @@ void EntityItem::adjustEditPacketForClockSkew(unsigned char* editPacketBuffer, s
|
|||
}
|
||||
|
||||
float EntityItem::computeMass() const {
|
||||
// NOTE: we group the operations here in and attempt to reduce floating point error.
|
||||
return ((_density * (_volumeMultiplier * _dimensions.x)) * _dimensions.y) * _dimensions.z;
|
||||
return _density * _volumeMultiplier * _dimensions.x * _dimensions.y * _dimensions.z;
|
||||
}
|
||||
|
||||
void EntityItem::setDensity(float density) {
|
||||
|
@ -609,10 +625,7 @@ void EntityItem::setMass(float mass) {
|
|||
// we must protect the density range to help maintain stability of physics simulation
|
||||
// therefore this method might not accept the mass that is supplied.
|
||||
|
||||
// NOTE: when computing the volume we group the _volumeMultiplier (typically a very large number, due
|
||||
// to the TREE_SCALE transformation) with the first dimension component (typically a very small number)
|
||||
// in an attempt to reduce floating point error of the final result.
|
||||
float volume = (_volumeMultiplier * _dimensions.x) * _dimensions.y * _dimensions.z;
|
||||
float volume = _volumeMultiplier * _dimensions.x * _dimensions.y * _dimensions.z;
|
||||
|
||||
// compute new density
|
||||
const float MIN_VOLUME = 1.0e-6f; // 0.001mm^3
|
||||
|
@ -674,41 +687,36 @@ void EntityItem::simulate(const quint64& now) {
|
|||
void EntityItem::simulateKinematicMotion(float timeElapsed) {
|
||||
if (hasAngularVelocity()) {
|
||||
// angular damping
|
||||
glm::vec3 angularVelocity = getAngularVelocity();
|
||||
if (_angularDamping > 0.0f) {
|
||||
angularVelocity *= powf(1.0f - _angularDamping, timeElapsed);
|
||||
_angularVelocity *= powf(1.0f - _angularDamping, timeElapsed);
|
||||
#ifdef WANT_DEBUG
|
||||
qDebug() << " angularDamping :" << _angularDamping;
|
||||
qDebug() << " newAngularVelocity:" << angularVelocity;
|
||||
qDebug() << " newAngularVelocity:" << _angularVelocity;
|
||||
#endif
|
||||
setAngularVelocity(angularVelocity);
|
||||
}
|
||||
|
||||
float angularSpeed = glm::length(_angularVelocity);
|
||||
|
||||
const float EPSILON_ANGULAR_VELOCITY_LENGTH = 0.1f; //
|
||||
const float EPSILON_ANGULAR_VELOCITY_LENGTH = 0.0017453f; // 0.0017453 rad/sec = 0.1f degrees/sec
|
||||
if (angularSpeed < EPSILON_ANGULAR_VELOCITY_LENGTH) {
|
||||
if (angularSpeed > 0.0f) {
|
||||
_dirtyFlags |= EntityItem::DIRTY_MOTION_TYPE;
|
||||
}
|
||||
setAngularVelocity(ENTITY_ITEM_ZERO_VEC3);
|
||||
_angularVelocity = ENTITY_ITEM_ZERO_VEC3;
|
||||
} else {
|
||||
// NOTE: angularSpeed is currently in degrees/sec!!!
|
||||
// TODO: Andrew to convert to radians/sec
|
||||
glm::vec3 angularVelocity = glm::radians(_angularVelocity);
|
||||
// for improved agreement with the way Bullet integrates rotations we use an approximation
|
||||
// and break the integration into bullet-sized substeps
|
||||
glm::quat rotation = getRotation();
|
||||
float dt = timeElapsed;
|
||||
while (dt > PHYSICS_ENGINE_FIXED_SUBSTEP) {
|
||||
glm::quat dQ = computeBulletRotationStep(angularVelocity, PHYSICS_ENGINE_FIXED_SUBSTEP);
|
||||
glm::quat dQ = computeBulletRotationStep(_angularVelocity, PHYSICS_ENGINE_FIXED_SUBSTEP);
|
||||
rotation = glm::normalize(dQ * rotation);
|
||||
dt -= PHYSICS_ENGINE_FIXED_SUBSTEP;
|
||||
}
|
||||
// NOTE: this final partial substep can drift away from a real Bullet simulation however
|
||||
// it only becomes significant for rapidly rotating objects
|
||||
// (e.g. around PI/4 radians per substep, or 7.5 rotations/sec at 60 substeps/sec).
|
||||
glm::quat dQ = computeBulletRotationStep(angularVelocity, dt);
|
||||
glm::quat dQ = computeBulletRotationStep(_angularVelocity, dt);
|
||||
rotation = glm::normalize(dQ * rotation);
|
||||
|
||||
setRotation(rotation);
|
||||
|
@ -753,7 +761,7 @@ void EntityItem::simulateKinematicMotion(float timeElapsed) {
|
|||
}
|
||||
|
||||
float speed = glm::length(velocity);
|
||||
const float EPSILON_LINEAR_VELOCITY_LENGTH = 0.001f / (float)TREE_SCALE; // 1mm/sec
|
||||
const float EPSILON_LINEAR_VELOCITY_LENGTH = 0.001f; // 1mm/sec
|
||||
if (speed < EPSILON_LINEAR_VELOCITY_LENGTH) {
|
||||
setVelocity(ENTITY_ITEM_ZERO_VEC3);
|
||||
if (speed > 0.0f) {
|
||||
|
@ -793,12 +801,12 @@ EntityItemProperties EntityItem::getProperties() const {
|
|||
|
||||
properties._type = getType();
|
||||
|
||||
COPY_ENTITY_PROPERTY_TO_PROPERTIES(position, getPositionInMeters);
|
||||
COPY_ENTITY_PROPERTY_TO_PROPERTIES(dimensions, getDimensionsInMeters); // NOTE: radius is obsolete
|
||||
COPY_ENTITY_PROPERTY_TO_PROPERTIES(position, getPosition);
|
||||
COPY_ENTITY_PROPERTY_TO_PROPERTIES(dimensions, getDimensions); // NOTE: radius is obsolete
|
||||
COPY_ENTITY_PROPERTY_TO_PROPERTIES(rotation, getRotation);
|
||||
COPY_ENTITY_PROPERTY_TO_PROPERTIES(density, getDensity);
|
||||
COPY_ENTITY_PROPERTY_TO_PROPERTIES(velocity, getVelocityInMeters);
|
||||
COPY_ENTITY_PROPERTY_TO_PROPERTIES(gravity, getGravityInMeters);
|
||||
COPY_ENTITY_PROPERTY_TO_PROPERTIES(velocity, getVelocity);
|
||||
COPY_ENTITY_PROPERTY_TO_PROPERTIES(gravity, getGravity);
|
||||
COPY_ENTITY_PROPERTY_TO_PROPERTIES(damping, getDamping);
|
||||
COPY_ENTITY_PROPERTY_TO_PROPERTIES(lifetime, getLifetime);
|
||||
COPY_ENTITY_PROPERTY_TO_PROPERTIES(script, getScript);
|
||||
|
@ -821,12 +829,12 @@ EntityItemProperties EntityItem::getProperties() const {
|
|||
bool EntityItem::setProperties(const EntityItemProperties& properties) {
|
||||
bool somethingChanged = false;
|
||||
|
||||
SET_ENTITY_PROPERTY_FROM_PROPERTIES(position, updatePositionInMeters); // this will call recalculate collision shape if needed
|
||||
SET_ENTITY_PROPERTY_FROM_PROPERTIES(dimensions, updateDimensionsInMeters); // NOTE: radius is obsolete
|
||||
SET_ENTITY_PROPERTY_FROM_PROPERTIES(position, updatePosition); // this will call recalculate collision shape if needed
|
||||
SET_ENTITY_PROPERTY_FROM_PROPERTIES(dimensions, updateDimensions); // NOTE: radius is obsolete
|
||||
SET_ENTITY_PROPERTY_FROM_PROPERTIES(rotation, updateRotation);
|
||||
SET_ENTITY_PROPERTY_FROM_PROPERTIES(density, updateDensity);
|
||||
SET_ENTITY_PROPERTY_FROM_PROPERTIES(velocity, updateVelocityInMeters);
|
||||
SET_ENTITY_PROPERTY_FROM_PROPERTIES(gravity, updateGravityInMeters);
|
||||
SET_ENTITY_PROPERTY_FROM_PROPERTIES(velocity, updateVelocity);
|
||||
SET_ENTITY_PROPERTY_FROM_PROPERTIES(gravity, updateGravity);
|
||||
SET_ENTITY_PROPERTY_FROM_PROPERTIES(damping, updateDamping);
|
||||
SET_ENTITY_PROPERTY_FROM_PROPERTIES(lifetime, updateLifetime);
|
||||
SET_ENTITY_PROPERTY_FROM_PROPERTIES(script, setScript);
|
||||
|
@ -888,11 +896,6 @@ void EntityItem::recordCreationTime() {
|
|||
}
|
||||
|
||||
|
||||
// TODO: is this really correct? how do we use size, does it need to handle rotation?
|
||||
float EntityItem::getSize() const {
|
||||
return glm::length(_dimensions);
|
||||
}
|
||||
|
||||
// TODO: doesn't this need to handle rotation?
|
||||
glm::vec3 EntityItem::getCenter() const {
|
||||
return _position + (_dimensions * (glm::vec3(0.5f,0.5f,0.5f) - _registrationPoint));
|
||||
|
@ -951,8 +954,7 @@ AACube EntityItem::getMinimumAACube() const {
|
|||
return AACube(cornerOfCube, longestSide);
|
||||
}
|
||||
|
||||
AABox EntityItem::getAABox() const {
|
||||
|
||||
AABox EntityItem::getAABox() const {
|
||||
// _position represents the position of the registration point.
|
||||
glm::vec3 registrationRemainder = glm::vec3(1.0f, 1.0f, 1.0f) - _registrationPoint;
|
||||
|
||||
|
@ -967,6 +969,11 @@ AABox EntityItem::getAABox() const {
|
|||
return AABox(rotatedExtentsRelativeToRegistrationPoint);
|
||||
}
|
||||
|
||||
AABox EntityItem::getAABoxInDomainUnits() const {
|
||||
AABox box = getAABox();
|
||||
box.scale(1.0f / (float)TREE_SCALE);
|
||||
return box;
|
||||
}
|
||||
|
||||
// NOTE: This should only be used in cases of old bitstreams which only contain radius data
|
||||
// 0,0,0 --> maxDimension,maxDimension,maxDimension
|
||||
|
@ -992,48 +999,41 @@ void EntityItem::setRadius(float value) {
|
|||
// ... cornerToCornerLength = sqrt(3 x maxDimension ^ 2)
|
||||
// ... radius = sqrt(3 x maxDimension ^ 2) / 2.0f;
|
||||
float EntityItem::getRadius() const {
|
||||
float length = glm::length(_dimensions);
|
||||
float radius = length / 2.0f;
|
||||
return radius;
|
||||
return 0.5f * glm::length(_dimensions);
|
||||
}
|
||||
|
||||
void EntityItem::computeShapeInfo(ShapeInfo& info) const {
|
||||
info.setParams(getShapeType(), 0.5f * getDimensionsInMeters());
|
||||
info.setParams(getShapeType(), 0.5f * getDimensions());
|
||||
}
|
||||
|
||||
const float MIN_POSITION_DELTA = 0.0001f;
|
||||
const float MIN_DIMENSIONS_DELTA = 0.0005f;
|
||||
const float MIN_ALIGNMENT_DOT = 0.999999f;
|
||||
const float MIN_VELOCITY_DELTA = 0.01f;
|
||||
const float MIN_DAMPING_DELTA = 0.001f;
|
||||
const float MIN_GRAVITY_DELTA = 0.001f;
|
||||
const float MIN_SPIN_DELTA = 0.0003f;
|
||||
|
||||
void EntityItem::updatePositionInDomainUnits(const glm::vec3& value) {
|
||||
glm::vec3 position = value * (float)TREE_SCALE;
|
||||
updatePosition(position);
|
||||
}
|
||||
|
||||
void EntityItem::updatePosition(const glm::vec3& value) {
|
||||
if (glm::distance(_position, value) * (float)TREE_SCALE > MIN_POSITION_DELTA) {
|
||||
_position = value;
|
||||
if (glm::distance(_position, value) > MIN_POSITION_DELTA) {
|
||||
_position = value;
|
||||
_dirtyFlags |= EntityItem::DIRTY_POSITION;
|
||||
}
|
||||
}
|
||||
|
||||
void EntityItem::updatePositionInMeters(const glm::vec3& value) {
|
||||
glm::vec3 position = glm::clamp(value / (float) TREE_SCALE, 0.0f, 1.0f);
|
||||
if (glm::distance(_position, position) * (float)TREE_SCALE > MIN_POSITION_DELTA) {
|
||||
_position = position;
|
||||
_dirtyFlags |= EntityItem::DIRTY_POSITION;
|
||||
}
|
||||
void EntityItem::updateDimensionsInDomainUnits(const glm::vec3& value) {
|
||||
glm::vec3 dimensions = value * (float)TREE_SCALE;
|
||||
updateDimensions(dimensions);
|
||||
}
|
||||
|
||||
void EntityItem::updateDimensions(const glm::vec3& value) {
|
||||
if (_dimensions != value) {
|
||||
_dimensions = glm::abs(value);
|
||||
_dirtyFlags |= (EntityItem::DIRTY_SHAPE | EntityItem::DIRTY_MASS);
|
||||
}
|
||||
}
|
||||
|
||||
void EntityItem::updateDimensionsInMeters(const glm::vec3& value) {
|
||||
glm::vec3 dimensions = glm::abs(value) / (float) TREE_SCALE;
|
||||
if (_dimensions != dimensions) {
|
||||
_dimensions = dimensions;
|
||||
if (glm::distance(_dimensions, value) > MIN_DIMENSIONS_DELTA) {
|
||||
_dimensions = value;
|
||||
_dirtyFlags |= (EntityItem::DIRTY_SHAPE | EntityItem::DIRTY_MASS);
|
||||
}
|
||||
}
|
||||
|
@ -1050,10 +1050,7 @@ void EntityItem::updateMass(float mass) {
|
|||
// we must protect the density range to help maintain stability of physics simulation
|
||||
// therefore this method might not accept the mass that is supplied.
|
||||
|
||||
// NOTE: when computing the volume we group the _volumeMultiplier (typically a very large number, due
|
||||
// to the TREE_SCALE transformation) with the first dimension component (typically a very small number)
|
||||
// in an attempt to reduce floating point error of the final result.
|
||||
float volume = (_volumeMultiplier * _dimensions.x) * _dimensions.y * _dimensions.z;
|
||||
float volume = _volumeMultiplier * _dimensions.x * _dimensions.y * _dimensions.z;
|
||||
|
||||
// compute new density
|
||||
float newDensity = _density;
|
||||
|
@ -1072,24 +1069,17 @@ void EntityItem::updateMass(float mass) {
|
|||
}
|
||||
}
|
||||
|
||||
void EntityItem::updateVelocity(const glm::vec3& value) {
|
||||
if (glm::distance(_velocity, value) * (float)TREE_SCALE > MIN_VELOCITY_DELTA) {
|
||||
if (glm::length(value) * (float)TREE_SCALE < MIN_VELOCITY_DELTA) {
|
||||
_velocity = ENTITY_ITEM_ZERO_VEC3;
|
||||
} else {
|
||||
_velocity = value;
|
||||
}
|
||||
_dirtyFlags |= EntityItem::DIRTY_VELOCITY;
|
||||
}
|
||||
void EntityItem::updateVelocityInDomainUnits(const glm::vec3& value) {
|
||||
glm::vec3 velocity = value * (float)TREE_SCALE;
|
||||
updateVelocity(velocity);
|
||||
}
|
||||
|
||||
void EntityItem::updateVelocityInMeters(const glm::vec3& value) {
|
||||
glm::vec3 velocity = value / (float) TREE_SCALE;
|
||||
if (glm::distance(_velocity, velocity) * (float)TREE_SCALE > MIN_VELOCITY_DELTA) {
|
||||
void EntityItem::updateVelocity(const glm::vec3& value) {
|
||||
if (glm::distance(_velocity, value) > MIN_VELOCITY_DELTA) {
|
||||
if (glm::length(value) < MIN_VELOCITY_DELTA) {
|
||||
_velocity = ENTITY_ITEM_ZERO_VEC3;
|
||||
} else {
|
||||
_velocity = velocity;
|
||||
_velocity = value;
|
||||
}
|
||||
_dirtyFlags |= EntityItem::DIRTY_VELOCITY;
|
||||
}
|
||||
|
@ -1102,17 +1092,14 @@ void EntityItem::updateDamping(float value) {
|
|||
}
|
||||
}
|
||||
|
||||
void EntityItem::updateGravity(const glm::vec3& value) {
|
||||
if (glm::distance(_gravity, value) * (float)TREE_SCALE > MIN_GRAVITY_DELTA) {
|
||||
_gravity = value;
|
||||
_dirtyFlags |= EntityItem::DIRTY_VELOCITY;
|
||||
}
|
||||
void EntityItem::updateGravityInDomainUnits(const glm::vec3& value) {
|
||||
glm::vec3 gravity = value * (float) TREE_SCALE;
|
||||
updateGravity(gravity);
|
||||
}
|
||||
|
||||
void EntityItem::updateGravityInMeters(const glm::vec3& value) {
|
||||
glm::vec3 gravity = value / (float) TREE_SCALE;
|
||||
if ( glm::distance(_gravity, gravity) * (float)TREE_SCALE > MIN_GRAVITY_DELTA) {
|
||||
_gravity = gravity;
|
||||
void EntityItem::updateGravity(const glm::vec3& value) {
|
||||
if ( glm::distance(_gravity, value) > MIN_GRAVITY_DELTA) {
|
||||
_gravity = value;
|
||||
_dirtyFlags |= EntityItem::DIRTY_VELOCITY;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -37,7 +37,7 @@ class EntityTreeElementExtraEncodeData;
|
|||
|
||||
#define debugTime(T, N) qPrintable(QString("%1 [ %2 ago]").arg(T, 16, 10).arg(formatUsecTime(N - T), 15))
|
||||
#define debugTimeOnly(T) qPrintable(QString("%1").arg(T, 16, 10))
|
||||
#define debugTreeVector(V) V << "[" << (V * (float)TREE_SCALE) << " in meters ]"
|
||||
#define debugTreeVector(V) V << "[" << V << " in meters ]"
|
||||
|
||||
|
||||
/// EntityItem class this is the base class for all entity types. It handles the basic properties and functionality available
|
||||
|
@ -145,26 +145,27 @@ public:
|
|||
|
||||
// attributes applicable to all entity types
|
||||
EntityTypes::EntityType getType() const { return _type; }
|
||||
const glm::vec3& getPosition() const { return _position; } /// get position in domain scale units (0.0 - 1.0)
|
||||
glm::vec3 getPositionInMeters() const { return _position * (float) TREE_SCALE; } /// get position in meters
|
||||
glm::vec3 getPositionInDomainUnits() const { return _position / (float)TREE_SCALE; } /// get position in domain scale units (0.0 - 1.0)
|
||||
const glm::vec3& getPosition() const { return _position; } /// get position in meters
|
||||
|
||||
/// set position in domain scale units (0.0 - 1.0)
|
||||
void setPosition(const glm::vec3& value) { _position = value; }
|
||||
void setPositionInMeters(const glm::vec3& value) /// set position in meter units (0.0 - TREE_SCALE)
|
||||
{ setPosition(glm::clamp(value / (float) TREE_SCALE, 0.0f, 1.0f)); }
|
||||
void setPositionInDomainUnits(const glm::vec3& value)
|
||||
{ setPosition(glm::clamp(value, 0.0f, 1.0f) * (float)TREE_SCALE); }
|
||||
void setPosition(const glm::vec3& value) {
|
||||
_position = value;
|
||||
}
|
||||
|
||||
glm::vec3 getCenter() const; /// calculates center of the entity in domain scale units (0.0 - 1.0)
|
||||
glm::vec3 getCenterInMeters() const { return getCenter() * (float) TREE_SCALE; }
|
||||
glm::vec3 getCenterInDomainUnits() const { return getCenter() / (float) TREE_SCALE; }
|
||||
glm::vec3 getCenter() const;
|
||||
|
||||
const glm::vec3& getDimensions() const { return _dimensions; } /// get dimensions in domain scale units (0.0 - 1.0)
|
||||
glm::vec3 getDimensionsInMeters() const { return _dimensions * (float) TREE_SCALE; } /// get dimensions in meters
|
||||
float getLargestDimension() const { return glm::length(_dimensions); } /// get the largest possible dimension
|
||||
glm::vec3 getDimensionsInDomainUnits() const { return _dimensions / (float)TREE_SCALE; } /// get dimensions in domain scale units (0.0 - 1.0)
|
||||
const glm::vec3& getDimensions() const { return _dimensions; } /// get dimensions in meters
|
||||
|
||||
/// set dimensions in domain scale units (0.0 - 1.0) this will also reset radius appropriately
|
||||
virtual void setDimensions(const glm::vec3& value) { _dimensions = value; }
|
||||
/// set dimensions in domain scale units (0.0 - 1.0)
|
||||
virtual void setDimensionsInDomainUnits(const glm::vec3& value) { _dimensions = glm::abs(value) * (float)TREE_SCALE; }
|
||||
|
||||
/// set dimensions in meter units (0.0 - TREE_SCALE) this will also reset radius appropriately
|
||||
void setDimensionsInMeters(const glm::vec3& value) { setDimensions(value / (float) TREE_SCALE); }
|
||||
/// set dimensions in meter units (0.0 - TREE_SCALE)
|
||||
virtual void setDimensions(const glm::vec3& value) { _dimensions = glm::abs(value); }
|
||||
|
||||
const glm::quat& getRotation() const { return _rotation; }
|
||||
void setRotation(const glm::quat& rotation) { _rotation = rotation; }
|
||||
|
@ -181,16 +182,16 @@ public:
|
|||
|
||||
float getDensity() const { return _density; }
|
||||
|
||||
const glm::vec3& getVelocity() const { return _velocity; } /// velocity in domain scale units (0.0-1.0) per second
|
||||
glm::vec3 getVelocityInMeters() const { return _velocity * (float) TREE_SCALE; } /// get velocity in meters
|
||||
void setVelocity(const glm::vec3& value) { _velocity = value; } /// velocity in domain scale units (0.0-1.0) per second
|
||||
void setVelocityInMeters(const glm::vec3& value) { _velocity = value / (float) TREE_SCALE; } /// velocity in meters
|
||||
glm::vec3 getVelocityInDomainUnits() const { return _velocity / (float)TREE_SCALE; } /// velocity in domain scale units (0.0-1.0) per second
|
||||
const glm::vec3 getVelocity() const { return _velocity; } /// get velocity in meters
|
||||
void setVelocityInDomainUnits(const glm::vec3& value) { _velocity = value * (float)TREE_SCALE; } /// velocity in domain scale units (0.0-1.0) per second
|
||||
void setVelocity(const glm::vec3& value) { _velocity = value; } /// velocity in meters
|
||||
bool hasVelocity() const { return _velocity != ENTITY_ITEM_ZERO_VEC3; }
|
||||
|
||||
const glm::vec3& getGravity() const { return _gravity; } /// gravity in domain scale units (0.0-1.0) per second squared
|
||||
glm::vec3 getGravityInMeters() const { return _gravity * (float) TREE_SCALE; } /// get gravity in meters
|
||||
void setGravity(const glm::vec3& value) { _gravity = value; } /// gravity in domain scale units (0.0-1.0) per second squared
|
||||
void setGravityInMeters(const glm::vec3& value) { _gravity = value / (float) TREE_SCALE; } /// gravity in meters
|
||||
glm::vec3 getGravityInDomainUnits() const { return _gravity / (float)TREE_SCALE; } /// gravity in domain scale units (0.0-1.0) per second squared
|
||||
const glm::vec3& getGravity() const { return _gravity; } /// get gravity in meters
|
||||
void setGravityInDomainUnits(const glm::vec3& value) { _gravity = value * (float)TREE_SCALE; } /// gravity in domain scale units (0.0-1.0) per second squared
|
||||
void setGravity(const glm::vec3& value) { _gravity = value; } /// gravity in meters
|
||||
bool hasGravity() const { return _gravity != ENTITY_ITEM_ZERO_VEC3; }
|
||||
|
||||
float getDamping() const { return _damping; }
|
||||
|
@ -212,10 +213,10 @@ public:
|
|||
quint64 getExpiry() const;
|
||||
|
||||
// position, size, and bounds related helpers
|
||||
float getSize() const; /// get maximum dimension in domain scale units (0.0 - 1.0)
|
||||
AACube getMaximumAACube() const;
|
||||
AACube getMinimumAACube() const;
|
||||
AABox getAABox() const; /// axis aligned bounding box in domain scale units (0.0 - 1.0)
|
||||
AABox getAABox() const; /// axis aligned bounding box in world-frame (meters)
|
||||
AABox getAABoxInDomainUnits() const; /// axis aligned bounding box in domain scale units (0.0 - 1.0)
|
||||
|
||||
const QString& getScript() const { return _script; }
|
||||
void setScript(const QString& value) { _script = value; }
|
||||
|
@ -250,29 +251,31 @@ public:
|
|||
const QString& getUserData() const { return _userData; }
|
||||
void setUserData(const QString& value) { _userData = value; }
|
||||
|
||||
// TODO: We need to get rid of these users of getRadius()...
|
||||
// TODO: get rid of users of getRadius()...
|
||||
float getRadius() const;
|
||||
|
||||
virtual bool contains(const glm::vec3& point) const { return getAABox().contains(point); }
|
||||
virtual bool containsInDomainUnits(const glm::vec3& point) const { return getAABoxInDomainUnits().contains(point); }
|
||||
virtual void computeShapeInfo(ShapeInfo& info) const;
|
||||
|
||||
/// return preferred shape type (actual physical shape may differ)
|
||||
virtual ShapeType getShapeType() const { return SHAPE_TYPE_NONE; }
|
||||
|
||||
// updateFoo() methods to be used when changes need to be accumulated in the _dirtyFlags
|
||||
void updatePositionInDomainUnits(const glm::vec3& value);
|
||||
void updatePosition(const glm::vec3& value);
|
||||
void updatePositionInMeters(const glm::vec3& value);
|
||||
void updateDimensionsInDomainUnits(const glm::vec3& value);
|
||||
void updateDimensions(const glm::vec3& value);
|
||||
void updateDimensionsInMeters(const glm::vec3& value);
|
||||
void updateRotation(const glm::quat& rotation);
|
||||
void updateDensity(float value);
|
||||
void updateMass(float value);
|
||||
void updateVelocityInDomainUnits(const glm::vec3& value);
|
||||
void updateVelocity(const glm::vec3& value);
|
||||
void updateVelocityInMeters(const glm::vec3& value);
|
||||
void updateDamping(float value);
|
||||
void updateGravityInDomainUnits(const glm::vec3& value);
|
||||
void updateGravity(const glm::vec3& value);
|
||||
void updateGravityInMeters(const glm::vec3& value);
|
||||
void updateAngularVelocity(const glm::vec3& value);
|
||||
void updateAngularVelocityInDegrees(const glm::vec3& value) { updateAngularVelocity(glm::radians(value)); }
|
||||
void updateAngularDamping(float value);
|
||||
void updateIgnoreForCollisions(bool value);
|
||||
void updateCollisionsWillMove(bool value);
|
||||
|
@ -318,11 +321,10 @@ protected:
|
|||
float _glowLevel;
|
||||
float _localRenderAlpha;
|
||||
float _density = ENTITY_ITEM_DEFAULT_DENSITY; // kg/m^3
|
||||
// NOTE: _volumeMultiplier is used to compute volume:
|
||||
// volume = _volumeMultiplier * _dimensions.x * _dimensions.y * _dimensions.z = m^3
|
||||
// DANGER: due to the size of TREE_SCALE the _volumeMultiplier is always a large number, and therefore
|
||||
// will tend to introduce floating point error. We must keep this in mind when using it.
|
||||
float _volumeMultiplier = (float)TREE_SCALE * (float)TREE_SCALE * (float)TREE_SCALE;
|
||||
// NOTE: _volumeMultiplier is used to allow some mass properties code exist in the EntityItem base class
|
||||
// rather than in all of the derived classes. If we ever collapse these classes to one we could do it a
|
||||
// different way.
|
||||
float _volumeMultiplier = 1.0f;
|
||||
glm::vec3 _velocity;
|
||||
glm::vec3 _gravity;
|
||||
float _damping;
|
||||
|
|
|
@ -321,7 +321,7 @@ QScriptValue EntityItemProperties::copyToScriptValue(QScriptEngine* engine) cons
|
|||
sittingPoints.setProperty("length", _sittingPoints.size());
|
||||
COPY_PROPERTY_TO_QSCRIPTVALUE_GETTER(sittingPoints, sittingPoints); // gettable, but not settable
|
||||
|
||||
AABox aaBox = getAABoxInMeters();
|
||||
AABox aaBox = getAABox();
|
||||
QScriptValue boundingBox = engine->newObject();
|
||||
QScriptValue bottomRightNear = vec3toScriptValue(engine, aaBox.getCorner());
|
||||
QScriptValue topFarLeft = vec3toScriptValue(engine, aaBox.calcTopFarLeft());
|
||||
|
@ -885,16 +885,10 @@ void EntityItemProperties::markAllChanged() {
|
|||
_particleRadiusChanged = true;
|
||||
}
|
||||
|
||||
AACube EntityItemProperties::getMaximumAACubeInTreeUnits() const {
|
||||
AACube maxCube = getMaximumAACubeInMeters();
|
||||
maxCube.scale(1.0f / (float)TREE_SCALE);
|
||||
return maxCube;
|
||||
}
|
||||
|
||||
/// The maximum bounding cube for the entity, independent of it's rotation.
|
||||
/// This accounts for the registration point (upon which rotation occurs around).
|
||||
///
|
||||
AACube EntityItemProperties::getMaximumAACubeInMeters() const {
|
||||
AACube EntityItemProperties::getMaximumAACube() const {
|
||||
// * we know that the position is the center of rotation
|
||||
glm::vec3 centerOfRotation = _position; // also where _registration point is
|
||||
|
||||
|
@ -918,7 +912,7 @@ AACube EntityItemProperties::getMaximumAACubeInMeters() const {
|
|||
}
|
||||
|
||||
// The minimum bounding box for the entity.
|
||||
AABox EntityItemProperties::getAABoxInMeters() const {
|
||||
AABox EntityItemProperties::getAABox() const {
|
||||
|
||||
// _position represents the position of the registration point.
|
||||
glm::vec3 registrationRemainder = glm::vec3(1.0f, 1.0f, 1.0f) - _registrationPoint;
|
||||
|
|
|
@ -140,9 +140,8 @@ public:
|
|||
/// used by EntityScriptingInterface to return EntityItemProperties for unknown models
|
||||
void setIsUnknownID() { _id = UNKNOWN_ENTITY_ID; _idSet = true; }
|
||||
|
||||
AACube getMaximumAACubeInTreeUnits() const;
|
||||
AACube getMaximumAACubeInMeters() const;
|
||||
AABox getAABoxInMeters() const;
|
||||
AACube getMaximumAACube() const;
|
||||
AABox getAABox() const;
|
||||
|
||||
void debugDump() const;
|
||||
void setLastEdited(quint64 usecTime);
|
||||
|
|
|
@ -20,8 +20,6 @@
|
|||
// creating a new one on the stack so we declare the ZERO_VEC3 constant as an optimization.
|
||||
const glm::vec3 ENTITY_ITEM_ZERO_VEC3(0.0f);
|
||||
|
||||
const glm::vec3 REGULAR_GRAVITY = glm::vec3(0, -9.8f / (float)TREE_SCALE, 0);
|
||||
|
||||
const bool ENTITY_ITEM_DEFAULT_LOCKED = false;
|
||||
const QString ENTITY_ITEM_DEFAULT_USER_DATA = QString("");
|
||||
|
||||
|
@ -37,7 +35,7 @@ const float ENTITY_ITEM_DEFAULT_LIFETIME = ENTITY_ITEM_IMMORTAL_LIFETIME;
|
|||
|
||||
const glm::quat ENTITY_ITEM_DEFAULT_ROTATION;
|
||||
const float ENTITY_ITEM_DEFAULT_WIDTH = 0.1f;
|
||||
const glm::vec3 ENTITY_ITEM_DEFAULT_DIMENSIONS = glm::vec3(ENTITY_ITEM_DEFAULT_WIDTH) / (float)TREE_SCALE;
|
||||
const glm::vec3 ENTITY_ITEM_DEFAULT_DIMENSIONS = glm::vec3(ENTITY_ITEM_DEFAULT_WIDTH);
|
||||
const float ENTITY_ITEM_DEFAULT_VOLUME = ENTITY_ITEM_DEFAULT_WIDTH * ENTITY_ITEM_DEFAULT_WIDTH * ENTITY_ITEM_DEFAULT_WIDTH;
|
||||
|
||||
const float ENTITY_ITEM_MAX_DENSITY = 10000.0f; // kg/m^3 density of silver
|
||||
|
|
|
@ -182,8 +182,7 @@ EntityItemID EntityScriptingInterface::findClosestEntity(const glm::vec3& center
|
|||
EntityItemID result(UNKNOWN_ENTITY_ID, UNKNOWN_ENTITY_TOKEN, false);
|
||||
if (_entityTree) {
|
||||
_entityTree->lockForRead();
|
||||
const EntityItem* closestEntity = _entityTree->findClosestEntity(center/(float)TREE_SCALE,
|
||||
radius/(float)TREE_SCALE);
|
||||
const EntityItem* closestEntity = _entityTree->findClosestEntity(center, radius);
|
||||
_entityTree->unlock();
|
||||
if (closestEntity) {
|
||||
result.id = closestEntity->getID();
|
||||
|
@ -207,7 +206,7 @@ QVector<EntityItemID> EntityScriptingInterface::findEntities(const glm::vec3& ce
|
|||
if (_entityTree) {
|
||||
_entityTree->lockForRead();
|
||||
QVector<const EntityItem*> entities;
|
||||
_entityTree->findEntities(center/(float)TREE_SCALE, radius/(float)TREE_SCALE, entities);
|
||||
_entityTree->findEntities(center, radius, entities);
|
||||
_entityTree->unlock();
|
||||
|
||||
foreach (const EntityItem* entity, entities) {
|
||||
|
|
|
@ -87,7 +87,7 @@ void EntitySimulation::sortEntitiesThatMoved() {
|
|||
// External changes to entity position/shape are expected to be sorted outside of the EntitySimulation.
|
||||
PerformanceTimer perfTimer("sortingEntities");
|
||||
MovingEntitiesOperator moveOperator(_entityTree);
|
||||
AACube domainBounds(glm::vec3(0.0f,0.0f,0.0f), 1.0f);
|
||||
AACube domainBounds(glm::vec3(0.0f,0.0f,0.0f), (float)TREE_SCALE);
|
||||
QSet<EntityItem*>::iterator itemItr = _entitiesToBeSorted.begin();
|
||||
while (itemItr != _entitiesToBeSorted.end()) {
|
||||
EntityItem* entity = *itemItr;
|
||||
|
@ -150,7 +150,7 @@ void EntitySimulation::entityChanged(EntityItem* entity) {
|
|||
bool wasRemoved = false;
|
||||
uint32_t dirtyFlags = entity->getDirtyFlags();
|
||||
if (dirtyFlags & EntityItem::DIRTY_POSITION) {
|
||||
AACube domainBounds(glm::vec3(0.0f,0.0f,0.0f), 1.0f);
|
||||
AACube domainBounds(glm::vec3(0.0f,0.0f,0.0f), (float)TREE_SCALE);
|
||||
AACube newCube = entity->getMaximumAACube();
|
||||
if (!domainBounds.touches(newCube)) {
|
||||
qDebug() << "Entity " << entity->getEntityItemID() << " moved out of domain bounds.";
|
||||
|
|
|
@ -424,8 +424,7 @@ bool EntityTree::findNearPointOperation(OctreeElement* element, void* extraData)
|
|||
EntityTreeElement* entityTreeElement = static_cast<EntityTreeElement*>(element);
|
||||
|
||||
glm::vec3 penetration;
|
||||
bool sphereIntersection = entityTreeElement->getAACube().findSpherePenetration(args->position,
|
||||
args->targetRadius, penetration);
|
||||
bool sphereIntersection = entityTreeElement->getAACube().findSpherePenetration(args->position, args->targetRadius, penetration);
|
||||
|
||||
// If this entityTreeElement contains the point, then search it...
|
||||
if (sphereIntersection) {
|
||||
|
@ -475,8 +474,7 @@ public:
|
|||
bool EntityTree::findInSphereOperation(OctreeElement* element, void* extraData) {
|
||||
FindAllNearPointArgs* args = static_cast<FindAllNearPointArgs*>(extraData);
|
||||
glm::vec3 penetration;
|
||||
bool sphereIntersection = element->getAACube().findSpherePenetration(args->position,
|
||||
args->targetRadius, penetration);
|
||||
bool sphereIntersection = element->getAACube().findSpherePenetration(args->position, args->targetRadius, penetration);
|
||||
|
||||
// If this element contains the point, then search it...
|
||||
if (sphereIntersection) {
|
||||
|
@ -511,8 +509,7 @@ public:
|
|||
|
||||
bool EntityTree::findInCubeOperation(OctreeElement* element, void* extraData) {
|
||||
FindEntitiesInCubeArgs* args = static_cast<FindEntitiesInCubeArgs*>(extraData);
|
||||
const AACube& elementCube = element->getAACube();
|
||||
if (elementCube.touches(args->_cube)) {
|
||||
if (element->getAACube().touches(args->_cube)) {
|
||||
EntityTreeElement* entityTreeElement = static_cast<EntityTreeElement*>(element);
|
||||
entityTreeElement->getEntities(args->_cube, args->_foundEntities);
|
||||
return true;
|
||||
|
|
|
@ -96,6 +96,8 @@ public:
|
|||
void deleteEntities(QSet<EntityItemID> entityIDs, bool force = false);
|
||||
void removeEntityFromSimulation(EntityItem* entity);
|
||||
|
||||
/// \param position point of query in world-frame (meters)
|
||||
/// \param targetRadius radius of query (meters)
|
||||
const EntityItem* findClosestEntity(glm::vec3 position, float targetRadius);
|
||||
EntityItem* findEntityByID(const QUuid& id);
|
||||
EntityItem* findEntityByEntityItemID(const EntityItemID& entityID);
|
||||
|
@ -104,14 +106,14 @@ public:
|
|||
|
||||
|
||||
/// finds all entities that touch a sphere
|
||||
/// \param center the center of the sphere
|
||||
/// \param radius the radius of the sphere
|
||||
/// \param center the center of the sphere in world-frame (meters)
|
||||
/// \param radius the radius of the sphere in world-frame (meters)
|
||||
/// \param foundEntities[out] vector of const EntityItem*
|
||||
/// \remark Side effect: any initial contents in foundEntities will be lost
|
||||
void findEntities(const glm::vec3& center, float radius, QVector<const EntityItem*>& foundEntities);
|
||||
|
||||
/// finds all entities that touch a cube
|
||||
/// \param cube the query cube
|
||||
/// \param cube the query cube in world-frame (meters)
|
||||
/// \param foundEntities[out] vector of non-const EntityItem*
|
||||
/// \remark Side effect: any initial contents in entities will be lost
|
||||
void findEntities(const AACube& cube, QVector<EntityItem*>& foundEntities);
|
||||
|
|
|
@ -50,7 +50,7 @@ EntityTreeElement* EntityTreeElement::addChildAtIndex(int index) {
|
|||
|
||||
void EntityTreeElement::debugExtraEncodeData(EncodeBitstreamParams& params) const {
|
||||
qDebug() << "EntityTreeElement::debugExtraEncodeData()... ";
|
||||
qDebug() << " element:" << getAACube();
|
||||
qDebug() << " element:" << _cube;
|
||||
|
||||
OctreeElementExtraEncodeData* extraEncodeData = params.extraEncodeData;
|
||||
assert(extraEncodeData); // EntityTrees always require extra encode data on their encoding passes
|
||||
|
@ -159,7 +159,7 @@ void EntityTreeElement::elementEncodeComplete(EncodeBitstreamParams& params, Oct
|
|||
const bool wantDebug = false;
|
||||
|
||||
if (wantDebug) {
|
||||
qDebug() << "EntityTreeElement::elementEncodeComplete() element:" << getAACube();
|
||||
qDebug() << "EntityTreeElement::elementEncodeComplete() element:" << _cube;
|
||||
}
|
||||
|
||||
OctreeElementExtraEncodeData* extraEncodeData = params.extraEncodeData;
|
||||
|
@ -194,7 +194,7 @@ void EntityTreeElement::elementEncodeComplete(EncodeBitstreamParams& params, Oct
|
|||
= static_cast<EntityTreeElementExtraEncodeData*>(extraEncodeData->value(childElement));
|
||||
|
||||
if (wantDebug) {
|
||||
qDebug() << "checking child: " << childElement->getAACube();
|
||||
qDebug() << "checking child: " << childElement->_cube;
|
||||
qDebug() << " childElement->isLeaf():" << childElement->isLeaf();
|
||||
qDebug() << " childExtraEncodeData->elementCompleted:" << childExtraEncodeData->elementCompleted;
|
||||
qDebug() << " childExtraEncodeData->subtreeCompleted:" << childExtraEncodeData->subtreeCompleted;
|
||||
|
@ -215,7 +215,7 @@ void EntityTreeElement::elementEncodeComplete(EncodeBitstreamParams& params, Oct
|
|||
}
|
||||
|
||||
if (wantDebug) {
|
||||
qDebug() << "for this element: " << getAACube();
|
||||
qDebug() << "for this element: " << _cube;
|
||||
qDebug() << " WAS elementCompleted:" << thisExtraEncodeData->elementCompleted;
|
||||
qDebug() << " WAS subtreeCompleted:" << thisExtraEncodeData->subtreeCompleted;
|
||||
}
|
||||
|
@ -302,7 +302,6 @@ OctreeElement::AppendState EntityTreeElement::appendElementData(OctreePacketData
|
|||
// the entity may not be in view and then in view a frame later, let the client side handle it's view
|
||||
// frustum culling on rendering.
|
||||
AACube entityCube = entity->getMaximumAACube();
|
||||
entityCube.scale(TREE_SCALE);
|
||||
if (params.viewFrustum->cubeInFrustum(entityCube) == ViewFrustum::OUTSIDE) {
|
||||
includeThisEntity = false; // out of view, don't include it
|
||||
}
|
||||
|
@ -417,11 +416,11 @@ bool EntityTreeElement::bestFitEntityBounds(const EntityItem* entity) const {
|
|||
}
|
||||
|
||||
bool EntityTreeElement::containsBounds(const EntityItemProperties& properties) const {
|
||||
return containsBounds(properties.getMaximumAACubeInTreeUnits());
|
||||
return containsBounds(properties.getMaximumAACube());
|
||||
}
|
||||
|
||||
bool EntityTreeElement::bestFitBounds(const EntityItemProperties& properties) const {
|
||||
return bestFitBounds(properties.getMaximumAACubeInTreeUnits());
|
||||
return bestFitBounds(properties.getMaximumAACube());
|
||||
}
|
||||
|
||||
bool EntityTreeElement::containsBounds(const AACube& bounds) const {
|
||||
|
@ -441,14 +440,14 @@ bool EntityTreeElement::bestFitBounds(const AABox& bounds) const {
|
|||
}
|
||||
|
||||
bool EntityTreeElement::containsBounds(const glm::vec3& minPoint, const glm::vec3& maxPoint) const {
|
||||
glm::vec3 clampedMin = glm::clamp(minPoint, 0.0f, 1.0f);
|
||||
glm::vec3 clampedMax = glm::clamp(maxPoint, 0.0f, 1.0f);
|
||||
glm::vec3 clampedMin = glm::clamp(minPoint, 0.0f, (float)TREE_SCALE);
|
||||
glm::vec3 clampedMax = glm::clamp(maxPoint, 0.0f, (float)TREE_SCALE);
|
||||
return _cube.contains(clampedMin) && _cube.contains(clampedMax);
|
||||
}
|
||||
|
||||
bool EntityTreeElement::bestFitBounds(const glm::vec3& minPoint, const glm::vec3& maxPoint) const {
|
||||
glm::vec3 clampedMin = glm::clamp(minPoint, 0.0f, 1.0f);
|
||||
glm::vec3 clampedMax = glm::clamp(maxPoint, 0.0f, 1.0f);
|
||||
glm::vec3 clampedMin = glm::clamp(minPoint, 0.0f, (float)TREE_SCALE);
|
||||
glm::vec3 clampedMax = glm::clamp(maxPoint, 0.0f, (float)TREE_SCALE);
|
||||
|
||||
if (_cube.contains(clampedMin) && _cube.contains(clampedMax)) {
|
||||
|
||||
|
@ -823,9 +822,7 @@ bool EntityTreeElement::pruneChildren() {
|
|||
|
||||
void EntityTreeElement::debugDump() {
|
||||
qDebug() << "EntityTreeElement...";
|
||||
AACube temp = getAACube();
|
||||
temp.scale((float)TREE_SCALE);
|
||||
qDebug() << " cube:" << temp;
|
||||
qDebug() << " cube:" << _cube;
|
||||
qDebug() << " has child elements:" << getChildCount();
|
||||
if (_entityItems->size()) {
|
||||
qDebug() << " has entities:" << _entityItems->size();
|
||||
|
|
|
@ -265,8 +265,8 @@ void ModelEntityItem::update(const quint64& now) {
|
|||
void ModelEntityItem::debugDump() const {
|
||||
qDebug() << "ModelEntityItem id:" << getEntityItemID();
|
||||
qDebug() << " edited ago:" << getEditedAgo();
|
||||
qDebug() << " position:" << getPosition() * (float)TREE_SCALE;
|
||||
qDebug() << " dimensions:" << getDimensions() * (float)TREE_SCALE;
|
||||
qDebug() << " position:" << getPosition();
|
||||
qDebug() << " dimensions:" << getDimensions();
|
||||
qDebug() << " model URL:" << getModelURL();
|
||||
qDebug() << " collision model URL:" << getCollisionModelURL();
|
||||
}
|
||||
|
|
|
@ -51,7 +51,7 @@ MovingEntitiesOperator::~MovingEntitiesOperator() {
|
|||
|
||||
void MovingEntitiesOperator::addEntityToMoveList(EntityItem* entity, const AACube& newCube) {
|
||||
EntityTreeElement* oldContainingElement = _tree->getContainingElement(entity->getEntityItemID());
|
||||
AABox newCubeClamped = newCube.clamp(0.0f, 1.0f);
|
||||
AABox newCubeClamped = newCube.clamp(0.0f, (float)TREE_SCALE);
|
||||
|
||||
if (_wantDebug) {
|
||||
qDebug() << "MovingEntitiesOperator::addEntityToMoveList() -----------------------------";
|
||||
|
@ -114,7 +114,7 @@ bool MovingEntitiesOperator::shouldRecurseSubTree(OctreeElement* element) {
|
|||
// If we don't have an old entity, then we don't contain the entity, otherwise
|
||||
// check the bounds
|
||||
if (_entitiesToMove.size() > 0) {
|
||||
AACube elementCube = element->getAACube();
|
||||
const AACube& elementCube = element->getAACube();
|
||||
int detailIndex = 0;
|
||||
foreach(const EntityToMoveDetails& details, _entitiesToMove) {
|
||||
|
||||
|
|
|
@ -15,11 +15,11 @@
|
|||
class EntityToMoveDetails {
|
||||
public:
|
||||
EntityItem* entity;
|
||||
AACube oldCube;
|
||||
AACube newCube;
|
||||
AABox newCubeClamped;
|
||||
AACube oldCube; // meters
|
||||
AACube newCube; // meters
|
||||
AABox newCubeClamped; // meters
|
||||
EntityTreeElement* oldContainingElement;
|
||||
AACube oldContainingElementCube;
|
||||
AACube oldContainingElementCube; // meters
|
||||
bool oldFound;
|
||||
bool newFound;
|
||||
};
|
||||
|
|
|
@ -268,10 +268,10 @@ void ParticleEffectEntityItem::update(const quint64& now) {
|
|||
|
||||
// update the dimensions
|
||||
glm::vec3 dims;
|
||||
dims.x = glm::max(glm::abs(_paXmin), glm::abs(_paXmax)) * 2.0;
|
||||
dims.y = glm::max(glm::abs(_paYmin), glm::abs(_paYmax)) * 2.0;
|
||||
dims.z = glm::max(glm::abs(_paZmin), glm::abs(_paZmax)) * 2.0;
|
||||
setDimensionsInMeters(dims);
|
||||
dims.x = glm::max(glm::abs(_paXmin), glm::abs(_paXmax)) * 2.0f;
|
||||
dims.y = glm::max(glm::abs(_paYmin), glm::abs(_paYmax)) * 2.0f;
|
||||
dims.z = glm::max(glm::abs(_paZmin), glm::abs(_paZmax)) * 2.0f;
|
||||
setDimensions(dims);
|
||||
|
||||
EntityItem::update(now); // let our base class handle it's updates...
|
||||
}
|
||||
|
@ -418,8 +418,8 @@ QString ParticleEffectEntityItem::getAnimationSettings() const {
|
|||
}
|
||||
|
||||
void ParticleEffectEntityItem::stepSimulation(float deltaTime) {
|
||||
_paXmin = _paYmin = _paZmin = -1.0;
|
||||
_paXmax = _paYmax = _paZmax = 1.0;
|
||||
_paXmin = _paYmin = _paZmin = -1.0f;
|
||||
_paXmax = _paYmax = _paZmax = 1.0f;
|
||||
|
||||
// update particles
|
||||
quint32 updateIter = _paHead;
|
||||
|
@ -493,8 +493,8 @@ void ParticleEffectEntityItem::stepSimulation(float deltaTime) {
|
|||
}
|
||||
|
||||
void ParticleEffectEntityItem::resetSimulation() {
|
||||
for (int i = 0; i < _maxParticles; i++) {
|
||||
int j = i * XYZ_STRIDE;
|
||||
for (quint32 i = 0; i < _maxParticles; i++) {
|
||||
quint32 j = i * XYZ_STRIDE;
|
||||
_paLife[i] = -1.0f;
|
||||
_paPosition[j] = 0.0f;
|
||||
_paPosition[j+1] = 0.0f;
|
||||
|
|
|
@ -32,9 +32,6 @@ SphereEntityItem::SphereEntityItem(const EntityItemID& entityItemID, const Entit
|
|||
{
|
||||
_type = EntityTypes::Sphere;
|
||||
setProperties(properties);
|
||||
// NOTE: _volumeMultiplier is used to compute volume:
|
||||
// volume = _volumeMultiplier * _dimensions.x * _dimensions.y * _dimensions.z
|
||||
// The formula below looks funny because _dimension.xyz = diameter rather than radius.
|
||||
_volumeMultiplier *= PI / 6.0f;
|
||||
}
|
||||
|
||||
|
|
|
@ -40,10 +40,16 @@ TextEntityItem::TextEntityItem(const EntityItemID& entityItemID, const EntityIte
|
|||
setProperties(properties);
|
||||
}
|
||||
|
||||
const float TEXT_ENTITY_ITEM_FIXED_DEPTH = 0.01f;
|
||||
|
||||
void TextEntityItem::setDimensions(const glm::vec3& value) {
|
||||
// NOTE: Text Entities always have a "depth" of 1cm.
|
||||
float fixedDepth = 0.01f / (float)TREE_SCALE;
|
||||
_dimensions = glm::vec3(value.x, value.y, fixedDepth);
|
||||
_dimensions = glm::vec3(value.x, value.y, TEXT_ENTITY_ITEM_FIXED_DEPTH);
|
||||
}
|
||||
|
||||
void TextEntityItem::setDimensionsInDomainUnits(const glm::vec3& value) {
|
||||
// NOTE: Text Entities always have a "depth" of 1cm.
|
||||
_dimensions = glm::vec3(value.x * (float)TREE_SCALE, value.y * (float)TREE_SCALE, TEXT_ENTITY_ITEM_FIXED_DEPTH);
|
||||
}
|
||||
|
||||
EntityItemProperties TextEntityItem::getProperties() const {
|
||||
|
@ -136,7 +142,7 @@ bool TextEntityItem::findDetailedRayIntersection(const glm::vec3& origin, const
|
|||
const glm::vec3 UNROTATED_NORMAL(0.0f, 0.0f, -1.0f);
|
||||
glm::vec3 normal = _rotation * UNROTATED_NORMAL;
|
||||
plane.setNormal(normal);
|
||||
plane.setPoint(_position); // the position is definitely a point on our plane
|
||||
plane.setPoint(getPosition()); // the position is definitely a point on our plane
|
||||
|
||||
bool intersects = plane.findRayIntersection(rayInfo);
|
||||
|
||||
|
|
|
@ -24,6 +24,7 @@ public:
|
|||
|
||||
/// set dimensions in domain scale units (0.0 - 1.0) this will also reset radius appropriately
|
||||
virtual void setDimensions(const glm::vec3& value);
|
||||
virtual void setDimensionsInDomainUnits(const glm::vec3& value);
|
||||
virtual ShapeType getShapeType() const { return SHAPE_TYPE_BOX; }
|
||||
|
||||
// methods for getting/setting all properties of an entity
|
||||
|
|
|
@ -46,7 +46,7 @@ UpdateEntityOperator::UpdateEntityOperator(EntityTree* tree,
|
|||
// which can handle all potential rotations?
|
||||
// the getMaximumAACube is the relaxed form.
|
||||
_oldEntityCube = _existingEntity->getMaximumAACube();
|
||||
_oldEntityBox = _oldEntityCube.clamp(0.0f, 1.0f); // clamp to domain bounds
|
||||
_oldEntityBox = _oldEntityCube.clamp(0.0f, (float)TREE_SCALE); // clamp to domain bounds
|
||||
|
||||
// If the old properties doesn't contain the properties required to calculate a bounding box,
|
||||
// get them from the existing entity. Registration point is required to correctly calculate
|
||||
|
@ -59,8 +59,8 @@ UpdateEntityOperator::UpdateEntityOperator(EntityTree* tree,
|
|||
// get the old property value and set it in our properties in order for our bounds
|
||||
// calculations to work.
|
||||
if (_properties.containsPositionChange() && !_properties.containsDimensionsChange()) {
|
||||
glm::vec3 oldDimensionsInMeters = _existingEntity->getDimensions() * (float)TREE_SCALE;
|
||||
_properties.setDimensions(oldDimensionsInMeters);
|
||||
glm::vec3 oldDimensions= _existingEntity->getDimensions();
|
||||
_properties.setDimensions(oldDimensions);
|
||||
|
||||
if (_wantDebug) {
|
||||
qDebug() << " ** setting properties dimensions - had position change, no dimension change **";
|
||||
|
@ -68,8 +68,8 @@ UpdateEntityOperator::UpdateEntityOperator(EntityTree* tree,
|
|||
|
||||
}
|
||||
if (!_properties.containsPositionChange() && _properties.containsDimensionsChange()) {
|
||||
glm::vec3 oldPositionInMeters = _existingEntity->getPosition() * (float)TREE_SCALE;
|
||||
_properties.setPosition(oldPositionInMeters);
|
||||
glm::vec3 oldPosition= _existingEntity->getPosition();
|
||||
_properties.setPosition(oldPosition);
|
||||
|
||||
if (_wantDebug) {
|
||||
qDebug() << " ** setting properties position - had dimensions change, no position change **";
|
||||
|
@ -114,7 +114,7 @@ UpdateEntityOperator::UpdateEntityOperator(EntityTree* tree,
|
|||
}
|
||||
|
||||
} else {
|
||||
_newEntityCube = _properties.getMaximumAACubeInTreeUnits();
|
||||
_newEntityCube = _properties.getMaximumAACube();
|
||||
_removeOld = true; // our properties are going to move us, so remember this for later processing
|
||||
|
||||
if (_wantDebug) {
|
||||
|
@ -122,7 +122,7 @@ UpdateEntityOperator::UpdateEntityOperator(EntityTree* tree,
|
|||
}
|
||||
}
|
||||
|
||||
_newEntityBox = _newEntityCube.clamp(0.0f, 1.0f); // clamp to domain bounds
|
||||
_newEntityBox = _newEntityCube.clamp(0.0f, (float)TREE_SCALE); // clamp to domain bounds
|
||||
|
||||
|
||||
if (_wantDebug) {
|
||||
|
|
|
@ -129,8 +129,9 @@ const PacketVersion VERSION_ENTITIES_HAVE_USER_DATA = 6;
|
|||
const PacketVersion VERSION_ENTITIES_HAS_LAST_SIMULATED_TIME = 7;
|
||||
const PacketVersion VERSION_MODEL_ENTITIES_SUPPORT_SHAPE_TYPE = 8;
|
||||
const PacketVersion VERSION_ENTITIES_LIGHT_HAS_INTENSITY_AND_COLOR_PROPERTIES = 9;
|
||||
const PacketVersion VERSION_OCTREE_HAS_FILE_BREAKS = 1;
|
||||
const PacketVersion VERSION_ENTITIES_HAS_PARTICLES = 10;
|
||||
const PacketVersion VERSION_ENTITIES_HAS_COLLISION_MODEL = 11;
|
||||
const PacketVersion VERSION_ENTITIES_USE_METERS_AND_RADIANS = 11;
|
||||
const PacketVersion VERSION_ENTITIES_HAS_COLLISION_MODEL = 12;
|
||||
const PacketVersion VERSION_OCTREE_HAS_FILE_BREAKS = 1;
|
||||
|
||||
#endif // hifi_PacketHeaders_h
|
||||
|
|
|
@ -274,7 +274,7 @@ int Octree::readElementData(OctreeElement* destinationElement, const unsigned ch
|
|||
|
||||
if (destinationElement->getScale() < SCALE_AT_DANGEROUSLY_DEEP_RECURSION) {
|
||||
qDebug() << "UNEXPECTED: readElementData() destination element is unreasonably small ["
|
||||
<< destinationElement->getScale() * (float)TREE_SCALE << " meters] "
|
||||
<< destinationElement->getScale() << " meters] "
|
||||
<< " Discarding " << bytesAvailable << " remaining bytes.";
|
||||
return bytesAvailable; // assume we read the entire buffer...
|
||||
}
|
||||
|
@ -706,7 +706,7 @@ bool findRayIntersectionOp(OctreeElement* element, void* extraData) {
|
|||
bool Octree::findRayIntersection(const glm::vec3& origin, const glm::vec3& direction,
|
||||
OctreeElement*& element, float& distance, BoxFace& face, void** intersectedObject,
|
||||
Octree::lockType lockType, bool* accurateResult, bool precisionPicking) {
|
||||
RayArgs args = { origin / (float)(TREE_SCALE), direction, element, distance, face,
|
||||
RayArgs args = { origin, direction, element, distance, face,
|
||||
intersectedObject, false, precisionPicking};
|
||||
distance = FLT_MAX;
|
||||
|
||||
|
@ -726,10 +726,6 @@ bool Octree::findRayIntersection(const glm::vec3& origin, const glm::vec3& direc
|
|||
|
||||
recurseTreeWithOperation(findRayIntersectionOp, &args);
|
||||
|
||||
if (args.found) {
|
||||
args.distance *= (float)(TREE_SCALE); // scale back up to meters
|
||||
}
|
||||
|
||||
if (gotLock) {
|
||||
unlock();
|
||||
}
|
||||
|
@ -753,8 +749,7 @@ bool findSpherePenetrationOp(OctreeElement* element, void* extraData) {
|
|||
SphereArgs* args = static_cast<SphereArgs*>(extraData);
|
||||
|
||||
// coarse check against bounds
|
||||
const AACube& box = element->getAACube();
|
||||
if (!box.expandedContains(args->center, args->radius)) {
|
||||
if (!element->getAACube().expandedContains(args->center, args->radius)) {
|
||||
return false;
|
||||
}
|
||||
if (element->hasContent()) {
|
||||
|
@ -762,7 +757,7 @@ bool findSpherePenetrationOp(OctreeElement* element, void* extraData) {
|
|||
if (element->findSpherePenetration(args->center, args->radius, elementPenetration, &args->penetratedObject)) {
|
||||
// NOTE: it is possible for this penetration accumulation algorithm to produce a
|
||||
// final penetration vector with zero length.
|
||||
args->penetration = addPenetrations(args->penetration, elementPenetration * (float)(TREE_SCALE));
|
||||
args->penetration = addPenetrations(args->penetration, elementPenetration);
|
||||
args->found = true;
|
||||
}
|
||||
}
|
||||
|
@ -776,8 +771,8 @@ bool Octree::findSpherePenetration(const glm::vec3& center, float radius, glm::v
|
|||
void** penetratedObject, Octree::lockType lockType, bool* accurateResult) {
|
||||
|
||||
SphereArgs args = {
|
||||
center / (float)(TREE_SCALE),
|
||||
radius / (float)(TREE_SCALE),
|
||||
center,
|
||||
radius,
|
||||
penetration,
|
||||
false,
|
||||
NULL };
|
||||
|
@ -838,14 +833,13 @@ bool findCapsulePenetrationOp(OctreeElement* element, void* extraData) {
|
|||
CapsuleArgs* args = static_cast<CapsuleArgs*>(extraData);
|
||||
|
||||
// coarse check against bounds
|
||||
const AACube& box = element->getAACube();
|
||||
if (!box.expandedIntersectsSegment(args->start, args->end, args->radius)) {
|
||||
if (!element->getAACube().expandedIntersectsSegment(args->start, args->end, args->radius)) {
|
||||
return false;
|
||||
}
|
||||
if (element->hasContent()) {
|
||||
glm::vec3 nodePenetration;
|
||||
if (box.findCapsulePenetration(args->start, args->end, args->radius, nodePenetration)) {
|
||||
args->penetration = addPenetrations(args->penetration, nodePenetration * (float)(TREE_SCALE));
|
||||
if (element->getAACube().findCapsulePenetration(args->start, args->end, args->radius, nodePenetration)) {
|
||||
args->penetration = addPenetrations(args->penetration, nodePenetration);
|
||||
args->found = true;
|
||||
}
|
||||
}
|
||||
|
@ -872,8 +866,7 @@ bool findContentInCubeOp(OctreeElement* element, void* extraData) {
|
|||
ContentArgs* args = static_cast<ContentArgs*>(extraData);
|
||||
|
||||
// coarse check against bounds
|
||||
AACube cube = element->getAACube();
|
||||
cube.scale(TREE_SCALE);
|
||||
const AACube& cube = element->getAACube();
|
||||
if (!cube.touches(args->cube)) {
|
||||
return false;
|
||||
}
|
||||
|
@ -892,12 +885,7 @@ bool findContentInCubeOp(OctreeElement* element, void* extraData) {
|
|||
bool Octree::findCapsulePenetration(const glm::vec3& start, const glm::vec3& end, float radius,
|
||||
glm::vec3& penetration, Octree::lockType lockType, bool* accurateResult) {
|
||||
|
||||
CapsuleArgs args = {
|
||||
start / (float)(TREE_SCALE),
|
||||
end / (float)(TREE_SCALE),
|
||||
radius / (float)(TREE_SCALE),
|
||||
penetration,
|
||||
false };
|
||||
CapsuleArgs args = { start, end, radius, penetration, false };
|
||||
penetration = glm::vec3(0.0f, 0.0f, 0.0f);
|
||||
|
||||
bool gotLock = false;
|
||||
|
@ -945,8 +933,7 @@ public:
|
|||
// Find the smallest colored voxel enclosing a point (if there is one)
|
||||
bool getElementEnclosingOperation(OctreeElement* element, void* extraData) {
|
||||
GetElementEnclosingArgs* args = static_cast<GetElementEnclosingArgs*>(extraData);
|
||||
AACube elementBox = element->getAACube();
|
||||
if (elementBox.contains(args->point)) {
|
||||
if (element->getAACube().contains(args->point)) {
|
||||
if (element->hasContent() && element->isLeaf()) {
|
||||
// we've reached a solid leaf containing the point, return the element.
|
||||
args->element = element;
|
||||
|
@ -1212,9 +1199,8 @@ int Octree::encodeTreeBitstreamRecursion(OctreeElement* element,
|
|||
// If the user also asked for occlusion culling, check if this element is occluded, but only if it's not a leaf.
|
||||
// leaf occlusion is handled down below when we check child nodes
|
||||
if (params.wantOcclusionCulling && !element->isLeaf()) {
|
||||
AACube voxelBox = element->getAACube();
|
||||
voxelBox.scale(TREE_SCALE);
|
||||
OctreeProjectedPolygon* voxelPolygon = new OctreeProjectedPolygon(params.viewFrustum->getProjectedPolygon(voxelBox));
|
||||
OctreeProjectedPolygon* voxelPolygon =
|
||||
new OctreeProjectedPolygon(params.viewFrustum->getProjectedPolygon(element->getAACube()));
|
||||
|
||||
// In order to check occlusion culling, the shadow has to be "all in view" otherwise, we will ignore occlusion
|
||||
// culling and proceed as normal
|
||||
|
@ -1365,10 +1351,8 @@ int Octree::encodeTreeBitstreamRecursion(OctreeElement* element,
|
|||
if (params.wantOcclusionCulling && childElement->isLeaf()) {
|
||||
// Don't check occlusion here, just add them to our distance ordered array...
|
||||
|
||||
AACube voxelBox = childElement->getAACube();
|
||||
voxelBox.scale(TREE_SCALE);
|
||||
OctreeProjectedPolygon* voxelPolygon = new OctreeProjectedPolygon(
|
||||
params.viewFrustum->getProjectedPolygon(voxelBox));
|
||||
params.viewFrustum->getProjectedPolygon(childElement->getAACube()));
|
||||
|
||||
// In order to check occlusion culling, the shadow has to be "all in view" otherwise, we ignore occlusion
|
||||
// culling and proceed as normal
|
||||
|
@ -2084,58 +2068,6 @@ bool Octree::countOctreeElementsOperation(OctreeElement* element, void* extraDat
|
|||
return true; // keep going
|
||||
}
|
||||
|
||||
void Octree::copySubTreeIntoNewTree(OctreeElement* startElement, Octree* destinationTree, bool rebaseToRoot) {
|
||||
OctreeElementBag elementBag;
|
||||
elementBag.insert(startElement);
|
||||
int chopLevels = 0;
|
||||
if (rebaseToRoot) {
|
||||
chopLevels = numberOfThreeBitSectionsInCode(startElement->getOctalCode());
|
||||
}
|
||||
|
||||
EncodeBitstreamParams params(INT_MAX, IGNORE_VIEW_FRUSTUM, WANT_COLOR, NO_EXISTS_BITS, chopLevels);
|
||||
OctreeElementExtraEncodeData extraEncodeData;
|
||||
params.extraEncodeData = &extraEncodeData;
|
||||
|
||||
OctreePacketData packetData;
|
||||
|
||||
while (!elementBag.isEmpty()) {
|
||||
OctreeElement* subTree = elementBag.extract();
|
||||
packetData.reset(); // reset the packet between usage
|
||||
// ask our tree to write a bitsteam
|
||||
encodeTreeBitstream(subTree, &packetData, elementBag, params);
|
||||
// ask destination tree to read the bitstream
|
||||
ReadBitstreamToTreeParams args(WANT_COLOR, NO_EXISTS_BITS);
|
||||
destinationTree->readBitstreamToTree(packetData.getUncompressedData(), packetData.getUncompressedSize(), args);
|
||||
}
|
||||
}
|
||||
|
||||
void Octree::copyFromTreeIntoSubTree(Octree* sourceTree, OctreeElement* destinationElement) {
|
||||
OctreeElementBag elementBag;
|
||||
// If we were given a specific element, start from there, otherwise start from root
|
||||
elementBag.insert(sourceTree->_rootElement);
|
||||
|
||||
OctreePacketData packetData;
|
||||
|
||||
EncodeBitstreamParams params(INT_MAX, IGNORE_VIEW_FRUSTUM, WANT_COLOR, NO_EXISTS_BITS);
|
||||
OctreeElementExtraEncodeData extraEncodeData;
|
||||
params.extraEncodeData = &extraEncodeData;
|
||||
|
||||
while (!elementBag.isEmpty()) {
|
||||
OctreeElement* subTree = elementBag.extract();
|
||||
|
||||
packetData.reset(); // reset between usage
|
||||
|
||||
// ask our tree to write a bitsteam
|
||||
sourceTree->encodeTreeBitstream(subTree, &packetData, elementBag, params);
|
||||
|
||||
// ask destination tree to read the bitstream
|
||||
bool wantImportProgress = true;
|
||||
ReadBitstreamToTreeParams args(WANT_COLOR, NO_EXISTS_BITS, destinationElement,
|
||||
0, SharedNodePointer(), wantImportProgress);
|
||||
readBitstreamToTree(packetData.getUncompressedData(), packetData.getUncompressedSize(), args);
|
||||
}
|
||||
}
|
||||
|
||||
void Octree::cancelImport() {
|
||||
_stopImport = true;
|
||||
}
|
||||
|
|
|
@ -270,6 +270,9 @@ public:
|
|||
void recurseTreeWithOperation(RecurseOctreeOperation operation, void* extraData = NULL);
|
||||
void recurseTreeWithPostOperation(RecurseOctreeOperation operation, void* extraData = NULL);
|
||||
|
||||
/// \param operation type of operation
|
||||
/// \param point point in world-frame (meters)
|
||||
/// \param extraData hook for user data to be interpreted by special context
|
||||
void recurseTreeWithOperationDistanceSorted(RecurseOctreeOperation operation,
|
||||
const glm::vec3& point, void* extraData = NULL);
|
||||
|
||||
|
@ -308,8 +311,13 @@ public:
|
|||
bool findCapsulePenetration(const glm::vec3& start, const glm::vec3& end, float radius, glm::vec3& penetration,
|
||||
Octree::lockType lockType = Octree::TryLock, bool* accurateResult = NULL);
|
||||
|
||||
/// \param cube query cube in world-frame (meters)
|
||||
/// \param[out] cubes list of cubes (world-frame) of child elements that have content
|
||||
bool findContentInCube(const AACube& cube, CubeList& cubes);
|
||||
|
||||
/// \param point query point in world-frame (meters)
|
||||
/// \param lockType how to lock the tree (Lock, TryLock, NoLock)
|
||||
/// \param[out] accurateResult pointer to output result, will be set "true" or "false" if non-null
|
||||
OctreeElement* getElementEnclosingPoint(const glm::vec3& point,
|
||||
Octree::lockType lockType = Octree::TryLock, bool* accurateResult = NULL);
|
||||
|
||||
|
@ -323,9 +331,6 @@ public:
|
|||
|
||||
unsigned long getOctreeElementsCount();
|
||||
|
||||
void copySubTreeIntoNewTree(OctreeElement* startElement, Octree* destinationTree, bool rebaseToRoot);
|
||||
void copyFromTreeIntoSubTree(Octree* sourceTree, OctreeElement* destinationElement);
|
||||
|
||||
bool getShouldReaverage() const { return _shouldReaverage; }
|
||||
|
||||
void recurseElementWithOperation(OctreeElement* element, RecurseOctreeOperation operation,
|
||||
|
|
|
@ -194,14 +194,14 @@ void OctreeElement::setShouldRender(bool shouldRender) {
|
|||
}
|
||||
|
||||
void OctreeElement::calculateAACube() {
|
||||
glm::vec3 corner;
|
||||
|
||||
// copy corner into cube
|
||||
copyFirstVertexForCode(getOctalCode(),(float*)&corner);
|
||||
glm::vec3 corner;
|
||||
copyFirstVertexForCode(getOctalCode(), (float*)&corner);
|
||||
|
||||
// this tells you the "size" of the voxel
|
||||
float voxelScale = 1 / powf(2, numberOfThreeBitSectionsInCode(getOctalCode()));
|
||||
_cube.setBox(corner,voxelScale);
|
||||
float voxelScale = (float)TREE_SCALE / powf(2.0f, numberOfThreeBitSectionsInCode(getOctalCode()));
|
||||
corner *= (float)TREE_SCALE;
|
||||
_cube.setBox(corner, voxelScale);
|
||||
}
|
||||
|
||||
void OctreeElement::deleteChildAtIndex(int childIndex) {
|
||||
|
@ -1221,9 +1221,7 @@ float OctreeElement::getEnclosingRadius() const {
|
|||
}
|
||||
|
||||
ViewFrustum::location OctreeElement::inFrustum(const ViewFrustum& viewFrustum) const {
|
||||
AACube cube = _cube; // use temporary cube so we can scale it
|
||||
cube.scale(TREE_SCALE);
|
||||
return viewFrustum.cubeInFrustum(cube);
|
||||
return viewFrustum.cubeInFrustum(_cube);
|
||||
}
|
||||
|
||||
// There are two types of nodes for which we want to "render"
|
||||
|
@ -1257,14 +1255,13 @@ bool OctreeElement::calculateShouldRender(const ViewFrustum* viewFrustum, float
|
|||
// does as much math as possible in voxel scale and then scales up to TREE_SCALE at end
|
||||
float OctreeElement::furthestDistanceToCamera(const ViewFrustum& viewFrustum) const {
|
||||
glm::vec3 furthestPoint;
|
||||
viewFrustum.getFurthestPointFromCameraVoxelScale(getAACube(), furthestPoint);
|
||||
glm::vec3 temp = viewFrustum.getPositionVoxelScale() - furthestPoint;
|
||||
float distanceToFurthestPoint = sqrtf(glm::dot(temp, temp));
|
||||
return distanceToFurthestPoint * (float)TREE_SCALE;
|
||||
viewFrustum.getFurthestPointFromCamera(_cube, furthestPoint);
|
||||
glm::vec3 temp = viewFrustum.getPosition() - furthestPoint;
|
||||
return sqrtf(glm::dot(temp, temp));
|
||||
}
|
||||
|
||||
float OctreeElement::distanceToCamera(const ViewFrustum& viewFrustum) const {
|
||||
glm::vec3 center = _cube.calcCenter() * (float)TREE_SCALE;
|
||||
glm::vec3 center = _cube.calcCenter();
|
||||
glm::vec3 temp = viewFrustum.getPosition() - center;
|
||||
float distanceToVoxelCenter = sqrtf(glm::dot(temp, temp));
|
||||
return distanceToVoxelCenter;
|
||||
|
@ -1337,16 +1334,12 @@ bool OctreeElement::findRayIntersection(const glm::vec3& origin, const glm::vec3
|
|||
|
||||
keepSearching = true; // assume that we will continue searching after this.
|
||||
|
||||
AACube cube = getAACube();
|
||||
float distanceToElementCube = std::numeric_limits<float>::max();
|
||||
float distanceToElementDetails = distance;
|
||||
BoxFace localFace;
|
||||
|
||||
AACube debugCube = cube;
|
||||
debugCube.scale((float)TREE_SCALE);
|
||||
|
||||
// if the ray doesn't intersect with our cube, we can stop searching!
|
||||
if (!cube.findRayIntersection(origin, direction, distanceToElementCube, localFace)) {
|
||||
if (!_cube.findRayIntersection(origin, direction, distanceToElementCube, localFace)) {
|
||||
keepSearching = false; // no point in continuing to search
|
||||
return false; // we did not intersect
|
||||
}
|
||||
|
@ -1358,7 +1351,7 @@ bool OctreeElement::findRayIntersection(const glm::vec3& origin, const glm::vec3
|
|||
|
||||
// if the distance to the element cube is not less than the current best distance, then it's not possible
|
||||
// for any details inside the cube to be closer so we don't need to consider them.
|
||||
if (cube.contains(origin) || distanceToElementCube < distance) {
|
||||
if (_cube.contains(origin) || distanceToElementCube < distance) {
|
||||
|
||||
if (findDetailedRayIntersection(origin, direction, keepSearching, element, distanceToElementDetails,
|
||||
face, intersectedObject, precisionPicking, distanceToElementCube)) {
|
||||
|
@ -1392,6 +1385,7 @@ bool OctreeElement::findDetailedRayIntersection(const glm::vec3& origin, const g
|
|||
|
||||
bool OctreeElement::findSpherePenetration(const glm::vec3& center, float radius,
|
||||
glm::vec3& penetration, void** penetratedObject) const {
|
||||
// center and radius are in meters, so we have to scale the _cube into world-frame
|
||||
return _cube.findSpherePenetration(center, radius, penetration);
|
||||
}
|
||||
|
||||
|
@ -1529,15 +1523,15 @@ int OctreeElement::getMyChildContaining(const AACube& cube) const {
|
|||
if (cubeScale > ourScale) {
|
||||
qDebug() << "UNEXPECTED -- OctreeElement::getMyChildContaining() -- (cubeScale > ourScale)";
|
||||
qDebug() << " cube=" << cube;
|
||||
qDebug() << " elements AACube=" << getAACube();
|
||||
qDebug() << " elements AACube=" << _cube;
|
||||
qDebug() << " cubeScale=" << cubeScale;
|
||||
qDebug() << " ourScale=" << ourScale;
|
||||
assert(false);
|
||||
}
|
||||
|
||||
// Determine which of our children the minimum and maximum corners of the cube live in...
|
||||
glm::vec3 cubeCornerMinimum = glm::clamp(cube.getCorner(), 0.0f, 1.0f);
|
||||
glm::vec3 cubeCornerMaximum = glm::clamp(cube.calcTopFarLeft(), 0.0f, 1.0f);
|
||||
glm::vec3 cubeCornerMinimum = glm::clamp(cube.getCorner(), 0.0f, (float)TREE_SCALE);
|
||||
glm::vec3 cubeCornerMaximum = glm::clamp(cube.calcTopFarLeft(), 0.0f, (float)TREE_SCALE);
|
||||
|
||||
if (_cube.contains(cubeCornerMinimum) && _cube.contains(cubeCornerMaximum)) {
|
||||
int childIndexCubeMinimum = getMyChildContainingPoint(cubeCornerMinimum);
|
||||
|
|
|
@ -125,6 +125,10 @@ public:
|
|||
bool& keepSearching, OctreeElement*& element, float& distance, BoxFace& face,
|
||||
void** intersectedObject, bool precisionPicking, float distanceToElementCube);
|
||||
|
||||
/// \param center center of sphere in meters
|
||||
/// \param radius radius of sphere in meters
|
||||
/// \param[out] penetration pointing into cube from sphere
|
||||
/// \param penetratedObject unused
|
||||
virtual bool findSpherePenetration(const glm::vec3& center, float radius,
|
||||
glm::vec3& penetration, void** penetratedObject) const;
|
||||
|
||||
|
|
|
@ -101,7 +101,6 @@ void OctreeHeadlessViewer::queryOctree() {
|
|||
voxelDetailsForCode(rootCode, rootDetails);
|
||||
jurisdictions.unlock();
|
||||
AACube serverBounds(glm::vec3(rootDetails.x, rootDetails.y, rootDetails.z), rootDetails.s);
|
||||
serverBounds.scale(TREE_SCALE);
|
||||
|
||||
ViewFrustum::location serverFrustumLocation = _viewFrustum.cubeInFrustum(serverBounds);
|
||||
|
||||
|
@ -170,7 +169,6 @@ void OctreeHeadlessViewer::queryOctree() {
|
|||
voxelDetailsForCode(rootCode, rootDetails);
|
||||
jurisdictions.unlock();
|
||||
AACube serverBounds(glm::vec3(rootDetails.x, rootDetails.y, rootDetails.z), rootDetails.s);
|
||||
serverBounds.scale(TREE_SCALE);
|
||||
|
||||
ViewFrustum::location serverFrustumLocation = _viewFrustum.cubeInFrustum(serverBounds);
|
||||
if (serverFrustumLocation != ViewFrustum::OUTSIDE) {
|
||||
|
|
|
@ -65,7 +65,8 @@ void OctreeRenderer::processDatagram(const QByteArray& dataByteArray, const Shar
|
|||
unsigned int numBytesPacketHeader = numBytesForPacketHeader(dataByteArray);
|
||||
QUuid sourceUUID = uuidFromPacketHeader(dataByteArray);
|
||||
PacketType expectedType = getExpectedPacketType();
|
||||
PacketVersion expectedVersion = _tree->expectedVersion(); // TODO: would be better to read this from the packet!
|
||||
// packetVersion is the second byte
|
||||
PacketVersion packetVersion = dataByteArray[1];
|
||||
|
||||
if(command == expectedType) {
|
||||
PerformanceWarning warn(showTimingDetails, "OctreeRenderer::processDatagram expected PacketType", showTimingDetails);
|
||||
|
@ -117,7 +118,7 @@ void OctreeRenderer::processDatagram(const QByteArray& dataByteArray, const Shar
|
|||
if (sectionLength) {
|
||||
// ask the VoxelTree to read the bitstream into the tree
|
||||
ReadBitstreamToTreeParams args(packetIsColored ? WANT_COLOR : NO_COLOR, WANT_EXISTS_BITS, NULL,
|
||||
sourceUUID, sourceNode, false, expectedVersion);
|
||||
sourceUUID, sourceNode, false, packetVersion);
|
||||
_tree->lockForWrite();
|
||||
OctreePacketData packetData(packetIsCompressed);
|
||||
packetData.loadFinalizedContent(dataAt, sectionLength);
|
||||
|
|
|
@ -837,33 +837,6 @@ void ViewFrustum::getFurthestPointFromCamera(const AACube& box, glm::vec3& furth
|
|||
}
|
||||
}
|
||||
|
||||
void ViewFrustum::getFurthestPointFromCameraVoxelScale(const AACube& box, glm::vec3& furthestPoint) const {
|
||||
const glm::vec3& bottomNearRight = box.getCorner();
|
||||
float scale = box.getScale();
|
||||
float halfScale = scale * 0.5f;
|
||||
|
||||
if (_positionVoxelScale.x < bottomNearRight.x + halfScale) {
|
||||
// we are to the right of the center, so the left edge is furthest
|
||||
furthestPoint.x = bottomNearRight.x + scale;
|
||||
} else {
|
||||
furthestPoint.x = bottomNearRight.x;
|
||||
}
|
||||
|
||||
if (_positionVoxelScale.y < bottomNearRight.y + halfScale) {
|
||||
// we are below of the center, so the top edge is furthest
|
||||
furthestPoint.y = bottomNearRight.y + scale;
|
||||
} else {
|
||||
furthestPoint.y = bottomNearRight.y;
|
||||
}
|
||||
|
||||
if (_positionVoxelScale.z < bottomNearRight.z + halfScale) {
|
||||
// we are to the near side of the center, so the far side edge is furthest
|
||||
furthestPoint.z = bottomNearRight.z + scale;
|
||||
} else {
|
||||
furthestPoint.z = bottomNearRight.z;
|
||||
}
|
||||
}
|
||||
|
||||
float ViewFrustum::distanceToCamera(const glm::vec3& point) const {
|
||||
glm::vec3 temp = getPosition() - point;
|
||||
float distanceToPoint = sqrtf(glm::dot(temp, temp));
|
||||
|
|
|
@ -30,19 +30,18 @@ const float DEFAULT_KEYHOLE_RADIUS = 3.0f;
|
|||
const float DEFAULT_FIELD_OF_VIEW_DEGREES = 45.0f;
|
||||
const float DEFAULT_ASPECT_RATIO = 16.0f/9.0f;
|
||||
const float DEFAULT_NEAR_CLIP = 0.08f;
|
||||
const float DEFAULT_FAR_CLIP = TREE_SCALE;
|
||||
const float DEFAULT_FAR_CLIP = (float)TREE_SCALE;
|
||||
|
||||
class ViewFrustum {
|
||||
public:
|
||||
ViewFrustum();
|
||||
|
||||
// setters for camera attributes
|
||||
void setPosition(const glm::vec3& p) { _position = p; _positionVoxelScale = (p / (float)TREE_SCALE); }
|
||||
void setPosition(const glm::vec3& p) { _position = p; }
|
||||
void setOrientation(const glm::quat& orientationAsQuaternion);
|
||||
|
||||
// getters for camera attributes
|
||||
const glm::vec3& getPosition() const { return _position; }
|
||||
const glm::vec3& getPositionVoxelScale() const { return _positionVoxelScale; }
|
||||
const glm::quat& getOrientation() const { return _orientation; }
|
||||
const glm::vec3& getDirection() const { return _direction; }
|
||||
const glm::vec3& getUp() const { return _up; }
|
||||
|
@ -119,9 +118,6 @@ public:
|
|||
OctreeProjectedPolygon getProjectedPolygon(const AACube& box) const;
|
||||
void getFurthestPointFromCamera(const AACube& box, glm::vec3& furthestPoint) const;
|
||||
|
||||
// assumes box is in voxel scale, not TREE_SCALE, will scale view frustum's position accordingly
|
||||
void getFurthestPointFromCameraVoxelScale(const AACube& box, glm::vec3& furthestPoint) const;
|
||||
|
||||
float distanceToCamera(const glm::vec3& point) const;
|
||||
|
||||
void evalProjectionMatrix(glm::mat4& proj) const;
|
||||
|
@ -135,8 +131,7 @@ private:
|
|||
void calculateOrthographic();
|
||||
|
||||
// camera location/orientation attributes
|
||||
glm::vec3 _position = glm::vec3(0.0f); // the position in TREE_SCALE
|
||||
glm::vec3 _positionVoxelScale = glm::vec3(0.0f); // the position in voxel scale
|
||||
glm::vec3 _position = glm::vec3(0.0f); // the position in world-frame
|
||||
glm::quat _orientation = glm::quat();
|
||||
|
||||
// calculated for orientation
|
||||
|
|
|
@ -84,23 +84,22 @@ void EntityMotionState::getWorldTransform(btTransform& worldTrans) const {
|
|||
// bypass const-ness so we can remember the substep
|
||||
const_cast<EntityMotionState*>(this)->_lastKinematicSubstep = substep;
|
||||
}
|
||||
worldTrans.setOrigin(glmToBullet(_entity->getPositionInMeters() - ObjectMotionState::getWorldOffset()));
|
||||
worldTrans.setOrigin(glmToBullet(_entity->getPosition() - ObjectMotionState::getWorldOffset()));
|
||||
worldTrans.setRotation(glmToBullet(_entity->getRotation()));
|
||||
}
|
||||
|
||||
// This callback is invoked by the physics simulation at the end of each simulation frame...
|
||||
// iff the corresponding RigidBody is DYNAMIC and has moved.
|
||||
void EntityMotionState::setWorldTransform(const btTransform& worldTrans) {
|
||||
_entity->setPositionInMeters(bulletToGLM(worldTrans.getOrigin()) + ObjectMotionState::getWorldOffset());
|
||||
_entity->setPosition(bulletToGLM(worldTrans.getOrigin()) + ObjectMotionState::getWorldOffset());
|
||||
_entity->setRotation(bulletToGLM(worldTrans.getRotation()));
|
||||
|
||||
glm::vec3 v;
|
||||
getVelocity(v);
|
||||
_entity->setVelocityInMeters(v);
|
||||
_entity->setVelocity(v);
|
||||
|
||||
getAngularVelocity(v);
|
||||
// DANGER! EntityItem stores angularVelocity in degrees/sec!!!
|
||||
_entity->setAngularVelocity(glm::degrees(v));
|
||||
_entity->setAngularVelocity(v);
|
||||
|
||||
_entity->setLastSimulated(usecTimestampNow());
|
||||
|
||||
|
@ -119,7 +118,7 @@ void EntityMotionState::setWorldTransform(const btTransform& worldTrans) {
|
|||
void EntityMotionState::updateObjectEasy(uint32_t flags, uint32_t frame) {
|
||||
if (flags & (EntityItem::DIRTY_POSITION | EntityItem::DIRTY_VELOCITY)) {
|
||||
if (flags & EntityItem::DIRTY_POSITION) {
|
||||
_sentPosition = _entity->getPositionInMeters() - ObjectMotionState::getWorldOffset();
|
||||
_sentPosition = _entity->getPosition() - ObjectMotionState::getWorldOffset();
|
||||
btTransform worldTrans;
|
||||
worldTrans.setOrigin(glmToBullet(_sentPosition));
|
||||
|
||||
|
@ -156,14 +155,13 @@ void EntityMotionState::updateObjectEasy(uint32_t flags, uint32_t frame) {
|
|||
|
||||
void EntityMotionState::updateObjectVelocities() {
|
||||
if (_body) {
|
||||
_sentVelocity = _entity->getVelocityInMeters();
|
||||
_sentVelocity = _entity->getVelocity();
|
||||
setVelocity(_sentVelocity);
|
||||
|
||||
// DANGER! EntityItem stores angularVelocity in degrees/sec!!!
|
||||
_sentAngularVelocity = glm::radians(_entity->getAngularVelocity());
|
||||
_sentAngularVelocity = _entity->getAngularVelocity();
|
||||
setAngularVelocity(_sentAngularVelocity);
|
||||
|
||||
_sentAcceleration = _entity->getGravityInMeters();
|
||||
_sentAcceleration = _entity->getGravity();
|
||||
setGravity(_sentAcceleration);
|
||||
|
||||
_body->setActivationState(ACTIVE_TAG);
|
||||
|
@ -219,8 +217,7 @@ void EntityMotionState::sendUpdate(OctreeEditPacketSender* packetSender, uint32_
|
|||
properties.setVelocity(_sentVelocity);
|
||||
_sentAcceleration = bulletToGLM(_body->getGravity());
|
||||
properties.setGravity(_sentAcceleration);
|
||||
// DANGER! EntityItem stores angularVelocity in degrees/sec!!!
|
||||
properties.setAngularVelocity(glm::degrees(_sentAngularVelocity));
|
||||
properties.setAngularVelocity(_sentAngularVelocity);
|
||||
}
|
||||
|
||||
// RELIABLE_SEND_HACK: count number of updates for entities at rest so we can stop sending them after some limit.
|
||||
|
|
|
@ -471,17 +471,17 @@ AABox AABox::clamp(float min, float max) const {
|
|||
return AABox(clampedCorner, clampedScale);
|
||||
}
|
||||
|
||||
AABox& AABox::operator += (const glm::vec3& point) {
|
||||
_corner = glm::min(_corner, point);
|
||||
_scale = glm::max(_scale, point - _corner);
|
||||
|
||||
return (*this);
|
||||
}
|
||||
|
||||
AABox& AABox::operator += (const AABox& box) {
|
||||
if (!box.isInvalid()) {
|
||||
(*this) += box._corner;
|
||||
_scale = glm::max(_scale, box.calcTopFarLeft() - _corner);
|
||||
}
|
||||
return (*this);
|
||||
}
|
||||
AABox& AABox::operator += (const glm::vec3& point) {
|
||||
_corner = glm::min(_corner, point);
|
||||
_scale = glm::max(_scale, point - _corner);
|
||||
|
||||
return (*this);
|
||||
}
|
||||
|
||||
AABox& AABox::operator += (const AABox& box) {
|
||||
if (!box.isInvalid()) {
|
||||
(*this) += box._corner;
|
||||
_scale = glm::max(_scale, box.calcTopFarLeft() - _corner);
|
||||
}
|
||||
return (*this);
|
||||
}
|
||||
|
|
|
@ -129,18 +129,17 @@ unsigned char* childOctalCode(const unsigned char* parentOctalCode, char childNu
|
|||
void voxelDetailsForCode(const unsigned char* octalCode, VoxelPositionSize& voxelPositionSize) {
|
||||
float output[3];
|
||||
memset(&output[0], 0, 3 * sizeof(float));
|
||||
float currentScale = 1.0;
|
||||
float currentScale = 1.0f;
|
||||
|
||||
if (octalCode) {
|
||||
for (int i = 0; i < numberOfThreeBitSectionsInCode(octalCode); i++) {
|
||||
currentScale *= 0.5;
|
||||
currentScale *= 0.5f;
|
||||
int sectionIndex = sectionValue(octalCode + 1 + (BITS_IN_OCTAL * i / BITS_IN_BYTE),
|
||||
(BITS_IN_OCTAL * i) % BITS_IN_BYTE);
|
||||
|
||||
for (int j = 0; j < BITS_IN_OCTAL; j++) {
|
||||
output[j] += currentScale * (int)oneAtBit(sectionIndex, (BITS_IN_BYTE - BITS_IN_OCTAL) + j);
|
||||
output[j] += currentScale * (float)oneAtBit(sectionIndex, (BITS_IN_BYTE - BITS_IN_OCTAL) + j);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
voxelPositionSize.x = output[0];
|
||||
|
@ -152,7 +151,7 @@ void voxelDetailsForCode(const unsigned char* octalCode, VoxelPositionSize& voxe
|
|||
void copyFirstVertexForCode(const unsigned char* octalCode, float* output) {
|
||||
memset(output, 0, 3 * sizeof(float));
|
||||
|
||||
float currentScale = 0.5;
|
||||
float currentScale = 0.5f;
|
||||
|
||||
for (int i = 0; i < numberOfThreeBitSectionsInCode(octalCode); i++) {
|
||||
int sectionIndex = sectionValue(octalCode + 1 + (3 * i / 8), (3 * i) % 8);
|
||||
|
@ -165,12 +164,6 @@ void copyFirstVertexForCode(const unsigned char* octalCode, float* output) {
|
|||
}
|
||||
}
|
||||
|
||||
float * firstVertexForCode(const unsigned char* octalCode) {
|
||||
float * firstVertex = new float[3];
|
||||
copyFirstVertexForCode(octalCode, firstVertex);
|
||||
return firstVertex;
|
||||
}
|
||||
|
||||
OctalCodeComparison compareOctalCodes(const unsigned char* codeA, const unsigned char* codeB) {
|
||||
if (!codeA || !codeB) {
|
||||
return ILLEGAL_CODE;
|
||||
|
|
|
@ -43,9 +43,6 @@ const int CHECK_NODE_ONLY = -1;
|
|||
bool isAncestorOf(const unsigned char* possibleAncestor, const unsigned char* possibleDescendent,
|
||||
int descendentsChild = CHECK_NODE_ONLY);
|
||||
|
||||
// Note: copyFirstVertexForCode() is preferred because it doesn't allocate memory for the return
|
||||
// but other than that these do the same thing.
|
||||
float * firstVertexForCode(const unsigned char* octalCode);
|
||||
void copyFirstVertexForCode(const unsigned char* octalCode, float* output);
|
||||
|
||||
struct VoxelPositionSize {
|
||||
|
|
|
@ -45,12 +45,9 @@ void EntityTests::entityTreeTests(bool verbose) {
|
|||
entityID.isKnownID = false; // this is a temporary workaround to allow local tree entities to be added with known IDs
|
||||
EntityItemProperties properties;
|
||||
float oneMeter = 1.0f;
|
||||
//float halfMeter = oneMeter / 2.0f;
|
||||
float halfOfDomain = TREE_SCALE * 0.5f;
|
||||
glm::vec3 positionNearOriginInMeters(oneMeter, oneMeter, oneMeter); // when using properties, these are in meter not tree units
|
||||
glm::vec3 positionAtCenterInMeters(halfOfDomain, halfOfDomain, halfOfDomain);
|
||||
glm::vec3 positionNearOriginInTreeUnits = positionNearOriginInMeters / (float)TREE_SCALE;
|
||||
glm::vec3 positionAtCenterInTreeUnits = positionAtCenterInMeters / (float)TREE_SCALE;
|
||||
glm::vec3 positionNearOrigin(oneMeter, oneMeter, oneMeter); // when using properties, these are in meter not tree units
|
||||
glm::vec3 positionAtCenter(halfOfDomain, halfOfDomain, halfOfDomain);
|
||||
|
||||
{
|
||||
testsTaken++;
|
||||
|
@ -59,28 +56,27 @@ void EntityTests::entityTreeTests(bool verbose) {
|
|||
qDebug() << "Test" << testsTaken <<":" << qPrintable(testName);
|
||||
}
|
||||
|
||||
properties.setPosition(positionAtCenterInMeters);
|
||||
properties.setPosition(positionAtCenter);
|
||||
// TODO: Fix these unit tests.
|
||||
//properties.setRadius(halfMeter);
|
||||
//properties.setModelURL("http://s3.amazonaws.com/hifi-public/ozan/theater.fbx");
|
||||
|
||||
tree.addEntity(entityID, properties);
|
||||
|
||||
float targetRadius = oneMeter * 2.0 / (float)TREE_SCALE; // in tree units
|
||||
const EntityItem* foundEntityByRadius = tree.findClosestEntity(positionAtCenterInTreeUnits, targetRadius);
|
||||
float targetRadius = oneMeter * 2.0f;
|
||||
const EntityItem* foundEntityByRadius = tree.findClosestEntity(positionAtCenter, targetRadius);
|
||||
const EntityItem* foundEntityByID = tree.findEntityByEntityItemID(entityID);
|
||||
EntityTreeElement* containingElement = tree.getContainingElement(entityID);
|
||||
AACube elementCube = containingElement ? containingElement->getAACube() : AACube();
|
||||
const AACube& elementCube = containingElement ? containingElement->getAACube() : AACube();
|
||||
|
||||
if (verbose) {
|
||||
qDebug() << "foundEntityByRadius=" << foundEntityByRadius;
|
||||
qDebug() << "foundEntityByID=" << foundEntityByID;
|
||||
qDebug() << "containingElement=" << containingElement;
|
||||
qDebug() << "containingElement.box="
|
||||
<< elementCube.getCorner().x * TREE_SCALE << ","
|
||||
<< elementCube.getCorner().y * TREE_SCALE << ","
|
||||
<< elementCube.getCorner().z * TREE_SCALE << ":"
|
||||
<< elementCube.getScale() * TREE_SCALE;
|
||||
<< elementCube.getCorner().x << ","
|
||||
<< elementCube.getCorner().y << ","
|
||||
<< elementCube.getCorner().z << ":"
|
||||
<< elementCube.getScale();
|
||||
qDebug() << "elementCube.getScale()=" << elementCube.getScale();
|
||||
//containingElement->printDebugDetails("containingElement");
|
||||
}
|
||||
|
@ -103,27 +99,27 @@ void EntityTests::entityTreeTests(bool verbose) {
|
|||
qDebug() << "Test" << testsTaken <<":" << qPrintable(testName);
|
||||
}
|
||||
|
||||
glm::vec3 newPosition = positionNearOriginInMeters;
|
||||
glm::vec3 newPosition = positionNearOrigin;
|
||||
|
||||
properties.setPosition(newPosition);
|
||||
|
||||
tree.updateEntity(entityID, properties, true);
|
||||
|
||||
float targetRadius = oneMeter * 2.0 / (float)TREE_SCALE; // in tree units
|
||||
const EntityItem* foundEntityByRadius = tree.findClosestEntity(positionNearOriginInTreeUnits, targetRadius);
|
||||
float targetRadius = oneMeter * 2.0f;
|
||||
const EntityItem* foundEntityByRadius = tree.findClosestEntity(positionNearOrigin, targetRadius);
|
||||
const EntityItem* foundEntityByID = tree.findEntityByEntityItemID(entityID);
|
||||
EntityTreeElement* containingElement = tree.getContainingElement(entityID);
|
||||
AACube elementCube = containingElement ? containingElement->getAACube() : AACube();
|
||||
const AACube& elementCube = containingElement ? containingElement->getAACube() : AACube();
|
||||
|
||||
if (verbose) {
|
||||
qDebug() << "foundEntityByRadius=" << foundEntityByRadius;
|
||||
qDebug() << "foundEntityByID=" << foundEntityByID;
|
||||
qDebug() << "containingElement=" << containingElement;
|
||||
qDebug() << "containingElement.box="
|
||||
<< elementCube.getCorner().x * TREE_SCALE << ","
|
||||
<< elementCube.getCorner().y * TREE_SCALE << ","
|
||||
<< elementCube.getCorner().z * TREE_SCALE << ":"
|
||||
<< elementCube.getScale() * TREE_SCALE;
|
||||
<< elementCube.getCorner().x << ","
|
||||
<< elementCube.getCorner().y << ","
|
||||
<< elementCube.getCorner().z << ":"
|
||||
<< elementCube.getScale();
|
||||
//containingElement->printDebugDetails("containingElement");
|
||||
}
|
||||
|
||||
|
@ -143,27 +139,27 @@ void EntityTests::entityTreeTests(bool verbose) {
|
|||
qDebug() << "Test" << testsTaken <<":" << qPrintable(testName);
|
||||
}
|
||||
|
||||
glm::vec3 newPosition = positionAtCenterInMeters;
|
||||
glm::vec3 newPosition = positionAtCenter;
|
||||
|
||||
properties.setPosition(newPosition);
|
||||
|
||||
tree.updateEntity(entityID, properties, true);
|
||||
|
||||
float targetRadius = oneMeter * 2.0 / (float)TREE_SCALE; // in tree units
|
||||
const EntityItem* foundEntityByRadius = tree.findClosestEntity(positionAtCenterInTreeUnits, targetRadius);
|
||||
float targetRadius = oneMeter * 2.0f;
|
||||
const EntityItem* foundEntityByRadius = tree.findClosestEntity(positionAtCenter, targetRadius);
|
||||
const EntityItem* foundEntityByID = tree.findEntityByEntityItemID(entityID);
|
||||
EntityTreeElement* containingElement = tree.getContainingElement(entityID);
|
||||
AACube elementCube = containingElement ? containingElement->getAACube() : AACube();
|
||||
const AACube& elementCube = containingElement ? containingElement->getAACube() : AACube();
|
||||
|
||||
if (verbose) {
|
||||
qDebug() << "foundEntityByRadius=" << foundEntityByRadius;
|
||||
qDebug() << "foundEntityByID=" << foundEntityByID;
|
||||
qDebug() << "containingElement=" << containingElement;
|
||||
qDebug() << "containingElement.box="
|
||||
<< elementCube.getCorner().x * TREE_SCALE << ","
|
||||
<< elementCube.getCorner().y * TREE_SCALE << ","
|
||||
<< elementCube.getCorner().z * TREE_SCALE << ":"
|
||||
<< elementCube.getScale() * TREE_SCALE;
|
||||
<< elementCube.getCorner().x << ","
|
||||
<< elementCube.getCorner().y << ","
|
||||
<< elementCube.getCorner().z << ":"
|
||||
<< elementCube.getScale();
|
||||
//containingElement->printDebugDetails("containingElement");
|
||||
}
|
||||
|
||||
|
@ -184,11 +180,11 @@ void EntityTests::entityTreeTests(bool verbose) {
|
|||
qDebug() << "Test" << testsTaken <<":" << qPrintable(testName);
|
||||
}
|
||||
|
||||
float targetRadius = oneMeter * 2.0 / (float)TREE_SCALE; // in tree units
|
||||
float targetRadius = oneMeter * 2.0f;
|
||||
quint64 start = usecTimestampNow();
|
||||
const EntityItem* foundEntityByRadius = NULL;
|
||||
for (int i = 0; i < TEST_ITERATIONS; i++) {
|
||||
foundEntityByRadius = tree.findClosestEntity(positionAtCenterInTreeUnits, targetRadius);
|
||||
foundEntityByRadius = tree.findClosestEntity(positionAtCenter, targetRadius);
|
||||
}
|
||||
quint64 end = usecTimestampNow();
|
||||
|
||||
|
@ -262,13 +258,11 @@ void EntityTests::entityTreeTests(bool verbose) {
|
|||
float randomX = randFloatInRange(1.0f ,(float)TREE_SCALE - 1.0f);
|
||||
float randomY = randFloatInRange(1.0f ,(float)TREE_SCALE - 1.0f);
|
||||
float randomZ = randFloatInRange(1.0f ,(float)TREE_SCALE - 1.0f);
|
||||
glm::vec3 randomPositionInMeters(randomX,randomY,randomZ);
|
||||
glm::vec3 randomPositionInTreeUnits = randomPositionInMeters / (float)TREE_SCALE;
|
||||
glm::vec3 randomPosition(randomX,randomY,randomZ);
|
||||
|
||||
properties.setPosition(randomPositionInMeters);
|
||||
properties.setPosition(randomPosition);
|
||||
|
||||
// TODO: fix these unit tests
|
||||
//properties.setRadius(halfMeter);
|
||||
//properties.setModelURL("http://s3.amazonaws.com/hifi-public/ozan/theater.fbx");
|
||||
|
||||
if (extraVerbose) {
|
||||
|
@ -287,14 +281,14 @@ void EntityTests::entityTreeTests(bool verbose) {
|
|||
}
|
||||
|
||||
quint64 startFind = usecTimestampNow();
|
||||
float targetRadius = oneMeter * 2.0 / (float)TREE_SCALE; // in tree units
|
||||
const EntityItem* foundEntityByRadius = tree.findClosestEntity(randomPositionInTreeUnits, targetRadius);
|
||||
float targetRadius = oneMeter * 2.0f;
|
||||
const EntityItem* foundEntityByRadius = tree.findClosestEntity(randomPosition, targetRadius);
|
||||
const EntityItem* foundEntityByID = tree.findEntityByEntityItemID(entityID);
|
||||
quint64 endFind = usecTimestampNow();
|
||||
totalElapsedFind += (endFind - startFind);
|
||||
|
||||
EntityTreeElement* containingElement = tree.getContainingElement(entityID);
|
||||
AACube elementCube = containingElement ? containingElement->getAACube() : AACube();
|
||||
const AACube& elementCube = containingElement ? containingElement->getAACube() : AACube();
|
||||
|
||||
bool elementIsBestFit = containingElement->bestFitEntityBounds(foundEntityByID);
|
||||
|
||||
|
@ -303,10 +297,10 @@ void EntityTests::entityTreeTests(bool verbose) {
|
|||
qDebug() << "foundEntityByID=" << foundEntityByID;
|
||||
qDebug() << "containingElement=" << containingElement;
|
||||
qDebug() << "containingElement.box="
|
||||
<< elementCube.getCorner().x * TREE_SCALE << ","
|
||||
<< elementCube.getCorner().y * TREE_SCALE << ","
|
||||
<< elementCube.getCorner().z * TREE_SCALE << ":"
|
||||
<< elementCube.getScale() * TREE_SCALE;
|
||||
<< elementCube.getCorner().x << ","
|
||||
<< elementCube.getCorner().y << ","
|
||||
<< elementCube.getCorner().z << ":"
|
||||
<< elementCube.getScale();
|
||||
qDebug() << "elementCube.getScale()=" << elementCube.getScale();
|
||||
//containingElement->printDebugDetails("containingElement");
|
||||
qDebug() << "elementIsBestFit=" << elementIsBestFit;
|
||||
|
|
Loading…
Reference in a new issue