mirror of
https://github.com/overte-org/overte.git
synced 2025-04-22 09:33:36 +02:00
Merge branch 'master' of https://github.com/highfidelity/hifi into metavoxels
Conflicts: interface/src/Application.cpp
This commit is contained in:
commit
e80eb03ba9
3 changed files with 85 additions and 112 deletions
|
@ -2004,15 +2004,9 @@ void Application::updateMyAvatarLookAtPosition(glm::vec3& lookAtSpot) {
|
|||
_viewFrustum.computePickRay(0.5f, 0.5f, rayOrigin, rayDirection);
|
||||
lookAtSpot = rayOrigin + rayDirection * FAR_AWAY_STARE;
|
||||
|
||||
} else if (!_lookatTargetAvatar) {
|
||||
if (_isHoverVoxel) {
|
||||
// Look at the hovered voxel
|
||||
lookAtSpot = getMouseVoxelWorldCoordinates(_hoverVoxel);
|
||||
|
||||
} else {
|
||||
// Just look in direction of the mouse ray
|
||||
lookAtSpot = _mouseRayOrigin + _mouseRayDirection * FAR_AWAY_STARE;
|
||||
}
|
||||
} else {
|
||||
// just look in direction of the mouse ray
|
||||
lookAtSpot = _mouseRayOrigin + _mouseRayDirection * FAR_AWAY_STARE;
|
||||
}
|
||||
if (_faceshift.isActive()) {
|
||||
// deflect using Faceshift gaze data
|
||||
|
|
|
@ -34,7 +34,7 @@ void MetavoxelData::guide(MetavoxelVisitor& visitor) {
|
|||
const float TOP_LEVEL_SIZE = 1.0f;
|
||||
const QVector<AttributePointer>& inputs = visitor.getInputs();
|
||||
const QVector<AttributePointer>& outputs = visitor.getOutputs();
|
||||
MetavoxelVisitation firstVisitation = { visitor, QVector<MetavoxelNode*>(inputs.size() + 1),
|
||||
MetavoxelVisitation firstVisitation = { this, NULL, visitor, QVector<MetavoxelNode*>(inputs.size() + 1),
|
||||
QVector<MetavoxelNode*>(outputs.size()), { glm::vec3(), TOP_LEVEL_SIZE,
|
||||
QVector<AttributeValue>(inputs.size() + 1), QVector<AttributeValue>(outputs.size()) } };
|
||||
for (int i = 0; i < inputs.size(); i++) {
|
||||
|
@ -52,32 +52,16 @@ void MetavoxelData::guide(MetavoxelVisitor& visitor) {
|
|||
}
|
||||
static_cast<MetavoxelGuide*>(firstVisitation.info.inputValues.last().getInlineValue<
|
||||
PolymorphicDataPointer>().data())->guide(firstVisitation);
|
||||
}
|
||||
|
||||
void MetavoxelData::setAttributeValue(const MetavoxelPath& path, const AttributeValue& attributeValue) {
|
||||
MetavoxelNode*& node = _roots[attributeValue.getAttribute()];
|
||||
if (node == NULL) {
|
||||
node = new MetavoxelNode(attributeValue.getAttribute());
|
||||
}
|
||||
if (node->setAttributeValue(path, 0, attributeValue) && attributeValue.isDefault()) {
|
||||
node->decrementReferenceCount(attributeValue.getAttribute());
|
||||
_roots.remove(attributeValue.getAttribute());
|
||||
}
|
||||
}
|
||||
|
||||
AttributeValue MetavoxelData::getAttributeValue(const MetavoxelPath& path, const AttributePointer& attribute) const {
|
||||
MetavoxelNode* node = _roots.value(attribute);
|
||||
if (node == NULL) {
|
||||
return AttributeValue(attribute);
|
||||
}
|
||||
for (int i = 0, n = path.getSize(); i < n; i++) {
|
||||
MetavoxelNode* child = node->getChild(path[i]);
|
||||
if (child == NULL) {
|
||||
return node->getAttributeValue(attribute);
|
||||
for (int i = 0; i < outputs.size(); i++) {
|
||||
AttributeValue& value = firstVisitation.info.outputValues[i];
|
||||
if (value.getAttribute()) {
|
||||
MetavoxelNode* node = firstVisitation.outputNodes.at(i);
|
||||
if (node->isLeaf() && value.isDefault()) {
|
||||
node->decrementReferenceCount(value.getAttribute());
|
||||
_roots.remove(value.getAttribute());
|
||||
}
|
||||
}
|
||||
node = child;
|
||||
}
|
||||
return node->getAttributeValue(attribute);
|
||||
}
|
||||
|
||||
void MetavoxelData::read(Bitstream& in) {
|
||||
|
@ -221,34 +205,6 @@ MetavoxelNode::MetavoxelNode(const AttributeValue& attributeValue) : _referenceC
|
|||
}
|
||||
}
|
||||
|
||||
bool MetavoxelNode::setAttributeValue(const MetavoxelPath& path, int index, const AttributeValue& attributeValue) {
|
||||
if (index == path.getSize()) {
|
||||
setAttributeValue(attributeValue);
|
||||
return true;
|
||||
}
|
||||
int element = path[index];
|
||||
if (_children[element] == NULL) {
|
||||
AttributeValue ownAttributeValue = getAttributeValue(attributeValue.getAttribute());
|
||||
for (int i = 0; i < CHILD_COUNT; i++) {
|
||||
_children[i] = new MetavoxelNode(ownAttributeValue);
|
||||
}
|
||||
}
|
||||
_children[element]->setAttributeValue(path, index + 1, attributeValue);
|
||||
|
||||
void* childValues[CHILD_COUNT];
|
||||
bool allLeaves = true;
|
||||
for (int i = 0; i < CHILD_COUNT; i++) {
|
||||
childValues[i] = _children[i]->_attributeValue;
|
||||
allLeaves &= _children[i]->isLeaf();
|
||||
}
|
||||
if (attributeValue.getAttribute()->merge(_attributeValue, childValues) && allLeaves) {
|
||||
clearChildren(attributeValue.getAttribute());
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void MetavoxelNode::setAttributeValue(const AttributeValue& attributeValue) {
|
||||
attributeValue.getAttribute()->destroy(_attributeValue);
|
||||
_attributeValue = attributeValue.copy();
|
||||
|
@ -259,6 +215,18 @@ AttributeValue MetavoxelNode::getAttributeValue(const AttributePointer& attribut
|
|||
return AttributeValue(attribute, _attributeValue);
|
||||
}
|
||||
|
||||
void MetavoxelNode::mergeChildren(const AttributePointer& attribute) {
|
||||
void* childValues[CHILD_COUNT];
|
||||
bool allLeaves = true;
|
||||
for (int i = 0; i < CHILD_COUNT; i++) {
|
||||
childValues[i] = _children[i]->_attributeValue;
|
||||
allLeaves &= _children[i]->isLeaf();
|
||||
}
|
||||
if (attribute->merge(_attributeValue, childValues) && allLeaves) {
|
||||
clearChildren(attribute);
|
||||
}
|
||||
}
|
||||
|
||||
bool MetavoxelNode::isLeaf() const {
|
||||
for (int i = 0; i < CHILD_COUNT; i++) {
|
||||
if (_children[i]) {
|
||||
|
@ -361,20 +329,6 @@ void MetavoxelNode::clearChildren(const AttributePointer& attribute) {
|
|||
}
|
||||
}
|
||||
|
||||
int MetavoxelPath::operator[](int index) const {
|
||||
return (int)_array.at(index * BITS_PER_ELEMENT) | ((int)_array.at(index * BITS_PER_ELEMENT + 1) << 1) |
|
||||
((int)_array.at(index * BITS_PER_ELEMENT + 2) << 2);
|
||||
}
|
||||
|
||||
MetavoxelPath& MetavoxelPath::operator+=(int element) {
|
||||
int offset = _array.size();
|
||||
_array.resize(offset + BITS_PER_ELEMENT);
|
||||
_array.setBit(offset, element & 0x01);
|
||||
_array.setBit(offset + 1, (element >> 1) & 0x01);
|
||||
_array.setBit(offset + 2, element >> 2);
|
||||
return *this;
|
||||
}
|
||||
|
||||
MetavoxelVisitor::MetavoxelVisitor(const QVector<AttributePointer>& inputs, const QVector<AttributePointer>& outputs) :
|
||||
_inputs(inputs),
|
||||
_outputs(outputs) {
|
||||
|
@ -390,12 +344,24 @@ const int Z_MAXIMUM_FLAG = 4;
|
|||
|
||||
void DefaultMetavoxelGuide::guide(MetavoxelVisitation& visitation) {
|
||||
visitation.info.isLeaf = visitation.allInputNodesLeaves();
|
||||
if (!visitation.visitor.visit(visitation.info)) {
|
||||
bool keepGoing = visitation.visitor.visit(visitation.info);
|
||||
for (int i = 0; i < visitation.outputNodes.size(); i++) {
|
||||
AttributeValue& value = visitation.info.outputValues[i];
|
||||
if (value.getAttribute()) {
|
||||
MetavoxelNode*& node = visitation.outputNodes[i];
|
||||
if (!node) {
|
||||
node = visitation.createOutputNode(i);
|
||||
}
|
||||
node->setAttributeValue(value);
|
||||
}
|
||||
}
|
||||
if (!keepGoing) {
|
||||
return;
|
||||
}
|
||||
MetavoxelVisitation nextVisitation = { visitation.visitor, QVector<MetavoxelNode*>(visitation.inputNodes.size()),
|
||||
QVector<MetavoxelNode*>(visitation.outputNodes.size()), { glm::vec3(), visitation.info.size * 0.5f,
|
||||
QVector<AttributeValue>(visitation.inputNodes.size()), QVector<AttributeValue>(visitation.outputNodes.size()) } };
|
||||
MetavoxelVisitation nextVisitation = { visitation.data, &visitation, visitation.visitor,
|
||||
QVector<MetavoxelNode*>(visitation.inputNodes.size()), QVector<MetavoxelNode*>(visitation.outputNodes.size()),
|
||||
{ glm::vec3(), visitation.info.size * 0.5f, QVector<AttributeValue>(visitation.inputNodes.size()),
|
||||
QVector<AttributeValue>(visitation.outputNodes.size()) } };
|
||||
for (int i = 0; i < MetavoxelNode::CHILD_COUNT; i++) {
|
||||
for (int j = 0; j < visitation.inputNodes.size(); j++) {
|
||||
MetavoxelNode* node = visitation.inputNodes.at(j);
|
||||
|
@ -413,8 +379,24 @@ void DefaultMetavoxelGuide::guide(MetavoxelVisitation& visitation) {
|
|||
(i & X_MAXIMUM_FLAG) ? nextVisitation.info.size : 0.0f,
|
||||
(i & Y_MAXIMUM_FLAG) ? nextVisitation.info.size : 0.0f,
|
||||
(i & Z_MAXIMUM_FLAG) ? nextVisitation.info.size : 0.0f);
|
||||
nextVisitation.childIndex = i;
|
||||
static_cast<MetavoxelGuide*>(nextVisitation.info.inputValues.last().getInlineValue<
|
||||
PolymorphicDataPointer>().data())->guide(nextVisitation);
|
||||
for (int j = 0; j < nextVisitation.outputNodes.size(); j++) {
|
||||
AttributeValue& value = nextVisitation.info.outputValues[j];
|
||||
if (value.getAttribute()) {
|
||||
visitation.info.outputValues[j] = value;
|
||||
value = AttributeValue();
|
||||
}
|
||||
}
|
||||
}
|
||||
for (int i = 0; i < visitation.outputNodes.size(); i++) {
|
||||
AttributeValue& value = visitation.info.outputValues[i];
|
||||
if (value.getAttribute()) {
|
||||
MetavoxelNode* node = visitation.outputNodes.at(i);
|
||||
node->mergeChildren(value.getAttribute());
|
||||
value = node->getAttributeValue(value.getAttribute());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -524,3 +506,21 @@ bool MetavoxelVisitation::allInputNodesLeaves() const {
|
|||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
MetavoxelNode* MetavoxelVisitation::createOutputNode(int index) {
|
||||
const AttributePointer& attribute = visitor.getOutputs().at(index);
|
||||
if (previous) {
|
||||
MetavoxelNode*& parent = previous->outputNodes[index];
|
||||
if (!parent) {
|
||||
parent = previous->createOutputNode(index);
|
||||
}
|
||||
AttributeValue value = parent->getAttributeValue(attribute);
|
||||
for (int i = 0; i < MetavoxelNode::CHILD_COUNT; i++) {
|
||||
parent->_children[i] = new MetavoxelNode(value);
|
||||
}
|
||||
return parent->_children[childIndex];
|
||||
|
||||
} else {
|
||||
return data->_roots[attribute] = new MetavoxelNode(attribute);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -24,7 +24,6 @@
|
|||
class QScriptContext;
|
||||
|
||||
class MetavoxelNode;
|
||||
class MetavoxelPath;
|
||||
class MetavoxelVisitation;
|
||||
class MetavoxelVisitor;
|
||||
|
||||
|
@ -41,12 +40,6 @@ public:
|
|||
/// Applies the specified visitor to the contained voxels.
|
||||
void guide(MetavoxelVisitor& visitor);
|
||||
|
||||
/// Sets the attribute value corresponding to the specified path.
|
||||
void setAttributeValue(const MetavoxelPath& path, const AttributeValue& attributeValue);
|
||||
|
||||
/// Retrieves the attribute value corresponding to the specified path.
|
||||
AttributeValue getAttributeValue(const MetavoxelPath& path, const AttributePointer& attribute) const;
|
||||
|
||||
void read(Bitstream& in);
|
||||
void write(Bitstream& out) const;
|
||||
|
||||
|
@ -54,6 +47,8 @@ public:
|
|||
void writeDelta(const MetavoxelData& reference, Bitstream& out) const;
|
||||
|
||||
private:
|
||||
|
||||
friend class MetavoxelVisitation;
|
||||
|
||||
void incrementRootReferenceCounts();
|
||||
void decrementRootReferenceCounts();
|
||||
|
@ -74,17 +69,13 @@ public:
|
|||
static const int CHILD_COUNT = 8;
|
||||
|
||||
MetavoxelNode(const AttributeValue& attributeValue);
|
||||
|
||||
/// Descends the voxel tree in order to set the value of a node.
|
||||
/// \param path the path to follow
|
||||
/// \param index the position in the path
|
||||
/// \return whether or not the node is entirely equal to the value
|
||||
bool setAttributeValue(const MetavoxelPath& path, int index, const AttributeValue& attributeValue);
|
||||
|
||||
|
||||
void setAttributeValue(const AttributeValue& attributeValue);
|
||||
|
||||
AttributeValue getAttributeValue(const AttributePointer& attribute) const;
|
||||
|
||||
void mergeChildren(const AttributePointer& attribute);
|
||||
|
||||
MetavoxelNode* getChild(int index) const { return _children[index]; }
|
||||
void setChild(int index, MetavoxelNode* child) { _children[index] = child; }
|
||||
|
||||
|
@ -108,6 +99,8 @@ public:
|
|||
private:
|
||||
Q_DISABLE_COPY(MetavoxelNode)
|
||||
|
||||
friend class MetavoxelVisitation;
|
||||
|
||||
void clearChildren(const AttributePointer& attribute);
|
||||
|
||||
int _referenceCount;
|
||||
|
@ -115,24 +108,6 @@ private:
|
|||
MetavoxelNode* _children[CHILD_COUNT];
|
||||
};
|
||||
|
||||
/// A path down an octree.
|
||||
class MetavoxelPath {
|
||||
public:
|
||||
|
||||
int getSize() const { return _array.size() / BITS_PER_ELEMENT; }
|
||||
bool isEmpty() const { return _array.isEmpty(); }
|
||||
|
||||
int operator[](int index) const;
|
||||
|
||||
MetavoxelPath& operator+=(int element);
|
||||
|
||||
private:
|
||||
|
||||
static const int BITS_PER_ELEMENT = 3;
|
||||
|
||||
QBitArray _array;
|
||||
};
|
||||
|
||||
/// Contains information about a metavoxel (explicit or procedural).
|
||||
class MetavoxelInfo {
|
||||
public:
|
||||
|
@ -220,12 +195,16 @@ private:
|
|||
class MetavoxelVisitation {
|
||||
public:
|
||||
|
||||
MetavoxelData* data;
|
||||
MetavoxelVisitation* previous;
|
||||
MetavoxelVisitor& visitor;
|
||||
QVector<MetavoxelNode*> inputNodes;
|
||||
QVector<MetavoxelNode*> outputNodes;
|
||||
MetavoxelInfo info;
|
||||
int childIndex;
|
||||
|
||||
bool allInputNodesLeaves() const;
|
||||
MetavoxelNode* createOutputNode(int index);
|
||||
};
|
||||
|
||||
#endif /* defined(__interface__MetavoxelData__) */
|
||||
|
|
Loading…
Reference in a new issue