Files
FlaxEngine/Source/Engine/Physics/Colliders/SphereCollider.cpp
2023-01-10 15:29:37 +01:00

87 lines
2.1 KiB
C++

// Copyright (c) 2012-2023 Wojciech Figat. All rights reserved.
#include "SphereCollider.h"
#include "Engine/Serialization/Serialization.h"
SphereCollider::SphereCollider(const SpawnParams& params)
: Collider(params)
, _radius(50.0f)
{
}
void SphereCollider::SetRadius(const float value)
{
if (Math::NearEqual(value, _radius))
return;
_radius = value;
UpdateGeometry();
UpdateBounds();
}
#if USE_EDITOR
#include "Engine/Debug/DebugDraw.h"
#include "Engine/Graphics/RenderView.h"
void SphereCollider::DrawPhysicsDebug(RenderView& view)
{
const BoundingSphere sphere(_sphere.Center - view.Origin, _sphere.Radius);
if (!view.CullingFrustum.Intersects(sphere))
return;
if (view.Mode == ViewMode::PhysicsColliders && !GetIsTrigger())
DEBUG_DRAW_SPHERE(_sphere, _staticActor ? Color::CornflowerBlue : Color::Orchid, 0, true);
else
DEBUG_DRAW_WIRE_SPHERE(_sphere, Color::GreenYellow * 0.8f, 0, true);
}
void SphereCollider::OnDebugDrawSelected()
{
DEBUG_DRAW_WIRE_SPHERE(_sphere, Color::GreenYellow, 0, false);
// Base
Collider::OnDebugDrawSelected();
}
#endif
bool SphereCollider::IntersectsItself(const Ray& ray, Real& distance, Vector3& normal)
{
return _sphere.Intersects(ray, distance, normal);
}
void SphereCollider::Serialize(SerializeStream& stream, const void* otherObj)
{
// Base
Collider::Serialize(stream, otherObj);
SERIALIZE_GET_OTHER_OBJ(SphereCollider);
SERIALIZE_MEMBER(Radius, _radius);
}
void SphereCollider::Deserialize(DeserializeStream& stream, ISerializeModifier* modifier)
{
// Base
Collider::Deserialize(stream, modifier);
DESERIALIZE_MEMBER(Radius, _radius);
}
void SphereCollider::UpdateBounds()
{
// Cache bounds
_sphere.Center = _transform.LocalToWorld(_center);
_sphere.Radius = _radius * _transform.Scale.MaxValue();
_sphere.GetBoundingBox(_box);
}
void SphereCollider::GetGeometry(CollisionShape& collision)
{
const float scaling = _cachedScale.GetAbsolute().MaxValue();
const float radius = Math::Abs(_radius) * scaling;
const float minSize = 0.001f;
collision.SetSphere(Math::Max(radius, minSize));
}