File Shape.h¶
File List > Amplitude > Math > Shape.h
Go to the documentation of this file
// Copyright (c) 2021-present Sparky Studios. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#pragma once
#ifndef _AM_MATH_SHAPE_H
#define _AM_MATH_SHAPE_H
#include <SparkyStudios/Audio/Amplitude/Core/Common.h>
#include <SparkyStudios/Audio/Amplitude/Core/Entity.h>
#include <SparkyStudios/Audio/Amplitude/Core/Listener.h>
#include <array>
#include <memory>
#include <span>
namespace SparkyStudios::Audio::Amplitude
{
class ShapeDefinition;
class BoxShapeDefinition;
class CapsuleShapeDefinition;
class ConeShapeDefinition;
class SphereShapeDefinition;
class AM_API_PUBLIC Shape
{
public:
static std::shared_ptr<Shape> Create(const ShapeDefinition* definition);
Shape();
virtual ~Shape() = default;
[[nodiscard]] virtual AmReal32 GetShortestDistanceToEdge(const Entity& entity) const;
[[nodiscard]] virtual AmReal32 GetShortestDistanceToEdge(const Listener& listener) const;
[[nodiscard]] virtual AmReal32 GetShortestDistanceToEdge(const AmVector3& location) const = 0;
[[nodiscard]] virtual bool Contains(const Entity& entity) const;
[[nodiscard]] virtual bool Contains(const Listener& listener) const;
[[nodiscard]] virtual bool Contains(const AmVector3& location) const = 0;
void SetLocation(const AmVector3& location);
void SetOrientation(const Orientation& orientation);
[[nodiscard]] const Orientation& GetOrientation() const;
[[nodiscard]] const AmMatrix4& GetLookAt() const;
[[nodiscard]] const AmVector3& GetLocation() const;
[[nodiscard]] AmVector3 GetDirection() const;
[[nodiscard]] AmVector3 GetUp() const;
protected:
virtual void Update() = 0;
AM_INLINE void UpdateIfNeeded() const
{
if (m_needUpdate)
{
auto* self = const_cast<Shape*>(this);
self->Update();
self->m_needUpdate = false;
}
}
AmVector3 m_location;
Orientation m_orientation;
AmMatrix4 m_lookAtMatrix;
bool m_needUpdate;
};
class AM_API_PUBLIC Zone
{
public:
explicit Zone(std::shared_ptr<Shape> inner, std::shared_ptr<Shape> outer);
virtual ~Zone();
[[nodiscard]] virtual AM_INLINE AmReal32 GetFactor(const Entity& entity) const
{
return GetFactor(entity.GetLocation());
}
[[nodiscard]] virtual AM_INLINE AmReal32 GetFactor(const Listener& listener) const
{
return GetFactor(listener.GetLocation());
}
[[nodiscard]] virtual AmReal32 GetFactor(const AmVector3& position) const = 0;
void SetLocation(const AmVector3& location);
[[nodiscard]] const AmVector3& GetLocation() const;
void SetOrientation(const Orientation& orientation);
[[nodiscard]] const Orientation& GetOrientation() const;
[[nodiscard]] AmVector3 GetDirection() const;
[[nodiscard]] AmVector3 GetUp() const;
protected:
std::shared_ptr<Shape> m_innerShape;
std::shared_ptr<Shape> m_outerShape;
};
class AM_API_PUBLIC BoxShape final : public Shape
{
friend class BoxZone;
public:
static std::shared_ptr<BoxShape> Create(const BoxShapeDefinition* definition);
explicit BoxShape(AmReal32 halfWidth, AmReal32 halfHeight, AmReal32 halfDepth);
explicit BoxShape(const AmVector3& position, const AmVector3& dimensions);
[[nodiscard]] AmReal32 GetHalfWidth() const;
[[nodiscard]] AmReal32 GetHalfHeight() const;
[[nodiscard]] AmReal32 GetHalfDepth() const;
[[nodiscard]] AmReal32 GetWidth() const;
[[nodiscard]] AmReal32 GetHeight() const;
[[nodiscard]] AmReal32 GetDepth() const;
void SetHalfWidth(AmReal32 halfWidth);
void SetHalfHeight(AmReal32 halfHeight);
void SetHalfDepth(AmReal32 halfDepth);
[[nodiscard]] AmReal32 GetShortestDistanceToEdge(const AmVector3& location) const override;
[[nodiscard]] bool Contains(const AmVector3& location) const override;
[[nodiscard]] AmVector3 GetClosestPoint(const AmVector3& location) const;
[[nodiscard]] std::span<const AmVector3> GetCorners() const;
bool operator==(const BoxShape& other) const;
bool operator!=(const BoxShape& other) const;
private:
void Update() override;
AmReal32 _halfWidth;
AmReal32 _halfHeight;
AmReal32 _halfDepth;
AmVector3 _u;
AmVector3 _v;
AmVector3 _w;
AmVector3 _p1, _p2, _p3, _p4;
AmReal32 _uP1, _vP1, _wP1, _uP2, _vP3, _wP4;
std::array<AmVector3, 8> _corners;
};
class AM_API_PUBLIC CapsuleShape final : public Shape
{
friend class CapsuleZone;
public:
static std::shared_ptr<CapsuleShape> Create(const CapsuleShapeDefinition* definition);
explicit CapsuleShape(AmReal32 radius, AmReal32 halfHeight);
[[nodiscard]] AmReal32 GetRadius() const;
[[nodiscard]] AmReal32 GetHalfHeight() const;
[[nodiscard]] AmReal32 GetDiameter() const;
[[nodiscard]] AmReal32 GetHeight() const;
void SetRadius(AmReal32 radius);
void SetHalfHeight(AmReal32 halfHeight);
[[nodiscard]] AmReal32 GetShortestDistanceToEdge(const AmVector3& location) const override;
[[nodiscard]] bool Contains(const AmVector3& location) const override;
bool operator==(const CapsuleShape& other) const;
bool operator!=(const CapsuleShape& other) const;
private:
void Update() override;
AmReal32 _radius;
AmReal32 _halfHeight;
AmVector3 _a, _b;
};
class AM_API_PUBLIC ConeShape final : public Shape
{
friend class ConeZone;
public:
static std::shared_ptr<ConeShape> Create(const ConeShapeDefinition* definition);
explicit ConeShape(AmReal32 radius, AmReal32 height);
[[nodiscard]] AmReal32 GetRadius() const;
[[nodiscard]] AmReal32 GetDiameter() const;
[[nodiscard]] AmReal32 GetHeight() const;
void SetRadius(AmReal32 radius);
void SetHeight(AmReal32 height);
[[nodiscard]] AmReal32 GetShortestDistanceToEdge(const AmVector3& location) const override;
[[nodiscard]] bool Contains(const AmVector3& location) const override;
bool operator==(const ConeShape& other) const;
bool operator!=(const ConeShape& other) const;
private:
void Update() override;
AmReal32 _radius;
AmReal32 _height;
};
class AM_API_PUBLIC SphereShape final : public Shape
{
friend class SphereZone;
public:
static std::shared_ptr<SphereShape> Create(const SphereShapeDefinition* definition);
explicit SphereShape(AmReal32 radius);
[[nodiscard]] AmReal32 GetRadius() const;
[[nodiscard]] AmReal32 GetDiameter() const;
void SetRadius(AmReal32 radius);
[[nodiscard]] AmReal32 GetShortestDistanceToEdge(const AmVector3& location) const override;
[[nodiscard]] bool Contains(const AmVector3& location) const override;
bool operator==(const SphereShape& other) const;
bool operator!=(const SphereShape& other) const;
private:
void Update() override;
AmReal32 _radius;
};
class AM_API_PUBLIC BoxZone : public Zone
{
public:
BoxZone(std::shared_ptr<BoxShape> inner, std::shared_ptr<BoxShape> outer);
[[nodiscard]] AmReal32 GetFactor(const AmVector3& position) const override;
};
class AM_API_PUBLIC CapsuleZone : public Zone
{
public:
CapsuleZone(std::shared_ptr<CapsuleShape> inner, std::shared_ptr<CapsuleShape> outer);
[[nodiscard]] AmReal32 GetFactor(const AmVector3& position) const override;
};
class AM_API_PUBLIC ConeZone : public Zone
{
public:
ConeZone(std::shared_ptr<ConeShape> inner, std::shared_ptr<ConeShape> outer);
[[nodiscard]] AmReal32 GetFactor(const AmVector3& position) const override;
};
class AM_API_PUBLIC SphereZone : public Zone
{
public:
SphereZone(std::shared_ptr<SphereShape> inner, std::shared_ptr<SphereShape> outer);
[[nodiscard]] AmReal32 GetFactor(const AmVector3& position) const override;
};
} // namespace SparkyStudios::Audio::Amplitude
#endif // _AM_MATH_SHAPE_H