75 lines
1.9 KiB
C++
75 lines
1.9 KiB
C++
// Copyright (c) Wojciech Figat. All rights reserved.
|
|
|
|
#include "SphereCollider.h"
|
|
|
|
SphereCollider::SphereCollider(const SpawnParams& params)
|
|
: Collider(params)
|
|
, _radius(50.0f)
|
|
{
|
|
}
|
|
|
|
void SphereCollider::SetRadius(const float value)
|
|
{
|
|
if (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);
|
|
|
|
if (_contactOffset > 0)
|
|
{
|
|
BoundingSphere contactBounds = _sphere;
|
|
contactBounds.Radius += _contactOffset;
|
|
DEBUG_DRAW_WIRE_SPHERE(contactBounds, Color::Blue.AlphaMultiplied(0.2f), 0, false);
|
|
}
|
|
|
|
// Base
|
|
Collider::OnDebugDrawSelected();
|
|
}
|
|
|
|
#endif
|
|
|
|
bool SphereCollider::IntersectsItself(const Ray& ray, Real& distance, Vector3& normal)
|
|
{
|
|
return _sphere.Intersects(ray, distance, normal);
|
|
}
|
|
|
|
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));
|
|
}
|