$#include "Octree.h" /// %Octree component. Should be added only to the root scene node class Octree : public Component { public: /// Resize octree. If octree is not empty, drawable objects will be temporarily moved to the root. void Resize(const BoundingBox& box, unsigned numLevels); /// Update and reinsert drawable objects. void Update(const FrameInfo& frame); /// Add a drawable manually. void AddManualDrawable(Drawable* drawable); /// Remove a manually added drawable. void RemoveManualDrawable(Drawable* drawable); /// Return drawable objects by a query. void GetDrawables(OctreeQuery& query) const; /// Return drawable objects by a ray query. void Raycast(RayOctreeQuery& query) const; /// Return the closest drawable object by a ray query. // void RaycastSingle(RayOctreeQuery& query) const; tolua_outside RayQueryResult OctreeRaycastSingle @ RaycastSingle(const Ray& ray, RayQueryLevel level, float maxDistance, unsigned char drawableFlags); /// Return subdivision levels. unsigned GetNumLevels() const { return numLevels_; } /// Mark drawable object as requiring an update. void QueueUpdate(Drawable* drawable); /// Mark drawable object as requiring a reinsertion. Is thread-safe. void QueueReinsertion(Drawable* drawable); /// Visualize the component as debug geometry. void DrawDebugGeometry(bool depthTest); }; ${ static RayQueryResult OctreeRaycastSingle(Octree* octree, const Ray& ray, RayQueryLevel level, float maxDistance, unsigned char drawableFlags) { PODVector result; RayOctreeQuery query(result, ray, level, maxDistance, drawableFlags); octree->RaycastSingle(query); if (!query.result_.Empty()) return query.result_[0]; else { RayQueryResult empty; empty.drawable_ = 0; empty.node_ = 0; empty.distance_ = M_INFINITY; empty.subObject_ = 0; return empty; } } $}