瀏覽代碼

Removed the "unculled drawable" mechanism. Instead added occludee-flag to Drawable.
Added missing attributes to ParticleEmitter.

Lasse Öörni 14 年之前
父節點
當前提交
75beda5f3a

+ 5 - 3
Bin/Data/Scripts/Editor/EditorGizmo.as

@@ -70,15 +70,17 @@ void CreateGizmo()
     gizmo.materials[1] = cache.GetResource("Material", "Materials/GreenUnlit.xml");
     gizmo.materials[2] = cache.GetResource("Material", "Materials/BlueUnlit.xml");
     gizmo.visible = false;
-    
+    gizmo.viewMask = 0x80000000; // Editor raycasts use viewmask 0x7fffffff
+    gizmo.occludee = false;
+
     gizmoAxisX.lastSelected = false;
     gizmoAxisY.lastSelected = false;
     gizmoAxisZ.lastSelected = false;
     lastGizmoMode = EDIT_MOVE;
 
-    // Add to the octree without culling. This also makes the gizmo invisible to raycasts
+    // Add to the octree manually
     if (editorScene.octree !is null)
-        editorScene.octree.AddManualDrawable(gizmo, false);
+        editorScene.octree.AddManualDrawable(gizmo);
 }
 
 void HideGizmo()

+ 15 - 8
Docs/ScriptAPI.dox

@@ -1747,9 +1747,10 @@ Properties:<br>
 - uint id (readonly)
 - Node@ node (readonly)
 - bool inView (readonly)
+- bool visible
 - bool castShadows
 - bool occluder
-- bool visible
+- bool occludee
 - float drawDistance
 - float shadowDistance
 - float lodBias
@@ -1810,9 +1811,10 @@ Properties:<br>
 - uint id (readonly)
 - Node@ node (readonly)
 - bool inView (readonly)
+- bool visible
 - bool castShadows
 - bool occluder
-- bool visible
+- bool occludee
 - float drawDistance
 - float shadowDistance
 - float lodBias
@@ -1864,9 +1866,10 @@ Properties:<br>
 - uint id (readonly)
 - Node@ node (readonly)
 - bool inView (readonly)
+- bool visible
 - bool castShadows
 - bool occluder
-- bool visible
+- bool occludee
 - float drawDistance
 - float shadowDistance
 - float lodBias
@@ -1910,9 +1913,10 @@ Properties:<br>
 - uint id (readonly)
 - Node@ node (readonly)
 - bool inView (readonly)
+- bool visible
 - bool castShadows
 - bool occluder
-- bool visible
+- bool occludee
 - float drawDistance
 - float shadowDistance
 - float lodBias
@@ -1952,9 +1956,10 @@ Properties:<br>
 - uint id (readonly)
 - Node@ node (readonly)
 - bool inView (readonly)
+- bool visible
 - bool castShadows
 - bool occluder
-- bool visible
+- bool occludee
 - float drawDistance
 - float shadowDistance
 - float lodBias
@@ -2022,9 +2027,10 @@ Properties:<br>
 - uint id (readonly)
 - Node@ node (readonly)
 - bool inView (readonly)
+- bool visible
 - bool castShadows
 - bool occluder
-- bool visible
+- bool occludee
 - float drawDistance
 - float shadowDistance
 - float lodBias
@@ -2131,9 +2137,10 @@ Properties:<br>
 - uint id (readonly)
 - Node@ node (readonly)
 - bool inView (readonly)
+- bool visible
 - bool castShadows
 - bool occluder
-- bool visible
+- bool occludee
 - float drawDistance
 - float shadowDistance
 - float lodBias
@@ -2207,7 +2214,7 @@ Methods:<br>
 - void Remove()
 - void Resize(const BoundingBox&, uint)
 - void DrawDebugGeometry(bool) const
