mirror of
https://github.com/lubosz/overte.git
synced 2025-04-23 20:54:25 +02:00
Merge pull request #2158 from ZappoMan/cruft_removal
Cruft removal, Bug fixes, and Audio.startDrumSound() in JS
This commit is contained in:
commit
a2a90aa547
35 changed files with 487 additions and 1676 deletions
|
@ -19,7 +19,6 @@
|
|||
#include <OctalCode.h>
|
||||
#include <PacketHeaders.h>
|
||||
#include <JurisdictionListener.h>
|
||||
#include <SceneUtils.h>
|
||||
#include <SharedUtil.h>
|
||||
#include <VoxelEditPacketSender.h>
|
||||
#include <VoxelTree.h>
|
||||
|
|
|
@ -1277,12 +1277,55 @@ function touchEndEvent(event) {
|
|||
}
|
||||
}
|
||||
|
||||
var lastFingerAddVoxel = { x: -1, y: -1, z: -1}; // off of the build-able area
|
||||
var lastFingerDeleteVoxel = { x: -1, y: -1, z: -1}; // off of the build-able area
|
||||
|
||||
function checkControllers() {
|
||||
var controllersPerPalm = 2; // palm and finger
|
||||
for (var palm = 0; palm < 2; palm++) {
|
||||
var palmController = palm * controllersPerPalm;
|
||||
var fingerTipController = palmController + 1;
|
||||
var fingerTipPosition = Controller.getSpatialControlPosition(fingerTipController);
|
||||
|
||||
var BUTTON_COUNT = 6;
|
||||
var BUTTON_BASE = palm * BUTTON_COUNT;
|
||||
var BUTTON_1 = BUTTON_BASE + 1;
|
||||
var BUTTON_2 = BUTTON_BASE + 2;
|
||||
var FINGERTIP_VOXEL_SIZE = 0.05;
|
||||
|
||||
if (Controller.isButtonPressed(BUTTON_1)) {
|
||||
if (Vec3.length(Vec3.subtract(fingerTipPosition,lastFingerAddVoxel)) > (FINGERTIP_VOXEL_SIZE / 2)) {
|
||||
if (whichColor == -1) {
|
||||
newColor = { red: colors[0].red, green: colors[0].green, blue: colors[0].blue };
|
||||
} else {
|
||||
newColor = { red: colors[whichColor].red, green: colors[whichColor].green, blue: colors[whichColor].blue };
|
||||
}
|
||||
|
||||
Voxels.eraseVoxel(fingerTipPosition.x, fingerTipPosition.y, fingerTipPosition.z, FINGERTIP_VOXEL_SIZE);
|
||||
Voxels.setVoxel(fingerTipPosition.x, fingerTipPosition.y, fingerTipPosition.z, FINGERTIP_VOXEL_SIZE,
|
||||
newColor.red, newColor.green, newColor.blue);
|
||||
|
||||
lastFingerAddVoxel = fingerTipPosition;
|
||||
}
|
||||
} else if (Controller.isButtonPressed(BUTTON_2)) {
|
||||
if (Vec3.length(Vec3.subtract(fingerTipPosition,lastFingerDeleteVoxel)) > (FINGERTIP_VOXEL_SIZE / 2)) {
|
||||
Voxels.eraseVoxel(fingerTipPosition.x, fingerTipPosition.y, fingerTipPosition.z, FINGERTIP_VOXEL_SIZE);
|
||||
lastFingerDeleteVoxel = fingerTipPosition;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function update() {
|
||||
var newWindowDimensions = Controller.getViewportDimensions();
|
||||
if (newWindowDimensions.x != windowDimensions.x || newWindowDimensions.y != windowDimensions.y) {
|
||||
windowDimensions = newWindowDimensions;
|
||||
moveTools();
|
||||
}
|
||||
|
||||
if (editToolsOn) {
|
||||
checkControllers();
|
||||
}
|
||||
}
|
||||
|
||||
function wheelEvent(event) {
|
||||
|
|
167
examples/voxelDrumming.js
Normal file
167
examples/voxelDrumming.js
Normal file
|
@ -0,0 +1,167 @@
|
|||
//
|
||||
// voxelDrumming.js
|
||||
// hifi
|
||||
//
|
||||
// Created by Brad Hefta-Gaub on 2/14/14.
|
||||
// Copyright (c) 2014 HighFidelity, Inc. All rights reserved.
|
||||
//
|
||||
// This is an example script that demonstrates use of the Overlays, Controller, and Audio classes
|
||||
//
|
||||
// It adds Hydra controller "fingertip on voxels" drumming
|
||||
//
|
||||
|
||||
Menu.addMenuItem({
|
||||
menuName: "Developer > Hand Options",
|
||||
menuItemName: "Voxel Drumming",
|
||||
isCheckable: true,
|
||||
isChecked: false
|
||||
});
|
||||
|
||||
var collisionCenter = new Array();
|
||||
collisionCenter[0] = { x: 0, y: 0, z: 0};
|
||||
collisionCenter[1] = { x: 0, y: 0, z: 0};
|
||||
|
||||
var collisionAge = new Array();
|
||||
collisionAge[0] = 0;
|
||||
collisionAge[1] = 0;
|
||||
|
||||
var collisionDuration = new Array();
|
||||
collisionDuration[0] = 0;
|
||||
collisionDuration[1] = 0;
|
||||
|
||||
var isColliding = new Array();
|
||||
isColliding[0] = false;
|
||||
isColliding[1] = false;
|
||||
|
||||
var highlightVoxel = Overlays.addOverlay("cube",
|
||||
{
|
||||
position: { x: 0, y: 0, z: 0},
|
||||
size: 0,
|
||||
color: { red: 0, green: 0, blue: 0 },
|
||||
visible: false,
|
||||
lineWidth: 3,
|
||||
solid: false
|
||||
});
|
||||
|
||||
var collisionBubble = new Array();
|
||||
collisionBubble[0] = Overlays.addOverlay("sphere",
|
||||
{
|
||||
position: { x: 0, y: 0, z: 0},
|
||||
size: 0,
|
||||
color: { red: 0, green: 0, blue: 0 },
|
||||
alpha: 0.5,
|
||||
visible: false
|
||||
});
|
||||
collisionBubble[1] = Overlays.addOverlay("sphere",
|
||||
{
|
||||
position: { x: 0, y: 0, z: 0},
|
||||
size: 0,
|
||||
color: { red: 0, green: 0, blue: 0 },
|
||||
alpha: 0.5,
|
||||
visible: false
|
||||
});
|
||||
|
||||
var audioOptions = new AudioInjectionOptions();
|
||||
audioOptions.position = { x: MyAvatar.position.x, y: MyAvatar.position.y + 1, z: MyAvatar.position.z };
|
||||
audioOptions.volume = 1;
|
||||
|
||||
|
||||
function clamp(valueToClamp, minValue, maxValue) {
|
||||
return Math.max(minValue, Math.min(maxValue, valueToClamp));
|
||||
}
|
||||
|
||||
function produceCollisionSound(palm, voxelDetail) {
|
||||
// Collision between finger and a voxel plays sound
|
||||
|
||||
var palmVelocity = Controller.getSpatialControlVelocity(palm * 2);
|
||||
var speed = Vec3.length(palmVelocity);
|
||||
var fingerTipPosition = Controller.getSpatialControlPosition(palm * 2 + 1);
|
||||
|
||||
var deltaTime = 1/60; //close enough
|
||||
var LOWEST_FREQUENCY = 100.0;
|
||||
var HERTZ_PER_RGB = 3.0;
|
||||
var DECAY_PER_SAMPLE = 0.0005;
|
||||
var DURATION_MAX = 2.0;
|
||||
var MIN_VOLUME = 0.1;
|
||||
var volume = MIN_VOLUME + clamp(speed, 0.0, (1.0 - MIN_VOLUME));
|
||||
var duration = volume;
|
||||
|
||||
collisionCenter[palm] = fingerTipPosition;
|
||||
collisionAge[palm] = deltaTime;
|
||||
collisionDuration[palm] = duration;
|
||||
|
||||
var voxelBrightness = voxelDetail.red + voxelDetail.green + voxelDetail.blue;
|
||||
var frequency = LOWEST_FREQUENCY + (voxelBrightness * HERTZ_PER_RGB);
|
||||
|
||||
audioOptions.position = fingerTipPosition;
|
||||
Audio.startDrumSound(volume, frequency, DURATION_MAX, DECAY_PER_SAMPLE, audioOptions);
|
||||
}
|
||||
|
||||
function update() {
|
||||
var deltaTime = 1/60; //close enough
|
||||
|
||||
// Voxel Drumming with fingertips if enabled
|
||||
if (Menu.isOptionChecked("Voxel Drumming")) {
|
||||
|
||||
for (var palm = 0; palm < 2; palm++) {
|
||||
var fingerTipPosition = Controller.getSpatialControlPosition(palm * 2 + 1);
|
||||
|
||||
var voxel = Voxels.getVoxelEnclosingPoint(fingerTipPosition);
|
||||
if (voxel.s > 0) {
|
||||
if (!isColliding[palm]) {
|
||||
// Collision has just started
|
||||
isColliding[palm] = true;
|
||||
produceCollisionSound(palm, voxel);
|
||||
|
||||
// Set highlight voxel
|
||||
Overlays.editOverlay(highlightVoxel,
|
||||
{
|
||||
position: { x: voxel.x, y: voxel.y, z: voxel.z},
|
||||
size: voxel.s + 0.002,
|
||||
color: { red: voxel.red + 128, green: voxel.green + 128, blue: voxel.blue + 128 },
|
||||
visible: true
|
||||
});
|
||||
}
|
||||
} else {
|
||||
if (isColliding[palm]) {
|
||||
// Collision has just ended
|
||||
isColliding[palm] = false;
|
||||
Overlays.editOverlay(highlightVoxel, { visible: false });
|
||||
}
|
||||
}
|
||||
|
||||
if (collisionAge[palm] > 0) {
|
||||
collisionAge[palm] += deltaTime;
|
||||
}
|
||||
|
||||
// If hand/voxel collision has happened, render a little expanding sphere
|
||||
if (collisionAge[palm] > 0) {
|
||||
var opacity = clamp(1 - (collisionAge[palm] / collisionDuration[palm]), 0, 1);
|
||||
var size = collisionAge[palm] * 0.25;
|
||||
|
||||
Overlays.editOverlay(collisionBubble[palm],
|
||||
{
|
||||
position: { x: collisionCenter[palm].x, y: collisionCenter[palm].y, z: collisionCenter[palm].z},
|
||||
size: size,
|
||||
color: { red: 255, green: 0, blue: 0 },
|
||||
alpha: 0.5 * opacity,
|
||||
visible: true
|
||||
});
|
||||
|
||||
if (collisionAge[palm] > collisionDuration[palm]) {
|
||||
collisionAge[palm] = 0;
|
||||
Overlays.editOverlay(collisionBubble[palm], { visible: false });
|
||||
}
|
||||
}
|
||||
} // palm loop
|
||||
} // menu item check
|
||||
}
|
||||
Script.willSendVisualDataCallback.connect(update);
|
||||
|
||||
function scriptEnding() {
|
||||
Overlays.deleteOverlay(highlightVoxel);
|
||||
Overlays.deleteOverlay(collisionBubble[0]);
|
||||
Overlays.deleteOverlay(collisionBubble[1]);
|
||||
Menu.removeMenuItem("Developer > Hand Options","Voxel Drumming");
|
||||
}
|
||||
Script.scriptEnding.connect(scriptEnding);
|
|
@ -139,8 +139,6 @@ Application::Application(int& argc, char** argv, timeval &startup_time) :
|
|||
_touchAvgY(0.0f),
|
||||
_isTouchPressed(false),
|
||||
_mousePressed(false),
|
||||
_isHoverVoxel(false),
|
||||
_isHighlightVoxel(false),
|
||||
_chatEntryOn(false),
|
||||
_audio(&_audioScope, STARTUP_JITTER_SAMPLES),
|
||||
_enableProcessVoxelsThread(true),
|
||||
|
@ -742,9 +740,7 @@ void Application::keyPressEvent(QKeyEvent* event) {
|
|||
break;
|
||||
|
||||
case Qt::Key_S:
|
||||
if (isShifted && !isMeta) {
|
||||
_voxels.collectStatsForTreesAndVBOs();
|
||||
} else if (isShifted && isMeta) {
|
||||
if (isShifted && isMeta) {
|
||||
Menu::getInstance()->triggerOption(MenuOption::SuppressShortTimings);
|
||||
} else if (!isShifted && isMeta) {
|
||||
takeSnapshot();
|
||||
|
@ -1031,11 +1027,6 @@ void Application::mousePressEvent(QMouseEvent* event) {
|
|||
return;
|
||||
}
|
||||
|
||||
if (!_isHoverVoxel || _myAvatar->getLookAtTargetAvatar()) {
|
||||
// disable for now
|
||||
// _pieMenu.mousePressEvent(_mouseX, _mouseY);
|
||||
}
|
||||
|
||||
} else if (event->button() == Qt::RightButton) {
|
||||
// right click items here
|
||||
}
|
||||
|
@ -1290,7 +1281,7 @@ void Application::removeVoxel(glm::vec3 position,
|
|||
_voxelEditSender.sendVoxelEditMessage(PacketTypeVoxelErase, voxel);
|
||||
|
||||
// delete it locally to see the effect immediately (and in case no voxel server is present)
|
||||
_voxels.deleteVoxelAt(voxel.x, voxel.y, voxel.z, voxel.s);
|
||||
_voxels.getTree()->deleteVoxelAt(voxel.x, voxel.y, voxel.z, voxel.s);
|
||||
}
|
||||
|
||||
|
||||
|
@ -1312,8 +1303,7 @@ void Application::makeVoxel(glm::vec3 position,
|
|||
_voxelEditSender.sendVoxelEditMessage(message, voxel);
|
||||
|
||||
// create the voxel locally so it appears immediately
|
||||
|
||||
_voxels.createVoxel(voxel.x, voxel.y, voxel.z, voxel.s,
|
||||
_voxels.getTree()->createVoxel(voxel.x, voxel.y, voxel.z, voxel.s,
|
||||
voxel.red, voxel.green, voxel.blue,
|
||||
isDestructive);
|
||||
}
|
||||
|
@ -1372,10 +1362,11 @@ void Application::exportVoxels(const VoxelDetail& sourceVoxel) {
|
|||
tr("Sparse Voxel Octree Files (*.svo)"));
|
||||
QByteArray fileNameAscii = fileNameString.toLocal8Bit();
|
||||
const char* fileName = fileNameAscii.data();
|
||||
VoxelTreeElement* selectedNode = _voxels.getVoxelAt(sourceVoxel.x, sourceVoxel.y, sourceVoxel.z, sourceVoxel.s);
|
||||
|
||||
VoxelTreeElement* selectedNode = _voxels.getTree()->getVoxelAt(sourceVoxel.x, sourceVoxel.y, sourceVoxel.z, sourceVoxel.s);
|
||||
if (selectedNode) {
|
||||
VoxelTree exportTree;
|
||||
_voxels.copySubTreeIntoNewTree(selectedNode, &exportTree, true);
|
||||
getVoxelTree()->copySubTreeIntoNewTree(selectedNode, &exportTree, true);
|
||||
exportTree.writeToSVOFile(fileName);
|
||||
}
|
||||
|
||||
|
@ -1417,9 +1408,10 @@ void Application::copyVoxels(const VoxelDetail& sourceVoxel) {
|
|||
}
|
||||
|
||||
// then copy onto it if there is something to copy
|
||||
VoxelTreeElement* selectedNode = _voxels.getVoxelAt(sourceVoxel.x, sourceVoxel.y, sourceVoxel.z, sourceVoxel.s);
|
||||
VoxelTreeElement* selectedNode = _voxels.getTree()->getVoxelAt(sourceVoxel.x, sourceVoxel.y, sourceVoxel.z, sourceVoxel.s);
|
||||
if (selectedNode) {
|
||||
_voxels.copySubTreeIntoNewTree(selectedNode, &_sharedVoxelSystem, true);
|
||||
getVoxelTree()->copySubTreeIntoNewTree(selectedNode, _sharedVoxelSystem.getTree(), true);
|
||||
_sharedVoxelSystem.forceRedrawEntireTree();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1440,7 +1432,7 @@ void Application::pasteVoxelsToOctalCode(const unsigned char* octalCodeDestinati
|
|||
|
||||
void Application::pasteVoxels(const VoxelDetail& sourceVoxel) {
|
||||
unsigned char* calculatedOctCode = NULL;
|
||||
VoxelTreeElement* selectedNode = _voxels.getVoxelAt(sourceVoxel.x, sourceVoxel.y, sourceVoxel.z, sourceVoxel.s);
|
||||
VoxelTreeElement* selectedNode = _voxels.getTree()->getVoxelAt(sourceVoxel.x, sourceVoxel.y, sourceVoxel.z, sourceVoxel.s);
|
||||
|
||||
// we only need the selected voxel to get the newBaseOctCode, which we can actually calculate from the
|
||||
// voxel size/position details. If we don't have an actual selectedNode then use the mouseVoxel to create a
|
||||
|
@ -1460,7 +1452,7 @@ void Application::pasteVoxels(const VoxelDetail& sourceVoxel) {
|
|||
}
|
||||
|
||||
void Application::nudgeVoxelsByVector(const VoxelDetail& sourceVoxel, const glm::vec3& nudgeVec) {
|
||||
VoxelTreeElement* nodeToNudge = _voxels.getVoxelAt(sourceVoxel.x, sourceVoxel.y, sourceVoxel.z, sourceVoxel.s);
|
||||
VoxelTreeElement* nodeToNudge = _voxels.getTree()->getVoxelAt(sourceVoxel.x, sourceVoxel.y, sourceVoxel.z, sourceVoxel.s);
|
||||
if (nodeToNudge) {
|
||||
_voxels.getTree()->nudgeSubTree(nodeToNudge, nudgeVec, _voxelEditSender);
|
||||
}
|
||||
|
@ -1618,20 +1610,6 @@ bool Application::isLookingAtMyAvatar(Avatar* avatar) {
|
|||
return false;
|
||||
}
|
||||
|
||||
void Application::renderHighlightVoxel(VoxelDetail voxel) {
|
||||
glDisable(GL_LIGHTING);
|
||||
glPushMatrix();
|
||||
glScalef(TREE_SCALE, TREE_SCALE, TREE_SCALE);
|
||||
const float EDGE_EXPAND = 1.02f;
|
||||
glColor3ub(voxel.red + 128, voxel.green + 128, voxel.blue + 128);
|
||||
glTranslatef(voxel.x + voxel.s * 0.5f,
|
||||
voxel.y + voxel.s * 0.5f,
|
||||
voxel.z + voxel.s * 0.5f);
|
||||
glLineWidth(2.0f);
|
||||
glutWireCube(voxel.s * EDGE_EXPAND);
|
||||
glPopMatrix();
|
||||
}
|
||||
|
||||
void Application::updateMouseRay() {
|
||||
|
||||
bool showWarnings = Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings);
|
||||
|
@ -1702,9 +1680,6 @@ void Application::updateMyAvatarLookAtPosition() {
|
|||
if (_myAvatar->getLookAtTargetAvatar()) {
|
||||
distance = glm::distance(_mouseRayOrigin,
|
||||
static_cast<Avatar*>(_myAvatar->getLookAtTargetAvatar())->getHead()->calculateAverageEyePosition());
|
||||
|
||||
} else if (_isHoverVoxel) {
|
||||
distance = glm::distance(_mouseRayOrigin, getMouseVoxelWorldCoordinates(_hoverVoxel));
|
||||
}
|
||||
const float FIXED_MIN_EYE_DISTANCE = 0.3f;
|
||||
float minEyeDistance = FIXED_MIN_EYE_DISTANCE + (_myCamera.getMode() == CAMERA_MODE_FIRST_PERSON ? 0.0f :
|
||||
|
@ -1735,17 +1710,6 @@ void Application::updateMyAvatarLookAtPosition() {
|
|||
_myAvatar->getHead()->setLookAtPosition(lookAtSpot);
|
||||
}
|
||||
|
||||
void Application::updateHoverVoxels(float deltaTime, float& distance, BoxFace& face) {
|
||||
|
||||
bool showWarnings = Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings);
|
||||
PerformanceWarning warn(showWarnings, "Application::updateHoverVoxels()");
|
||||
|
||||
if (!_mousePressed) {
|
||||
PerformanceWarning warn(showWarnings, "Application::updateHoverVoxels() _voxels.findRayIntersection()");
|
||||
_isHoverVoxel = _voxels.findRayIntersection(_mouseRayOrigin, _mouseRayDirection, _hoverVoxel, distance, face);
|
||||
}
|
||||
}
|
||||
|
||||
void Application::updateHandAndTouch(float deltaTime) {
|
||||
bool showWarnings = Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings);
|
||||
PerformanceWarning warn(showWarnings, "Application::updateHandAndTouch()");
|
||||
|
@ -1894,11 +1858,6 @@ void Application::update(float deltaTime) {
|
|||
_myAvatar->updateLookAtTargetAvatar();
|
||||
updateMyAvatarLookAtPosition();
|
||||
|
||||
// Find the voxel we are hovering over, and respond if clicked
|
||||
float distance;
|
||||
BoxFace face;
|
||||
|
||||
updateHoverVoxels(deltaTime, distance, face); // clicking on voxels and making sounds
|
||||
updateHandAndTouch(deltaTime); // Update state for touch sensors
|
||||
updateLeap(deltaTime); // Leap finger-sensing device
|
||||
updateSixense(deltaTime); // Razer Hydra controllers
|
||||
|
@ -2403,11 +2362,6 @@ void Application::displaySide(Camera& whichCamera, bool selfAvatarOnly) {
|
|||
|
||||
// restore default, white specular
|
||||
glMaterialfv(GL_FRONT, GL_SPECULAR, WHITE_SPECULAR_COLOR);
|
||||
|
||||
// Render the highlighted voxel
|
||||
if (_isHighlightVoxel) {
|
||||
renderHighlightVoxel(_highlightVoxel);
|
||||
}
|
||||
}
|
||||
|
||||
bool forceRenderMyHead = (whichCamera.getInterpolatedMode() == CAMERA_MODE_MIRROR);
|
||||
|
@ -2518,15 +2472,6 @@ void Application::displayOverlay() {
|
|||
}
|
||||
}
|
||||
|
||||
// testing rendering coverage map
|
||||
if (Menu::getInstance()->isOptionChecked(MenuOption::CoverageMapV2)) {
|
||||
renderCoverageMapV2();
|
||||
}
|
||||
|
||||
if (Menu::getInstance()->isOptionChecked(MenuOption::CoverageMap)) {
|
||||
renderCoverageMap();
|
||||
}
|
||||
|
||||
// Show chat entry field
|
||||
if (_chatEntryOn) {
|
||||
_chatEntry.render(_glWidget->width(), _glWidget->height());
|
||||
|
@ -2968,115 +2913,6 @@ glm::vec2 Application::getScaledScreenPoint(glm::vec2 projectedPoint) {
|
|||
return screenPoint;
|
||||
}
|
||||
|
||||
// render the coverage map on screen
|
||||
void Application::renderCoverageMapV2() {
|
||||
glDisable(GL_LIGHTING);
|
||||
glLineWidth(2.0);
|
||||
glBegin(GL_LINES);
|
||||
glColor3f(0,1,1);
|
||||
|
||||
renderCoverageMapsV2Recursively(&_voxels.myCoverageMapV2);
|
||||
|
||||
glEnd();
|
||||
glEnable(GL_LIGHTING);
|
||||
}
|
||||
|
||||
void Application::renderCoverageMapsV2Recursively(CoverageMapV2* map) {
|
||||
// render ourselves...
|
||||
if (map->isCovered()) {
|
||||
BoundingBox box = map->getBoundingBox();
|
||||
|
||||
glm::vec2 firstPoint = getScaledScreenPoint(box.getVertex(0));
|
||||
glm::vec2 lastPoint(firstPoint);
|
||||
|
||||
for (int i = 1; i < box.getVertexCount(); i++) {
|
||||
glm::vec2 thisPoint = getScaledScreenPoint(box.getVertex(i));
|
||||
|
||||
glVertex2f(lastPoint.x, lastPoint.y);
|
||||
glVertex2f(thisPoint.x, thisPoint.y);
|
||||
lastPoint = thisPoint;
|
||||
}
|
||||
|
||||
glVertex2f(lastPoint.x, lastPoint.y);
|
||||
glVertex2f(firstPoint.x, firstPoint.y);
|
||||
} else {
|
||||
// iterate our children and call render on them.
|
||||
for (int i = 0; i < CoverageMapV2::NUMBER_OF_CHILDREN; i++) {
|
||||
CoverageMapV2* childMap = map->getChild(i);
|
||||
if (childMap) {
|
||||
renderCoverageMapsV2Recursively(childMap);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// render the coverage map on screen
|
||||
void Application::renderCoverageMap() {
|
||||
|
||||
glDisable(GL_LIGHTING);
|
||||
glLineWidth(2.0);
|
||||
glBegin(GL_LINES);
|
||||
glColor3f(0,0,1);
|
||||
|
||||
renderCoverageMapsRecursively(&_voxels.myCoverageMap);
|
||||
|
||||
glEnd();
|
||||
glEnable(GL_LIGHTING);
|
||||
}
|
||||
|
||||
void Application::renderCoverageMapsRecursively(CoverageMap* map) {
|
||||
for (int i = 0; i < map->getPolygonCount(); i++) {
|
||||
|
||||
OctreeProjectedPolygon* polygon = map->getPolygon(i);
|
||||
|
||||
if (polygon->getProjectionType() == (PROJECTION_RIGHT | PROJECTION_NEAR | PROJECTION_BOTTOM)) {
|
||||
glColor3f(.5,0,0); // dark red
|
||||
} else if (polygon->getProjectionType() == (PROJECTION_NEAR | PROJECTION_RIGHT)) {
|
||||
glColor3f(.5,.5,0); // dark yellow
|
||||
} else if (polygon->getProjectionType() == (PROJECTION_NEAR | PROJECTION_LEFT)) {
|
||||
glColor3f(.5,.5,.5); // gray
|
||||
} else if (polygon->getProjectionType() == (PROJECTION_NEAR | PROJECTION_LEFT | PROJECTION_BOTTOM)) {
|
||||
glColor3f(.5,0,.5); // dark magenta
|
||||
} else if (polygon->getProjectionType() == (PROJECTION_NEAR | PROJECTION_BOTTOM)) {
|
||||
glColor3f(.75,0,0); // red
|
||||
} else if (polygon->getProjectionType() == (PROJECTION_NEAR | PROJECTION_TOP)) {
|
||||
glColor3f(1,0,1); // magenta
|
||||
} else if (polygon->getProjectionType() == (PROJECTION_NEAR | PROJECTION_LEFT | PROJECTION_TOP)) {
|
||||
glColor3f(0,0,1); // Blue
|
||||
} else if (polygon->getProjectionType() == (PROJECTION_NEAR | PROJECTION_RIGHT | PROJECTION_TOP)) {
|
||||
glColor3f(0,1,0); // green
|
||||
} else if (polygon->getProjectionType() == (PROJECTION_NEAR)) {
|
||||
glColor3f(1,1,0); // yellow
|
||||
} else if (polygon->getProjectionType() == (PROJECTION_FAR | PROJECTION_RIGHT | PROJECTION_BOTTOM)) {
|
||||
glColor3f(0,.5,.5); // dark cyan
|
||||
} else {
|
||||
glColor3f(1,0,0);
|
||||
}
|
||||
|
||||
glm::vec2 firstPoint = getScaledScreenPoint(polygon->getVertex(0));
|
||||
glm::vec2 lastPoint(firstPoint);
|
||||
|
||||
for (int i = 1; i < polygon->getVertexCount(); i++) {
|
||||
glm::vec2 thisPoint = getScaledScreenPoint(polygon->getVertex(i));
|
||||
|
||||
glVertex2f(lastPoint.x, lastPoint.y);
|
||||
glVertex2f(thisPoint.x, thisPoint.y);
|
||||
lastPoint = thisPoint;
|
||||
}
|
||||
|
||||
glVertex2f(lastPoint.x, lastPoint.y);
|
||||
glVertex2f(firstPoint.x, firstPoint.y);
|
||||
}
|
||||
|
||||
// iterate our children and call render on them.
|
||||
for (int i = 0; i < CoverageMapV2::NUMBER_OF_CHILDREN; i++) {
|
||||
CoverageMap* childMap = map->getChild(i);
|
||||
if (childMap) {
|
||||
renderCoverageMapsRecursively(childMap);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Application::renderRearViewMirror(const QRect& region, bool billboard) {
|
||||
bool eyeRelativeCamera = false;
|
||||
if (billboard) {
|
||||
|
@ -3326,7 +3162,7 @@ void Application::deleteVoxelAt(const VoxelDetail& voxel) {
|
|||
_voxelEditSender.sendVoxelEditMessage(PacketTypeVoxelErase, voxel);
|
||||
|
||||
// delete it locally to see the effect immediately (and in case no voxel server is present)
|
||||
_voxels.deleteVoxelAt(voxel.x, voxel.y, voxel.z, voxel.s);
|
||||
_voxels.getTree()->deleteVoxelAt(voxel.x, voxel.y, voxel.z, voxel.s);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -34,12 +34,15 @@
|
|||
#include "BandwidthMeter.h"
|
||||
#include "BuckyBalls.h"
|
||||
#include "Camera.h"
|
||||
#include "ControllerScriptingInterface.h"
|
||||
#include "DatagramProcessor.h"
|
||||
#include "Environment.h"
|
||||
#include "FileLogger.h"
|
||||
#include "GLCanvas.h"
|
||||
#include "Menu.h"
|
||||
#include "MetavoxelSystem.h"
|
||||
#include "PacketHeaders.h"
|
||||
#include "ParticleTreeRenderer.h"
|
||||
#include "PieMenu.h"
|
||||
#include "Stars.h"
|
||||
#include "ViewFrustum.h"
|
||||
|
@ -68,9 +71,6 @@
|
|||
#include "ui/LodToolsDialog.h"
|
||||
#include "ui/LogDialog.h"
|
||||
#include "ui/UpdateDialog.h"
|
||||
#include "FileLogger.h"
|
||||
#include "ParticleTreeRenderer.h"
|
||||
#include "ControllerScriptingInterface.h"
|
||||
#include "ui/Overlays.h"
|
||||
|
||||
|
||||
|
@ -154,6 +154,7 @@ public:
|
|||
Camera* getCamera() { return &_myCamera; }
|
||||
ViewFrustum* getViewFrustum() { return &_viewFrustum; }
|
||||
VoxelSystem* getVoxels() { return &_voxels; }
|
||||
VoxelTree* getVoxelTree() { return _voxels.getTree(); }
|
||||
ParticleTreeRenderer* getParticles() { return &_particles; }
|
||||
MetavoxelSystem* getMetavoxels() { return &_metavoxels; }
|
||||
VoxelSystem* getSharedVoxelSystem() { return &_sharedVoxelSystem; }
|
||||
|
@ -214,10 +215,6 @@ public:
|
|||
NodeToJurisdictionMap& getParticleServerJurisdictions() { return _particleServerJurisdictions; }
|
||||
void pasteVoxelsToOctalCode(const unsigned char* octalCodeDestination);
|
||||
|
||||
/// set a voxel which is to be rendered with a highlight
|
||||
void setHighlightVoxel(const VoxelDetail& highlightVoxel) { _highlightVoxel = highlightVoxel; }
|
||||
void setIsHighlightVoxel(bool isHighlightVoxel) { _isHighlightVoxel = isHighlightVoxel; }
|
||||
|
||||
void skipVersion(QString latestVersion);
|
||||
|
||||
signals:
|
||||
|
@ -261,12 +258,6 @@ private slots:
|
|||
void setEnable3DTVMode(bool enable3DTVMode);
|
||||
void cameraMenuChanged();
|
||||
|
||||
void renderCoverageMap();
|
||||
void renderCoverageMapsRecursively(CoverageMap* map);
|
||||
|
||||
void renderCoverageMapV2();
|
||||
void renderCoverageMapsV2Recursively(CoverageMapV2* map);
|
||||
|
||||
glm::vec2 getScaledScreenPoint(glm::vec2 projectedPoint);
|
||||
|
||||
void closeMirrorView();
|
||||
|
@ -297,7 +288,6 @@ private:
|
|||
void updateFaceshift();
|
||||
void updateVisage();
|
||||
void updateMyAvatarLookAtPosition();
|
||||
void updateHoverVoxels(float deltaTime, float& distance, BoxFace& face);
|
||||
void updateHandAndTouch(float deltaTime);
|
||||
void updateLeap(float deltaTime);
|
||||
void updateSixense(float deltaTime);
|
||||
|
@ -313,7 +303,6 @@ private:
|
|||
bool isLookingAtMyAvatar(Avatar* avatar);
|
||||
|
||||
void renderLookatIndicator(glm::vec3 pointOfInterest);
|
||||
void renderHighlightVoxel(VoxelDetail voxel);
|
||||
|
||||
void updateMyAvatar(float deltaTime);
|
||||
void queryOctree(NodeType_t serverType, PacketType packetType, NodeToJurisdictionMap& jurisdictions);
|
||||
|
@ -434,12 +423,6 @@ private:
|
|||
|
||||
bool _mousePressed; // true if mouse has been pressed (clear when finished)
|
||||
|
||||
VoxelDetail _hoverVoxel; // Stuff about the voxel I am hovering or clicking
|
||||
bool _isHoverVoxel;
|
||||
|
||||
VoxelDetail _highlightVoxel;
|
||||
bool _isHighlightVoxel;
|
||||
|
||||
ChatEntry _chatEntry; // chat entry field
|
||||
bool _chatEntryOn; // Whether to show the chat entry
|
||||
|
||||
|
|
|
@ -272,7 +272,6 @@ Menu::Menu() :
|
|||
SLOT(setFilter(bool)));
|
||||
addCheckableActionToQMenuAndActionHash(handOptionsMenu, MenuOption::DisplayHands, 0, true);
|
||||
addCheckableActionToQMenuAndActionHash(handOptionsMenu, MenuOption::DisplayHandTargets, 0, false);
|
||||
addCheckableActionToQMenuAndActionHash(handOptionsMenu, MenuOption::VoxelDrumming, 0, false);
|
||||
addCheckableActionToQMenuAndActionHash(handOptionsMenu, MenuOption::PlaySlaps, 0, false);
|
||||
addCheckableActionToQMenuAndActionHash(handOptionsMenu, MenuOption::HandsCollideWithSelf, 0, false);
|
||||
|
||||
|
@ -282,11 +281,6 @@ Menu::Menu() :
|
|||
addCheckableActionToQMenuAndActionHash(timingMenu, MenuOption::TestPing, 0, true);
|
||||
addCheckableActionToQMenuAndActionHash(timingMenu, MenuOption::FrameTimer);
|
||||
addActionToQMenuAndActionHash(timingMenu, MenuOption::RunTimingTests, 0, this, SLOT(runTests()));
|
||||
addActionToQMenuAndActionHash(timingMenu,
|
||||
MenuOption::TreeStats,
|
||||
Qt::SHIFT | Qt::Key_S,
|
||||
appInstance->getVoxels(),
|
||||
SLOT(collectStatsForTreesAndVBOs()));
|
||||
|
||||
QMenu* frustumMenu = developerMenu->addMenu("View Frustum Debugging Tools");
|
||||
addCheckableActionToQMenuAndActionHash(frustumMenu, MenuOption::DisplayFrustum, Qt::SHIFT | Qt::Key_F);
|
||||
|
@ -302,62 +296,6 @@ Menu::Menu() :
|
|||
addCheckableActionToQMenuAndActionHash(renderDebugMenu, MenuOption::PipelineWarnings, Qt::CTRL | Qt::SHIFT | Qt::Key_P);
|
||||
addCheckableActionToQMenuAndActionHash(renderDebugMenu, MenuOption::SuppressShortTimings, Qt::CTRL | Qt::SHIFT | Qt::Key_S);
|
||||
|
||||
addCheckableActionToQMenuAndActionHash(renderDebugMenu, MenuOption::AutomaticallyAuditTree);
|
||||
|
||||
|
||||
addActionToQMenuAndActionHash(renderDebugMenu,
|
||||
MenuOption::ShowAllLocalVoxels,
|
||||
Qt::CTRL | Qt::Key_A,
|
||||
appInstance->getVoxels(),
|
||||
SLOT(showAllLocalVoxels()));
|
||||
|
||||
addActionToQMenuAndActionHash(renderDebugMenu,
|
||||
MenuOption::KillLocalVoxels,
|
||||
Qt::CTRL | Qt::Key_K,
|
||||
appInstance, SLOT(doKillLocalVoxels()));
|
||||
|
||||
addActionToQMenuAndActionHash(renderDebugMenu,
|
||||
MenuOption::RandomizeVoxelColors,
|
||||
Qt::CTRL | Qt::Key_R,
|
||||
appInstance->getVoxels(),
|
||||
SLOT(randomizeVoxelColors()));
|
||||
|
||||
addActionToQMenuAndActionHash(renderDebugMenu,
|
||||
MenuOption::FalseColorRandomly,
|
||||
0,
|
||||
appInstance->getVoxels(),
|
||||
SLOT(falseColorizeRandom()));
|
||||
|
||||
addActionToQMenuAndActionHash(renderDebugMenu,
|
||||
MenuOption::FalseColorEveryOtherVoxel,
|
||||
0,
|
||||
appInstance->getVoxels(),
|
||||
SLOT(falseColorizeRandomEveryOther()));
|
||||
|
||||
addActionToQMenuAndActionHash(renderDebugMenu,
|
||||
MenuOption::FalseColorByDistance,
|
||||
0,
|
||||
appInstance->getVoxels(),
|
||||
SLOT(falseColorizeDistanceFromView()));
|
||||
|
||||
addActionToQMenuAndActionHash(renderDebugMenu,
|
||||
MenuOption::FalseColorOutOfView,
|
||||
0,
|
||||
appInstance->getVoxels(),
|
||||
SLOT(falseColorizeInView()));
|
||||
|
||||
addActionToQMenuAndActionHash(renderDebugMenu,
|
||||
MenuOption::FalseColorBySource,
|
||||
0,
|
||||
appInstance->getVoxels(),
|
||||
SLOT(falseColorizeBySource()));
|
||||
|
||||
addActionToQMenuAndActionHash(renderDebugMenu,
|
||||
MenuOption::ShowTrueColors,
|
||||
Qt::CTRL | Qt::Key_T,
|
||||
appInstance->getVoxels(),
|
||||
SLOT(trueColorize()));
|
||||
|
||||
addCheckableActionToQMenuAndActionHash(renderDebugMenu,
|
||||
MenuOption::CullSharedFaces,
|
||||
Qt::CTRL | Qt::SHIFT | Qt::Key_C,
|
||||
|
@ -372,22 +310,6 @@ Menu::Menu() :
|
|||
appInstance->getVoxels(),
|
||||
SLOT(showCulledSharedFaces()));
|
||||
|
||||
addDisabledActionAndSeparator(renderDebugMenu, "Coverage Maps");
|
||||
addActionToQMenuAndActionHash(renderDebugMenu,
|
||||
MenuOption::FalseColorOccluded,
|
||||
0,
|
||||
appInstance->getVoxels(),
|
||||
SLOT(falseColorizeOccluded()));
|
||||
|
||||
addActionToQMenuAndActionHash(renderDebugMenu,
|
||||
MenuOption::FalseColorOccludedV2,
|
||||
0,
|
||||
appInstance->getVoxels(),
|
||||
SLOT(falseColorizeOccludedV2()));
|
||||
|
||||
addCheckableActionToQMenuAndActionHash(renderDebugMenu, MenuOption::CoverageMap, Qt::SHIFT | Qt::CTRL | Qt::Key_O);
|
||||
addCheckableActionToQMenuAndActionHash(renderDebugMenu, MenuOption::CoverageMapV2, Qt::SHIFT | Qt::CTRL | Qt::Key_P);
|
||||
|
||||
QMenu* audioDebugMenu = developerMenu->addMenu("Audio Debugging Tools");
|
||||
addCheckableActionToQMenuAndActionHash(audioDebugMenu, MenuOption::AudioNoiseReduction,
|
||||
0,
|
||||
|
@ -654,7 +576,11 @@ void Menu::setIsOptionChecked(const QString& menuOption, bool isChecked) {
|
|||
}
|
||||
|
||||
bool Menu::isOptionChecked(const QString& menuOption) {
|
||||
return _actionHash.value(menuOption)->isChecked();
|
||||
QAction* menu = _actionHash.value(menuOption);
|
||||
if (menu) {
|
||||
return menu->isChecked();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void Menu::triggerOption(const QString& menuOption) {
|
||||
|
|
|
@ -203,7 +203,6 @@ namespace MenuOption {
|
|||
const QString Avatars = "Avatars";
|
||||
const QString Atmosphere = "Atmosphere";
|
||||
const QString DisableAutoAdjustLOD = "Disable Automatically Adjusting LOD";
|
||||
const QString AutomaticallyAuditTree = "Automatically Audit Tree Stats";
|
||||
const QString Bandwidth = "Bandwidth Display";
|
||||
const QString BandwidthDetails = "Bandwidth Details";
|
||||
const QString BuckyBalls = "Bucky Balls";
|
||||
|
@ -213,8 +212,6 @@ namespace MenuOption {
|
|||
const QString CollideWithParticles = "Collide With Particles";
|
||||
const QString CollideWithVoxels = "Collide With Voxels";
|
||||
const QString CollideWithEnvironment = "Collide With World Boundaries";
|
||||
const QString CoverageMap = "Render Coverage Map";
|
||||
const QString CoverageMapV2 = "Render Coverage Map V2";
|
||||
const QString CullSharedFaces = "Cull Shared Voxel Faces";
|
||||
const QString DecreaseAvatarSize = "Decrease Avatar Size";
|
||||
const QString DecreaseVoxelSize = "Decrease Voxel Size";
|
||||
|
@ -231,13 +228,6 @@ namespace MenuOption {
|
|||
const QString HeadMouse = "Head Mouse";
|
||||
const QString HandsCollideWithSelf = "Collide With Self";
|
||||
const QString FaceshiftTCP = "Faceshift (TCP)";
|
||||
const QString FalseColorByDistance = "FALSE Color By Distance";
|
||||
const QString FalseColorBySource = "FALSE Color By Source";
|
||||
const QString FalseColorEveryOtherVoxel = "FALSE Color Every Other Randomly";
|
||||
const QString FalseColorOccluded = "FALSE Color Occluded Voxels";
|
||||
const QString FalseColorOccludedV2 = "FALSE Color Occluded V2 Voxels";
|
||||
const QString FalseColorOutOfView = "FALSE Color Voxel Out of View";
|
||||
const QString FalseColorRandomly = "FALSE Color Voxels Randomly";
|
||||
const QString FirstPerson = "First Person";
|
||||
const QString FrameTimer = "Show Timer";
|
||||
const QString FrustumRenderMode = "Render Mode";
|
||||
|
@ -249,7 +239,6 @@ namespace MenuOption {
|
|||
const QString GoTo = "Go To...";
|
||||
const QString IncreaseAvatarSize = "Increase Avatar Size";
|
||||
const QString IncreaseVoxelSize = "Increase Voxel Size";
|
||||
const QString KillLocalVoxels = "Kill Local Voxels";
|
||||
const QString GoHome = "Go Home";
|
||||
const QString Gravity = "Use Gravity";
|
||||
const QString LodTools = "LOD Tools";
|
||||
|
@ -274,7 +263,6 @@ namespace MenuOption {
|
|||
const QString PipelineWarnings = "Show Render Pipeline Warnings";
|
||||
const QString PlaySlaps = "Play Slaps";
|
||||
const QString Preferences = "Preferences...";
|
||||
const QString RandomizeVoxelColors = "Randomize Voxel TRUE Colors";
|
||||
const QString ReloadAllScripts = "Reload All Scripts";
|
||||
const QString RenderSkeletonCollisionProxies = "Skeleton Collision Proxies";
|
||||
const QString RenderHeadCollisionProxies = "Head Collision Proxies";
|
||||
|
@ -283,19 +271,15 @@ namespace MenuOption {
|
|||
const QString SettingsImport = "Import Settings";
|
||||
const QString Shadows = "Shadows";
|
||||
const QString SettingsExport = "Export Settings";
|
||||
const QString ShowAllLocalVoxels = "Show All Local Voxels";
|
||||
const QString ShowCulledSharedFaces = "Show Culled Shared Voxel Faces";
|
||||
const QString ShowTrueColors = "Show TRUE Colors";
|
||||
const QString SuppressShortTimings = "Suppress Timings Less than 10ms";
|
||||
const QString Stars = "Stars";
|
||||
const QString Stats = "Stats";
|
||||
const QString StopAllScripts = "Stop All Scripts";
|
||||
const QString TestPing = "Test Ping";
|
||||
const QString TreeStats = "Calculate Tree Stats";
|
||||
const QString TransmitterDrive = "Transmitter Drive";
|
||||
const QString Quit = "Quit";
|
||||
const QString Voxels = "Voxels";
|
||||
const QString VoxelDrumming = "Voxel Drumming";
|
||||
const QString VoxelMode = "Cycle Voxel Mode";
|
||||
const QString VoxelStats = "Voxel Stats";
|
||||
const QString VoxelTextures = "Voxel Textures";
|
||||
|
|
|
@ -143,11 +143,11 @@ void ImportTask::run() {
|
|||
|
||||
// Then we call the righ method for the job
|
||||
if (_filename.endsWith(".png", Qt::CaseInsensitive)) {
|
||||
voxelSystem->readFromSquareARGB32Pixels(_filename.toLocal8Bit().data());
|
||||
voxelSystem->getTree()->readFromSquareARGB32Pixels(_filename.toLocal8Bit().data());
|
||||
} else if (_filename.endsWith(".svo", Qt::CaseInsensitive)) {
|
||||
voxelSystem->readFromSVOFile(_filename.toLocal8Bit().data());
|
||||
voxelSystem->getTree()->readFromSVOFile(_filename.toLocal8Bit().data());
|
||||
} else if (_filename.endsWith(".schematic", Qt::CaseInsensitive)) {
|
||||
voxelSystem->readFromSchematicFile(_filename.toLocal8Bit().data());
|
||||
voxelSystem->getTree()->readFromSchematicFile(_filename.toLocal8Bit().data());
|
||||
} else {
|
||||
// We should never get here.
|
||||
qDebug() << "[ERROR] Invalid file extension." << endl;
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -14,7 +14,6 @@
|
|||
|
||||
#include <SharedUtil.h>
|
||||
|
||||
#include <CoverageMapV2.h>
|
||||
#include <NodeData.h>
|
||||
#include <ViewFrustum.h>
|
||||
#include <VoxelTree.h>
|
||||
|
@ -68,11 +67,6 @@ public:
|
|||
|
||||
ViewFrustum* getLastCulledViewFrustum() { return &_lastCulledViewFrustum; }
|
||||
|
||||
void writeToSVOFile(const char* filename, VoxelTreeElement* element) const;
|
||||
bool readFromSVOFile(const char* filename);
|
||||
bool readFromSquareARGB32Pixels(const char* filename);
|
||||
bool readFromSchematicFile(const char* filename);
|
||||
|
||||
void setMaxVoxels(int maxVoxels);
|
||||
long int getMaxVoxels() const { return _maxVoxels; }
|
||||
unsigned long getVoxelMemoryUsageRAM() const { return _memoryUsageRAM; }
|
||||
|
@ -82,66 +76,25 @@ public:
|
|||
|
||||
void killLocalVoxels();
|
||||
|
||||
virtual void removeOutOfView();
|
||||
virtual void hideOutOfView(bool forceFullFrustum = false);
|
||||
void inspectForOcclusions();
|
||||
bool hasViewChanged();
|
||||
bool isViewChanging();
|
||||
|
||||
bool findRayIntersection(const glm::vec3& origin, const glm::vec3& direction,
|
||||
VoxelDetail& detail, float& distance, BoxFace& face);
|
||||
|
||||
bool findSpherePenetration(const glm::vec3& center, float radius, glm::vec3& penetration);
|
||||
bool findCapsulePenetration(const glm::vec3& start, const glm::vec3& end, float radius, glm::vec3& penetration);
|
||||
|
||||
void deleteVoxelAt(float x, float y, float z, float s);
|
||||
VoxelTreeElement* getVoxelAt(float x, float y, float z, float s) const;
|
||||
void createVoxel(float x, float y, float z, float s,
|
||||
unsigned char red, unsigned char green, unsigned char blue, bool destructive = false);
|
||||
void createLine(glm::vec3 point1, glm::vec3 point2, float unitSize, rgbColor color, bool destructive = false);
|
||||
|
||||
void copySubTreeIntoNewTree(VoxelTreeElement* startNode, VoxelSystem* destinationTree, bool rebaseToRoot);
|
||||
void copySubTreeIntoNewTree(VoxelTreeElement* startNode, VoxelTree* destinationTree, bool rebaseToRoot);
|
||||
void copyFromTreeIntoSubTree(VoxelTree* sourceTree, VoxelTreeElement* destinationNode);
|
||||
|
||||
void recurseTreeWithOperation(RecurseOctreeOperation operation, void* extraData=NULL);
|
||||
|
||||
CoverageMapV2 myCoverageMapV2;
|
||||
CoverageMap myCoverageMap;
|
||||
|
||||
virtual void elementDeleted(OctreeElement* element);
|
||||
virtual void elementUpdated(OctreeElement* element);
|
||||
|
||||
VoxelTreeElement* getVoxelEnclosing(const glm::vec3& point);
|
||||
|
||||
signals:
|
||||
void importSize(float x, float y, float z);
|
||||
void importProgress(int progress);
|
||||
|
||||
public slots:
|
||||
void nodeAdded(SharedNodePointer node);
|
||||
void nodeKilled(SharedNodePointer node);
|
||||
|
||||
void collectStatsForTreesAndVBOs();
|
||||
|
||||
// Methods that recurse tree
|
||||
void showAllLocalVoxels();
|
||||
void randomizeVoxelColors();
|
||||
void falseColorizeRandom();
|
||||
void trueColorize();
|
||||
void falseColorizeInView();
|
||||
void falseColorizeDistanceFromView();
|
||||
void falseColorizeRandomEveryOther();
|
||||
void falseColorizeOccluded();
|
||||
void falseColorizeOccludedV2();
|
||||
void falseColorizeBySource();
|
||||
void forceRedrawEntireTree();
|
||||
void clearAllNodesBufferIndex();
|
||||
void cullSharedFaces();
|
||||
void showCulledSharedFaces();
|
||||
|
||||
void cancelImport();
|
||||
|
||||
void setDisableFastVoxelPipeline(bool disableFastVoxelPipeline);
|
||||
void setUseVoxelShader(bool useVoxelShader);
|
||||
void setVoxelsAsPoints(bool voxelsAsPoints);
|
||||
|
@ -154,18 +107,24 @@ protected:
|
|||
void setupNewVoxelsForDrawing();
|
||||
static const bool DONT_BAIL_EARLY; // by default we will bail early, if you want to force not bailing, then use this
|
||||
void setupNewVoxelsForDrawingSingleNode(bool allowBailEarly = true);
|
||||
|
||||
/// called on the hide/show thread to hide any out of view voxels and show any newly in view voxels.
|
||||
void checkForCulling();
|
||||
|
||||
/// single pass to remove old VBO data and fill it with correct current view, used when switching LOD or needing to force
|
||||
/// a full redraw of everything in view
|
||||
void recreateVoxelGeometryInView();
|
||||
|
||||
glm::vec3 computeVoxelVertex(const glm::vec3& startVertex, float voxelScale, int index) const;
|
||||
|
||||
|
||||
virtual void updateArraysDetails(glBufferIndex nodeIndex, const glm::vec3& startVertex,
|
||||
float voxelScale, const nodeColor& color);
|
||||
virtual void copyWrittenDataSegmentToReadArrays(glBufferIndex segmentStart, glBufferIndex segmentEnd);
|
||||
virtual void updateVBOSegment(glBufferIndex segmentStart, glBufferIndex segmentEnd);
|
||||
virtual void applyScaleAndBindProgram(bool texture);
|
||||
virtual void removeScaleAndReleaseProgram(bool texture);
|
||||
|
||||
|
||||
virtual void applyScaleAndBindProgram(bool texture); /// used in render() to apply shadows and textures
|
||||
virtual void removeScaleAndReleaseProgram(bool texture); /// stop the shaders for shadows and textures
|
||||
|
||||
private:
|
||||
// disallow copying of VoxelSystem objects
|
||||
|
@ -178,19 +137,6 @@ private:
|
|||
|
||||
// Operation functions for tree recursion methods
|
||||
static int _nodeCount;
|
||||
static bool randomColorOperation(OctreeElement* element, void* extraData);
|
||||
static bool falseColorizeRandomOperation(OctreeElement* element, void* extraData);
|
||||
static bool trueColorizeOperation(OctreeElement* element, void* extraData);
|
||||
static bool falseColorizeInViewOperation(OctreeElement* element, void* extraData);
|
||||
static bool falseColorizeDistanceFromViewOperation(OctreeElement* element, void* extraData);
|
||||
static bool getDistanceFromViewRangeOperation(OctreeElement* element, void* extraData);
|
||||
static bool removeOutOfViewOperation(OctreeElement* element, void* extraData);
|
||||
static bool falseColorizeRandomEveryOtherOperation(OctreeElement* element, void* extraData);
|
||||
static bool collectStatsForTreesAndVBOsOperation(OctreeElement* element, void* extraData);
|
||||
static bool falseColorizeOccludedOperation(OctreeElement* element, void* extraData);
|
||||
static bool falseColorizeSubTreeOperation(OctreeElement* element, void* extraData);
|
||||
static bool falseColorizeOccludedV2Operation(OctreeElement* element, void* extraData);
|
||||
static bool falseColorizeBySourceOperation(OctreeElement* element, void* extraData);
|
||||
static bool killSourceVoxelsOperation(OctreeElement* element, void* extraData);
|
||||
static bool forceRedrawEntireTreeOperation(OctreeElement* element, void* extraData);
|
||||
static bool clearAllNodesBufferIndexOperation(OctreeElement* element, void* extraData);
|
||||
|
@ -199,7 +145,6 @@ private:
|
|||
static bool hideOutOfViewOperation(OctreeElement* element, void* extraData);
|
||||
static bool hideAllSubTreeOperation(OctreeElement* element, void* extraData);
|
||||
static bool showAllSubTreeOperation(OctreeElement* element, void* extraData);
|
||||
static bool showAllLocalVoxelsOperation(OctreeElement* element, void* extraData);
|
||||
static bool getVoxelEnclosingOperation(OctreeElement* element, void* extraData);
|
||||
static bool recreateVoxelGeometryInViewOperation(OctreeElement* element, void* extraData);
|
||||
|
||||
|
|
|
@ -20,7 +20,6 @@
|
|||
using namespace std;
|
||||
|
||||
const float FINGERTIP_COLLISION_RADIUS = 0.01f;
|
||||
const float FINGERTIP_VOXEL_SIZE = 0.05f;
|
||||
const float PALM_COLLISION_RADIUS = 0.03f;
|
||||
|
||||
|
||||
|
@ -29,7 +28,6 @@ Hand::Hand(Avatar* owningAvatar) :
|
|||
|
||||
_owningAvatar(owningAvatar),
|
||||
_renderAlpha(1.0),
|
||||
_ballColor(0.0, 0.0, 0.4),
|
||||
_collisionCenter(0,0,0),
|
||||
_collisionAge(0),
|
||||
_collisionDuration(0)
|
||||
|
@ -37,13 +35,6 @@ Hand::Hand(Avatar* owningAvatar) :
|
|||
}
|
||||
|
||||
void Hand::init() {
|
||||
// Different colors for my hand and others' hands
|
||||
if (_owningAvatar && _owningAvatar->isMyAvatar()) {
|
||||
_ballColor = glm::vec3(0.0, 0.4, 0.0);
|
||||
}
|
||||
else {
|
||||
_ballColor = glm::vec3(0.0, 0.0, 0.4);
|
||||
}
|
||||
}
|
||||
|
||||
void Hand::reset() {
|
||||
|
@ -61,61 +52,6 @@ void Hand::simulate(float deltaTime, bool isMine) {
|
|||
// Iterate hand controllers, take actions as needed
|
||||
for (size_t i = 0; i < getNumPalms(); ++i) {
|
||||
PalmData& palm = getPalms()[i];
|
||||
if (palm.isActive()) {
|
||||
FingerData& finger = palm.getFingers()[0]; // Sixense has only one finger
|
||||
glm::vec3 fingerTipPosition = finger.getTipPosition();
|
||||
|
||||
|
||||
if (palm.getControllerButtons() & BUTTON_1) {
|
||||
if (glm::length(fingerTipPosition - _lastFingerAddVoxel) > (FINGERTIP_VOXEL_SIZE / 2.f)) {
|
||||
// TODO: we need to move this code to JS so it can access the editVoxels.js color palette
|
||||
QColor paintColor(128,128,128);
|
||||
Application::getInstance()->makeVoxel(fingerTipPosition,
|
||||
FINGERTIP_VOXEL_SIZE,
|
||||
paintColor.red(),
|
||||
paintColor.green(),
|
||||
paintColor.blue(),
|
||||
true);
|
||||
_lastFingerAddVoxel = fingerTipPosition;
|
||||
}
|
||||
} else if (palm.getControllerButtons() & BUTTON_2) {
|
||||
if (glm::length(fingerTipPosition - _lastFingerDeleteVoxel) > (FINGERTIP_VOXEL_SIZE / 2.f)) {
|
||||
Application::getInstance()->removeVoxel(fingerTipPosition, FINGERTIP_VOXEL_SIZE);
|
||||
_lastFingerDeleteVoxel = fingerTipPosition;
|
||||
}
|
||||
}
|
||||
|
||||
// Voxel Drumming with fingertips if enabled
|
||||
if (Menu::getInstance()->isOptionChecked(MenuOption::VoxelDrumming)) {
|
||||
VoxelTreeElement* fingerNode = Application::getInstance()->getVoxels()->getVoxelEnclosing(
|
||||
glm::vec3(fingerTipPosition / (float)TREE_SCALE));
|
||||
if (fingerNode) {
|
||||
if (!palm.getIsCollidingWithVoxel()) {
|
||||
// Collision has just started
|
||||
palm.setIsCollidingWithVoxel(true);
|
||||
handleVoxelCollision(&palm, fingerTipPosition, fingerNode, deltaTime);
|
||||
// Set highlight voxel
|
||||
VoxelDetail voxel;
|
||||
glm::vec3 pos = fingerNode->getCorner();
|
||||
voxel.x = pos.x;
|
||||
voxel.y = pos.y;
|
||||
voxel.z = pos.z;
|
||||
voxel.s = fingerNode->getScale();
|
||||
voxel.red = fingerNode->getColor()[0];
|
||||
voxel.green = fingerNode->getColor()[1];
|
||||
voxel.blue = fingerNode->getColor()[2];
|
||||
Application::getInstance()->setHighlightVoxel(voxel);
|
||||
Application::getInstance()->setIsHighlightVoxel(true);
|
||||
}
|
||||
} else {
|
||||
if (palm.getIsCollidingWithVoxel()) {
|
||||
// Collision has just ended
|
||||
palm.setIsCollidingWithVoxel(false);
|
||||
Application::getInstance()->setIsHighlightVoxel(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
palm.setLastControllerButtons(palm.getControllerButtons());
|
||||
}
|
||||
}
|
||||
|
@ -349,7 +285,6 @@ void Hand::renderLeapHands(bool isMine) {
|
|||
|
||||
const float alpha = 1.0f;
|
||||
|
||||
//const glm::vec3 handColor = _ballColor;
|
||||
const glm::vec3 handColor(1.0, 0.84, 0.66); // use the skin color
|
||||
|
||||
glEnable(GL_DEPTH_TEST);
|
||||
|
|
|
@ -51,7 +51,6 @@ public:
|
|||
void reset();
|
||||
void simulate(float deltaTime, bool isMine);
|
||||
void render(bool isMine);
|
||||
void setBallColor (glm::vec3 ballColor ) { _ballColor = ballColor; }
|
||||
|
||||
// getters
|
||||
const glm::vec3& getLeapFingerTipBallPosition (int ball) const { return _leapFingerTipBalls [ball].position;}
|
||||
|
@ -69,7 +68,6 @@ private:
|
|||
|
||||
Avatar* _owningAvatar;
|
||||
float _renderAlpha;
|
||||
glm::vec3 _ballColor;
|
||||
std::vector<HandBall> _leapFingerTipBalls;
|
||||
std::vector<HandBall> _leapFingerRootBalls;
|
||||
|
||||
|
|
|
@ -810,7 +810,7 @@ void MyAvatar::updateCollisionWithVoxels(float deltaTime, float radius) {
|
|||
const float VOXEL_COLLISION_FREQUENCY = 0.5f;
|
||||
glm::vec3 penetration;
|
||||
float pelvisFloatingHeight = getPelvisFloatingHeight();
|
||||
if (Application::getInstance()->getVoxels()->findCapsulePenetration(
|
||||
if (Application::getInstance()->getVoxelTree()->findCapsulePenetration(
|
||||
_position - glm::vec3(0.0f, pelvisFloatingHeight - radius, 0.0f),
|
||||
_position + glm::vec3(0.0f, getSkeletonHeight() - pelvisFloatingHeight + radius, 0.0f), radius, penetration)) {
|
||||
_lastCollisionPosition = _position;
|
||||
|
|
|
@ -18,8 +18,6 @@
|
|||
|
||||
#include "AudioInjector.h"
|
||||
|
||||
int abstractAudioPointerMeta = qRegisterMetaType<AbstractAudioInterface*>("AbstractAudioInterface*");
|
||||
|
||||
AudioInjector::AudioInjector(Sound* sound, const AudioInjectorOptions& injectorOptions) :
|
||||
_sound(sound),
|
||||
_options(injectorOptions)
|
||||
|
|
|
@ -18,9 +18,6 @@
|
|||
#include "AudioInjectorOptions.h"
|
||||
#include "Sound.h"
|
||||
|
||||
class AbstractAudioInterface;
|
||||
class AudioScriptingInterface;
|
||||
|
||||
class AudioInjector : public QObject {
|
||||
Q_OBJECT
|
||||
public:
|
||||
|
|
|
@ -25,4 +25,26 @@ void AudioScriptingInterface::playSound(Sound* sound, const AudioInjectorOptions
|
|||
connect(injectorThread, SIGNAL(finished()), injectorThread, SLOT(deleteLater()));
|
||||
|
||||
injectorThread->start();
|
||||
}
|
||||
}
|
||||
|
||||
void AudioScriptingInterface::startDrumSound(float volume, float frequency, float duration, float decay,
|
||||
const AudioInjectorOptions* injectorOptions) {
|
||||
|
||||
Sound* sound = new Sound(volume, frequency, duration, decay);
|
||||
AudioInjector* injector = new AudioInjector(sound, *injectorOptions);
|
||||
sound->setParent(injector);
|
||||
|
||||
QThread* injectorThread = new QThread();
|
||||
|
||||
injector->moveToThread(injectorThread);
|
||||
|
||||
// start injecting when the injector thread starts
|
||||
connect(injectorThread, SIGNAL(started()), injector, SLOT(injectAudio()));
|
||||
|
||||
// connect the right slots and signals so that the AudioInjector is killed once the injection is complete
|
||||
connect(injector, SIGNAL(finished()), injector, SLOT(deleteLater()));
|
||||
connect(injector, SIGNAL(finished()), injectorThread, SLOT(quit()));
|
||||
connect(injectorThread, SIGNAL(finished()), injectorThread, SLOT(deleteLater()));
|
||||
|
||||
injectorThread->start();
|
||||
}
|
||||
|
|
|
@ -18,6 +18,8 @@ class AudioScriptingInterface : public QObject {
|
|||
Q_OBJECT
|
||||
public slots:
|
||||
static void playSound(Sound* sound, const AudioInjectorOptions* injectorOptions = NULL);
|
||||
static void startDrumSound(float volume, float frequency, float duration, float decay,
|
||||
const AudioInjectorOptions* injectorOptions = NULL);
|
||||
|
||||
};
|
||||
#endif /* defined(__hifi__AudioScriptingInterface__) */
|
||||
|
|
|
@ -9,6 +9,8 @@
|
|||
|
||||
#include <stdint.h>
|
||||
|
||||
#include <glm/glm.hpp>
|
||||
|
||||
#include <QDataStream>
|
||||
#include <QtCore/QDebug>
|
||||
#include <QtNetwork/QNetworkAccessManager>
|
||||
|
@ -16,8 +18,51 @@
|
|||
#include <QtNetwork/QNetworkReply>
|
||||
#include <qendian.h>
|
||||
|
||||
#include <SharedUtil.h>
|
||||
|
||||
#include "AudioRingBuffer.h"
|
||||
#include "Sound.h"
|
||||
|
||||
// procedural audio version of Sound
|
||||
Sound::Sound(float volume, float frequency, float duration, float decay, QObject* parent) :
|
||||
QObject(parent)
|
||||
{
|
||||
static char monoAudioData[MAX_PACKET_SIZE];
|
||||
static int16_t* monoAudioSamples = (int16_t*)(monoAudioData);
|
||||
|
||||
float t;
|
||||
const float AUDIO_CALLBACK_MSECS = (float) NETWORK_BUFFER_LENGTH_SAMPLES_PER_CHANNEL / (float)SAMPLE_RATE * 1000.0;
|
||||
const float MAX_VOLUME = 32000.f;
|
||||
const float MAX_DURATION = 2.f;
|
||||
const float MIN_AUDIBLE_VOLUME = 0.001f;
|
||||
const float NOISE_MAGNITUDE = 0.02f;
|
||||
const int MAX_SAMPLE_VALUE = std::numeric_limits<int16_t>::max();
|
||||
const int MIN_SAMPLE_VALUE = std::numeric_limits<int16_t>::min();
|
||||
int numSamples = NETWORK_BUFFER_LENGTH_SAMPLES_PER_CHANNEL; // we add sounds in chunks of this many samples
|
||||
|
||||
int chunkStartingSample = 0;
|
||||
float waveFrequency = (frequency / SAMPLE_RATE) * PI_TIMES_TWO;
|
||||
while (volume > 0.f) {
|
||||
for (int i = 0; i < numSamples; i++) {
|
||||
t = (float)chunkStartingSample + (float)i;
|
||||
float sample = sinf(t * waveFrequency);
|
||||
sample += ((randFloat() - 0.5f) * NOISE_MAGNITUDE);
|
||||
sample *= volume * MAX_VOLUME;
|
||||
|
||||
monoAudioSamples[i] = glm::clamp((int)sample, MIN_SAMPLE_VALUE, MAX_SAMPLE_VALUE);
|
||||
volume *= (1.f - decay);
|
||||
}
|
||||
// add the monoAudioSamples to our actual output Byte Array
|
||||
_byteArray.append(monoAudioData, numSamples * sizeof(int16_t));
|
||||
chunkStartingSample += numSamples;
|
||||
duration = glm::clamp(duration - (AUDIO_CALLBACK_MSECS / 1000.f), 0.f, MAX_DURATION);
|
||||
//qDebug() << "decaying... _duration=" << _duration;
|
||||
if (duration == 0.f || (volume < MIN_AUDIBLE_VOLUME)) {
|
||||
volume = 0.f;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Sound::Sound(const QUrl& sampleURL, QObject* parent) :
|
||||
QObject(parent)
|
||||
{
|
||||
|
|
|
@ -17,7 +17,8 @@ class QNetworkReply;
|
|||
class Sound : public QObject {
|
||||
Q_OBJECT
|
||||
public:
|
||||
Sound(const QUrl& sampleURL, QObject* parent = 0);
|
||||
Sound(const QUrl& sampleURL, QObject* parent = NULL);
|
||||
Sound(float volume, float frequency, float duration, float decay, QObject* parent = NULL);
|
||||
|
||||
const QByteArray& getByteArray() { return _byteArray; }
|
||||
|
||||
|
|
|
@ -330,7 +330,9 @@ void Octree::readBitstreamToTree(const unsigned char * bitstream, unsigned long
|
|||
|
||||
void Octree::deleteOctreeElementAt(float x, float y, float z, float s) {
|
||||
unsigned char* octalCode = pointToOctalCode(x,y,z,s);
|
||||
lockForWrite();
|
||||
deleteOctalCodeFromTree(octalCode);
|
||||
unlock();
|
||||
delete[] octalCode; // cleanup memory
|
||||
}
|
||||
|
||||
|
@ -586,9 +588,16 @@ bool findRayIntersectionOp(OctreeElement* node, void* extraData) {
|
|||
}
|
||||
|
||||
bool Octree::findRayIntersection(const glm::vec3& origin, const glm::vec3& direction,
|
||||
OctreeElement*& node, float& distance, BoxFace& face) {
|
||||
OctreeElement*& node, float& distance, BoxFace& face, bool tryLock) {
|
||||
RayArgs args = { origin / (float)(TREE_SCALE), direction, node, distance, face };
|
||||
recurseTreeWithOperation(findRayIntersectionOp, &args);
|
||||
|
||||
if (!tryLock) {
|
||||
lockForRead();
|
||||
}
|
||||
if (tryLock && tryLockForRead()) {
|
||||
recurseTreeWithOperation(findRayIntersectionOp, &args);
|
||||
unlock();
|
||||
}
|
||||
return args.found;
|
||||
}
|
||||
|
||||
|
@ -624,7 +633,7 @@ bool findSpherePenetrationOp(OctreeElement* element, void* extraData) {
|
|||
}
|
||||
|
||||
bool Octree::findSpherePenetration(const glm::vec3& center, float radius, glm::vec3& penetration,
|
||||
void** penetratedObject) {
|
||||
void** penetratedObject, bool tryLock) {
|
||||
|
||||
SphereArgs args = {
|
||||
center / (float)(TREE_SCALE),
|
||||
|
@ -633,9 +642,16 @@ bool Octree::findSpherePenetration(const glm::vec3& center, float radius, glm::v
|
|||
false,
|
||||
NULL };
|
||||
penetration = glm::vec3(0.0f, 0.0f, 0.0f);
|
||||
recurseTreeWithOperation(findSpherePenetrationOp, &args);
|
||||
if (penetratedObject) {
|
||||
*penetratedObject = args.penetratedObject;
|
||||
|
||||
if (!tryLock) {
|
||||
lockForRead();
|
||||
}
|
||||
if (tryLock && tryLockForRead()) {
|
||||
recurseTreeWithOperation(findSpherePenetrationOp, &args);
|
||||
if (penetratedObject) {
|
||||
*penetratedObject = args.penetratedObject;
|
||||
}
|
||||
unlock();
|
||||
}
|
||||
return args.found;
|
||||
}
|
||||
|
@ -670,17 +686,67 @@ bool findCapsulePenetrationOp(OctreeElement* node, void* extraData) {
|
|||
return false;
|
||||
}
|
||||
|
||||
bool Octree::findCapsulePenetration(const glm::vec3& start, const glm::vec3& end, float radius, glm::vec3& penetration) {
|
||||
bool Octree::findCapsulePenetration(const glm::vec3& start, const glm::vec3& end, float radius,
|
||||
glm::vec3& penetration, bool tryLock) {
|
||||
|
||||
CapsuleArgs args = {
|
||||
start / (float)(TREE_SCALE),
|
||||
end / (float)(TREE_SCALE),
|
||||
radius / (float)(TREE_SCALE),
|
||||
penetration };
|
||||
penetration,
|
||||
false };
|
||||
penetration = glm::vec3(0.0f, 0.0f, 0.0f);
|
||||
recurseTreeWithOperation(findCapsulePenetrationOp, &args);
|
||||
|
||||
if (!tryLock) {
|
||||
lockForRead();
|
||||
}
|
||||
if (tryLock && tryLockForRead()) {
|
||||
recurseTreeWithOperation(findCapsulePenetrationOp, &args);
|
||||
unlock();
|
||||
}
|
||||
return args.found;
|
||||
}
|
||||
|
||||
class GetElementEnclosingArgs {
|
||||
public:
|
||||
OctreeElement* element;
|
||||
glm::vec3 point;
|
||||
};
|
||||
|
||||
// Find the smallest colored voxel enclosing a point (if there is one)
|
||||
bool getElementEnclosingOperation(OctreeElement* element, void* extraData) {
|
||||
GetElementEnclosingArgs* args = static_cast<GetElementEnclosingArgs*>(extraData);
|
||||
AABox elementBox = element->getAABox();
|
||||
if (elementBox.contains(args->point)) {
|
||||
if (element->hasContent() && element->isLeaf()) {
|
||||
// we've reached a solid leaf containing the point, return the node.
|
||||
args->element = element;
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
// The point is not inside this voxel, so stop recursing.
|
||||
return false;
|
||||
}
|
||||
return true; // keep looking
|
||||
}
|
||||
|
||||
OctreeElement* Octree::getElementEnclosingPoint(const glm::vec3& point, bool tryLock) {
|
||||
GetElementEnclosingArgs args;
|
||||
args.point = point;
|
||||
args.element = NULL;
|
||||
|
||||
if (!tryLock) {
|
||||
lockForRead();
|
||||
}
|
||||
if (tryLock && tryLockForRead()) {
|
||||
recurseTreeWithOperation(getElementEnclosingOperation, (void*)&args);
|
||||
unlock();
|
||||
}
|
||||
return args.element;
|
||||
}
|
||||
|
||||
|
||||
|
||||
int Octree::encodeTreeBitstream(OctreeElement* node,
|
||||
OctreePacketData* packetData, OctreeElementBag& bag,
|
||||
EncodeBitstreamParams& params) {
|
||||
|
|
|
@ -12,7 +12,6 @@
|
|||
#include <set>
|
||||
#include <SimpleMovingAverage.h>
|
||||
|
||||
//#include "CoverageMap.h"
|
||||
class CoverageMap;
|
||||
class ReadBitstreamToTreeParams;
|
||||
class Octree;
|
||||
|
@ -223,12 +222,15 @@ public:
|
|||
void setDirtyBit() { _isDirty = true; }
|
||||
|
||||
bool findRayIntersection(const glm::vec3& origin, const glm::vec3& direction,
|
||||
OctreeElement*& node, float& distance, BoxFace& face);
|
||||
OctreeElement*& node, float& distance, BoxFace& face, bool tryLock = true);
|
||||
|
||||
bool findSpherePenetration(const glm::vec3& center, float radius, glm::vec3& penetration,
|
||||
void** penetratedObject = NULL);
|
||||
void** penetratedObject = NULL, bool tryLock = true);
|
||||
|
||||
bool findCapsulePenetration(const glm::vec3& start, const glm::vec3& end, float radius, glm::vec3& penetration);
|
||||
bool findCapsulePenetration(const glm::vec3& start, const glm::vec3& end, float radius,
|
||||
glm::vec3& penetration, bool tryLock = true);
|
||||
|
||||
OctreeElement* getElementEnclosingPoint(const glm::vec3& point, bool tryLock = true);
|
||||
|
||||
// Note: this assumes the fileFormat is the HIO individual voxels code files
|
||||
void loadOctreeFile(const char* fileName, bool wantColorRandomizer);
|
||||
|
@ -236,9 +238,6 @@ public:
|
|||
// these will read/write files that match the wireformat, excluding the 'V' leading
|
||||
void writeToSVOFile(const char* filename, OctreeElement* node = NULL);
|
||||
bool readFromSVOFile(const char* filename);
|
||||
// reads voxels from square image with alpha as a Y-axis
|
||||
bool readFromSquareARGB32Pixels(const char *filename);
|
||||
bool readFromSchematicFile(const char* filename);
|
||||
|
||||
// Octree does not currently handle its own locking, caller must use these to lock/unlock
|
||||
void lockForRead() { lock.lockForRead(); }
|
||||
|
|
|
@ -14,16 +14,32 @@
|
|||
#include <PerfStat.h>
|
||||
#include "OctreeRenderer.h"
|
||||
|
||||
OctreeRenderer::OctreeRenderer() {
|
||||
_tree = NULL;
|
||||
_viewFrustum = NULL;
|
||||
OctreeRenderer::OctreeRenderer() :
|
||||
_tree(NULL),
|
||||
_managedTree(false),
|
||||
_viewFrustum(NULL)
|
||||
{
|
||||
}
|
||||
|
||||
void OctreeRenderer::init() {
|
||||
_tree = createTree();
|
||||
if (!_tree) {
|
||||
_tree = createTree();
|
||||
_managedTree = true;
|
||||
}
|
||||
}
|
||||
|
||||
OctreeRenderer::~OctreeRenderer() {
|
||||
if (_tree && _managedTree) {
|
||||
delete _tree;
|
||||
}
|
||||
}
|
||||
|
||||
void OctreeRenderer::setTree(Octree* newTree) {
|
||||
if (_tree && _managedTree) {
|
||||
delete _tree;
|
||||
_managedTree = false;
|
||||
}
|
||||
_tree = newTree;
|
||||
}
|
||||
|
||||
void OctreeRenderer::processDatagram(const QByteArray& dataByteArray, const SharedNodePointer& sourceNode) {
|
||||
|
|
|
@ -44,6 +44,8 @@ public:
|
|||
virtual PacketType getMyQueryMessageType() const = 0;
|
||||
virtual PacketType getExpectedPacketType() const = 0;
|
||||
virtual void renderElement(OctreeElement* element, RenderArgs* args) = 0;
|
||||
|
||||
virtual void setTree(Octree* newTree);
|
||||
|
||||
/// process incoming data
|
||||
virtual void processDatagram(const QByteArray& dataByteArray, const SharedNodePointer& sourceNode);
|
||||
|
@ -63,6 +65,7 @@ public:
|
|||
void clear();
|
||||
protected:
|
||||
Octree* _tree;
|
||||
bool _managedTree;
|
||||
ViewFrustum* _viewFrustum;
|
||||
};
|
||||
|
||||
|
|
|
@ -16,7 +16,6 @@
|
|||
|
||||
#include <QtCore/QDebug>
|
||||
|
||||
//#include "CoverageMap.h"
|
||||
#include "GeometryUtil.h"
|
||||
#include "SharedUtil.h"
|
||||
#include "ViewFrustum.h"
|
||||
|
|
|
@ -1,16 +0,0 @@
|
|||
//
|
||||
// VoxelPacketData.cpp
|
||||
// hifi
|
||||
//
|
||||
// Created by Brad Hefta-Gaub on 11/19/2013.
|
||||
// Copyright (c) 2013 HighFidelity, Inc. All rights reserved.
|
||||
//
|
||||
|
||||
#include <PerfStat.h>
|
||||
#include "VoxelPacketData.h"
|
||||
|
||||
// currently just an alias for OctreePacketData
|
||||
|
||||
VoxelPacketData::VoxelPacketData(bool enableCompression, int maxFinalizedSize) :
|
||||
OctreePacketData(enableCompression, maxFinalizedSize) {
|
||||
};
|
|
@ -1,35 +0,0 @@
|
|||
//
|
||||
// VoxelPacketData.h
|
||||
// hifi
|
||||
//
|
||||
// Created by Brad Hefta-Gaub on 11/19/2013
|
||||
//
|
||||
// TO DO:
|
||||
//
|
||||
// * add stats tracking for number of unique colors and consecutive identical colors.
|
||||
// (as research for color dictionaries and RLE)
|
||||
//
|
||||
// * further testing of compression to determine optimal configuration for performance and compression
|
||||
//
|
||||
// * improve semantics for "reshuffle" - current approach will work for now and with compression
|
||||
// but wouldn't work with RLE because the colors in the levels would get reordered and RLE would need
|
||||
// to be recalculated
|
||||
//
|
||||
|
||||
#ifndef __hifi__VoxelPacketData__
|
||||
#define __hifi__VoxelPacketData__
|
||||
|
||||
#include <SharedUtil.h>
|
||||
|
||||
#include <OctreePacketData.h>
|
||||
|
||||
#include "VoxelConstants.h"
|
||||
#include "VoxelTreeElement.h"
|
||||
|
||||
/// Handles packing of the data portion of PacketType_VOXEL_DATA messages.
|
||||
class VoxelPacketData : public OctreePacketData {
|
||||
public:
|
||||
VoxelPacketData(bool enableCompression = false, int maxFinalizedSize = MAX_OCTREE_PACKET_DATA_SIZE);
|
||||
};
|
||||
|
||||
#endif /* defined(__hifi__VoxelPacketData__) */
|
|
@ -47,28 +47,12 @@ void VoxelTree::createVoxel(float x, float y, float z, float s,
|
|||
unsigned char red, unsigned char green, unsigned char blue, bool destructive) {
|
||||
|
||||
unsigned char* voxelData = pointToVoxel(x,y,z,s,red,green,blue);
|
||||
|
||||
//int length = bytesRequiredForCodeLength(numberOfThreeBitSectionsInCode(voxelData)) + BYTES_PER_COLOR;
|
||||
//printf("createVoxel()...");
|
||||
//outputBufferBits(voxelData,length);
|
||||
|
||||
this->readCodeColorBufferToTree(voxelData, destructive);
|
||||
lockForWrite();
|
||||
readCodeColorBufferToTree(voxelData, destructive);
|
||||
unlock();
|
||||
delete[] voxelData;
|
||||
}
|
||||
|
||||
|
||||
void VoxelTree::createLine(glm::vec3 point1, glm::vec3 point2, float unitSize, rgbColor color, bool destructive) {
|
||||
glm::vec3 distance = point2 - point1;
|
||||
glm::vec3 items = distance / unitSize;
|
||||
int maxItems = std::max(items.x, std::max(items.y, items.z));
|
||||
glm::vec3 increment = distance * (1.0f/ maxItems);
|
||||
glm::vec3 pointAt = point1;
|
||||
for (int i = 0; i <= maxItems; i++ ) {
|
||||
pointAt += increment;
|
||||
createVoxel(pointAt.x, pointAt.y, pointAt.z, unitSize, color[0], color[1], color[2], destructive);
|
||||
}
|
||||
}
|
||||
|
||||
class NodeChunkArgs {
|
||||
public:
|
||||
VoxelTree* thisVoxelTree;
|
||||
|
@ -577,4 +561,3 @@ int VoxelTree::processEditPacketData(PacketType packetType, const unsigned char*
|
|||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -9,17 +9,9 @@
|
|||
#ifndef __hifi__VoxelTree__
|
||||
#define __hifi__VoxelTree__
|
||||
|
||||
#include <set>
|
||||
#include <SimpleMovingAverage.h>
|
||||
#include <OctreeElementBag.h>
|
||||
#include <Octree.h>
|
||||
#include <CoverageMap.h>
|
||||
#include <JurisdictionMap.h>
|
||||
#include <ViewFrustum.h>
|
||||
|
||||
#include "VoxelTreeElement.h"
|
||||
#include "VoxelPacketData.h"
|
||||
#include "VoxelSceneStats.h"
|
||||
#include "VoxelEditPacketSender.h"
|
||||
|
||||
class ReadCodeColorBufferToTreeArgs;
|
||||
|
@ -38,11 +30,8 @@ public:
|
|||
void createVoxel(float x, float y, float z, float s,
|
||||
unsigned char red, unsigned char green, unsigned char blue, bool destructive = false);
|
||||
|
||||
void createLine(glm::vec3 point1, glm::vec3 point2, float unitSize, rgbColor color, bool destructive = false);
|
||||
|
||||
void nudgeSubTree(VoxelTreeElement* elementToNudge, const glm::vec3& nudgeAmount, VoxelEditPacketSender& voxelEditSender);
|
||||
|
||||
|
||||
/// reads voxels from square image with alpha as a Y-axis
|
||||
bool readFromSquareARGB32Pixels(const char *filename);
|
||||
|
||||
|
@ -55,16 +44,6 @@ public:
|
|||
virtual bool handlesEditPacketType(PacketType packetType) const;
|
||||
virtual int processEditPacketData(PacketType packetType, const unsigned char* packetData, int packetLength,
|
||||
const unsigned char* editData, int maxLength, const SharedNodePointer& node);
|
||||
void processSetVoxelsBitstream(const unsigned char* bitstream, int bufferSizeBytes);
|
||||
|
||||
/**
|
||||
signals:
|
||||
void importSize(float x, float y, float z);
|
||||
void importProgress(int progress);
|
||||
|
||||
public slots:
|
||||
void cancelImport();
|
||||
**/
|
||||
|
||||
private:
|
||||
// helper functions for nudgeSubTree
|
||||
|
|
|
@ -39,8 +39,7 @@ void VoxelTreeElement::init(unsigned char* octalCode) {
|
|||
setVoxelSystem(NULL);
|
||||
setBufferIndex(GLBUFFER_INDEX_UNKNOWN);
|
||||
_falseColored = false; // assume true color
|
||||
_currentColor[0] = _currentColor[1] = _currentColor[2] = _currentColor[3] = 0;
|
||||
_trueColor[0] = _trueColor[1] = _trueColor[2] = _trueColor[3] = 0;
|
||||
_color[0] = _color[1] = _color[2] = _color[3] = 0;
|
||||
_density = 0.0f;
|
||||
OctreeElement::init(octalCode);
|
||||
_voxelMemoryUsage += sizeof(VoxelTreeElement);
|
||||
|
@ -115,39 +114,9 @@ void VoxelTreeElement::setVoxelSystem(VoxelSystem* voxelSystem) {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
void VoxelTreeElement::setFalseColor(colorPart red, colorPart green, colorPart blue) {
|
||||
if (_falseColored != true || _currentColor[0] != red || _currentColor[1] != green || _currentColor[2] != blue) {
|
||||
_falseColored=true;
|
||||
_currentColor[0] = red;
|
||||
_currentColor[1] = green;
|
||||
_currentColor[2] = blue;
|
||||
_currentColor[3] = 1; // XXXBHG - False colors are always considered set
|
||||
_isDirty = true;
|
||||
markWithChangedTime();
|
||||
}
|
||||
}
|
||||
|
||||
void VoxelTreeElement::setFalseColored(bool isFalseColored) {
|
||||
if (_falseColored != isFalseColored) {
|
||||
// if we were false colored, and are no longer false colored, then swap back
|
||||
if (_falseColored && !isFalseColored) {
|
||||
memcpy(&_currentColor,&_trueColor,sizeof(nodeColor));
|
||||
}
|
||||
_falseColored = isFalseColored;
|
||||
_isDirty = true;
|
||||
_density = 1.0f; // If color set, assume leaf, re-averaging will update density if needed.
|
||||
markWithChangedTime();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
void VoxelTreeElement::setColor(const nodeColor& color) {
|
||||
if (_trueColor[0] != color[0] || _trueColor[1] != color[1] || _trueColor[2] != color[2]) {
|
||||
memcpy(&_trueColor,&color,sizeof(nodeColor));
|
||||
if (!_falseColored) {
|
||||
memcpy(&_currentColor,&color,sizeof(nodeColor));
|
||||
}
|
||||
if (_color[0] != color[0] || _color[1] != color[1] || _color[2] != color[2]) {
|
||||
memcpy(&_color,&color,sizeof(nodeColor));
|
||||
_isDirty = true;
|
||||
if (color[3]) {
|
||||
_density = 1.0f; // If color set, assume leaf, re-averaging will update density if needed.
|
||||
|
@ -168,7 +137,7 @@ void VoxelTreeElement::calculateAverageFromChildren() {
|
|||
VoxelTreeElement* childAt = getChildAtIndex(i);
|
||||
if (childAt && childAt->isColored()) {
|
||||
for (int j = 0; j < 3; j++) {
|
||||
colorArray[j] += childAt->getTrueColor()[j]; // color averaging should always be based on true colors
|
||||
colorArray[j] += childAt->getColor()[j]; // color averaging should always be based on true colors
|
||||
}
|
||||
colorArray[3]++;
|
||||
}
|
||||
|
@ -260,9 +229,9 @@ bool VoxelTreeElement::findSpherePenetration(const glm::vec3& center, float radi
|
|||
voxelDetails->y = _box.getCorner().y;
|
||||
voxelDetails->z = _box.getCorner().z;
|
||||
voxelDetails->s = _box.getScale();
|
||||
voxelDetails->red = getTrueColor()[RED_INDEX];
|
||||
voxelDetails->green = getTrueColor()[GREEN_INDEX];
|
||||
voxelDetails->blue = getTrueColor()[BLUE_INDEX];
|
||||
voxelDetails->red = getColor()[RED_INDEX];
|
||||
voxelDetails->green = getColor()[GREEN_INDEX];
|
||||
voxelDetails->blue = getColor()[BLUE_INDEX];
|
||||
|
||||
*penetratedObject = (void*)voxelDetails;
|
||||
}
|
||||
|
|
|
@ -57,14 +57,10 @@ public:
|
|||
|
||||
virtual bool isRendered() const { return isKnownBufferIndex(); }
|
||||
|
||||
bool isColored() const { return _trueColor[3] == 1; }
|
||||
bool isColored() const { return _color[3] == 1; }
|
||||
|
||||
void setFalseColor(colorPart red, colorPart green, colorPart blue);
|
||||
void setFalseColored(bool isFalseColored);
|
||||
bool getFalseColored() { return _falseColored; }
|
||||
void setColor(const nodeColor& color);
|
||||
const nodeColor& getTrueColor() const { return _trueColor; }
|
||||
const nodeColor& getColor() const { return _currentColor; }
|
||||
const nodeColor& getColor() const { return _color; }
|
||||
|
||||
void setDensity(float density) { _density = density; }
|
||||
float getDensity() const { return _density; }
|
||||
|
@ -92,8 +88,7 @@ protected:
|
|||
|
||||
float _density; /// Client and server, If leaf: density = 1, if internal node: 0-1 density of voxels inside, 4 bytes
|
||||
|
||||
nodeColor _trueColor; /// Client and server, true color of this voxel, 4 bytes
|
||||
nodeColor _currentColor; /// Client only, false color of this voxel, 4 bytes
|
||||
nodeColor _color; /// Client and server, true color of this voxel, 4 bytes
|
||||
|
||||
private:
|
||||
unsigned char _exteriorOcclusions; ///< Exterior shared partition boundaries that are completely occupied
|
||||
|
|
|
@ -47,9 +47,7 @@ void VoxelsScriptingInterface::setVoxelNonDestructive(float x, float y, float z,
|
|||
|
||||
// handle the local tree also...
|
||||
if (_tree) {
|
||||
_tree->lockForWrite();
|
||||
_tree->createVoxel(addVoxelDetail.x, addVoxelDetail.y, addVoxelDetail.z, addVoxelDetail.s, red, green, blue, false);
|
||||
_tree->unlock();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -64,9 +62,7 @@ void VoxelsScriptingInterface::setVoxel(float x, float y, float z, float scale,
|
|||
|
||||
// handle the local tree also...
|
||||
if (_tree) {
|
||||
_tree->lockForWrite();
|
||||
_tree->createVoxel(addVoxelDetail.x, addVoxelDetail.y, addVoxelDetail.z, addVoxelDetail.s, red, green, blue, true);
|
||||
_tree->unlock();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -80,9 +76,7 @@ void VoxelsScriptingInterface::eraseVoxel(float x, float y, float z, float scale
|
|||
|
||||
// handle the local tree also...
|
||||
if (_tree) {
|
||||
_tree->lockForWrite();
|
||||
_tree->deleteVoxelAt(deleteVoxelDetail.x, deleteVoxelDetail.y, deleteVoxelDetail.z, deleteVoxelDetail.s);
|
||||
_tree->unlock();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -90,21 +84,18 @@ void VoxelsScriptingInterface::eraseVoxel(float x, float y, float z, float scale
|
|||
RayToVoxelIntersectionResult VoxelsScriptingInterface::findRayIntersection(const PickRay& ray) {
|
||||
RayToVoxelIntersectionResult result;
|
||||
if (_tree) {
|
||||
if (_tree->tryLockForRead()) {
|
||||
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);
|
||||
}
|
||||
_tree->unlock();
|
||||
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;
|
||||
|
@ -127,3 +118,22 @@ glm::vec3 VoxelsScriptingInterface::getFaceVector(const QString& face) {
|
|||
return glm::vec3(0, 0, 0); //error case
|
||||
}
|
||||
|
||||
VoxelDetail VoxelsScriptingInterface::getVoxelEnclosingPoint(const glm::vec3& point) {
|
||||
VoxelDetail result = { 0.0f, 0.0f, 0.0f, 0.0f, 0, 0, 0 };
|
||||
if (_tree) {
|
||||
OctreeElement* element = _tree->getElementEnclosingPoint(point / (float)TREE_SCALE);
|
||||
if (element) {
|
||||
VoxelTreeElement* voxel = static_cast<VoxelTreeElement*>(element);
|
||||
result.x = voxel->getCorner().x;
|
||||
result.y = voxel->getCorner().y;
|
||||
result.z = voxel->getCorner().z;
|
||||
result.s = voxel->getScale();
|
||||
result.red = voxel->getColor()[0];
|
||||
result.green = voxel->getColor()[1];
|
||||
result.blue = voxel->getColor()[2];
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -70,6 +70,11 @@ public slots:
|
|||
|
||||
/// returns a voxel space axis aligned vector for the face, useful in doing voxel math
|
||||
glm::vec3 getFaceVector(const QString& face);
|
||||
|
||||
/// checks the local voxel tree for the smallest voxel enclosing the point
|
||||
/// \param point the x,y,z coordinates of the point (in meter units)
|
||||
/// \return VoxelDetail - if no voxel encloses the point then VoxelDetail items will be 0
|
||||
VoxelDetail getVoxelEnclosingPoint(const glm::vec3& point);
|
||||
|
||||
private:
|
||||
void queueVoxelAdd(PacketType addPacketType, VoxelDetail& addVoxelDetails);
|
||||
|
|
|
@ -27,18 +27,6 @@ void addCornersAndAxisLines(VoxelTree* tree) {
|
|||
tree->createVoxel(1.0 - voxelSize, 1.0 - voxelSize, 0 , voxelSize, 255, 255 ,0 );
|
||||
tree->createVoxel(1.0 - voxelSize, 1.0 - voxelSize, 1.0 - voxelSize, voxelSize, 255, 255 ,255);
|
||||
printf("DONE creating corner points...\n");
|
||||
|
||||
// Now some more examples... creating some lines using the line primitive
|
||||
printf("creating voxel lines...\n");
|
||||
// We want our line voxels to be about 1/32 meter high, and our TREE_SCALE is in meters, so...
|
||||
float lineVoxelSize = 1.f / (32 * TREE_SCALE);
|
||||
rgbColor red = {255, 0, 0};
|
||||
rgbColor green = {0, 255, 0};
|
||||
rgbColor blue = {0, 0, 255};
|
||||
tree->createLine(glm::vec3(0, 0, 0), glm::vec3(0, 0, 1), lineVoxelSize, blue);
|
||||
tree->createLine(glm::vec3(0, 0, 0), glm::vec3(1, 0, 0), lineVoxelSize, red);
|
||||
tree->createLine(glm::vec3(0, 0, 0), glm::vec3(0, 1, 0), lineVoxelSize, green);
|
||||
printf("DONE creating lines...\n");
|
||||
}
|
||||
|
||||
void addSurfaceScene(VoxelTree * tree) {
|
|
@ -1,4 +1,4 @@
|
|||
//
|
||||
//
|
||||
// main.cpp
|
||||
// Voxel Edit
|
||||
//
|
||||
|
@ -8,7 +8,7 @@
|
|||
|
||||
#include <VoxelTree.h>
|
||||
#include <SharedUtil.h>
|
||||
#include <SceneUtils.h>
|
||||
#include "SceneUtils.h"
|
||||
#include <JurisdictionMap.h>
|
||||
#include <QString>
|
||||
#include <QStringList>
|
||||
|
@ -163,9 +163,9 @@ bool copyAndFillOperation(OctreeElement* element, void* extraData) {
|
|||
float y = voxel->getCorner().y;
|
||||
float z = voxel->getCorner().z;
|
||||
float s = voxel->getScale();
|
||||
unsigned char red = voxel->getTrueColor()[RED_INDEX];
|
||||
unsigned char green = voxel->getTrueColor()[GREEN_INDEX];
|
||||
unsigned char blue = voxel->getTrueColor()[BLUE_INDEX];
|
||||
unsigned char red = voxel->getColor()[RED_INDEX];
|
||||
unsigned char green = voxel->getColor()[GREEN_INDEX];
|
||||
unsigned char blue = voxel->getColor()[BLUE_INDEX];
|
||||
bool destructive = true;
|
||||
|
||||
args->destinationTree->createVoxel(x, y, z, s, red, green, blue, destructive);
|
||||
|
|
Loading…
Reference in a new issue