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; }
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 }