-- void AddManualDrawable(Drawable@, bool)
+- void AddManualDrawable(Drawable@)
 - void RemoveManualDrawable(Drawable@)
 - RayQueryResult[]@ Raycast(const Ray&, RayQueryLevel arg1 = RAY_TRIANGLE, float arg2 = M_INFINITY, uint8 arg3 = DRAWABLE_ANY, uint arg4 = DEFAULT_VIEWMASK) const
 - RayQueryResult RaycastSingle(const Ray&, RayQueryLevel arg1 = RAY_TRIANGLE, float arg2 = M_INFINITY, uint8 arg3 = DRAWABLE_ANY, uint arg4 = DEFAULT_VIEWMASK) const

+ 4 - 2
Engine/Engine/APITemplates.h

@@ -624,12 +624,14 @@ template <class T> void RegisterDrawable(asIScriptEngine* engine, const char* cl
     RegisterSubclass<Drawable, T>(engine, "Drawable", className);
     engine->RegisterObjectMethod(className, "void DrawDebugGeometry(DebugRenderer@+, bool)", asMETHOD(T, DrawDebugGeometry), asCALL_THISCALL);
     engine->RegisterObjectMethod(className, "bool get_inView() const", asFUNCTION(DrawableIsInView), asCALL_CDECL_OBJLAST);
+    engine->RegisterObjectMethod(className, "void set_visible(bool)", asMETHOD(T, SetVisible), asCALL_THISCALL);
+    engine->RegisterObjectMethod(className, "bool get_visible() const", asMETHOD(T, IsVisible), asCALL_THISCALL);
     engine->RegisterObjectMethod(className, "void set_castShadows(bool)", asMETHOD(T, SetCastShadows), asCALL_THISCALL);
     engine->RegisterObjectMethod(className, "bool get_castShadows() const", asMETHOD(T, GetCastShadows), asCALL_THISCALL);
     engine->RegisterObjectMethod(className, "void set_occluder(bool)", asMETHOD(T, SetOccluder), asCALL_THISCALL);
     engine->RegisterObjectMethod(className, "bool get_occluder() const", asMETHOD(T, IsOccluder), asCALL_THISCALL);
-    engine->RegisterObjectMethod(className, "void set_visible(bool)", asMETHOD(T, SetVisible), asCALL_THISCALL);
-    engine->RegisterObjectMethod(className, "bool get_visible() const", asMETHOD(T, IsVisible), asCALL_THISCALL);
+    engine->RegisterObjectMethod(className, "void set_occludee(bool)", asMETHOD(T, SetOccludee), asCALL_THISCALL);
+    engine->RegisterObjectMethod(className, "bool get_occludee() const", asMETHOD(T, IsOccludee), asCALL_THISCALL);
     engine->RegisterObjectMethod(className, "void set_drawDistance(float)", asMETHOD(T, SetDrawDistance), asCALL_THISCALL);
     engine->RegisterObjectMethod(className, "float get_drawDistance() const", asMETHOD(T, GetDrawDistance), asCALL_THISCALL);
     engine->RegisterObjectMethod(className, "void set_shadowDistance(float)", asMETHOD(T, SetShadowDistance), asCALL_THISCALL);

+ 1 - 1
Engine/Engine/GraphicsAPI.cpp

@@ -999,7 +999,7 @@ static void RegisterOctree(asIScriptEngine* engine)
     RegisterComponent<Octree>(engine, "Octree");
     engine->RegisterObjectMethod("Octree", "void Resize(const BoundingBox&in, uint)", asMETHOD(Octree, Resize), asCALL_THISCALL);
     engine->RegisterObjectMethod("Octree", "void DrawDebugGeometry(bool) const", asMETHOD(Octree, DrawDebugGeometry), asCALL_THISCALL);
-    engine->RegisterObjectMethod("Octree", "void AddManualDrawable(Drawable@+, bool)", asMETHOD(Octree, AddManualDrawable), asCALL_THISCALL);
+    engine->RegisterObjectMethod("Octree", "void AddManualDrawable(Drawable@+)", asMETHOD(Octree, AddManualDrawable), asCALL_THISCALL);
     engine->RegisterObjectMethod("Octree", "void RemoveManualDrawable(Drawable@+)", asMETHOD(Octree, RemoveManualDrawable), asCALL_THISCALL);
     engine->RegisterObjectMethod("Octree", "Array<RayQueryResult>@ Raycast(const Ray&in, RayQueryLevel level = RAY_TRIANGLE, float maxDistance = M_INFINITY, uint8 drawableFlags = DRAWABLE_ANY, uint viewMask = DEFAULT_VIEWMASK) const", asFUNCTION(OctreeRaycast), asCALL_CDECL_OBJLAST);
     engine->RegisterObjectMethod("Octree", "RayQueryResult RaycastSingle(const Ray&in, RayQueryLevel level = RAY_TRIANGLE, float maxDistance = M_INFINITY, uint8 drawableFlags = DRAWABLE_ANY, uint viewMask = DEFAULT_VIEWMASK) const", asFUNCTION(OctreeRaycastSingle), asCALL_CDECL_OBJLAST);

+ 1 - 0
Engine/Graphics/AnimatedModel.cpp

@@ -83,6 +83,7 @@ void AnimatedModel::RegisterObject(Context* context)
     ACCESSOR_ATTRIBUTE(AnimatedModel, VAR_RESOURCEREFLIST, "Material", GetMaterialsAttr, SetMaterialsAttr, ResourceRefList, ResourceRefList(Material::GetTypeStatic()), AM_DEFAULT);
     ATTRIBUTE(AnimatedModel, VAR_BOOL, "Is Visible", visible_, true, AM_DEFAULT);
     ATTRIBUTE(AnimatedModel, VAR_BOOL, "Is Occluder", occluder_, false, AM_DEFAULT);
+    ATTRIBUTE(AnimatedModel, VAR_BOOL, "Can Be Occluded", occludee_, true, AM_DEFAULT);
     ATTRIBUTE(AnimatedModel, VAR_BOOL, "Cast Shadows", castShadows_, false, AM_DEFAULT);
     ACCESSOR_ATTRIBUTE(AnimatedModel, VAR_FLOAT, "Draw Distance", GetDrawDistance, SetDrawDistance, float, 0.0f, AM_DEFAULT);
     ACCESSOR_ATTRIBUTE(AnimatedModel, VAR_FLOAT, "Shadow Distance", GetShadowDistance, SetShadowDistance, float, 0.0f, AM_DEFAULT);

+ 1 - 0
Engine/Graphics/BillboardSet.cpp

@@ -77,6 +77,7 @@ void BillboardSet::RegisterObject(Context* context)
     
     ACCESSOR_ATTRIBUTE(BillboardSet, VAR_RESOURCEREF, "Material", GetMaterialAttr, SetMaterialAttr, ResourceRef, ResourceRef(Material::GetTypeStatic()), AM_DEFAULT);
     ATTRIBUTE(BillboardSet, VAR_BOOL, "Is Visible", visible_, true, AM_DEFAULT);
+    ATTRIBUTE(BillboardSet, VAR_BOOL, "Can Be Occluded", occludee_, true, AM_DEFAULT);
     ATTRIBUTE(BillboardSet, VAR_BOOL, "Cast Shadows", castShadows_, false, AM_DEFAULT);
     ACCESSOR_ATTRIBUTE(BillboardSet, VAR_FLOAT, "Draw Distance", GetDrawDistance, SetDrawDistance, float, 0.0f, AM_DEFAULT);
     ACCESSOR_ATTRIBUTE(BillboardSet, VAR_FLOAT, "Shadow Distance", GetShadowDistance, SetShadowDistance, float, 0.0f, AM_DEFAULT);

+ 6 - 0
Engine/Graphics/Drawable.cpp

@@ -60,6 +60,7 @@ Drawable::Drawable(Context* context) :
     visible_(true),
     castShadows_(false),
     occluder_(false),
+    occludee_(true),
     worldBoundingBoxDirty_(true),
     updateQueued_(false),
     reinsertionQueued_(false)
@@ -167,6 +168,11 @@ void Drawable::SetOccluder(bool enable)
     occluder_ = enable;
 }
 
