void OCTree::ClipScene() { if (rebuild_tree_) { octree_.resize(1); AABBox bb_root(float3(0, 0, 0), float3(0, 0, 0)); octree_[0].first_child_index = -1; octree_[0].visible = BO_No; KLAYGE_FOREACH(SceneObjAABBPtrType const & soaabb, scene_objs_) { SceneObjectPtr const & obj = soaabb->so; uint32_t const attr = obj->Attrib(); if ((attr & SceneObject::SOA_Cullable) && !(attr & SceneObject::SOA_Overlay) && !(attr & SceneObject::SOA_Moveable)) { bb_root |= *soaabb->aabb_ws; octree_[0].obj_ptrs.push_back(soaabb); } } float3 const & center = bb_root.Center(); float3 const & extent = bb_root.HalfSize(); float longest_dim = std::max(std::max(extent.x(), extent.y()), extent.z()); float3 new_extent(longest_dim, longest_dim, longest_dim); octree_[0].bb = AABBox(center - new_extent, center + new_extent); this->DivideNode(0, 1); rebuild_tree_ = false; }
extent_list init_extent(const_extent_list ranges, const_index_entry_list quantifier_indices, const_user_type_entry_list user_type_table) { register unsigned int ix; extent_list extent = new_extent_list(); for (ix = 0; ix < ranges->sz; ix++) { int v = eval_int_expr(ranges->arr[ix]->from, quantifier_indices, user_type_table); append_extent_list(extent, new_extent(to_expr(new_expr_int(to_type(new_int_type()), v)), to_expr(new_expr_int(to_type(new_int_type()), v)))); } return extent; }
fbl::unique_ptr<SliceExtent> SliceExtent::Split(size_t vslice) { ZX_DEBUG_ASSERT(start() <= vslice); ZX_DEBUG_ASSERT(vslice < end()); fbl::AllocChecker ac; fbl::unique_ptr<SliceExtent> new_extent(new (&ac) SliceExtent(vslice + 1)); if (!ac.check()) { return nullptr; } new_extent->pslices_.reserve(end() - vslice, &ac); if (!ac.check()) { return nullptr; } for (size_t vs = vslice + 1; vs < end(); vs++) { ZX_ASSERT(new_extent->push_back(get(vs))); } while (!is_empty() && vslice + 1 != end()) { pop_back(); } return new_extent; }
void OCTree::ClipScene() { if (rebuild_tree_) { octree_.resize(1); AABBox bb_root(float3(0, 0, 0), float3(0, 0, 0)); octree_[0].first_child_index = -1; octree_[0].visible = BO_No; for (SceneObjsType::const_reference obj : scene_objs_) { uint32_t const attr = obj->Attrib(); if ((attr & SceneObject::SOA_Cullable) && !(attr & SceneObject::SOA_Moveable)) { bb_root |= *obj->PosBoundWS(); octree_[0].obj_ptrs.push_back(obj); } } float3 const & center = bb_root.Center(); float3 const & extent = bb_root.HalfSize(); float longest_dim = std::max(std::max(extent.x(), extent.y()), extent.z()); float3 new_extent(longest_dim, longest_dim, longest_dim); octree_[0].bb = AABBox(center - new_extent, center + new_extent); this->DivideNode(0, 1); rebuild_tree_ = false; } #ifdef KLAYGE_DRAW_NODES if (!node_renderable_) { node_renderable_ = MakeSharedPtr<NodeRenderable>(); } checked_pointer_cast<NodeRenderable>(node_renderable_)->ClearInstances(); #endif if (!octree_.empty()) { this->NodeVisible(0); } App3DFramework& app = Context::Instance().AppInstance(); Camera& camera = app.ActiveCamera(); float4x4 view_proj = camera.ViewProjMatrix(); DeferredRenderingLayerPtr const & drl = Context::Instance().DeferredRenderingLayerInstance(); if (drl) { int32_t cas_index = drl->CurrCascadeIndex(); if (cas_index >= 0) { view_proj *= drl->GetCascadedShadowLayer()->CascadeCropMatrix(cas_index); } } if (camera.OmniDirectionalMode()) { for (SceneObjsType::const_reference obj : scene_objs_) { if (obj->Visible()) { uint32_t const attr = obj->Attrib(); if (attr & SceneObject::SOA_Moveable) { obj->UpdateAbsModelMatrix(); } if (attr & SceneObject::SOA_Cullable) { AABBoxPtr aabb_ws = obj->PosBoundWS(); obj->VisibleMark((MathLib::perspective_area(camera.EyePos(), view_proj, *aabb_ws) > small_obj_threshold_) ? BO_Yes : BO_No); } } else { obj->VisibleMark(BO_No); } } } else { if (!octree_.empty()) { this->MarkNodeObjs(0, false); } for (SceneObjsType::const_reference obj : scene_objs_) { if (obj->Visible()) { BoundOverlap visible = this->VisibleTestFromParent(obj, camera.EyePos(), view_proj); if (BO_Partial == visible) { uint32_t const attr = obj->Attrib(); if (attr & SceneObject::SOA_Moveable) { obj->UpdateAbsModelMatrix(); } if (attr & SceneObject::SOA_Cullable) { if (attr & SceneObject::SOA_Moveable) { obj->VisibleMark(this->AABBVisible(*obj->PosBoundWS())); } else { obj->VisibleMark(visible); } } else { obj->VisibleMark(BO_Yes); } } else { obj->VisibleMark(visible); } } } } #ifdef KLAYGE_DRAW_NODES node_renderable_->Render(); #endif }
/* * grow_fork() * * Try to add enough allocation blocks to 'fork' * so that it is 'ablock' allocation blocks long. */ static int grow_fork(struct hfs_fork *fork, int ablocks) { struct hfs_cat_entry *entry = fork->entry; struct hfs_mdb *mdb = entry->mdb; struct hfs_extent *ext; int i, start, err; hfs_u16 need, len=0; hfs_u32 ablksz = mdb->alloc_blksz; hfs_u32 blocks, clumpablks; blocks = fork->psize; need = ablocks - blocks/ablksz; if (need < 1) { /* no need to grow the fork */ return 0; } /* round up to clumpsize */ if (entry->u.file.clumpablks) { clumpablks = entry->u.file.clumpablks; } else { clumpablks = mdb->clumpablks; } need = ((need + clumpablks - 1) / clumpablks) * clumpablks; /* find last extent record and try to extend it */ if (!(ext = find_ext(fork, blocks/ablksz - 1))) { /* somehow we couldn't find the end of the file! */ return -1; } /* determine which is the last used extent in the record */ /* then try to allocate the blocks immediately following it */ for (i=2; (i>=0) && !ext->length[i]; --i) {}; if (i>=0) { /* try to extend the last extent */ start = ext->block[i] + ext->length[i]; err = 0; lock_bitmap(mdb); len = hfs_vbm_count_free(mdb, start); if (!len) { unlock_bitmap(mdb); goto more_extents; } if (need < len) { len = need; } err = hfs_set_vbm_bits(mdb, start, len); unlock_bitmap(mdb); if (err) { relse_ext(ext); return -1; } zero_blocks(mdb, start, len); ext->length[i] += len; ext->end += len; blocks = (fork->psize += len * ablksz); need -= len; update_ext(fork, ext); } more_extents: /* add some more extents */ while (need) { len = need; err = 0; lock_bitmap(mdb); start = hfs_vbm_search_free(mdb, &len); if (need < len) { len = need; } err = hfs_set_vbm_bits(mdb, start, len); unlock_bitmap(mdb); if (!len || err) { relse_ext(ext); return -1; } zero_blocks(mdb, start, len); /* determine which is the first free extent in the record */ for (i=0; (i<3) && ext->length[i]; ++i) {}; if (i < 3) { ext->block[i] = start; ext->length[i] = len; ext->end += len; update_ext(fork, ext); } else { if (!(ext = new_extent(fork, ext, blocks/ablksz, start, len, ablksz))) { lock_bitmap(mdb); hfs_clear_vbm_bits(mdb, start, len); unlock_bitmap(mdb); return -1; } } blocks = (fork->psize += len * ablksz); need -= len; } set_cache(fork, ext); relse_ext(ext); return 0; }