Browse Source

Add Sphere::GetPoint and Sphere::GetLocalPoint functions. Add DebugRenderer::AddSphereSector function.

Eugene Kozlov 8 years ago
parent
commit
f266475994

+ 1 - 0
Source/Urho3D/AngelScript/GraphicsAPI.cpp

@@ -2056,6 +2056,7 @@ static void RegisterDebugRenderer(asIScriptEngine* engine)
     engine->RegisterObjectMethod("DebugRenderer", "void AddFrustum(const Frustum&in, const Color&in, bool depthTest = true)", asMETHOD(DebugRenderer, AddFrustum), asCALL_THISCALL);
     engine->RegisterObjectMethod("DebugRenderer", "void AddPolyhedron(const Polyhedron&in, const Color&in, bool depthTest = true)", asMETHOD(DebugRenderer, AddPolyhedron), asCALL_THISCALL);
     engine->RegisterObjectMethod("DebugRenderer", "void AddSphere(const Sphere&in, const Color&in, bool depthTest = true)", asMETHOD(DebugRenderer, AddSphere), asCALL_THISCALL);
+    engine->RegisterObjectMethod("DebugRenderer", "void AddSphereSector(const Sphere&in, const Quaternion&in, float, bool, const Color&in, bool depthTest = true)", asMETHOD(DebugRenderer, AddSphere), asCALL_THISCALL);
     engine->RegisterObjectMethod("DebugRenderer", "void AddSkeleton(Skeleton@+, const Color&in, bool depthTest = true)", asMETHOD(DebugRenderer, AddSkeleton), asCALL_THISCALL);
     engine->RegisterObjectMethod("DebugRenderer", "void AddCircle(const Vector3&in, const Vector3&in, float, const Color&in, int steps = 64, bool depthTest = true)", asMETHOD(DebugRenderer, AddCircle), asCALL_THISCALL);
     engine->RegisterObjectMethod("DebugRenderer", "void AddCross(const Vector3&in, float size, const Color&in, bool depthTest = true)", asMETHOD(DebugRenderer, AddCross), asCALL_THISCALL);

+ 2 - 0
Source/Urho3D/AngelScript/MathAPI.cpp

@@ -1302,6 +1302,8 @@ static void RegisterVolumes(asIScriptEngine* engine)
     engine->RegisterObjectMethod("Sphere", "Intersection IsInside(const BoundingBox&in) const", asMETHODPR(Sphere, IsInside, (const BoundingBox&) const, Intersection), asCALL_THISCALL);
     engine->RegisterObjectMethod("Sphere", "Intersection IsInsideFast(const BoundingBox&in) const", asMETHODPR(Sphere, IsInsideFast, (const BoundingBox&) const, Intersection), asCALL_THISCALL);
     engine->RegisterObjectMethod("Sphere", "float Distance(const Vector3&in) const", asMETHOD(Sphere, Distance), asCALL_THISCALL);
+    engine->RegisterObjectMethod("Sphere", "Vector3 GetLocalPoint(float, float) const", asMETHOD(Sphere, GetLocalPoint), asCALL_THISCALL);
+    engine->RegisterObjectMethod("Sphere", "Vector3 GetPoint(float, float) const", asMETHOD(Sphere, GetPoint), asCALL_THISCALL);
     engine->RegisterObjectProperty("Sphere", "Vector3 center", offsetof(Sphere, center_));
     engine->RegisterObjectProperty("Sphere", "float radius", offsetof(Sphere, radius_));
 }

+ 7 - 0
Source/Urho3D/Audio/SoundSource3D.cpp

@@ -139,6 +139,13 @@ void SoundSource3D::DrawDebugGeometry(DebugRenderer* debug, bool depthTest)
     // Draw cones for directional sounds, or spheres for non-directional
     if (innerAngle_ < DEFAULT_ANGLE && outerAngle_ > 0.0f)
     {
+        /// \todo Replace arcs with sphere sector
+        //const Quaternion rotation = worldRotation * Quaternion(Vector3::UP, Vector3::FORWARD);
+        //debug->AddSphereSector(Sphere(worldPosition, nearDistance_), rotation, innerAngle_, false, INNER_COLOR, depthTest);
+        //debug->AddSphereSector(Sphere(worldPosition, nearDistance_), rotation, outerAngle_, false, OUTER_COLOR, depthTest);
+        //debug->AddSphereSector(Sphere(worldPosition, farDistance_), rotation, innerAngle_, true, INNER_COLOR, depthTest);
+        //debug->AddSphereSector(Sphere(worldPosition, farDistance_), rotation, outerAngle_, true, OUTER_COLOR, depthTest);
+
         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);