+void Drawable::SetOccludee(bool enable)
+{
+    occludee_ = enable;
+}
+
 void Drawable::MarkForUpdate()
 {
     if (octant_ && !updateQueued_)

+ 7 - 1
Engine/Graphics/Drawable.h

@@ -133,6 +133,8 @@ public:
     void SetCastShadows(bool enable);
     /// %Set occlusion flag.
     void SetOccluder(bool enable);
+    /// %Set occludee flag.
+    void SetOccludee(bool enable);
     /// Mark for update before octree reinsertion.
     void MarkForUpdate();
     
@@ -160,8 +162,10 @@ public:
     bool IsVisible() const { return visible_; }
     /// Return shadowcaster flag.
     bool GetCastShadows() const { return castShadows_; }
-    /// Return occlusion flag.
+    /// Return occluder flag.
     bool IsOccluder() const { return occluder_; }
+    /// Return occludee flag.
+    bool IsOccludee() const { return occludee_; }
     
     /// %Set new zone.
     void SetZone(Zone* zone);
@@ -272,6 +276,8 @@ protected:
     bool castShadows_;
     /// Occluder flag.
     bool occluder_;
+    /// Occludee flag.
+    bool occludee_;
     /// Bounding box dirty flag.
     bool worldBoundingBoxDirty_;
     /// Octree update queued flag.

+ 2 - 1
Engine/Graphics/Light.cpp

@@ -116,8 +116,9 @@ void Light::RegisterObject(Context* context)
     ACCESSOR_ATTRIBUTE(Light, VAR_RESOURCEREF, "Attenuation Texture", GetRampTextureAttr, SetRampTextureAttr, ResourceRef, ResourceRef(Texture2D::GetTypeStatic()), AM_DEFAULT);
     ACCESSOR_ATTRIBUTE(Light, VAR_RESOURCEREF, "Light Shape Texture", GetShapeTextureAttr, SetShapeTextureAttr, ResourceRef, ResourceRef(Texture2D::GetTypeStatic()), AM_DEFAULT);
     ATTRIBUTE(Light, VAR_BOOL, "Is Visible", visible_, true, AM_DEFAULT);
-    ATTRIBUTE(Light, VAR_BOOL, "Per Vertex", perVertex_, false, AM_DEFAULT);
+    ATTRIBUTE(Light, VAR_BOOL, "Can Be Occluded", occludee_, true, AM_DEFAULT);
     ATTRIBUTE(Light, VAR_BOOL, "Cast Shadows", castShadows_, false, AM_DEFAULT);
+    ATTRIBUTE(Light, VAR_BOOL, "Per Vertex", perVertex_, false, AM_DEFAULT);
     ACCESSOR_ATTRIBUTE(Light, VAR_FLOAT, "Draw Distance", GetDrawDistance, SetDrawDistance, float, 0.0f, AM_DEFAULT);
     ACCESSOR_ATTRIBUTE(Light, VAR_FLOAT, "Fade Distance", GetFadeDistance, SetFadeDistance, float, 0.0f, AM_DEFAULT);
     ACCESSOR_ATTRIBUTE(Light, VAR_FLOAT, "Shadow Distance", GetShadowDistance, SetShadowDistance, float, 0.0f, AM_DEFAULT);

+ 2 - 40
Engine/Graphics/Octree.cpp

@@ -369,23 +369,12 @@ void Octree::Update(const FrameInfo& frame)
     ReinsertDrawables(frame);
 }
 
