Browse Source

Fix missing sound playback start/stop when using the play/pause buttons in editor toolbar. Improved sphere debug drawing. Added debug drawing to SoundSource3D. Closes #63.

Lasse Öörni 12 years ago
parent
commit
088dba041c

+ 12 - 7
Bin/Data/Scripts/Editor/EditorScene.as

@@ -338,19 +338,24 @@ void StopSceneUpdate()
 {
     runUpdate = false;
     audio.Stop();
+    toolBarDirty = true;
 }
 
-bool ToggleSceneUpdate()
+void StartSceneUpdate()
 {
-    runUpdate = !runUpdate;
+    runUpdate = true;
     // Run audio playback only when scene is updating, so that audio components' time-dependent attributes stay constant when
     // paused (similar to physics)
-    if (runUpdate)
-        audio.Play();
-    else
-        audio.Stop();
-
+    audio.Play();
     toolBarDirty = true;
+}
+
+bool ToggleSceneUpdate()
+{
+    if (!runUpdate)
+        StartSceneUpdate();
+    else
+        StopSceneUpdate();
     return true;
 }
 

+ 2 - 2
Bin/Data/Scripts/Editor/EditorToolBar.as

@@ -131,7 +131,7 @@ void ToolBarRunUpdatePlay(StringHash eventType, VariantMap& eventData)
 {
     CheckBox@ edit = eventData["Element"].GetUIElement();
     if (edit.checked)
-        runUpdate = true;
+        StartSceneUpdate();
     toolBarDirty = true;
 }
 
@@ -139,7 +139,7 @@ void ToolBarRunUpdatePause(StringHash eventType, VariantMap& eventData)
 {
     CheckBox@ edit = eventData["Element"].GetUIElement();
     if (edit.checked)
-        runUpdate = false;
+        StopSceneUpdate();
     toolBarDirty = true;
 }
 

+ 85 - 1
Source/Engine/Audio/SoundSource3D.cpp

@@ -23,6 +23,7 @@
 #include "Precompiled.h"
 #include "Audio.h"
 #include "Context.h"
+#include "DebugRenderer.h"
 #include "Node.h"
 #include "Sound.h"
 #include "SoundListener.h"
@@ -38,9 +39,68 @@ static const float DEFAULT_FARDISTANCE = 100.0f;
 static const float DEFAULT_ROLLOFF = 2.0f;
 static const float DEFAULT_ANGLE = 360.0f;
 static const float MIN_ROLLOFF = 0.1f;
+static const Color INNER_COLOR(1.0f, 0.5f, 1.0f);
+static const Color OUTER_COLOR(1.0f, 0.0f, 1.0f);
 
 extern const char* AUDIO_CATEGORY;
 
+static Vector3 PointOnSphere(float radius, float theta, float phi)
+{
+    // Zero angles point toward positive Z axis
+    phi += 90.0f;
+    
+    return Vector3(
+        radius * Sin(theta) * Sin(phi),
+        radius * Cos(phi),
+        radius * Cos(theta) * Sin(phi)
+    );
+}
+
+static void DrawDebugArc(const Vector3& worldPosition, const Quaternion& worldRotation, float angle, float distance, bool drawLines,
+    const Color& color, DebugRenderer* debug, bool depthTest)
+{
+    if (angle <= 0.f)
+        return;
+    else if (angle >= 360.0f)
+    {
+        debug->AddSphere(Sphere(worldPosition, distance), color, depthTest);
+        return;
+    }
+    
+    unsigned uintColor = color.ToUInt();
+    float halfAngle = 0.5f * angle;
+    
+    if (drawLines)
+    {
+        debug->AddLine(worldPosition, worldPosition + worldRotation * PointOnSphere(distance, halfAngle, halfAngle),
+            uintColor);
+        debug->AddLine(worldPosition, worldPosition + worldRotation * PointOnSphere(distance, -halfAngle, halfAngle),
+            uintColor);
+        debug->AddLine(worldPosition, worldPosition + worldRotation * PointOnSphere(distance, halfAngle, -halfAngle),
+            uintColor);
+        debug->AddLine(worldPosition, worldPosition + worldRotation * PointOnSphere(distance, -halfAngle, -halfAngle),
+            uintColor);
+    }
+    
+    const float step = 0.5f;
+    
+    for (float x = -1.0f; x < 1.0f; x += step)
+    {
+        debug->AddLine(worldPosition + worldRotation * PointOnSphere(distance, x * halfAngle, halfAngle),
+            worldPosition + worldRotation * PointOnSphere(distance, (x + step) * halfAngle, halfAngle),
+            uintColor);
+        debug->AddLine(worldPosition + worldRotation * PointOnSphere(distance, x * halfAngle, -halfAngle),
+            worldPosition + worldRotation * PointOnSphere(distance, (x + step) * halfAngle, -halfAngle),
+            uintColor);
+        debug->AddLine(worldPosition + worldRotation * PointOnSphere(distance, halfAngle, x * halfAngle),
+            worldPosition + worldRotation * PointOnSphere(distance, halfAngle, (x + step) * halfAngle),
+            uintColor);
+        debug->AddLine(worldPosition + worldRotation * PointOnSphere(distance, -halfAngle, x * halfAngle),
+            worldPosition + worldRotation * PointOnSphere(distance, -halfAngle, (x + step) * halfAngle),
+            uintColor);
+    }
+}
+
 SoundSource3D::SoundSource3D(Context* context) :
     SoundSource(context),
     nearDistance_(DEFAULT_NEARDISTANCE),