+ 63 - 19
Source/Urho3D/Graphics/DebugRenderer.cpp

@@ -225,7 +225,6 @@ void DebugRenderer::AddBoundingBox(const BoundingBox& box, const Matrix3x4& tran
     }
 }
 
-
 void DebugRenderer::AddFrustum(const Frustum& frustum, const Color& color, bool depthTest)
 {
     const Vector3* vertices = frustum.vertices_;
@@ -260,27 +259,18 @@ 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)
 {
     unsigned uintColor = color.ToUInt();
 
-    for (unsigned j = 0; j < 180; j += 45)
+    for (float j = 0; j < 180; j += 45)
     {
-        for (unsigned i = 0; i < 360; i += 45)
+        for (float 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);
+            Vector3 p1 = sphere.GetPoint(i, j);
+            Vector3 p2 = sphere.GetPoint(i + 45, j);
+            Vector3 p3 = sphere.GetPoint(i, j + 45);
+            Vector3 p4 = sphere.GetPoint(i + 45, j + 45);
 
             AddLine(p1, p2, uintColor, depthTest);
             AddLine(p3, p4, uintColor, depthTest);
@@ -290,16 +280,70 @@ void DebugRenderer::AddSphere(const Sphere& sphere, const Color& color, bool dep
     }
 }
 
+void DebugRenderer::AddSphereSector(const Sphere& sphere, const Quaternion& rotation, float angle,
+    bool drawLines, const Color& color, bool depthTest)
+{
+    if (angle <= 0.0f)
+        return;
+    else if (angle >= 360.0f)
+    {
+        AddSphere(sphere, color, depthTest);
+        return;
+    }
+
+    static const unsigned numCircleSegments = 8;
+    static const unsigned numLines = 4;
+    static const float arcStep = 45.0f;
+
+    const unsigned uintColor = color.ToUInt();
+    const float halfAngle = 0.5f * angle;
+    const unsigned numArcSegments = static_cast<unsigned>(Ceil(halfAngle / arcStep)) + 1;
+
+    // Draw circle
+    for (unsigned j = 0; j < numCircleSegments; ++j)
+    {
+        AddLine(
+            sphere.center_ + rotation * sphere.GetLocalPoint(j * 360.0f / numCircleSegments, halfAngle),
+            sphere.center_ + rotation * sphere.GetLocalPoint((j + 1) * 360.0f / numCircleSegments, halfAngle),
+            uintColor);
+    }
+
+    // Draw arcs
+    const unsigned step = numCircleSegments / numLines;
+    for (unsigned i = 0; i < numArcSegments - 1; ++i)
+    {
+        for (unsigned j = 0; j < numCircleSegments; j += step)
+        {
+            const float nextPhi = i + 1 == numArcSegments - 1 ? halfAngle : (i + 1) * arcStep;
+            AddLine(
+                sphere.center_ + rotation * sphere.GetLocalPoint(j * 360.0f / numCircleSegments, i * arcStep),
+                sphere.center_ + rotation * sphere.GetLocalPoint(j * 360.0f / numCircleSegments, nextPhi),
+                uintColor);
+        }
+    }
+
+    // Draw lines
+    if (drawLines)
+    {
+        for (unsigned j = 0; j < numCircleSegments; j += step)
+        {
+            AddLine(sphere.center_,
+                sphere.center_ + rotation * sphere.GetLocalPoint(j * 360.0f / numCircleSegments, halfAngle),
+                uintColor);
+        }
+    }
+}
+
 void DebugRenderer::AddCylinder(const Vector3& position, float radius, float height, const Color& color, bool depthTest)
 {
     Sphere sphere(position, radius);
     Vector3 heightVec(0, height, 0);
     Vector3 offsetXVec(radius, 0, 0);
     Vector3 offsetZVec(0, 0, radius);
-    for (unsigned i = 0; i < 360; i += 45)
+    for (float i = 0; i < 360; i += 45)
     {
-        Vector3 p1 = PointOnSphere(sphere, i, 90);
-        Vector3 p2 = PointOnSphere(sphere, i + 45, 90);
+        Vector3 p1 = sphere.GetPoint(i, 90);
+        Vector3 p2 = sphere.GetPoint(i + 45, 90);
         AddLine(p1, p2, color, depthTest);
         AddLine(p1 + heightVec, p2 + heightVec, color, depthTest);
     }

+ 3 - 0
Source/Urho3D/Graphics/DebugRenderer.h

@@ -132,6 +132,9 @@ public:
     void AddPolyhedron(const Polyhedron& poly, const Color& color, bool depthTest = true);
     /// Add a sphere.
     void AddSphere(const Sphere& sphere, const Color& color, bool depthTest = true);
+    /// Add a sphere sector.
+    void AddSphereSector(const Sphere& sphere, const Quaternion& rotation, float angle,
+        bool drawLines, const Color& color, bool depthTest = true);
     /// Add a cylinder
     void AddCylinder(const Vector3& position, float radius, float height, const Color& color, bool depthTest = true);
     /// Add a skeleton.

+ 1 - 0
Source/Urho3D/LuaScript/pkgs/Graphics/DebugRenderer.pkg

@@ -16,6 +16,7 @@ class DebugRenderer : public Component
     void AddFrustum(const Frustum& frustum, const Color& color, bool depthTest = true);
     void AddPolyhedron(const Polyhedron& poly, const Color& color, bool depthTest = true);
     void AddSphere(const Sphere& sphere, const Color& color, bool depthTest = true);
+    void AddSphereSector(const Sphere& sphere, const Quaternion& rotation, float angle, bool drawLines, const Color& color, bool depthTest = true);
     void AddSkeleton(const Skeleton& skeleton, const Color& color, bool depthTest = true);
     void AddTriangleMesh(const void* vertexData, unsigned vertexSize, const void* indexData, unsigned indexSize, unsigned indexStart, unsigned indexCount, const Matrix3x4& transform, const Color& color, bool depthTest = true);
     void AddCircle(const Vector3& center, const Vector3& normal, float radius, const Color& color, int steps = 64, bool depthTest = true);

+ 3 - 0
Source/Urho3D/LuaScript/pkgs/Math/Sphere.pkg

@@ -33,6 +33,9 @@ class Sphere
     Intersection IsInside(const BoundingBox& box) const;
     Intersection IsInsideFast(const BoundingBox& box) const;
     float Distance(const Vector3& point) const;
+    Vector3 GetLocalPoint(float theta, float phi) const;
+    Vector3 GetPoint(float theta, float phi) const;
+
 
     Vector3 center_ @ center;
     float radius_ @ radius;

+ 9 - 0
Source/Urho3D/Math/Sphere.cpp

@@ -254,4 +254,13 @@ Intersection Sphere::IsInsideFast(const BoundingBox& box) const
         return INSIDE;
 }
 
+Vector3 Sphere::GetLocalPoint(float theta, float phi) const
+{
+    return Vector3(
+        radius_ * Sin(theta) * Sin(phi),
+        radius_ * Cos(phi),
+        radius_ * Cos(theta) * Sin(phi)
+    );
+}
+
 }

+ 4 - 0
Source/Urho3D/Math/Sphere.h

@@ -202,6 +202,10 @@ public:
 
     /// Return distance of a point to the surface, or 0 if inside.
     float Distance(const Vector3& point) const { return Max((point - center_).Length() - radius_, 0.0f); }
+    /// Return point on the sphere relative to sphere position.
+    Vector3 GetLocalPoint(float theta, float phi) const;
+    /// Return point on the sphere.
+    Vector3 GetPoint(float theta, float phi) const { return center_ + GetLocalPoint(theta, phi); }
 
     /// Sphere center.
     Vector3 center_;