-void Octree::AddManualDrawable(Drawable* drawable, bool culling)
+void Octree::AddManualDrawable(Drawable* drawable)
 {
     if (!drawable || drawable->GetOctant())
         return;
     
-    if (culling)
-        AddDrawable(drawable);
-    else
-    {
-        for (Vector<WeakPtr<Drawable> >::ConstIterator i = unculledDrawables_.Begin(); i != unculledDrawables_.End(); ++i)
-        {
-            if ((*i) == drawable)
-                return;
-        }
-        
-        unculledDrawables_.Push(WeakPtr<Drawable>(drawable));
-    }
+    AddDrawable(drawable);
 }
 
 void Octree::RemoveManualDrawable(Drawable* drawable)
@@ -400,17 +389,6 @@ void Octree::RemoveManualDrawable(Drawable* drawable)
         CancelReinsertion(drawable);
         octant->RemoveDrawable(drawable);
     }
-    else
-    {
-        for (Vector<WeakPtr<Drawable> >::Iterator i = unculledDrawables_.Begin(); i != unculledDrawables_.End(); ++i)
-        {
-            if ((*i) == drawable)
-            {
-                unculledDrawables_.Erase(i);
-                return;
-            }
-        }
-    }
 }
 
 void Octree::GetDrawables(OctreeQuery& query) const