@@ -68,6 +128,30 @@ void SoundSource3D::RegisterObject(Context* context)
     ATTRIBUTE(SoundSource3D, VAR_FLOAT, "Rolloff Factor", rolloffFactor_, DEFAULT_ROLLOFF, AM_DEFAULT);
 }
 
+void SoundSource3D::DrawDebugGeometry(DebugRenderer* debug, bool depthTest)
+{
+    if (!debug || !node_ || !IsEnabledEffective())
+        return;
+    
+    const Matrix3x4& worldTransform = node_->GetWorldTransform();
+    Vector3 worldPosition = worldTransform.Translation();
+    Quaternion worldRotation = worldTransform.Rotation();
+    
+    // Draw cones for directional sounds, or spheres for non-directional
+    if (innerAngle_ < DEFAULT_ANGLE && outerAngle_ > 0.0f)
+    {
+        DrawDebugArc(worldPosition, worldRotation, innerAngle_, nearDistance_, false, INNER_COLOR, debug, depthTest);
+        DrawDebugArc(worldPosition, worldRotation, outerAngle_, nearDistance_, false, OUTER_COLOR, debug, depthTest);
+        DrawDebugArc(worldPosition, worldRotation, innerAngle_, farDistance_, true, INNER_COLOR, debug, depthTest);
+        DrawDebugArc(worldPosition, worldRotation, outerAngle_, farDistance_, true, OUTER_COLOR, debug, depthTest);
+    }
+    else
+    {
+        debug->AddSphere(Sphere(worldPosition, nearDistance_), INNER_COLOR, depthTest);
+        debug->AddSphere(Sphere(worldPosition, farDistance_), OUTER_COLOR, depthTest);
+    }
+}
+
 void SoundSource3D::Update(float timeStep)
 {
     CalculateAttenuation();
@@ -146,7 +230,7 @@ void SoundSource3D::CalculateAttenuation()
             panning_ = relativePos.Normalized().x_;
             
             // Angle attenuation
-            if (innerAngle_ < DEFAULT_ANGLE)
+            if (innerAngle_ < DEFAULT_ANGLE && outerAngle_ > 0.0f)
             {
                 Vector3 listenerRelativePos(node_->GetWorldRotation().Inverse() * (listenerNode->GetWorldPosition() -
                     node_->GetWorldPosition()));

+ 2 - 0
Source/Engine/Audio/SoundSource3D.h

@@ -40,6 +40,8 @@ public:
     /// Register object factory.
     static void RegisterObject(Context* context);
     
+    /// Visualize the component as debug geometry.
+    virtual void DrawDebugGeometry(DebugRenderer* debug, bool depthTest);
     /// Update sound source.
     virtual void Update(float timeStep);
     

+ 23 - 20
Source/Engine/Graphics/DebugRenderer.cpp

@@ -195,30 +195,33 @@ void DebugRenderer::AddPolyhedron(const Polyhedron& poly, const Color& color, bo
     }
 }
 
+static Vector3 PointOnSphere(const Sphere& sphere, unsigned theta, unsigned phi)
+{
+    return Vector3(
+        sphere.center_.x_ + sphere.radius_ * Sin((float)theta) * Sin((float)phi),
+        sphere.center_.y_ + sphere.radius_ * Cos((float)phi),
+        sphere.center_.z_ + sphere.radius_ * Cos((float)theta) * Sin((float)phi)
+    );
+}
+
 void DebugRenderer::AddSphere(const Sphere& sphere, const Color& color, bool depthTest)
 {
-    const Vector3& center = sphere.center_;
-    float radius = sphere.radius_;
     unsigned uintColor = color.ToUInt();
-
-    for (unsigned i = 0; i < 360; i += 45)
+    
+    for (unsigned j = 0; j < 180; j += 45)
     {
-        unsigned j = i + 45;
-        float a = radius * Sin((float)i);
-        float b = radius * Cos((float)i);
-        float c = radius * Sin((float)j);
-        float d = radius * Cos((float)j);
-        Vector3 start, end;
-
-        start = center + Vector3(a, b, 0.0f);
-        end = center + Vector3(c, d, 0.0f);
-        AddLine(start, end, uintColor, depthTest);
-        start = center + Vector3(a, 0.0f, b);
-        end = center + Vector3(c, 0.0f, d);
-        AddLine(start, end, uintColor, depthTest);
-        start = center + Vector3(0.0f, a, b);
-        end = center + Vector3(0.0f, c, d);
-        AddLine(start, end, uintColor, depthTest);
+        for (unsigned i = 0; i < 360; i += 45)
+        {
+            Vector3 p1 = PointOnSphere(sphere, i, j);
+            Vector3 p2 = PointOnSphere(sphere, i + 45, j);
+            Vector3 p3 = PointOnSphere(sphere, i, j + 45);
+            Vector3 p4 = PointOnSphere(sphere, i + 45, j + 45);
+            
+            AddLine(p1, p2, uintColor, depthTest);
+            AddLine(p3, p4, uintColor, depthTest);
+            AddLine(p1, p3, uintColor, depthTest);
+            AddLine(p2, p4, uintColor, depthTest);
+        }
     }
 }
 

+ 1 - 1
Source/Engine/Navigation/NavigationMesh.cpp

@@ -201,7 +201,7 @@ void NavigationMesh::RegisterObject(Context* context)
 
 void NavigationMesh::DrawDebugGeometry(DebugRenderer* debug, bool depthTest)
 {
-    if (!navMesh_ || !node_)
+    if (!debug || !navMesh_ || !node_)
         return;
     
     const Matrix3x4& worldTransform = node_->GetWorldTransform();