void CRasterTerrainModel::Update(CErrorMetric const & metric, GLUtils::CViewFrustum const & frustum) { InitGLResources(); mActivePatches.clear(); RecursiveUpdate(mRoot, metric, frustum); }
void dd::World::Update(double dt) { for (auto pair : m_Systems) { const std::string &type = pair.first; auto system = pair.second; EventBroker->Process(type); system->Update(dt); RecursiveUpdate(system, dt, 0); } ProcessEntityRemovals(); }
void VertexCoordRemapper::UpdateAndResetIndex() { DEBUG_DEBUG("mesh update update reset index"); // this sets scale, height, and width. MeshRemapper::UpdateAndResetIndex(); // we need to record the output projection for flipping around 180 degrees. output_projection = visualization_state->GetOptions()->getProjection(); o_width = visualization_state->GetOptions()->getWidth(); o_height = visualization_state->GetOptions()->getHeight(); // we want to make a remapped mesh, get the transformation we need: // HuginBase::SrcPanoImage *src = visualization_state->GetSrcImage(image_number); transform.createInvTransform(*image, *(visualization_state->GetOptions())); // use the scale to determine edge lengths in pixels for subdivision // DEBUG_INFO("updating mesh for image " << image_number << ", using scale " // << scale << ".\n"); // find key points used for +/- 180 degree boundary correction // {x|y}_add_360's are added to a value near the left/top boundary to get // the corresponding point over the right/bottom boundary. // other values are used to check where the boundary is. OutputProjectionInfo *info = visualization_state->GetProjectionInfo(); x_add_360 = info->GetXAdd360(); radius = info->GetRadius(); y_add_360 = info->GetYAdd360(); x_midpoint = info->GetMiddleX(); y_midpoint = info->GetMiddleY(); lower_bound = info->GetLowerX(); upper_bound = info->GetUpperX(); lower_bound_h = info->GetLowerY(); upper_bound_h = info->GetUpperY(); // Find the cropping region of the source image, so we can stick to the // bounding rectangle. SetCrop(); // the tree needs to know how to use the croping information for generating tree.x_crop_scale = crop_x2 - crop_x1; tree.x_crop_offs = crop_x1; tree.y_crop_scale = crop_y2 - crop_y1; tree.y_crop_offs = crop_y1; // make the tree reflect the transformation RecursiveUpdate(0, 0, 0); // now set up for examining the tree contents. tree.ResetIndex(); done_node = true; }
void CRasterTerrainModel::RecursiveUpdate(Patch * p, CErrorMetric const & metric, GLUtils::CViewFrustum const & frustum) { p->tessLevel = 0; if (frustum.Intersects(p->bbmin, p->bbmax)) { if (metric.Evaluate(p->bbmin, p->bbmax, p->error) && !p->IsLeaf()) { for (glm::uint i=0; i < 4; ++i) if (p->childs[i]) RecursiveUpdate(p->childs[i], metric, frustum); } else { p->Commit(); p->ReleaseChilds(); p->propagateTessLevel(0); mActivePatches.push_back(p); } } else { p->Release(); p->ReleaseChilds(); } }
void VertexCoordRemapper::RecursiveUpdate(unsigned int node_num, unsigned int stretch_x, unsigned stretch_y) { // find where we are and what we are mapping // TODO? GetPosition is called by GetInputCoordinates, reuse results? unsigned int x, y, row_size, depth; tree.GetPosition(node_num, x, y, row_size, depth); tree.GetInputCoordinates(node_num, tex_coords); TreeNode *node = &tree.nodes[node_num], *parent = (depth) ? &tree.nodes[tree.GetParentId(x, y, row_size, depth)] : 0, *left = (x % 2) ? &tree.nodes[tree.GetIndex(x-1, y, row_size, depth)] : 0, *top = (y % 2) ? &tree.nodes[tree.GetIndex(x, y-1, row_size, depth)] : 0; bool valid[2][2]; for (unsigned short int i = 0; i < 2; i++) { for (unsigned short int j = 0; j < 2; j++) { if (depth == 0) { // the top level has no parent, so we must calculate all points valid[i][j] = transform.transformImgCoord(node->verts[i][j][0], node->verts[i][j][1], tex_coords[i][j][0] * width, tex_coords[i][j][1] * height); } else // Look up where the point in the tree so far. If this is the first // occurrence of this point, we'll calculate the value. if (i == x %2 && j == y%2 && depth) { // extract a corner from the parent. node->verts[i][j][0] = parent->verts[i][j][0]; node->verts[i][j][1] = parent->verts[i][j][1]; valid[i][j] = !(parent->flags & (transform_fail_flag << (j*2 +i))); } else if (x % 2 && !i) { // copy from the left node->verts[0][j][0] = left->verts[1][j][0]; node->verts[0][j][1] = left->verts[1][j][1]; valid[i][j] = !(left->flags & (transform_fail_flag << (j *2 + 1))); } else if (y % 2 && !j) { // copy from the top node->verts[i][0][0] = top->verts[i][1][0]; node->verts[i][0][1] = top->verts[i][1][1]; valid[i][j] = !(top->flags & (transform_fail_flag << (2 + i))); } else { // We can't find it easily, try a more expensive search. // this will linearly interpolate along the edges where the // subdivision was higher, avoiding gaps when the detail level // was lower above or to the left. if (!tree.GetTransform(x + i * (1 << stretch_x), y + j * (1 << stretch_y), depth, x, y, node->verts[i][j][0], node->verts[i][j][1])) { // We can't find it, so calculate it: valid[i][j] = transform.transformImgCoord(node->verts[i][j][0], node->verts[i][j][1], tex_coords[i][j][0] * width, tex_coords[i][j][1] * height); // If the face results from a patch subdivision (for // aligning a subdivided face, otherwise it need not exist), // use the midpoint of the parent's vertices instead of // calculating a transformed one, so we can use less // subdivision on the other side. // subdivision in x // FIXME there are still gaps. I think there's a logic error if ( depth // not on the top level. // patching in y && (parent->flags & patch_flag_x) // we must be in the middle of the split, the nodes on // the corners of the parent line up anyway. && ((i + x) % 2) // we should be on the side away from the subdivison // (+ve y). && j // If we are alao split in y we can use the middle // node to provide more detail. && (!((parent->flags & split_flag_y) && !(y % 2))) // don't do this if we cross the 180 degree seam && (!(parent->flags & (vertex_side_flag_start * 15)))) { node->verts[i][1][0] = (parent->verts[0][1][0] + parent->verts[1][1][0]) / 2.0; node->verts[i][1][1] = (parent->verts[0][1][1] + parent->verts[1][1][1]) / 2.0; } // subdivision in y if ( depth && (parent->flags & patch_flag_y) && ((j + y) % 2) && i && (!((parent->flags & split_flag_x) && !(x % 2))) && (!(parent->flags & (vertex_side_flag_start * 15)))) { node->verts[1][j][0] = (parent->verts[1][0][0] + parent->verts[1][1][0]) / 2.0; node->verts[1][j][1] = (parent->verts[1][0][1] + parent->verts[1][1][1]) / 2.0; } } else { // we managed to find it from data already known. valid[i][j] = true; } } } } // now for the recursion // which directions should we divide in? TestSubdivide(node_num); // add the flags for invlaid transormations for (unsigned int i = 0; i < 2; i++) { for (unsigned int j = 0; j < 2; j++) { if (!valid[i][j]) { node->flags |= transform_fail_flag << (j * 2 + i); } } } // if the face should be split, now recurse to the child nodes. if (node->flags & (split_flag_x | split_flag_y)) { // we will split at least one way. if (!(node->flags & split_flag_x)) { // we are not splitting across x, but will will across y. // so the quad will be twice as wide stretch_x++; } else if (!(node->flags & split_flag_y)) { stretch_y++; } // find the top left sub-quad x *= 2; y *= 2; row_size *= 2; depth++; // the top left is always generated RecursiveUpdate(tree.GetIndex(x, y, row_size, depth), stretch_x, stretch_y); // split in x if (node->flags & split_flag_x) { RecursiveUpdate(tree.GetIndex(x + 1, y, row_size, depth), stretch_x, stretch_y); } // split in y if (node->flags & split_flag_y) { RecursiveUpdate(tree.GetIndex(x, y + 1, row_size, depth), stretch_x, stretch_y); // if we are splitting in both directions, do the lower right corner if (node->flags & split_flag_x) { RecursiveUpdate(tree.GetIndex(x + 1, y + 1, row_size, depth), stretch_x, stretch_y); } } } }