void DiffTraversal::Waypoint::getNextVisibleElementDifferential(DiffTraversal::VisibleElement& next, const DiffTraversal::View& view, const DiffTraversal::View& lastView) { if (_nextIndex == -1) { // root case is special ++_nextIndex; EntityTreeElementPointer element = _weakElement.lock(); next.element = element; next.intersection = ViewFrustum::INTERSECT; return; } else if (_nextIndex < NUMBER_OF_CHILDREN) { EntityTreeElementPointer element = _weakElement.lock(); if (element) { while (_nextIndex < NUMBER_OF_CHILDREN) { EntityTreeElementPointer nextElement = element->getChildAtIndex(_nextIndex); ++_nextIndex; if (nextElement) { AACube cube = nextElement->getAACube(); // check for LOD truncation float distance = glm::distance(view.viewFrustum.getPosition(), cube.calcCenter()) + MIN_VISIBLE_DISTANCE; float angularDiameter = cube.getScale() / distance; if (angularDiameter > MIN_ELEMENT_ANGULAR_DIAMETER * view.lodScaleFactor) { if (view.viewFrustum.calculateCubeKeyholeIntersection(cube) != ViewFrustum::OUTSIDE) { next.element = nextElement; next.intersection = ViewFrustum::OUTSIDE; return; } } } } } } next.element.reset(); next.intersection = ViewFrustum::OUTSIDE; }
float ConicalViewFrustum::getAngularSize(const AACube& cube) const { auto radius = 0.5f * SQRT_THREE * cube.getScale(); // radius of bounding sphere auto position = cube.calcCenter() - _position; // position of bounding sphere in view-frame float distance = glm::length(position); return getAngularSize(distance, radius); }
void VoxelShapeManager::updateVoxels(const quint64& now, CubeList& cubes) { const quint64 VOXEL_UPDATE_PERIOD = 100000; // usec _updateExpiry = now + VOXEL_UPDATE_PERIOD; PhysicsSimulation* simulation = getSimulation(); if (!simulation) { return; } int numChanges = 0; VoxelPool::iterator voxelItr = _voxels.begin(); while (voxelItr != _voxels.end()) { // look for this voxel in cubes CubeList::iterator cubeItr = cubes.find(voxelItr.key()); if (cubeItr == cubes.end()) { // did not find it --> remove the voxel simulation->removeShape(voxelItr.value()._shape); voxelItr = _voxels.erase(voxelItr); ++numChanges; } else { // found it --> remove the cube cubes.erase(cubeItr); voxelItr++; } } // add remaining cubes to _voxels glm::vec3 simulationOrigin = simulation->getTranslation(); CubeList::const_iterator cubeItr = cubes.constBegin(); while (cubeItr != cubes.constEnd()) { AACube cube = cubeItr.value(); AACubeShape* shape = new AACubeShape(cube.getScale(), cube.calcCenter() - simulationOrigin); shape->setEntity(this); VoxelInfo voxel = {cube, shape }; _voxels.insert(cubeItr.key(), voxel); ++numChanges; ++cubeItr; } if (numChanges > 0) { buildShapes(); } }
OctreeProjectedPolygon ViewFrustum::getProjectedPolygon(const AACube& box) const { const glm::vec3& bottomNearRight = box.getCorner(); glm::vec3 topFarLeft = box.calcTopFarLeft(); int lookUp = ((_position.x < bottomNearRight.x) ) // 1 = right | compute 6-bit + ((_position.x > topFarLeft.x ) << 1) // 2 = left | code to + ((_position.y < bottomNearRight.y) << 2) // 4 = bottom | classify camera + ((_position.y > topFarLeft.y ) << 3) // 8 = top | with respect to + ((_position.z < bottomNearRight.z) << 4) // 16 = front/near | the 6 defining + ((_position.z > topFarLeft.z ) << 5); // 32 = back/far | planes int vertexCount = hullVertexLookup[lookUp][0]; //look up number of vertices OctreeProjectedPolygon projectedPolygon(vertexCount); bool pointInView = true; bool allPointsInView = false; // assume the best, but wait till we know we have a vertex bool anyPointsInView = false; // assume the worst! if (vertexCount) { allPointsInView = true; // assume the best! for(int i = 0; i < vertexCount; i++) { int vertexNum = hullVertexLookup[lookUp][i+1]; glm::vec3 point = box.getVertex((BoxVertex)vertexNum); glm::vec2 projectedPoint = projectPoint(point, pointInView); allPointsInView = allPointsInView && pointInView; anyPointsInView = anyPointsInView || pointInView; projectedPolygon.setVertex(i, projectedPoint); } /*** // Now that we've got the polygon, if it extends beyond the clipping window, then let's clip it // NOTE: This clipping does not improve our overall performance. It basically causes more polygons to // end up in the same quad/half and so the polygon lists get longer, and that's more calls to polygon.occludes() if ( (projectedPolygon.getMaxX() > PolygonClip::RIGHT_OF_CLIPPING_WINDOW ) || (projectedPolygon.getMaxY() > PolygonClip::TOP_OF_CLIPPING_WINDOW ) || (projectedPolygon.getMaxX() < PolygonClip::LEFT_OF_CLIPPING_WINDOW ) || (projectedPolygon.getMaxY() < PolygonClip::BOTTOM_OF_CLIPPING_WINDOW) ) { CoverageRegion::_clippedPolygons++; glm::vec2* clippedVertices; int clippedVertexCount; PolygonClip::clipToScreen(projectedPolygon.getVertices(), vertexCount, clippedVertices, clippedVertexCount); // Now reset the vertices of our projectedPolygon object projectedPolygon.setVertexCount(clippedVertexCount); for(int i = 0; i < clippedVertexCount; i++) { projectedPolygon.setVertex(i, clippedVertices[i]); } delete[] clippedVertices; lookUp += PROJECTION_CLIPPED; } ***/ } // set the distance from our camera position, to the closest vertex float distance = glm::distance(getPosition(), box.calcCenter()); projectedPolygon.setDistance(distance); projectedPolygon.setAnyInView(anyPointsInView); projectedPolygon.setAllInView(allPointsInView); projectedPolygon.setProjectionType(lookUp); // remember the projection type return projectedPolygon; }
void EntityItem::recalculateCollisionShape() { AACube entityAACube = getMinimumAACube(); entityAACube.scale(TREE_SCALE); // scale to meters _collisionShape.setTranslation(entityAACube.calcCenter()); _collisionShape.setScale(entityAACube.getScale()); }