@@ -419,15 +397,6 @@ void Octree::GetDrawables(OctreeQuery& query) const
     GetDrawablesInternal(query, false);
 }
 
-void Octree::GetUnculledDrawables(PODVector<Drawable*>& dest, unsigned char drawableFlags) const
-{
-    for (Vector<WeakPtr<Drawable> >::ConstIterator i = unculledDrawables_.Begin(); i != unculledDrawables_.End(); ++i)
-    {
-        if (*i && (*i)->IsVisible() && (*i)->GetDrawableFlags() & drawableFlags)
-            dest.Push(*i);
-    }
-}
-
 void Octree::Raycast(RayOctreeQuery& query) const
 {
     PROFILE(Raycast);
@@ -612,13 +581,6 @@ void Octree::UpdateDrawables(const FrameInfo& frame)
     queue->Complete();
     scene->EndThreadedUpdate();
     drawableUpdates_.Clear();
-    
-    for (unsigned i = unculledDrawables_.Size() - 1; i < unculledDrawables_.Size(); --i)
-    {
-        // Remove expired unculled drawables at this point
-        if (!unculledDrawables_[i])
-            unculledDrawables_.Erase(i, 1);
-    }
 }
 
 void Octree::ReinsertDrawables(const FrameInfo& frame)

+ 2 - 6
Engine/Graphics/Octree.h

@@ -169,15 +169,13 @@ public:
     void Resize(const BoundingBox& box, unsigned numLevels);
     /// Update and reinsert drawable objects.
     void Update(const FrameInfo& frame);
-    /// Add a drawable manually, which can optionally be unculled.
-    void AddManualDrawable(Drawable* drawable, bool culling);
+    /// 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 unculled drawables by drawable type. The destination vector will not be cleared.
-    void GetUnculledDrawables(PODVector<Drawable*>& dest, unsigned char drawableFlags) const;
     /// Return drawable objects by a ray query.
     void Raycast(RayOctreeQuery& query) const;
     /// Return the closest drawable object by a ray query.
@@ -214,8 +212,6 @@ private:
     PODVector<Drawable*> drawableReinsertions_;
     /// Mutex for octree reinsertions.
     Mutex octreeMutex_;
-    /// Unculled drawables.
-    Vector<WeakPtr<Drawable> > unculledDrawables_;
     /// Current threaded ray query.
     mutable RayOctreeQuery* rayQuery_;
     /// Drawable list for threaded ray query.

+ 3 - 0
Engine/Graphics/ParticleEmitter.cpp

@@ -82,6 +82,9 @@ void ParticleEmitter::RegisterObject(Context* context)
     
     ACCESSOR_ATTRIBUTE(ParticleEmitter, VAR_RESOURCEREF, "Parameter Source", GetParameterSourceAttr, SetParameterSourceAttr, ResourceRef, ResourceRef(XMLFile::GetTypeStatic()), AM_DEFAULT);
     ATTRIBUTE(ParticleEmitter, VAR_BOOL, "Is Active", active_, true, AM_DEFAULT);
+    ATTRIBUTE(ParticleEmitter, VAR_BOOL, "Is Visible", visible_, true, AM_DEFAULT);
+    ATTRIBUTE(ParticleEmitter, VAR_BOOL, "Can Be Occluded", occludee_, true, AM_DEFAULT);
+    ATTRIBUTE(ParticleEmitter, VAR_BOOL, "Cast Shadows", castShadows_, false, AM_DEFAULT);
     ATTRIBUTE(ParticleEmitter, VAR_BOOL, "Relative Scale", scaled_, true, AM_DEFAULT);
     ACCESSOR_ATTRIBUTE(ParticleEmitter, VAR_FLOAT, "Animation LOD Bias", GetAnimationLodBias, SetAnimationLodBias, float, 1.0f, AM_DEFAULT);
     ATTRIBUTE(ParticleEmitter, VAR_FLOAT, "Period Timer", periodTimer_, 0.0f, AM_DEFAULT | AM_NOEDIT);

