mirror of
https://github.com/overte-org/overte.git
synced 2025-05-04 19:39:28 +02:00
156 lines
6.4 KiB
C++
156 lines
6.4 KiB
C++
//
|
|
// LocalVoxels.cpp
|
|
// libraries/script-engine/src
|
|
//
|
|
// Created by Clément Brisset on 2/24/14.
|
|
// Copyright 2014 High Fidelity, Inc.
|
|
//
|
|
// Distributed under the Apache License, Version 2.0.
|
|
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
|
//
|
|
|
|
#include "LocalVoxels.h"
|
|
|
|
LocalVoxels::LocalVoxels(QString name) :
|
|
QObject(NULL),
|
|
_name(name),
|
|
_tree(new VoxelTree(true))
|
|
{
|
|
LocalVoxelsList::getInstance()->insert(_name, _tree);
|
|
}
|
|
|
|
LocalVoxels::~LocalVoxels() {
|
|
_tree.clear();
|
|
LocalVoxelsList::getInstance()->remove(_name);
|
|
}
|
|
|
|
VoxelDetail LocalVoxels::getVoxelAt(float x, float y, float z, float scale) {
|
|
// setup a VoxelDetail struct with the data
|
|
VoxelDetail result = {0,0,0,0,0,0,0};
|
|
if (_tree) {
|
|
_tree->lockForRead();
|
|
|
|
VoxelTreeElement* voxel = static_cast<VoxelTreeElement*>(_tree->getOctreeElementAt(x / (float)TREE_SCALE,
|
|
y / (float)TREE_SCALE,
|
|
z / (float)TREE_SCALE,
|
|
scale / (float)TREE_SCALE));
|
|
_tree->unlock();
|
|
if (voxel) {
|
|
// Note: these need to be in voxel space because the VoxelDetail -> js converter will upscale
|
|
result.x = voxel->getCorner().x;
|
|
result.y = voxel->getCorner().y;
|
|
result.z = voxel->getCorner().z;
|
|
result.s = voxel->getScale();
|
|
result.red = voxel->getColor()[RED_INDEX];
|
|
result.green = voxel->getColor()[GREEN_INDEX];
|
|
result.blue = voxel->getColor()[BLUE_INDEX];
|
|
}
|
|
}
|
|
return result;
|
|
}
|
|
|
|
void LocalVoxels::setVoxelNonDestructive(float x, float y, float z, float scale,
|
|
uchar red, uchar green, uchar blue) {
|
|
if (_name == DOMAIN_TREE_NAME) {
|
|
qDebug() << "LocalVoxels::setVoxelNonDestructive(): Please use the \"Voxels\" interface to modify the domain tree.";
|
|
return;
|
|
}
|
|
if (_tree ) {
|
|
_tree->createVoxel(x / (float)TREE_SCALE,
|
|
y / (float)TREE_SCALE,
|
|
z / (float)TREE_SCALE,
|
|
scale / (float)TREE_SCALE,
|
|
red, green, blue, false);
|
|
}
|
|
}
|
|
|
|
void LocalVoxels::setVoxel(float x, float y, float z, float scale,
|
|
uchar red, uchar green, uchar blue) {
|
|
if (_name == DOMAIN_TREE_NAME) {
|
|
qDebug() << "LocalVoxels::setVoxel(): Please use the \"Voxels\" interface to modify the domain tree.";
|
|
return;
|
|
}
|
|
if (_tree ) {
|
|
_tree->createVoxel(x / (float)TREE_SCALE,
|
|
y / (float)TREE_SCALE,
|
|
z / (float)TREE_SCALE,
|
|
scale / (float)TREE_SCALE,
|
|
red, green, blue, true);
|
|
}
|
|
}
|
|
|
|
void LocalVoxels::eraseVoxel(float x, float y, float z, float scale) {
|
|
if (_name == DOMAIN_TREE_NAME) {
|
|
qDebug() << "LocalVoxels::eraseVoxel(): Please use the \"Voxels\" interface to modify the domain tree.";
|
|
return;
|
|
}
|
|
if (_tree ) {
|
|
_tree->deleteVoxelAt(x / (float)TREE_SCALE,
|
|
y / (float)TREE_SCALE,
|
|
z / (float)TREE_SCALE,
|
|
scale / (float)TREE_SCALE);
|
|
}
|
|
}
|
|
|
|
void LocalVoxels::copyTo(float x, float y, float z, float scale, const QString destination) {
|
|
if (destination == DOMAIN_TREE_NAME) {
|
|
qDebug() << "LocalVoxels::copyTo(): Please use the \"Voxels\" interface to modify the domain tree.";
|
|
return;
|
|
}
|
|
StrongVoxelTreePointer destinationTree = LocalVoxelsList::getInstance()->getTree(destination);
|
|
VoxelTreeElement* destinationNode = destinationTree->getVoxelAt(x / (float)TREE_SCALE,
|
|
y / (float)TREE_SCALE,
|
|
z / (float)TREE_SCALE,
|
|
scale / (float)TREE_SCALE);
|
|
destinationTree->copyFromTreeIntoSubTree(_tree.data(), destinationNode);
|
|
}
|
|
|
|
void LocalVoxels::pasteFrom(float x, float y, float z, float scale, const QString source) {
|
|
if (_name == DOMAIN_TREE_NAME) {
|
|
qDebug() << "LocalVoxels::pasteFrom(): Please use the \"Voxels\" interface to modify the domain tree.";
|
|
return;
|
|
}
|
|
StrongVoxelTreePointer sourceTree = LocalVoxelsList::getInstance()->getTree(source);
|
|
VoxelTreeElement* sourceNode = _tree->getVoxelAt(x / (float)TREE_SCALE,
|
|
y / (float)TREE_SCALE,
|
|
z / (float)TREE_SCALE,
|
|
scale / (float)TREE_SCALE);
|
|
_tree->copySubTreeIntoNewTree(sourceNode, sourceTree.data(), true);
|
|
}
|
|
|
|
RayToVoxelIntersectionResult LocalVoxels::findRayIntersection(const PickRay& ray) {
|
|
RayToVoxelIntersectionResult result;
|
|
if (_tree) {
|
|
OctreeElement* element;
|
|
result.intersects = _tree->findRayIntersection(ray.origin, ray.direction, element, result.distance, result.face);
|
|
if (result.intersects) {
|
|
VoxelTreeElement* voxel = (VoxelTreeElement*)element;
|
|
result.voxel.x = voxel->getCorner().x;
|
|
result.voxel.y = voxel->getCorner().y;
|
|
result.voxel.z = voxel->getCorner().z;
|
|
result.voxel.s = voxel->getScale();
|
|
result.voxel.red = voxel->getColor()[0];
|
|
result.voxel.green = voxel->getColor()[1];
|
|
result.voxel.blue = voxel->getColor()[2];
|
|
result.intersection = ray.origin + (ray.direction * result.distance);
|
|
}
|
|
}
|
|
return result;
|
|
}
|
|
|
|
glm::vec3 LocalVoxels::getFaceVector(const QString& face) {
|
|
if (face == "MIN_X_FACE") {
|
|
return glm::vec3(-1, 0, 0);
|
|
} else if (face == "MAX_X_FACE") {
|
|
return glm::vec3(1, 0, 0);
|
|
} else if (face == "MIN_Y_FACE") {
|
|
return glm::vec3(0, -1, 0);
|
|
} else if (face == "MAX_Y_FACE") {
|
|
return glm::vec3(0, 1, 0);
|
|
} else if (face == "MIN_Z_FACE") {
|
|
return glm::vec3(0, 0, -1);
|
|
} else if (face == "MAX_Z_FACE") {
|
|
return glm::vec3(0, 0, 1);
|
|
}
|
|
return glm::vec3(0, 0, 0); //error case
|
|
}
|