1579 lines · 58.7 KB · C++
RawDownload
                } break;            }        }    }    return true; // keep going!}  bool VoxelSystem::isViewChanging() {    bool result = false; // assume the best     // If our viewFrustum has changed since our _lastKnowViewFrustum    if (!_lastKnowViewFrustum.matches(Application::getInstance()->getViewFrustum())) {        result = true;        _lastKnowViewFrustum = *Application::getInstance()->getViewFrustum(); // save last known    }    return result;} bool VoxelSystem::hasViewChanged() {    bool result = false; // assume the best        // If we're still changing, report no change yet.    if (isViewChanging()) {        return false;    }        // If our viewFrustum has changed since our _lastKnowViewFrustum    if (!_lastStableViewFrustum.matches(Application::getInstance()->getViewFrustum())) {        result = true;        _lastStableViewFrustum = *Application::getInstance()->getViewFrustum(); // save last stable    }    return result;} void VoxelSystem::removeOutOfView() {    PerformanceWarning warn(_renderWarningsOn, "removeOutOfView()");    removeOutOfViewArgs args(this);    _tree->recurseTreeWithOperation(removeOutOfViewOperation,(void*)&args);     if (args.nodesRemoved) {        _tree->setDirtyBit();    }    bool showRemoveDebugDetails = false;    if (showRemoveDebugDetails) {        qDebug("removeOutOfView() scanned=%ld removed=%ld inside=%ld intersect=%ld outside=%ld _removedVoxels.count()=%d \n",                 args.nodesScanned, args.nodesRemoved, args.nodesInside,                 args.nodesIntersect, args.nodesOutside, _removedVoxels.count()            );    }} bool VoxelSystem::findRayIntersection(const glm::vec3& origin, const glm::vec3& direction,                                      VoxelDetail& detail, float& distance, BoxFace& face) {    pthread_mutex_lock(&_treeLock);                                      VoxelNode* node;    if (!_tree->findRayIntersection(origin, direction, node, distance, face)) {        pthread_mutex_unlock(&_treeLock);        return false;    }    detail.x = node->getCorner().x;    detail.y = node->getCorner().y;    detail.z = node->getCorner().z;    detail.s = node->getScale();    detail.red = node->getColor()[0];    detail.green = node->getColor()[1];    detail.blue = node->getColor()[2];    pthread_mutex_unlock(&_treeLock);    return true;} bool VoxelSystem::findSpherePenetration(const glm::vec3& center, float radius, glm::vec3& penetration) {    pthread_mutex_lock(&_treeLock);    bool result = _tree->findSpherePenetration(center, radius, penetration);    pthread_mutex_unlock(&_treeLock);    return result;} bool VoxelSystem::findCapsulePenetration(const glm::vec3& start, const glm::vec3& end, float radius, glm::vec3& penetration) {    pthread_mutex_lock(&_treeLock);    bool result = _tree->findCapsulePenetration(start, end, radius, penetration);    pthread_mutex_unlock(&_treeLock);    return result;} class falseColorizeRandomEveryOtherArgs {public:    falseColorizeRandomEveryOtherArgs() : totalNodes(0), colorableNodes(0), coloredNodes(0), colorThis(true) {};    unsigned long totalNodes;    unsigned long colorableNodes;    unsigned long coloredNodes;    bool colorThis;}; bool VoxelSystem::falseColorizeRandomEveryOtherOperation(VoxelNode* node, void* extraData) {    falseColorizeRandomEveryOtherArgs* args = (falseColorizeRandomEveryOtherArgs*)extraData;    args->totalNodes++;    if (node->isColored()) {        args->colorableNodes++;        if (args->colorThis) {            args->coloredNodes++;            node->setFalseColor(255, randomColorValue(150), randomColorValue(150));        }        args->colorThis = !args->colorThis;    }    return true; // keep going!} void VoxelSystem::falseColorizeRandomEveryOther() {    falseColorizeRandomEveryOtherArgs args;    _tree->recurseTreeWithOperation(falseColorizeRandomEveryOtherOperation,&args);    qDebug("randomized false color for every other node: total %ld, colorable %ld, colored %ld\n",         args.totalNodes, args.colorableNodes, args.coloredNodes);    _tree->setDirtyBit();    setupNewVoxelsForDrawing();} class collectStatsForTreesAndVBOsArgs {public:    collectStatsForTreesAndVBOsArgs() :         totalNodes(0),         dirtyNodes(0),         shouldRenderNodes(0),        coloredNodes(0),        nodesInVBO(0),        nodesInVBONotShouldRender(0),        nodesInVBOOverExpectedMax(0),        duplicateVBOIndex(0),        leafNodes(0)        {            memset(hasIndexFound, false, MAX_VOXELS_PER_SYSTEM * sizeof(bool));        };     unsigned long totalNodes;    unsigned long dirtyNodes;    unsigned long shouldRenderNodes;    unsigned long coloredNodes;    unsigned long nodesInVBO;    unsigned long nodesInVBONotShouldRender;    unsigned long nodesInVBOOverExpectedMax;    unsigned long duplicateVBOIndex;    unsigned long leafNodes;     unsigned long expectedMax;        bool hasIndexFound[MAX_VOXELS_PER_SYSTEM];}; bool VoxelSystem::collectStatsForTreesAndVBOsOperation(VoxelNode* node, void* extraData) {    collectStatsForTreesAndVBOsArgs* args = (collectStatsForTreesAndVBOsArgs*)extraData;    args->totalNodes++;     if (node->isLeaf()) {        args->leafNodes++;    }     if (node->isColored()) {        args->coloredNodes++;    }     if (node->getShouldRender()) {        args->shouldRenderNodes++;    }     if (node->isDirty()) {        args->dirtyNodes++;    }     if (node->isKnownBufferIndex()) {        args->nodesInVBO++;        unsigned long nodeIndex = node->getBufferIndex();        if (args->hasIndexFound[nodeIndex]) {            args->duplicateVBOIndex++;            qDebug("duplicateVBO found... index=%ld, isDirty=%s, shouldRender=%s \n", nodeIndex,                     debug::valueOf(node->isDirty()), debug::valueOf(node->getShouldRender()));        } else {            args->hasIndexFound[nodeIndex] = true;        }        if (nodeIndex > args->expectedMax) {            args->nodesInVBOOverExpectedMax++;        }                // if it's in VBO but not-shouldRender, track that also...        if (!node->getShouldRender()) {            args->nodesInVBONotShouldRender++;        }    }     return true; // keep going!} void VoxelSystem::collectStatsForTreesAndVBOs() {    PerformanceWarning warn(true, "collectStatsForTreesAndVBOs()", true);     glBufferIndex minDirty = GLBUFFER_INDEX_UNKNOWN;    glBufferIndex maxDirty = 0;     for (glBufferIndex i = 0; i < _voxelsInWriteArrays; i++) {        if (_writeVoxelDirtyArray[i]) {            minDirty = std::min(minDirty,i);            maxDirty = std::max(maxDirty,i);        }    }     collectStatsForTreesAndVBOsArgs args;    args.expectedMax = _voxelsInWriteArrays;    _tree->recurseTreeWithOperation(collectStatsForTreesAndVBOsOperation,&args);     qDebug("Local Voxel Tree Statistics:\n total nodes %ld \n leaves %ld \n dirty %ld \n colored %ld \n shouldRender %ld \n",        args.totalNodes, args.leafNodes, args.dirtyNodes, args.coloredNodes, args.shouldRenderNodes);     qDebug(" _voxelsDirty=%s \n _voxelsInWriteArrays=%ld \n minDirty=%ld \n maxDirty=%ld \n", debug::valueOf(_voxelsDirty),        _voxelsInWriteArrays, minDirty, maxDirty);     qDebug(" inVBO %ld \n nodesInVBOOverExpectedMax %ld \n duplicateVBOIndex %ld \n nodesInVBONotShouldRender %ld \n",         args.nodesInVBO, args.nodesInVBOOverExpectedMax, args.duplicateVBOIndex, args.nodesInVBONotShouldRender);     glBufferIndex minInVBO = GLBUFFER_INDEX_UNKNOWN;    glBufferIndex maxInVBO = 0;     for (glBufferIndex i = 0; i < MAX_VOXELS_PER_SYSTEM; i++) {        if (args.hasIndexFound[i]) {            minInVBO = std::min(minInVBO,i);            maxInVBO = std::max(maxInVBO,i);        }    }     qDebug(" minInVBO=%ld \n maxInVBO=%ld \n _voxelsInWriteArrays=%ld \n _voxelsInReadArrays=%ld \n",             minInVBO, maxInVBO, _voxelsInWriteArrays, _voxelsInReadArrays); }  void VoxelSystem::deleteVoxelAt(float x, float y, float z, float s) {    pthread_mutex_lock(&_treeLock);        _tree->deleteVoxelAt(x, y, z, s);        // redraw!    setupNewVoxelsForDrawing();  // do we even need to do this? Or will the next network receive kick in?        pthread_mutex_unlock(&_treeLock);}; VoxelNode* VoxelSystem::getVoxelAt(float x, float y, float z, float s) const {     return _tree->getVoxelAt(x, y, z, s); }; void VoxelSystem::createVoxel(float x, float y, float z, float s,                               unsigned char red, unsigned char green, unsigned char blue, bool destructive) {    pthread_mutex_lock(&_treeLock);        //qDebug("VoxelSystem::createVoxel(%f,%f,%f,%f)\n",x,y,z,s);    _tree->createVoxel(x, y, z, s, red, green, blue, destructive);     setupNewVoxelsForDrawing();         pthread_mutex_unlock(&_treeLock);}; void VoxelSystem::createLine(glm::vec3 point1, glm::vec3 point2, float unitSize, rgbColor color, bool destructive) {     _tree->createLine(point1, point2, unitSize, color, destructive);     setupNewVoxelsForDrawing(); }; void VoxelSystem::createSphere(float r,float xc, float yc, float zc, float s, bool solid,                                creationMode mode, bool destructive, bool debug) {     _tree->createSphere(r, xc, yc, zc, s, solid, mode, destructive, debug);     setupNewVoxelsForDrawing(); }; void VoxelSystem::copySubTreeIntoNewTree(VoxelNode* startNode, VoxelTree* destinationTree, bool rebaseToRoot) {    _tree->copySubTreeIntoNewTree(startNode, destinationTree, rebaseToRoot);} void VoxelSystem::copyFromTreeIntoSubTree(VoxelTree* sourceTree, VoxelNode* destinationNode) {    _tree->copyFromTreeIntoSubTree(sourceTree, destinationNode);} struct FalseColorizeOccludedArgs {    ViewFrustum* viewFrustum;    CoverageMap* map;    CoverageMapV2* mapV2;    VoxelTree* tree;    long totalVoxels;    long coloredVoxels;    long occludedVoxels;    long notOccludedVoxels;    long outOfView;    long subtreeVoxelsSkipped;    long nonLeaves;    long nonLeavesOutOfView;    long nonLeavesOccluded;}; struct FalseColorizeSubTreeOperationArgs {    unsigned char color[NUMBER_OF_COLORS];    long voxelsTouched;}; bool VoxelSystem::falseColorizeSubTreeOperation(VoxelNode* node, void* extraData) {    if (node->getShouldRender()) {        FalseColorizeSubTreeOperationArgs* args = (FalseColorizeSubTreeOperationArgs*) extraData;        node->setFalseColor(args->color[0], args->color[1], args->color[2]);        args->voxelsTouched++;    }    return true;    } bool VoxelSystem::falseColorizeOccludedOperation(VoxelNode* node, void* extraData) {     FalseColorizeOccludedArgs* args = (FalseColorizeOccludedArgs*) extraData;    args->totalVoxels++;     // If we are a parent, let's see if we're completely occluded.    if (!node->isLeaf()) {        args->nonLeaves++;         AABox voxelBox = node->getAABox();        voxelBox.scale(TREE_SCALE);        VoxelProjectedPolygon* voxelPolygon = new VoxelProjectedPolygon(args->viewFrustum->getProjectedPolygon(voxelBox));         // If we're not all in view, then ignore it, and just return. But keep searching...        if (!voxelPolygon->getAllInView()) {            args->nonLeavesOutOfView++;            delete voxelPolygon;            return true;        }         CoverageMapStorageResult result = args->map->checkMap(voxelPolygon, false);        if (result == OCCLUDED) {            args->nonLeavesOccluded++;            delete voxelPolygon;                        FalseColorizeSubTreeOperationArgs subArgs;            subArgs.color[0] = 0;            subArgs.color[1] = 255;            subArgs.color[2] = 0;            subArgs.voxelsTouched = 0;                        args->tree->recurseNodeWithOperation(node, falseColorizeSubTreeOperation, &subArgs );                        args->subtreeVoxelsSkipped += (subArgs.voxelsTouched - 1);            args->totalVoxels += (subArgs.voxelsTouched - 1);                        return false;        }         delete voxelPolygon;        return true; // keep looking...    }     if (node->isLeaf() && node->isColored() && node->getShouldRender()) {        args->coloredVoxels++;         AABox voxelBox = node->getAABox();        voxelBox.scale(TREE_SCALE);        VoxelProjectedPolygon* voxelPolygon = new VoxelProjectedPolygon(args->viewFrustum->getProjectedPolygon(voxelBox));         // If we're not all in view, then ignore it, and just return. But keep searching...        if (!voxelPolygon->getAllInView()) {            args->outOfView++;            delete voxelPolygon;            return true;        }         CoverageMapStorageResult result = args->map->checkMap(voxelPolygon, true);        if (result == OCCLUDED) {            node->setFalseColor(255, 0, 0);            args->occludedVoxels++;        } else if (result == STORED) {            args->notOccludedVoxels++;            //qDebug("***** falseColorizeOccludedOperation() NODE is STORED *****\n");        } else if (result == DOESNT_FIT) {            //qDebug("***** falseColorizeOccludedOperation() NODE DOESNT_FIT???? *****\n");        }    }    return true; // keep going!} void VoxelSystem::falseColorizeOccluded() {    PerformanceWarning warn(true, "falseColorizeOccluded()",true);    myCoverageMap.erase();        FalseColorizeOccludedArgs args;    args.viewFrustum = Application::getInstance()->getViewFrustum();    args.map = &myCoverageMap;     args.totalVoxels = 0;    args.coloredVoxels = 0;    args.occludedVoxels = 0;    args.notOccludedVoxels = 0;    args.outOfView = 0;    args.subtreeVoxelsSkipped = 0;    args.nonLeaves = 0;    args.nonLeavesOutOfView = 0;    args.nonLeavesOccluded = 0;    args.tree = _tree;     VoxelProjectedPolygon::pointInside_calls = 0;    VoxelProjectedPolygon::occludes_calls = 0;    VoxelProjectedPolygon::intersects_calls = 0;        glm::vec3 position = args.viewFrustum->getPosition() * (1.0f/TREE_SCALE);     _tree->recurseTreeWithOperationDistanceSorted(falseColorizeOccludedOperation, position, (void*)&args);     qDebug("falseColorizeOccluded()\n    position=(%f,%f)\n    total=%ld\n    colored=%ld\n    occluded=%ld\n    notOccluded=%ld\n    outOfView=%ld\n    subtreeVoxelsSkipped=%ld\n    nonLeaves=%ld\n    nonLeavesOutOfView=%ld\n    nonLeavesOccluded=%ld\n    pointInside_calls=%ld\n    occludes_calls=%ld\n intersects_calls=%ld\n",         position.x, position.y,        args.totalVoxels, args.coloredVoxels, args.occludedVoxels,         args.notOccludedVoxels, args.outOfView, args.subtreeVoxelsSkipped,         args.nonLeaves, args.nonLeavesOutOfView, args.nonLeavesOccluded,        VoxelProjectedPolygon::pointInside_calls,        VoxelProjectedPolygon::occludes_calls,        VoxelProjectedPolygon::intersects_calls    );      //myCoverageMap.erase();     _tree->setDirtyBit();    setupNewVoxelsForDrawing();} bool VoxelSystem::falseColorizeOccludedV2Operation(VoxelNode* node, void* extraData) {     FalseColorizeOccludedArgs* args = (FalseColorizeOccludedArgs*) extraData;    args->totalVoxels++;     // If we are a parent, let's see if we're completely occluded.    if (!node->isLeaf()) {        args->nonLeaves++;         AABox voxelBox = node->getAABox();        voxelBox.scale(TREE_SCALE);        VoxelProjectedPolygon* voxelPolygon = new VoxelProjectedPolygon(args->viewFrustum->getProjectedPolygon(voxelBox));         // If we're not all in view, then ignore it, and just return. But keep searching...        if (!voxelPolygon->getAllInView()) {            args->nonLeavesOutOfView++;            delete voxelPolygon;            return true;        }         CoverageMapV2StorageResult result = args->mapV2->checkMap(voxelPolygon, false);        if (result == V2_OCCLUDED) {            args->nonLeavesOccluded++;            delete voxelPolygon;                        FalseColorizeSubTreeOperationArgs subArgs;            subArgs.color[0] = 0;            subArgs.color[1] = 255;            subArgs.color[2] = 0;            subArgs.voxelsTouched = 0;                        args->tree->recurseNodeWithOperation(node, falseColorizeSubTreeOperation, &subArgs );                        args->subtreeVoxelsSkipped += (subArgs.voxelsTouched - 1);            args->totalVoxels += (subArgs.voxelsTouched - 1);                        return false;        }         delete voxelPolygon;        return true; // keep looking...    }     if (node->isLeaf() && node->isColored() && node->getShouldRender()) {        args->coloredVoxels++;         AABox voxelBox = node->getAABox();        voxelBox.scale(TREE_SCALE);        VoxelProjectedPolygon* voxelPolygon = new VoxelProjectedPolygon(args->viewFrustum->getProjectedPolygon(voxelBox));         // If we're not all in view, then ignore it, and just return. But keep searching...        if (!voxelPolygon->getAllInView()) {            args->outOfView++;            delete voxelPolygon;            return true;        }         CoverageMapV2StorageResult result = args->mapV2->checkMap(voxelPolygon, true);        if (result == V2_OCCLUDED) {            node->setFalseColor(255, 0, 0);            args->occludedVoxels++;        } else if (result == V2_STORED) {            args->notOccludedVoxels++;            //qDebug("***** falseColorizeOccludedOperation() NODE is STORED *****\n");        } else if (result == V2_DOESNT_FIT) {            //qDebug("***** falseColorizeOccludedOperation() NODE DOESNT_FIT???? *****\n");        }        delete voxelPolygon; // V2 maps don't store polygons, so we're always in charge of freeing    }    return true; // keep going!}  void VoxelSystem::falseColorizeOccludedV2() {    PerformanceWarning warn(true, "falseColorizeOccludedV2()",true);    myCoverageMapV2.erase();     CoverageMapV2::wantDebugging = true;

Lines 1001–1500 of 1579. Previous lines