+ 1 - 0
Engine/Graphics/StaticModel.cpp

@@ -62,6 +62,7 @@ void StaticModel::RegisterObject(Context* context)
     ACCESSOR_ATTRIBUTE(StaticModel, VAR_RESOURCEREFLIST, "Material", GetMaterialsAttr, SetMaterialsAttr, ResourceRefList, ResourceRefList(Material::GetTypeStatic()), AM_DEFAULT);
     ATTRIBUTE(StaticModel, VAR_BOOL, "Is Visible", visible_, true, AM_DEFAULT);
     ATTRIBUTE(StaticModel, VAR_BOOL, "Is Occluder", occluder_, false, AM_DEFAULT);
+    ATTRIBUTE(StaticModel, VAR_BOOL, "Can Be Occluded", occludee_, true, AM_DEFAULT);
     ATTRIBUTE(StaticModel, VAR_BOOL, "Cast Shadows", castShadows_, false, AM_DEFAULT);
     ACCESSOR_ATTRIBUTE(StaticModel, VAR_FLOAT, "Draw Distance", GetDrawDistance, SetDrawDistance, float, 0.0f, AM_DEFAULT);
     ACCESSOR_ATTRIBUTE(StaticModel, VAR_FLOAT, "Shadow Distance", GetShadowDistance, SetShadowDistance, float, 0.0f, AM_DEFAULT);

+ 1 - 7
Engine/Graphics/View.cpp

@@ -63,13 +63,11 @@ void CheckVisibilityWork(const WorkItem* item, unsigned threadIndex)
     View* view = reinterpret_cast<View*>(item->aux_);
     Drawable** start = reinterpret_cast<Drawable**>(item->start_);
     Drawable** end = reinterpret_cast<Drawable**>(item->end_);
-    Drawable** unculledStart = &view->tempDrawables_[0][0] + view->unculledDrawableStart_;
     OcclusionBuffer* buffer = view->occlusionBuffer_;
     
     while (start != end)
     {
         Drawable* drawable = *start;
-        bool useOcclusion = start < unculledStart;
         unsigned char flags = drawable->GetDrawableFlags();
         ++start;
         
@@ -83,7 +81,7 @@ void CheckVisibilityWork(const WorkItem* item, unsigned threadIndex)
         if (maxDistance > 0.0f && drawable->GetDistance() > maxDistance)
             continue;
         
-        if (buffer && useOcclusion && !buffer->IsVisible(drawable->GetWorldBoundingBox()))
+        if (buffer && drawable->IsOccludee() && !buffer->IsVisible(drawable->GetWorldBoundingBox()))
             continue;
         
         drawable->MarkInView(view->frame_);
@@ -372,10 +370,6 @@ void View::GetDrawables()
     FrustumOctreeQuery query(tempDrawables, frustum_, DRAWABLE_GEOMETRY | DRAWABLE_LIGHT | DRAWABLE_ZONE);
     octree_->GetDrawables(query);
     
-    // Add unculled geometries & lights
-    unculledDrawableStart_ = tempDrawables.Size();
-    octree_->GetUnculledDrawables(tempDrawables, DRAWABLE_GEOMETRY | DRAWABLE_LIGHT);
-    
     // Get zones and occluders first
     highestZonePriority_ = M_MIN_INT;
     int bestPriority = M_MIN_INT;

+ 0 - 2
Engine/Graphics/View.h

@@ -268,8 +268,6 @@ private:
     int maxOccluderTriangles_;
     /// Highest zone priority currently visible.
     int highestZonePriority_;
-    /// Start index of unculled drawables. These will not be tested for occlusion.
-    unsigned unculledDrawableStart_;
     /// Current stencil value for light optimization.
     unsigned char lightStencilValue_;
     /// Light prepass flag.