Merge remote-tracking branch 'origin/master'
This commit is contained in:
@@ -113,7 +113,7 @@ namespace FlaxEditor
|
|||||||
var bounds = BoundingSphere.FromBox(staticModel.Box);
|
var bounds = BoundingSphere.FromBox(staticModel.Box);
|
||||||
|
|
||||||
// Pick a proper LOD
|
// Pick a proper LOD
|
||||||
var center = (Float3)bounds.Center; // TODO: large-worlds
|
Float3 center = bounds.Center - renderContext.View.Origin;
|
||||||
int lodIndex = RenderTools.ComputeModelLOD(model, ref center, (float)bounds.Radius, ref renderContext);
|
int lodIndex = RenderTools.ComputeModelLOD(model, ref center, (float)bounds.Radius, ref renderContext);
|
||||||
var lods = model.LODs;
|
var lods = model.LODs;
|
||||||
if (lods == null || lods.Length < lodIndex || lodIndex < 0)
|
if (lods == null || lods.Length < lodIndex || lodIndex < 0)
|
||||||
|
|||||||
@@ -196,7 +196,7 @@ void Model::Draw(const RenderContext& renderContext, MaterialBase* material, con
|
|||||||
const BoundingBox box = GetBox(world);
|
const BoundingBox box = GetBox(world);
|
||||||
BoundingSphere sphere;
|
BoundingSphere sphere;
|
||||||
BoundingSphere::FromBox(box, sphere);
|
BoundingSphere::FromBox(box, sphere);
|
||||||
int32 lodIndex = RenderTools::ComputeModelLOD(this, sphere.Center, (float)sphere.Radius, renderContext); // TODO: large-worlds
|
int32 lodIndex = RenderTools::ComputeModelLOD(this, sphere.Center - renderContext.View.Origin, (float)sphere.Radius, renderContext);
|
||||||
if (lodIndex == -1)
|
if (lodIndex == -1)
|
||||||
return;
|
return;
|
||||||
lodIndex += renderContext.View.ModelLODBias;
|
lodIndex += renderContext.View.ModelLODBias;
|
||||||
|
|||||||
@@ -129,30 +129,28 @@ void BoundingBox::Transform(const BoundingBox& box, const Matrix& matrix, Boundi
|
|||||||
const auto zb = backward * box.Maximum.Z;
|
const auto zb = backward * box.Maximum.Z;
|
||||||
|
|
||||||
const auto translation = matrix.GetTranslation();
|
const auto translation = matrix.GetTranslation();
|
||||||
result = BoundingBox(
|
const auto min = Vector3::Min(xa, xb) + Vector3::Min(ya, yb) + Vector3::Min(za, zb) + translation;
|
||||||
Vector3::Min(xa, xb) + Vector3::Min(ya, yb) + Vector3::Min(za, zb) + translation,
|
const auto max = Vector3::Max(xa, xb) + Vector3::Max(ya, yb) + Vector3::Max(za, zb) + translation;
|
||||||
Vector3::Max(xa, xb) + Vector3::Max(ya, yb) + Vector3::Max(za, zb) + translation);
|
result = BoundingBox(min, max);
|
||||||
|
|
||||||
/*
|
|
||||||
// Get box corners
|
|
||||||
Vector3 corners[8];
|
|
||||||
box.GetCorners(corners);
|
|
||||||
|
|
||||||
// Transform them
|
|
||||||
for (int32 i = 0; i < 8; i++)
|
|
||||||
{
|
|
||||||
corners[i] = Vector3::Transform(corners[i], matrix);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Construct box from the points
|
|
||||||
result = FromPoints(corners, 8);
|
|
||||||
*/
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void BoundingBox::Transform(const BoundingBox& box, const ::Transform& transform, BoundingBox& result)
|
void BoundingBox::Transform(const BoundingBox& box, const ::Transform& transform, BoundingBox& result)
|
||||||
{
|
{
|
||||||
// TODO: optimize it and support large worlds without using Matrix
|
// Reference: http://dev.theomader.com/transform-bounding-boxes/
|
||||||
Matrix matrix;
|
|
||||||
transform.GetWorld(matrix);
|
const auto right = transform.GetRight();
|
||||||
Transform(box, matrix, result);
|
const auto xa = right * box.Minimum.X;
|
||||||
|
const auto xb = right * box.Maximum.X;
|
||||||
|
|
||||||
|
const auto up = transform.GetUp();
|
||||||
|
const auto ya = up * box.Minimum.Y;
|
||||||
|
const auto yb = up * box.Maximum.Y;
|
||||||
|
|
||||||
|
const auto backward = transform.GetBackward();
|
||||||
|
const auto za = backward * box.Minimum.Z;
|
||||||
|
const auto zb = backward * box.Maximum.Z;
|
||||||
|
|
||||||
|
const auto min = Vector3::Min(xa, xb) + Vector3::Min(ya, yb) + Vector3::Min(za, zb) + transform.Translation;
|
||||||
|
const auto max = Vector3::Max(xa, xb) + Vector3::Max(ya, yb) + Vector3::Max(za, zb) + transform.Translation;
|
||||||
|
result = BoundingBox(min, max);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -454,24 +454,48 @@ namespace FlaxEngine
|
|||||||
var zb = backward * box.Maximum.Z;
|
var zb = backward * box.Maximum.Z;
|
||||||
|
|
||||||
var translation = transform.TranslationVector;
|
var translation = transform.TranslationVector;
|
||||||
result = new BoundingBox(
|
var min = Vector3.Min(xa, xb) + Vector3.Min(ya, yb) + Vector3.Min(za, zb) + translation;
|
||||||
Vector3.Min(xa, xb) + Vector3.Min(ya, yb) + Vector3.Min(za, zb) + translation,
|
var max = Vector3.Max(xa, xb) + Vector3.Max(ya, yb) + Vector3.Max(za, zb) + translation;
|
||||||
Vector3.Max(xa, xb) + Vector3.Max(ya, yb) + Vector3.Max(za, zb) + translation);
|
result = new BoundingBox(min, max);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/// <summary>
|
||||||
// Get box corners
|
/// Transforms bounding box using the given transformation matrix.
|
||||||
var corners = new Vector3[8];
|
/// </summary>
|
||||||
box.GetCorners(corners);
|
/// <param name="box">The bounding box to transform.</param>
|
||||||
|
/// <param name="transform">The transformation matrix.</param>
|
||||||
|
/// <returns>The result of the transformation.</returns>
|
||||||
|
public static BoundingBox Transform(BoundingBox box, Transform transform)
|
||||||
|
{
|
||||||
|
Transform(ref box, ref transform, out BoundingBox result);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
// Transform them
|
/// <summary>
|
||||||
for (int i = 0; i < 8; i++)
|
/// Transforms bounding box using the given transformation.
|
||||||
{
|
/// </summary>
|
||||||
Vector3.Transform(ref corners[i], ref transform, out corners[i]);
|
/// <param name="box">The bounding box to transform.</param>
|
||||||
}
|
/// <param name="transform">The transformation.</param>
|
||||||
|
/// <param name="result">The result of the transformation.</param>
|
||||||
|
public static void Transform(ref BoundingBox box, ref Transform transform, out BoundingBox result)
|
||||||
|
{
|
||||||
|
// Reference: http://dev.theomader.com/transform-bounding-boxes/
|
||||||
|
|
||||||
// Construct box from the points
|
Double3 right = transform.Right;
|
||||||
FromPoints(corners, out result);
|
var xa = right * box.Minimum.X;
|
||||||
*/
|
var xb = right * box.Maximum.X;
|
||||||
|
|
||||||
|
Double3 up = transform.Up;
|
||||||
|
var ya = up * box.Minimum.Y;
|
||||||
|
var yb = up * box.Maximum.Y;
|
||||||
|
|
||||||
|
Double3 backward = transform.Backward;
|
||||||
|
var za = backward * box.Minimum.Z;
|
||||||
|
var zb = backward * box.Maximum.Z;
|
||||||
|
|
||||||
|
var min = Vector3.Min(xa, xb) + Vector3.Min(ya, yb) + Vector3.Min(za, zb) + transform.Translation;
|
||||||
|
var max = Vector3.Max(xa, xb) + Vector3.Max(ya, yb) + Vector3.Max(za, zb) + transform.Translation;
|
||||||
|
result = new BoundingBox(min, max);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|||||||
@@ -76,10 +76,11 @@ void ForwardShadingFeature::Bind(MaterialShader::BindParameters& params, Span<by
|
|||||||
// Set reflection probe data
|
// Set reflection probe data
|
||||||
EnvironmentProbe* probe = nullptr;
|
EnvironmentProbe* probe = nullptr;
|
||||||
// TODO: optimize env probe searching for a transparent material - use spatial cache for renderer to find it
|
// TODO: optimize env probe searching for a transparent material - use spatial cache for renderer to find it
|
||||||
|
const Vector3 drawCallOrigin = drawCall.World.GetTranslation() + view.Origin;
|
||||||
for (int32 i = 0; i < cache->EnvironmentProbes.Count(); i++)
|
for (int32 i = 0; i < cache->EnvironmentProbes.Count(); i++)
|
||||||
{
|
{
|
||||||
const auto p = cache->EnvironmentProbes[i];
|
const auto p = cache->EnvironmentProbes[i];
|
||||||
if (p->GetSphere().Contains(drawCall.World.GetTranslation()) != ContainmentType::Disjoint)
|
if (p->GetSphere().Contains(drawCallOrigin) != ContainmentType::Disjoint)
|
||||||
{
|
{
|
||||||
probe = p;
|
probe = p;
|
||||||
break;
|
break;
|
||||||
@@ -87,7 +88,7 @@ void ForwardShadingFeature::Bind(MaterialShader::BindParameters& params, Span<by
|
|||||||
}
|
}
|
||||||
if (probe && probe->GetProbe())
|
if (probe && probe->GetProbe())
|
||||||
{
|
{
|
||||||
probe->SetupProbeData(&data.EnvironmentProbe);
|
probe->SetupProbeData(params.RenderContext, &data.EnvironmentProbe);
|
||||||
const auto texture = probe->GetProbe()->GetTexture();
|
const auto texture = probe->GetProbe()->GetTexture();
|
||||||
context->BindSR(envProbeShaderRegisterIndex, GET_TEXTURE_VIEW_SAFE(texture));
|
context->BindSR(envProbeShaderRegisterIndex, GET_TEXTURE_VIEW_SAFE(texture));
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -44,10 +44,10 @@ float EnvironmentProbe::GetScaledRadius() const
|
|||||||
return _radius * _transform.Scale.MaxValue();
|
return _radius * _transform.Scale.MaxValue();
|
||||||
}
|
}
|
||||||
|
|
||||||
void EnvironmentProbe::SetupProbeData(ProbeData* data) const
|
void EnvironmentProbe::SetupProbeData(const RenderContext& renderContext, ProbeData* data) const
|
||||||
{
|
{
|
||||||
const float radius = GetScaledRadius();
|
const float radius = GetScaledRadius();
|
||||||
data->Data0 = Float4(GetPosition(), 0); // TODO: large-worlds
|
data->Data0 = Float4(GetPosition() - renderContext.View.Origin, 0);
|
||||||
data->Data1 = Float4(radius, 1.0f / radius, Brightness, 0);
|
data->Data1 = Float4(radius, 1.0f / radius, Brightness, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -89,8 +89,9 @@ public:
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Setup probe data structure
|
/// Setup probe data structure
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
/// <param name="data">Rendering context</param>
|
||||||
/// <param name="data">Packed probe data to set</param>
|
/// <param name="data">Packed probe data to set</param>
|
||||||
void SetupProbeData(struct ProbeData* data) const;
|
void SetupProbeData(const RenderContext& renderContext, struct ProbeData* data) const;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the custom probe (null if using baked one or none).
|
/// Gets the custom probe (null if using baked one or none).
|
||||||
|
|||||||
@@ -409,13 +409,11 @@ void ParticleEmitterGraphCPUExecutor::Draw(ParticleEmitter* emitter, ParticleEff
|
|||||||
const float radius = (float)GetValue(module->GetBox(1), 3);
|
const float radius = (float)GetValue(module->GetBox(1), 3);
|
||||||
const float fallOffExponent = (float)GetValue(module->GetBox(2), 4);
|
const float fallOffExponent = (float)GetValue(module->GetBox(2), 4);
|
||||||
|
|
||||||
lightData.Position = *(Float3*)positionPtr;
|
|
||||||
lightData.Color = Float3(color) * color.W;
|
lightData.Color = Float3(color) * color.W;
|
||||||
lightData.Radius = radius;
|
lightData.Radius = radius;
|
||||||
lightData.FallOffExponent = fallOffExponent;
|
lightData.FallOffExponent = fallOffExponent;
|
||||||
|
|
||||||
if (emitter->SimulationSpace == ParticlesSimulationSpace::Local)
|
Float3::Transform(*(Float3*)positionPtr, transform, lightData.Position);
|
||||||
Float3::Transform(lightData.Position, transform, lightData.Position);
|
|
||||||
|
|
||||||
renderContext.List->PointLights.Add(lightData);
|
renderContext.List->PointLights.Add(lightData);
|
||||||
|
|
||||||
|
|||||||
@@ -231,7 +231,11 @@ void GPUParticles::Execute(GPUContext* context, ParticleEmitter* emitter, Partic
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
Matrix worldMatrix;
|
Matrix worldMatrix;
|
||||||
effect->GetWorld(&worldMatrix);
|
const Transform transform = effect->GetTransform();
|
||||||
|
if (viewTask)
|
||||||
|
viewTask->View.GetWorldMatrix(transform, worldMatrix);
|
||||||
|
else
|
||||||
|
transform.GetWorld(worldMatrix);
|
||||||
Matrix::Transpose(worldMatrix, cbData->WorldMatrix);
|
Matrix::Transpose(worldMatrix, cbData->WorldMatrix);
|
||||||
worldMatrix.Invert();
|
worldMatrix.Invert();
|
||||||
Matrix::Transpose(worldMatrix, cbData->InvWorldMatrix);
|
Matrix::Transpose(worldMatrix, cbData->InvWorldMatrix);
|
||||||
|
|||||||
@@ -14,8 +14,8 @@ ParticleEffect::ParticleEffect(const SpawnParams& params)
|
|||||||
, _lastUpdateFrame(0)
|
, _lastUpdateFrame(0)
|
||||||
, _lastMinDstSqr(MAX_Real)
|
, _lastMinDstSqr(MAX_Real)
|
||||||
{
|
{
|
||||||
_world = Matrix::Identity;
|
_box = BoundingBox(_transform.Translation);
|
||||||
UpdateBounds();
|
BoundingSphere::FromBox(_box, _sphere);
|
||||||
|
|
||||||
ParticleSystem.Changed.Bind<ParticleEffect, &ParticleEffect::OnParticleSystemModified>(this);
|
ParticleSystem.Changed.Bind<ParticleEffect, &ParticleEffect::OnParticleSystemModified>(this);
|
||||||
ParticleSystem.Loaded.Bind<ParticleEffect, &ParticleEffect::OnParticleSystemLoaded>(this);
|
ParticleSystem.Loaded.Bind<ParticleEffect, &ParticleEffect::OnParticleSystemLoaded>(this);
|
||||||
@@ -295,7 +295,7 @@ void ParticleEffect::UpdateBounds()
|
|||||||
|
|
||||||
if (emitter->SimulationSpace == ParticlesSimulationSpace::Local)
|
if (emitter->SimulationSpace == ParticlesSimulationSpace::Local)
|
||||||
{
|
{
|
||||||
BoundingBox::Transform(emitterBounds, _world, emitterBounds);
|
BoundingBox::Transform(emitterBounds, _transform, emitterBounds);
|
||||||
}
|
}
|
||||||
|
|
||||||
BoundingBox::Merge(emitterBounds, bounds, bounds);
|
BoundingBox::Merge(emitterBounds, bounds, bounds);
|
||||||
@@ -737,6 +737,5 @@ void ParticleEffect::OnTransformChanged()
|
|||||||
// Base
|
// Base
|
||||||
Actor::OnTransformChanged();
|
Actor::OnTransformChanged();
|
||||||
|
|
||||||
_transform.GetWorld(_world);
|
|
||||||
UpdateBounds();
|
UpdateBounds();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -179,7 +179,6 @@ public:
|
|||||||
private:
|
private:
|
||||||
uint64 _lastUpdateFrame;
|
uint64 _lastUpdateFrame;
|
||||||
Real _lastMinDstSqr;
|
Real _lastMinDstSqr;
|
||||||
Matrix _world;
|
|
||||||
int32 _sceneRenderingKey = -1;
|
int32 _sceneRenderingKey = -1;
|
||||||
uint32 _parametersVersion = 0; // Version number for _parameters to be in sync with Instance.ParametersVersion
|
uint32 _parametersVersion = 0; // Version number for _parameters to be in sync with Instance.ParametersVersion
|
||||||
Array<ParticleEffectParameter> _parameters; // Cached for scripting API
|
Array<ParticleEffectParameter> _parameters; // Cached for scripting API
|
||||||
@@ -246,15 +245,6 @@ public:
|
|||||||
API_FIELD(Attributes="EditorDisplay(\"Particle Effect\"), EditorOrder(75), DefaultValue(DrawPass.Default)")
|
API_FIELD(Attributes="EditorDisplay(\"Particle Effect\"), EditorOrder(75), DefaultValue(DrawPass.Default)")
|
||||||
DrawPass DrawModes = DrawPass::Default;
|
DrawPass DrawModes = DrawPass::Default;
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets the actor world matrix transform.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="world">Result world matrix</param>
|
|
||||||
FORCE_INLINE void GetWorld(Matrix* world) const
|
|
||||||
{
|
|
||||||
*world = _world;
|
|
||||||
}
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the effect parameters collection. Those parameters are instanced from the <see cref="ParticleSystem"/> that contains a linear list of emitters and every emitter has a list of own parameters.
|
/// Gets the effect parameters collection. Those parameters are instanced from the <see cref="ParticleSystem"/> that contains a linear list of emitters and every emitter has a list of own parameters.
|
||||||
|
|||||||
@@ -362,7 +362,7 @@ Asset::LoadResult ParticleSystem::load()
|
|||||||
continue;
|
continue;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
EmittersParametersOverrides.Add(key, Variant(value));
|
EmittersParametersOverrides[key] = Variant(value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -441,7 +441,7 @@ Asset::LoadResult ParticleSystem::load()
|
|||||||
continue;
|
continue;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
EmittersParametersOverrides.Add(key, value);
|
EmittersParametersOverrides[key] = value;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -877,8 +877,9 @@ void Particles::DrawParticles(RenderContext& renderContext, ParticleEffect* effe
|
|||||||
const auto drawModes = static_cast<DrawPass>(view.Pass & effect->DrawModes);
|
const auto drawModes = static_cast<DrawPass>(view.Pass & effect->DrawModes);
|
||||||
if (drawModes == DrawPass::None || SpriteRenderer.Init())
|
if (drawModes == DrawPass::None || SpriteRenderer.Init())
|
||||||
return;
|
return;
|
||||||
Matrix world;
|
Matrix worlds[2];
|
||||||
effect->GetWorld(&world);
|
Matrix::Translation(-renderContext.View.Origin, worlds[0]); // World
|
||||||
|
renderContext.View.GetWorldMatrix(effect->GetTransform(), worlds[1]); // Local
|
||||||
const auto staticFlags = effect->GetStaticFlags();
|
const auto staticFlags = effect->GetStaticFlags();
|
||||||
|
|
||||||
// Draw lights
|
// Draw lights
|
||||||
@@ -888,14 +889,15 @@ void Particles::DrawParticles(RenderContext& renderContext, ParticleEffect* effe
|
|||||||
const auto buffer = emitterData.Buffer;
|
const auto buffer = emitterData.Buffer;
|
||||||
if (!buffer || (buffer->Mode == ParticlesSimulationMode::CPU && buffer->CPU.Count == 0))
|
if (!buffer || (buffer->Mode == ParticlesSimulationMode::CPU && buffer->CPU.Count == 0))
|
||||||
continue;
|
continue;
|
||||||
|
auto emitter = buffer->Emitter;
|
||||||
|
|
||||||
buffer->Emitter->GraphExecutorCPU.Draw(buffer->Emitter, effect, emitterData, renderContext, world);
|
buffer->Emitter->GraphExecutorCPU.Draw(buffer->Emitter, effect, emitterData, renderContext, worlds[(int32)emitter->SimulationSpace]);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Setup a draw call common data
|
// Setup a draw call common data
|
||||||
DrawCall drawCall;
|
DrawCall drawCall;
|
||||||
drawCall.PerInstanceRandom = effect->GetPerInstanceRandom();
|
drawCall.PerInstanceRandom = effect->GetPerInstanceRandom();
|
||||||
drawCall.ObjectPosition = world.GetTranslation();
|
drawCall.ObjectPosition = effect->GetPosition();
|
||||||
|
|
||||||
// Draw all emitters
|
// Draw all emitters
|
||||||
for (int32 emitterIndex = 0; emitterIndex < effect->Instance.Emitters.Count(); emitterIndex++)
|
for (int32 emitterIndex = 0; emitterIndex < effect->Instance.Emitters.Count(); emitterIndex++)
|
||||||
@@ -906,7 +908,7 @@ void Particles::DrawParticles(RenderContext& renderContext, ParticleEffect* effe
|
|||||||
continue;
|
continue;
|
||||||
auto emitter = buffer->Emitter;
|
auto emitter = buffer->Emitter;
|
||||||
|
|
||||||
drawCall.World = emitter->SimulationSpace == ParticlesSimulationSpace::World ? Matrix::Identity : world;
|
drawCall.World = worlds[(int32)emitter->SimulationSpace];
|
||||||
drawCall.WorldDeterminantSign = Math::FloatSelect(drawCall.World.RotDeterminant(), 1, -1);
|
drawCall.WorldDeterminantSign = Math::FloatSelect(drawCall.World.RotDeterminant(), 1, -1);
|
||||||
drawCall.Particle.Particles = buffer;
|
drawCall.Particle.Particles = buffer;
|
||||||
|
|
||||||
|
|||||||
@@ -327,7 +327,7 @@ void RigidBody::OnColliderChanged(Collider* c)
|
|||||||
|
|
||||||
void RigidBody::UpdateBounds()
|
void RigidBody::UpdateBounds()
|
||||||
{
|
{
|
||||||
void* actor = GetPhysicsActor();
|
void* actor = _actor;
|
||||||
if (actor && PhysicsBackend::GetRigidActorShapesCount(actor) != 0)
|
if (actor && PhysicsBackend::GetRigidActorShapesCount(actor) != 0)
|
||||||
PhysicsBackend::GetActorBounds(actor, _box);
|
PhysicsBackend::GetActorBounds(actor, _box);
|
||||||
else
|
else
|
||||||
@@ -406,7 +406,7 @@ void RigidBody::OnActiveTransformChanged()
|
|||||||
ASSERT(!_isUpdatingTransform);
|
ASSERT(!_isUpdatingTransform);
|
||||||
_isUpdatingTransform = true;
|
_isUpdatingTransform = true;
|
||||||
Transform transform;
|
Transform transform;
|
||||||
PhysicsBackend::GetRigidActorPose(GetPhysicsActor(), transform.Translation, transform.Orientation);
|
PhysicsBackend::GetRigidActorPose(_actor, transform.Translation, transform.Orientation);
|
||||||
transform.Scale = _transform.Scale;
|
transform.Scale = _transform.Scale;
|
||||||
if (_parent)
|
if (_parent)
|
||||||
{
|
{
|
||||||
@@ -424,7 +424,8 @@ void RigidBody::BeginPlay(SceneBeginData* data)
|
|||||||
{
|
{
|
||||||
// Create rigid body
|
// Create rigid body
|
||||||
ASSERT(_actor == nullptr);
|
ASSERT(_actor == nullptr);
|
||||||
_actor = PhysicsBackend::CreateRigidDynamicActor(this, _transform.Translation, _transform.Orientation);
|
void* scene = GetPhysicsScene()->GetPhysicsScene();
|
||||||
|
_actor = PhysicsBackend::CreateRigidDynamicActor(this, _transform.Translation, _transform.Orientation, scene);
|
||||||
|
|
||||||
// Apply properties
|
// Apply properties
|
||||||
auto actorFlags = PhysicsBackend::ActorFlags::None;
|
auto actorFlags = PhysicsBackend::ActorFlags::None;
|
||||||
@@ -462,7 +463,6 @@ void RigidBody::BeginPlay(SceneBeginData* data)
|
|||||||
PhysicsBackend::SetRigidDynamicActorCenterOfMassOffset(_actor, _centerOfMassOffset);
|
PhysicsBackend::SetRigidDynamicActorCenterOfMassOffset(_actor, _centerOfMassOffset);
|
||||||
|
|
||||||
// Register actor
|
// Register actor
|
||||||
void* scene = GetPhysicsScene()->GetPhysicsScene();
|
|
||||||
PhysicsBackend::AddSceneActor(scene, _actor);
|
PhysicsBackend::AddSceneActor(scene, _actor);
|
||||||
const bool putToSleep = !_startAwake && GetEnableSimulation() && !GetIsKinematic() && IsActiveInHierarchy();
|
const bool putToSleep = !_startAwake && GetEnableSimulation() && !GetIsKinematic() && IsActiveInHierarchy();
|
||||||
if (putToSleep)
|
if (putToSleep)
|
||||||
|
|||||||
@@ -258,13 +258,13 @@ void Collider::UpdateGeometry()
|
|||||||
void Collider::CreateStaticActor()
|
void Collider::CreateStaticActor()
|
||||||
{
|
{
|
||||||
ASSERT(_staticActor == nullptr);
|
ASSERT(_staticActor == nullptr);
|
||||||
_staticActor = PhysicsBackend::CreateRigidStaticActor(nullptr, _transform.Translation, _transform.Orientation);
|
void* scene = GetPhysicsScene()->GetPhysicsScene();
|
||||||
|
_staticActor = PhysicsBackend::CreateRigidStaticActor(nullptr, _transform.Translation, _transform.Orientation, scene);
|
||||||
|
|
||||||
// Reset local pos of the shape and link it to the actor
|
// Reset local pos of the shape and link it to the actor
|
||||||
PhysicsBackend::SetShapeLocalPose(_shape, _center, Quaternion::Identity);
|
PhysicsBackend::SetShapeLocalPose(_shape, _center, Quaternion::Identity);
|
||||||
PhysicsBackend::AttachShape(_shape, _staticActor);
|
PhysicsBackend::AttachShape(_shape, _staticActor);
|
||||||
|
|
||||||
void* scene = GetPhysicsScene()->GetPhysicsScene();
|
|
||||||
PhysicsBackend::AddSceneActor(scene, _staticActor);
|
PhysicsBackend::AddSceneActor(scene, _staticActor);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -65,6 +65,7 @@ struct ScenePhysX
|
|||||||
PxCpuDispatcher* CpuDispatcher = nullptr;
|
PxCpuDispatcher* CpuDispatcher = nullptr;
|
||||||
PxControllerManager* ControllerManager = nullptr;
|
PxControllerManager* ControllerManager = nullptr;
|
||||||
void* ScratchMemory = nullptr;
|
void* ScratchMemory = nullptr;
|
||||||
|
Vector3 Origin = Vector3::Zero;
|
||||||
float LastDeltaTime = 0.0f;
|
float LastDeltaTime = 0.0f;
|
||||||
FixedStepper Stepper;
|
FixedStepper Stepper;
|
||||||
SimulationEventCallback EventsCallback;
|
SimulationEventCallback EventsCallback;
|
||||||
@@ -303,7 +304,8 @@ protected:
|
|||||||
DynamicHitBuffer<PxOverlapHit> buffer
|
DynamicHitBuffer<PxOverlapHit> buffer
|
||||||
|
|
||||||
#define SCENE_QUERY_COLLECT_SINGLE() const auto& hit = buffer.getAnyHit(0); \
|
#define SCENE_QUERY_COLLECT_SINGLE() const auto& hit = buffer.getAnyHit(0); \
|
||||||
P2C(hit, hitInfo)
|
P2C(hit, hitInfo); \
|
||||||
|
hitInfo.Point += scenePhysX->Origin
|
||||||
|
|
||||||
#define SCENE_QUERY_COLLECT_ALL() results.Clear(); \
|
#define SCENE_QUERY_COLLECT_ALL() results.Clear(); \
|
||||||
results.Resize(buffer.getNbAnyHits(), false); \
|
results.Resize(buffer.getNbAnyHits(), false); \
|
||||||
@@ -311,6 +313,7 @@ protected:
|
|||||||
{ \
|
{ \
|
||||||
const auto& hit = buffer.getAnyHit(i); \
|
const auto& hit = buffer.getAnyHit(i); \
|
||||||
P2C(hit, results[i]); \
|
P2C(hit, results[i]); \
|
||||||
|
results[i].Point += scenePhysX->Origin; \
|
||||||
}
|
}
|
||||||
|
|
||||||
#define SCENE_QUERY_COLLECT_OVERLAP() results.Clear(); \
|
#define SCENE_QUERY_COLLECT_OVERLAP() results.Clear(); \
|
||||||
@@ -348,6 +351,7 @@ namespace
|
|||||||
QueryFilterPhysX QueryFilter;
|
QueryFilterPhysX QueryFilter;
|
||||||
CharacterQueryFilterPhysX CharacterQueryFilter;
|
CharacterQueryFilterPhysX CharacterQueryFilter;
|
||||||
CharacterControllerFilterPhysX CharacterControllerFilter;
|
CharacterControllerFilterPhysX CharacterControllerFilter;
|
||||||
|
Dictionary<PxScene*, Vector3, InlinedAllocation<32>> SceneOrigins;
|
||||||
|
|
||||||
CriticalSection FlushLocker;
|
CriticalSection FlushLocker;
|
||||||
Array<PxBase*> DeleteObjects;
|
Array<PxBase*> DeleteObjects;
|
||||||
@@ -721,6 +725,9 @@ bool PhysicsBackend::Init()
|
|||||||
// Create default material
|
// Create default material
|
||||||
DefaultMaterial = PhysX->createMaterial(0.7f, 0.7f, 0.3f);
|
DefaultMaterial = PhysX->createMaterial(0.7f, 0.7f, 0.3f);
|
||||||
|
|
||||||
|
// Return origin 0,0,0 for invalid/null scenes
|
||||||
|
SceneOrigins.Add((PxScene*)nullptr, Vector3::Zero);
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -772,6 +779,7 @@ void PhysicsBackend::Shutdown()
|
|||||||
RELEASE_PHYSX(PVD);
|
RELEASE_PHYSX(PVD);
|
||||||
#endif
|
#endif
|
||||||
RELEASE_PHYSX(Foundation);
|
RELEASE_PHYSX(Foundation);
|
||||||
|
SceneOrigins.Clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
void PhysicsBackend::ApplySettings(const PhysicsSettings& settings)
|
void PhysicsBackend::ApplySettings(const PhysicsSettings& settings)
|
||||||
@@ -825,6 +833,7 @@ void* PhysicsBackend::CreateScene(const PhysicsSettings& settings)
|
|||||||
// Create scene
|
// Create scene
|
||||||
scenePhysX->Scene = PhysX->createScene(sceneDesc);
|
scenePhysX->Scene = PhysX->createScene(sceneDesc);
|
||||||
CHECK_INIT(scenePhysX->Scene, "createScene failed!");
|
CHECK_INIT(scenePhysX->Scene, "createScene failed!");
|
||||||
|
SceneOrigins[scenePhysX->Scene] = Vector3::Zero;
|
||||||
#if WITH_PVD
|
#if WITH_PVD
|
||||||
auto pvdClient = scenePhysX->Scene->getScenePvdClient();
|
auto pvdClient = scenePhysX->Scene->getScenePvdClient();
|
||||||
if (pvdClient)
|
if (pvdClient)
|
||||||
@@ -852,6 +861,7 @@ void PhysicsBackend::DestroyScene(void* scene)
|
|||||||
FlushRequests(scene);
|
FlushRequests(scene);
|
||||||
|
|
||||||
// Release resources
|
// Release resources
|
||||||
|
SceneOrigins.Remove(scenePhysX->Scene);
|
||||||
#if WITH_VEHICLE
|
#if WITH_VEHICLE
|
||||||
RELEASE_PHYSX(scenePhysX->WheelRaycastBatchQuery);
|
RELEASE_PHYSX(scenePhysX->WheelRaycastBatchQuery);
|
||||||
#endif
|
#endif
|
||||||
@@ -1182,15 +1192,15 @@ void PhysicsBackend::EndSimulateScene(void* scene)
|
|||||||
auto& state = wheelData.State;
|
auto& state = wheelData.State;
|
||||||
state.IsInAir = perWheel.isInAir;
|
state.IsInAir = perWheel.isInAir;
|
||||||
state.TireContactCollider = perWheel.tireContactShape ? static_cast<PhysicsColliderActor*>(perWheel.tireContactShape->userData) : nullptr;
|
state.TireContactCollider = perWheel.tireContactShape ? static_cast<PhysicsColliderActor*>(perWheel.tireContactShape->userData) : nullptr;
|
||||||
state.TireContactPoint = P2C(perWheel.tireContactPoint);
|
state.TireContactPoint = P2C(perWheel.tireContactPoint) + scenePhysX->Origin;
|
||||||
state.TireContactNormal = P2C(perWheel.tireContactNormal);
|
state.TireContactNormal = P2C(perWheel.tireContactNormal);
|
||||||
state.TireFriction = perWheel.tireFriction;
|
state.TireFriction = perWheel.tireFriction;
|
||||||
state.SteerAngle = RadiansToDegrees * perWheel.steerAngle;
|
state.SteerAngle = RadiansToDegrees * perWheel.steerAngle;
|
||||||
state.RotationAngle = -RadiansToDegrees * drive->mWheelsDynData.getWheelRotationAngle(j);
|
state.RotationAngle = -RadiansToDegrees * drive->mWheelsDynData.getWheelRotationAngle(j);
|
||||||
state.SuspensionOffset = perWheel.suspJounce;
|
state.SuspensionOffset = perWheel.suspJounce;
|
||||||
#if USE_EDITOR
|
#if USE_EDITOR
|
||||||
state.SuspensionTraceStart = P2C(perWheel.suspLineStart);
|
state.SuspensionTraceStart = P2C(perWheel.suspLineStart) + scenePhysX->Origin;
|
||||||
state.SuspensionTraceEnd = P2C(perWheel.suspLineStart + perWheel.suspLineDir * perWheel.suspLineLength);
|
state.SuspensionTraceEnd = P2C(perWheel.suspLineStart + perWheel.suspLineDir * perWheel.suspLineLength) + scenePhysX->Origin;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (!wheelData.Collider)
|
if (!wheelData.Collider)
|
||||||
@@ -1274,6 +1284,26 @@ void PhysicsBackend::SetSceneBounceThresholdVelocity(void* scene, float value)
|
|||||||
scenePhysX->Scene->setBounceThresholdVelocity(value);
|
scenePhysX->Scene->setBounceThresholdVelocity(value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void PhysicsBackend::SetSceneOrigin(void* scene, const Vector3& oldOrigin, const Vector3& newOrigin)
|
||||||
|
{
|
||||||
|
auto scenePhysX = (ScenePhysX*)scene;
|
||||||
|
const PxVec3 shift = C2P(newOrigin - oldOrigin);
|
||||||
|
scenePhysX->Origin = newOrigin;
|
||||||
|
scenePhysX->Scene->shiftOrigin(shift);
|
||||||
|
scenePhysX->ControllerManager->shiftOrigin(shift);
|
||||||
|
WheelVehiclesCache.Clear();
|
||||||
|
for (auto wheelVehicle : scenePhysX->WheelVehicles)
|
||||||
|
{
|
||||||
|
if (!wheelVehicle->IsActiveInHierarchy())
|
||||||
|
continue;
|
||||||
|
auto drive = (PxVehicleWheels*)wheelVehicle->_vehicle;
|
||||||
|
ASSERT(drive);
|
||||||
|
WheelVehiclesCache.Add(drive);
|
||||||
|
}
|
||||||
|
PxVehicleShiftOrigin(shift, WheelVehiclesCache.Count(), WheelVehiclesCache.Get());
|
||||||
|
SceneOrigins[scenePhysX->Scene] = newOrigin;
|
||||||
|
}
|
||||||
|
|
||||||
void PhysicsBackend::AddSceneActor(void* scene, void* actor)
|
void PhysicsBackend::AddSceneActor(void* scene, void* actor)
|
||||||
{
|
{
|
||||||
auto scenePhysX = (ScenePhysX*)scene;
|
auto scenePhysX = (ScenePhysX*)scene;
|
||||||
@@ -1304,14 +1334,14 @@ bool PhysicsBackend::RayCast(void* scene, const Vector3& origin, const Vector3&
|
|||||||
{
|
{
|
||||||
SCENE_QUERY_SETUP(true);
|
SCENE_QUERY_SETUP(true);
|
||||||
PxRaycastBuffer buffer;
|
PxRaycastBuffer buffer;
|
||||||
return scenePhysX->Scene->raycast(C2P(origin), C2P(direction), maxDistance, buffer, hitFlags, filterData, &QueryFilter);
|
return scenePhysX->Scene->raycast(C2P(origin - scenePhysX->Origin), C2P(direction), maxDistance, buffer, hitFlags, filterData, &QueryFilter);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool PhysicsBackend::RayCast(void* scene, const Vector3& origin, const Vector3& direction, RayCastHit& hitInfo, const float maxDistance, uint32 layerMask, bool hitTriggers)
|
bool PhysicsBackend::RayCast(void* scene, const Vector3& origin, const Vector3& direction, RayCastHit& hitInfo, const float maxDistance, uint32 layerMask, bool hitTriggers)
|
||||||
{
|
{
|
||||||
SCENE_QUERY_SETUP(true);
|
SCENE_QUERY_SETUP(true);
|
||||||
PxRaycastBuffer buffer;
|
PxRaycastBuffer buffer;
|
||||||
if (!scenePhysX->Scene->raycast(C2P(origin), C2P(direction), maxDistance, buffer, hitFlags, filterData, &QueryFilter))
|
if (!scenePhysX->Scene->raycast(C2P(origin - scenePhysX->Origin), C2P(direction), maxDistance, buffer, hitFlags, filterData, &QueryFilter))
|
||||||
return false;
|
return false;
|
||||||
SCENE_QUERY_COLLECT_SINGLE();
|
SCENE_QUERY_COLLECT_SINGLE();
|
||||||
return true;
|
return true;
|
||||||
@@ -1321,7 +1351,7 @@ bool PhysicsBackend::RayCastAll(void* scene, const Vector3& origin, const Vector
|
|||||||
{
|
{
|
||||||
SCENE_QUERY_SETUP(false);
|
SCENE_QUERY_SETUP(false);
|
||||||
DynamicHitBuffer<PxRaycastHit> buffer;
|
DynamicHitBuffer<PxRaycastHit> buffer;
|
||||||
if (!scenePhysX->Scene->raycast(C2P(origin), C2P(direction), maxDistance, buffer, hitFlags, filterData, &QueryFilter))
|
if (!scenePhysX->Scene->raycast(C2P(origin - scenePhysX->Origin), C2P(direction), maxDistance, buffer, hitFlags, filterData, &QueryFilter))
|
||||||
return false;
|
return false;
|
||||||
SCENE_QUERY_COLLECT_ALL();
|
SCENE_QUERY_COLLECT_ALL();
|
||||||
return true;
|
return true;
|
||||||
@@ -1330,7 +1360,7 @@ bool PhysicsBackend::RayCastAll(void* scene, const Vector3& origin, const Vector
|
|||||||
bool PhysicsBackend::BoxCast(void* scene, const Vector3& center, const Vector3& halfExtents, const Vector3& direction, const Quaternion& rotation, const float maxDistance, uint32 layerMask, bool hitTriggers)
|
bool PhysicsBackend::BoxCast(void* scene, const Vector3& center, const Vector3& halfExtents, const Vector3& direction, const Quaternion& rotation, const float maxDistance, uint32 layerMask, bool hitTriggers)
|
||||||
{
|
{
|
||||||
SCENE_QUERY_SETUP_SWEEP_1();
|
SCENE_QUERY_SETUP_SWEEP_1();
|
||||||
const PxTransform pose(C2P(center), C2P(rotation));
|
const PxTransform pose(C2P(center - scenePhysX->Origin), C2P(rotation));
|
||||||
const PxBoxGeometry geometry(C2P(halfExtents));
|
const PxBoxGeometry geometry(C2P(halfExtents));
|
||||||
return scenePhysX->Scene->sweep(geometry, pose, C2P(direction), maxDistance, buffer, hitFlags, filterData, &QueryFilter);
|
return scenePhysX->Scene->sweep(geometry, pose, C2P(direction), maxDistance, buffer, hitFlags, filterData, &QueryFilter);
|
||||||
}
|
}
|
||||||
@@ -1338,7 +1368,7 @@ bool PhysicsBackend::BoxCast(void* scene, const Vector3& center, const Vector3&
|
|||||||
bool PhysicsBackend::BoxCast(void* scene, const Vector3& center, const Vector3& halfExtents, const Vector3& direction, RayCastHit& hitInfo, const Quaternion& rotation, const float maxDistance, uint32 layerMask, bool hitTriggers)
|
bool PhysicsBackend::BoxCast(void* scene, const Vector3& center, const Vector3& halfExtents, const Vector3& direction, RayCastHit& hitInfo, const Quaternion& rotation, const float maxDistance, uint32 layerMask, bool hitTriggers)
|
||||||
{
|
{
|
||||||
SCENE_QUERY_SETUP_SWEEP_1();
|
SCENE_QUERY_SETUP_SWEEP_1();
|
||||||
const PxTransform pose(C2P(center), C2P(rotation));
|
const PxTransform pose(C2P(center - scenePhysX->Origin), C2P(rotation));
|
||||||
const PxBoxGeometry geometry(C2P(halfExtents));
|
const PxBoxGeometry geometry(C2P(halfExtents));
|
||||||
if (!scenePhysX->Scene->sweep(geometry, pose, C2P(direction), maxDistance, buffer, hitFlags, filterData, &QueryFilter))
|
if (!scenePhysX->Scene->sweep(geometry, pose, C2P(direction), maxDistance, buffer, hitFlags, filterData, &QueryFilter))
|
||||||
return false;
|
return false;
|
||||||
@@ -1349,7 +1379,7 @@ bool PhysicsBackend::BoxCast(void* scene, const Vector3& center, const Vector3&
|
|||||||
bool PhysicsBackend::BoxCastAll(void* scene, const Vector3& center, const Vector3& halfExtents, const Vector3& direction, Array<RayCastHit>& results, const Quaternion& rotation, const float maxDistance, uint32 layerMask, bool hitTriggers)
|
bool PhysicsBackend::BoxCastAll(void* scene, const Vector3& center, const Vector3& halfExtents, const Vector3& direction, Array<RayCastHit>& results, const Quaternion& rotation, const float maxDistance, uint32 layerMask, bool hitTriggers)
|
||||||
{
|
{
|
||||||
SCENE_QUERY_SETUP_SWEEP();
|
SCENE_QUERY_SETUP_SWEEP();
|
||||||
const PxTransform pose(C2P(center), C2P(rotation));
|
const PxTransform pose(C2P(center - scenePhysX->Origin), C2P(rotation));
|
||||||
const PxBoxGeometry geometry(C2P(halfExtents));
|
const PxBoxGeometry geometry(C2P(halfExtents));
|
||||||
if (!scenePhysX->Scene->sweep(geometry, pose, C2P(direction), maxDistance, buffer, hitFlags, filterData, &QueryFilter))
|
if (!scenePhysX->Scene->sweep(geometry, pose, C2P(direction), maxDistance, buffer, hitFlags, filterData, &QueryFilter))
|
||||||
return false;
|
return false;
|
||||||
@@ -1360,7 +1390,7 @@ bool PhysicsBackend::BoxCastAll(void* scene, const Vector3& center, const Vector
|
|||||||
bool PhysicsBackend::SphereCast(void* scene, const Vector3& center, const float radius, const Vector3& direction, const float maxDistance, uint32 layerMask, bool hitTriggers)
|
bool PhysicsBackend::SphereCast(void* scene, const Vector3& center, const float radius, const Vector3& direction, const float maxDistance, uint32 layerMask, bool hitTriggers)
|
||||||
{
|
{
|
||||||
SCENE_QUERY_SETUP_SWEEP_1();
|
SCENE_QUERY_SETUP_SWEEP_1();
|
||||||
const PxTransform pose(C2P(center));
|
const PxTransform pose(C2P(center - scenePhysX->Origin));
|
||||||
const PxSphereGeometry geometry(radius);
|
const PxSphereGeometry geometry(radius);
|
||||||
return scenePhysX->Scene->sweep(geometry, pose, C2P(direction), maxDistance, buffer, hitFlags, filterData, &QueryFilter);
|
return scenePhysX->Scene->sweep(geometry, pose, C2P(direction), maxDistance, buffer, hitFlags, filterData, &QueryFilter);
|
||||||
}
|
}
|
||||||
@@ -1368,7 +1398,7 @@ bool PhysicsBackend::SphereCast(void* scene, const Vector3& center, const float
|
|||||||
bool PhysicsBackend::SphereCast(void* scene, const Vector3& center, const float radius, const Vector3& direction, RayCastHit& hitInfo, const float maxDistance, uint32 layerMask, bool hitTriggers)
|
bool PhysicsBackend::SphereCast(void* scene, const Vector3& center, const float radius, const Vector3& direction, RayCastHit& hitInfo, const float maxDistance, uint32 layerMask, bool hitTriggers)
|
||||||
{
|
{
|
||||||
SCENE_QUERY_SETUP_SWEEP_1();
|
SCENE_QUERY_SETUP_SWEEP_1();
|
||||||
const PxTransform pose(C2P(center));
|
const PxTransform pose(C2P(center - scenePhysX->Origin));
|
||||||
const PxSphereGeometry geometry(radius);
|
const PxSphereGeometry geometry(radius);
|
||||||
if (!scenePhysX->Scene->sweep(geometry, pose, C2P(direction), maxDistance, buffer, hitFlags, filterData, &QueryFilter))
|
if (!scenePhysX->Scene->sweep(geometry, pose, C2P(direction), maxDistance, buffer, hitFlags, filterData, &QueryFilter))
|
||||||
return false;
|
return false;
|
||||||
@@ -1379,7 +1409,7 @@ bool PhysicsBackend::SphereCast(void* scene, const Vector3& center, const float
|
|||||||
bool PhysicsBackend::SphereCastAll(void* scene, const Vector3& center, const float radius, const Vector3& direction, Array<RayCastHit>& results, const float maxDistance, uint32 layerMask, bool hitTriggers)
|
bool PhysicsBackend::SphereCastAll(void* scene, const Vector3& center, const float radius, const Vector3& direction, Array<RayCastHit>& results, const float maxDistance, uint32 layerMask, bool hitTriggers)
|
||||||
{
|
{
|
||||||
SCENE_QUERY_SETUP_SWEEP();
|
SCENE_QUERY_SETUP_SWEEP();
|
||||||
const PxTransform pose(C2P(center));
|
const PxTransform pose(C2P(center - scenePhysX->Origin));
|
||||||
const PxSphereGeometry geometry(radius);
|
const PxSphereGeometry geometry(radius);
|
||||||
if (!scenePhysX->Scene->sweep(geometry, pose, C2P(direction), maxDistance, buffer, hitFlags, filterData, &QueryFilter))
|
if (!scenePhysX->Scene->sweep(geometry, pose, C2P(direction), maxDistance, buffer, hitFlags, filterData, &QueryFilter))
|
||||||
return false;
|
return false;
|
||||||
@@ -1390,7 +1420,7 @@ bool PhysicsBackend::SphereCastAll(void* scene, const Vector3& center, const flo
|
|||||||
bool PhysicsBackend::CapsuleCast(void* scene, const Vector3& center, const float radius, const float height, const Vector3& direction, const Quaternion& rotation, const float maxDistance, uint32 layerMask, bool hitTriggers)
|
bool PhysicsBackend::CapsuleCast(void* scene, const Vector3& center, const float radius, const float height, const Vector3& direction, const Quaternion& rotation, const float maxDistance, uint32 layerMask, bool hitTriggers)
|
||||||
{
|
{
|
||||||
SCENE_QUERY_SETUP_SWEEP_1();
|
SCENE_QUERY_SETUP_SWEEP_1();
|
||||||
const PxTransform pose(C2P(center), C2P(rotation));
|
const PxTransform pose(C2P(center - scenePhysX->Origin), C2P(rotation));
|
||||||
const PxCapsuleGeometry geometry(radius, height * 0.5f);
|
const PxCapsuleGeometry geometry(radius, height * 0.5f);
|
||||||
return scenePhysX->Scene->sweep(geometry, pose, C2P(direction), maxDistance, buffer, hitFlags, filterData, &QueryFilter);
|
return scenePhysX->Scene->sweep(geometry, pose, C2P(direction), maxDistance, buffer, hitFlags, filterData, &QueryFilter);
|
||||||
}
|
}
|
||||||
@@ -1398,7 +1428,7 @@ bool PhysicsBackend::CapsuleCast(void* scene, const Vector3& center, const float
|
|||||||
bool PhysicsBackend::CapsuleCast(void* scene, const Vector3& center, const float radius, const float height, const Vector3& direction, RayCastHit& hitInfo, const Quaternion& rotation, const float maxDistance, uint32 layerMask, bool hitTriggers)
|
bool PhysicsBackend::CapsuleCast(void* scene, const Vector3& center, const float radius, const float height, const Vector3& direction, RayCastHit& hitInfo, const Quaternion& rotation, const float maxDistance, uint32 layerMask, bool hitTriggers)
|
||||||
{
|
{
|
||||||
SCENE_QUERY_SETUP_SWEEP_1();
|
SCENE_QUERY_SETUP_SWEEP_1();
|
||||||
const PxTransform pose(C2P(center), C2P(rotation));
|
const PxTransform pose(C2P(center - scenePhysX->Origin), C2P(rotation));
|
||||||
const PxCapsuleGeometry geometry(radius, height * 0.5f);
|
const PxCapsuleGeometry geometry(radius, height * 0.5f);
|
||||||
if (!scenePhysX->Scene->sweep(geometry, pose, C2P(direction), maxDistance, buffer, hitFlags, filterData, &QueryFilter))
|
if (!scenePhysX->Scene->sweep(geometry, pose, C2P(direction), maxDistance, buffer, hitFlags, filterData, &QueryFilter))
|
||||||
return false;
|
return false;
|
||||||
@@ -1409,7 +1439,7 @@ bool PhysicsBackend::CapsuleCast(void* scene, const Vector3& center, const float
|
|||||||
bool PhysicsBackend::CapsuleCastAll(void* scene, const Vector3& center, const float radius, const float height, const Vector3& direction, Array<RayCastHit>& results, const Quaternion& rotation, const float maxDistance, uint32 layerMask, bool hitTriggers)
|
bool PhysicsBackend::CapsuleCastAll(void* scene, const Vector3& center, const float radius, const float height, const Vector3& direction, Array<RayCastHit>& results, const Quaternion& rotation, const float maxDistance, uint32 layerMask, bool hitTriggers)
|
||||||
{
|
{
|
||||||
SCENE_QUERY_SETUP_SWEEP();
|
SCENE_QUERY_SETUP_SWEEP();
|
||||||
const PxTransform pose(C2P(center), C2P(rotation));
|
const PxTransform pose(C2P(center - scenePhysX->Origin), C2P(rotation));
|
||||||
const PxCapsuleGeometry geometry(radius, height * 0.5f);
|
const PxCapsuleGeometry geometry(radius, height * 0.5f);
|
||||||
if (!scenePhysX->Scene->sweep(geometry, pose, C2P(direction), maxDistance, buffer, hitFlags, filterData, &QueryFilter))
|
if (!scenePhysX->Scene->sweep(geometry, pose, C2P(direction), maxDistance, buffer, hitFlags, filterData, &QueryFilter))
|
||||||
return false;
|
return false;
|
||||||
@@ -1421,7 +1451,7 @@ bool PhysicsBackend::ConvexCast(void* scene, const Vector3& center, const Collis
|
|||||||
{
|
{
|
||||||
CHECK_RETURN(convexMesh && convexMesh->GetOptions().Type == CollisionDataType::ConvexMesh, false)
|
CHECK_RETURN(convexMesh && convexMesh->GetOptions().Type == CollisionDataType::ConvexMesh, false)
|
||||||
SCENE_QUERY_SETUP_SWEEP_1();
|
SCENE_QUERY_SETUP_SWEEP_1();
|
||||||
const PxTransform pose(C2P(center), C2P(rotation));
|
const PxTransform pose(C2P(center - scenePhysX->Origin), C2P(rotation));
|
||||||
const PxConvexMeshGeometry geometry((PxConvexMesh*)convexMesh->GetConvex(), PxMeshScale(C2P(scale)));
|
const PxConvexMeshGeometry geometry((PxConvexMesh*)convexMesh->GetConvex(), PxMeshScale(C2P(scale)));
|
||||||
return scenePhysX->Scene->sweep(geometry, pose, C2P(direction), maxDistance, buffer, hitFlags, filterData, &QueryFilter);
|
return scenePhysX->Scene->sweep(geometry, pose, C2P(direction), maxDistance, buffer, hitFlags, filterData, &QueryFilter);
|
||||||
}
|
}
|
||||||
@@ -1430,7 +1460,7 @@ bool PhysicsBackend::ConvexCast(void* scene, const Vector3& center, const Collis
|
|||||||
{
|
{
|
||||||
CHECK_RETURN(convexMesh && convexMesh->GetOptions().Type == CollisionDataType::ConvexMesh, false)
|
CHECK_RETURN(convexMesh && convexMesh->GetOptions().Type == CollisionDataType::ConvexMesh, false)
|
||||||
SCENE_QUERY_SETUP_SWEEP_1();
|
SCENE_QUERY_SETUP_SWEEP_1();
|
||||||
const PxTransform pose(C2P(center), C2P(rotation));
|
const PxTransform pose(C2P(center - scenePhysX->Origin), C2P(rotation));
|
||||||
const PxConvexMeshGeometry geometry((PxConvexMesh*)convexMesh->GetConvex(), PxMeshScale(C2P(scale)));
|
const PxConvexMeshGeometry geometry((PxConvexMesh*)convexMesh->GetConvex(), PxMeshScale(C2P(scale)));
|
||||||
if (!scenePhysX->Scene->sweep(geometry, pose, C2P(direction), maxDistance, buffer, hitFlags, filterData, &QueryFilter))
|
if (!scenePhysX->Scene->sweep(geometry, pose, C2P(direction), maxDistance, buffer, hitFlags, filterData, &QueryFilter))
|
||||||
return false;
|
return false;
|
||||||
@@ -1442,7 +1472,7 @@ bool PhysicsBackend::ConvexCastAll(void* scene, const Vector3& center, const Col
|
|||||||
{
|
{
|
||||||
CHECK_RETURN(convexMesh && convexMesh->GetOptions().Type == CollisionDataType::ConvexMesh, false)
|
CHECK_RETURN(convexMesh && convexMesh->GetOptions().Type == CollisionDataType::ConvexMesh, false)
|
||||||
SCENE_QUERY_SETUP_SWEEP();
|
SCENE_QUERY_SETUP_SWEEP();
|
||||||
const PxTransform pose(C2P(center), C2P(rotation));
|
const PxTransform pose(C2P(center - scenePhysX->Origin), C2P(rotation));
|
||||||
const PxConvexMeshGeometry geometry((PxConvexMesh*)convexMesh->GetConvex(), PxMeshScale(C2P(scale)));
|
const PxConvexMeshGeometry geometry((PxConvexMesh*)convexMesh->GetConvex(), PxMeshScale(C2P(scale)));
|
||||||
if (!scenePhysX->Scene->sweep(geometry, pose, C2P(direction), maxDistance, buffer, hitFlags, filterData, &QueryFilter))
|
if (!scenePhysX->Scene->sweep(geometry, pose, C2P(direction), maxDistance, buffer, hitFlags, filterData, &QueryFilter))
|
||||||
return false;
|
return false;
|
||||||
@@ -1453,7 +1483,7 @@ bool PhysicsBackend::ConvexCastAll(void* scene, const Vector3& center, const Col
|
|||||||
bool PhysicsBackend::CheckBox(void* scene, const Vector3& center, const Vector3& halfExtents, const Quaternion& rotation, uint32 layerMask, bool hitTriggers)
|
bool PhysicsBackend::CheckBox(void* scene, const Vector3& center, const Vector3& halfExtents, const Quaternion& rotation, uint32 layerMask, bool hitTriggers)
|
||||||
{
|
{
|
||||||
SCENE_QUERY_SETUP_OVERLAP_1();
|
SCENE_QUERY_SETUP_OVERLAP_1();
|
||||||
const PxTransform pose(C2P(center), C2P(rotation));
|
const PxTransform pose(C2P(center - scenePhysX->Origin), C2P(rotation));
|
||||||
const PxBoxGeometry geometry(C2P(halfExtents));
|
const PxBoxGeometry geometry(C2P(halfExtents));
|
||||||
return scenePhysX->Scene->overlap(geometry, pose, buffer, filterData, &QueryFilter);
|
return scenePhysX->Scene->overlap(geometry, pose, buffer, filterData, &QueryFilter);
|
||||||
}
|
}
|
||||||
@@ -1461,7 +1491,7 @@ bool PhysicsBackend::CheckBox(void* scene, const Vector3& center, const Vector3&
|
|||||||
bool PhysicsBackend::CheckSphere(void* scene, const Vector3& center, const float radius, uint32 layerMask, bool hitTriggers)
|
bool PhysicsBackend::CheckSphere(void* scene, const Vector3& center, const float radius, uint32 layerMask, bool hitTriggers)
|
||||||
{
|
{
|
||||||
SCENE_QUERY_SETUP_OVERLAP_1();
|
SCENE_QUERY_SETUP_OVERLAP_1();
|
||||||
const PxTransform pose(C2P(center));
|
const PxTransform pose(C2P(center - scenePhysX->Origin));
|
||||||
const PxSphereGeometry geometry(radius);
|
const PxSphereGeometry geometry(radius);
|
||||||
return scenePhysX->Scene->overlap(geometry, pose, buffer, filterData, &QueryFilter);
|
return scenePhysX->Scene->overlap(geometry, pose, buffer, filterData, &QueryFilter);
|
||||||
}
|
}
|
||||||
@@ -1469,7 +1499,7 @@ bool PhysicsBackend::CheckSphere(void* scene, const Vector3& center, const float
|
|||||||
bool PhysicsBackend::CheckCapsule(void* scene, const Vector3& center, const float radius, const float height, const Quaternion& rotation, uint32 layerMask, bool hitTriggers)
|
bool PhysicsBackend::CheckCapsule(void* scene, const Vector3& center, const float radius, const float height, const Quaternion& rotation, uint32 layerMask, bool hitTriggers)
|
||||||
{
|
{
|
||||||
SCENE_QUERY_SETUP_OVERLAP_1();
|
SCENE_QUERY_SETUP_OVERLAP_1();
|
||||||
const PxTransform pose(C2P(center), C2P(rotation));
|
const PxTransform pose(C2P(center - scenePhysX->Origin), C2P(rotation));
|
||||||
const PxCapsuleGeometry geometry(radius, height * 0.5f);
|
const PxCapsuleGeometry geometry(radius, height * 0.5f);
|
||||||
return scenePhysX->Scene->overlap(geometry, pose, buffer, filterData, &QueryFilter);
|
return scenePhysX->Scene->overlap(geometry, pose, buffer, filterData, &QueryFilter);
|
||||||
}
|
}
|
||||||
@@ -1478,7 +1508,7 @@ bool PhysicsBackend::CheckConvex(void* scene, const Vector3& center, const Colli
|
|||||||
{
|
{
|
||||||
CHECK_RETURN(convexMesh && convexMesh->GetOptions().Type == CollisionDataType::ConvexMesh, false)
|
CHECK_RETURN(convexMesh && convexMesh->GetOptions().Type == CollisionDataType::ConvexMesh, false)
|
||||||
SCENE_QUERY_SETUP_OVERLAP_1();
|
SCENE_QUERY_SETUP_OVERLAP_1();
|
||||||
const PxTransform pose(C2P(center), C2P(rotation));
|
const PxTransform pose(C2P(center - scenePhysX->Origin), C2P(rotation));
|
||||||
const PxConvexMeshGeometry geometry((PxConvexMesh*)convexMesh->GetConvex(), PxMeshScale(C2P(scale)));
|
const PxConvexMeshGeometry geometry((PxConvexMesh*)convexMesh->GetConvex(), PxMeshScale(C2P(scale)));
|
||||||
return scenePhysX->Scene->overlap(geometry, pose, buffer, filterData, &QueryFilter);
|
return scenePhysX->Scene->overlap(geometry, pose, buffer, filterData, &QueryFilter);
|
||||||
}
|
}
|
||||||
@@ -1486,7 +1516,7 @@ bool PhysicsBackend::CheckConvex(void* scene, const Vector3& center, const Colli
|
|||||||
bool PhysicsBackend::OverlapBox(void* scene, const Vector3& center, const Vector3& halfExtents, Array<Collider*>& results, const Quaternion& rotation, uint32 layerMask, bool hitTriggers)
|
bool PhysicsBackend::OverlapBox(void* scene, const Vector3& center, const Vector3& halfExtents, Array<Collider*>& results, const Quaternion& rotation, uint32 layerMask, bool hitTriggers)
|
||||||
{
|
{
|
||||||
SCENE_QUERY_SETUP_OVERLAP();
|
SCENE_QUERY_SETUP_OVERLAP();
|
||||||
const PxTransform pose(C2P(center), C2P(rotation));
|
const PxTransform pose(C2P(center - scenePhysX->Origin), C2P(rotation));
|
||||||
const PxBoxGeometry geometry(C2P(halfExtents));
|
const PxBoxGeometry geometry(C2P(halfExtents));
|
||||||
if (!scenePhysX->Scene->overlap(geometry, pose, buffer, filterData, &QueryFilter))
|
if (!scenePhysX->Scene->overlap(geometry, pose, buffer, filterData, &QueryFilter))
|
||||||
return false;
|
return false;
|
||||||
@@ -1497,7 +1527,7 @@ bool PhysicsBackend::OverlapBox(void* scene, const Vector3& center, const Vector
|
|||||||
bool PhysicsBackend::OverlapSphere(void* scene, const Vector3& center, const float radius, Array<Collider*>& results, uint32 layerMask, bool hitTriggers)
|
bool PhysicsBackend::OverlapSphere(void* scene, const Vector3& center, const float radius, Array<Collider*>& results, uint32 layerMask, bool hitTriggers)
|
||||||
{
|
{
|
||||||
SCENE_QUERY_SETUP_OVERLAP();
|
SCENE_QUERY_SETUP_OVERLAP();
|
||||||
const PxTransform pose(C2P(center));
|
const PxTransform pose(C2P(center - scenePhysX->Origin));
|
||||||
const PxSphereGeometry geometry(radius);
|
const PxSphereGeometry geometry(radius);
|
||||||
if (!scenePhysX->Scene->overlap(geometry, pose, buffer, filterData, &QueryFilter))
|
if (!scenePhysX->Scene->overlap(geometry, pose, buffer, filterData, &QueryFilter))
|
||||||
return false;
|
return false;
|
||||||
@@ -1508,7 +1538,7 @@ bool PhysicsBackend::OverlapSphere(void* scene, const Vector3& center, const flo
|
|||||||
bool PhysicsBackend::OverlapCapsule(void* scene, const Vector3& center, const float radius, const float height, Array<Collider*>& results, const Quaternion& rotation, uint32 layerMask, bool hitTriggers)
|
bool PhysicsBackend::OverlapCapsule(void* scene, const Vector3& center, const float radius, const float height, Array<Collider*>& results, const Quaternion& rotation, uint32 layerMask, bool hitTriggers)
|
||||||
{
|
{
|
||||||
SCENE_QUERY_SETUP_OVERLAP();
|
SCENE_QUERY_SETUP_OVERLAP();
|
||||||
const PxTransform pose(C2P(center), C2P(rotation));
|
const PxTransform pose(C2P(center - scenePhysX->Origin), C2P(rotation));
|
||||||
const PxCapsuleGeometry geometry(radius, height * 0.5f);
|
const PxCapsuleGeometry geometry(radius, height * 0.5f);
|
||||||
if (!scenePhysX->Scene->overlap(geometry, pose, buffer, filterData, &QueryFilter))
|
if (!scenePhysX->Scene->overlap(geometry, pose, buffer, filterData, &QueryFilter))
|
||||||
return false;
|
return false;
|
||||||
@@ -1520,7 +1550,7 @@ bool PhysicsBackend::OverlapConvex(void* scene, const Vector3& center, const Col
|
|||||||
{
|
{
|
||||||
CHECK_RETURN(convexMesh && convexMesh->GetOptions().Type == CollisionDataType::ConvexMesh, false)
|
CHECK_RETURN(convexMesh && convexMesh->GetOptions().Type == CollisionDataType::ConvexMesh, false)
|
||||||
SCENE_QUERY_SETUP_OVERLAP();
|
SCENE_QUERY_SETUP_OVERLAP();
|
||||||
const PxTransform pose(C2P(center), C2P(rotation));
|
const PxTransform pose(C2P(center - scenePhysX->Origin), C2P(rotation));
|
||||||
const PxConvexMeshGeometry geometry((PxConvexMesh*)convexMesh->GetConvex(), PxMeshScale(C2P(scale)));
|
const PxConvexMeshGeometry geometry((PxConvexMesh*)convexMesh->GetConvex(), PxMeshScale(C2P(scale)));
|
||||||
if (!scenePhysX->Scene->overlap(geometry, pose, buffer, filterData, &QueryFilter))
|
if (!scenePhysX->Scene->overlap(geometry, pose, buffer, filterData, &QueryFilter))
|
||||||
return false;
|
return false;
|
||||||
@@ -1531,7 +1561,7 @@ bool PhysicsBackend::OverlapConvex(void* scene, const Vector3& center, const Col
|
|||||||
bool PhysicsBackend::OverlapBox(void* scene, const Vector3& center, const Vector3& halfExtents, Array<PhysicsColliderActor*>& results, const Quaternion& rotation, uint32 layerMask, bool hitTriggers)
|
bool PhysicsBackend::OverlapBox(void* scene, const Vector3& center, const Vector3& halfExtents, Array<PhysicsColliderActor*>& results, const Quaternion& rotation, uint32 layerMask, bool hitTriggers)
|
||||||
{
|
{
|
||||||
SCENE_QUERY_SETUP_OVERLAP();
|
SCENE_QUERY_SETUP_OVERLAP();
|
||||||
const PxTransform pose(C2P(center), C2P(rotation));
|
const PxTransform pose(C2P(center - scenePhysX->Origin), C2P(rotation));
|
||||||
const PxBoxGeometry geometry(C2P(halfExtents));
|
const PxBoxGeometry geometry(C2P(halfExtents));
|
||||||
if (!scenePhysX->Scene->overlap(geometry, pose, buffer, filterData, &QueryFilter))
|
if (!scenePhysX->Scene->overlap(geometry, pose, buffer, filterData, &QueryFilter))
|
||||||
return false;
|
return false;
|
||||||
@@ -1542,7 +1572,7 @@ bool PhysicsBackend::OverlapBox(void* scene, const Vector3& center, const Vector
|
|||||||
bool PhysicsBackend::OverlapSphere(void* scene, const Vector3& center, const float radius, Array<PhysicsColliderActor*>& results, uint32 layerMask, bool hitTriggers)
|
bool PhysicsBackend::OverlapSphere(void* scene, const Vector3& center, const float radius, Array<PhysicsColliderActor*>& results, uint32 layerMask, bool hitTriggers)
|
||||||
{
|
{
|
||||||
SCENE_QUERY_SETUP_OVERLAP();
|
SCENE_QUERY_SETUP_OVERLAP();
|
||||||
const PxTransform pose(C2P(center));
|
const PxTransform pose(C2P(center - scenePhysX->Origin));
|
||||||
const PxSphereGeometry geometry(radius);
|
const PxSphereGeometry geometry(radius);
|
||||||
if (!scenePhysX->Scene->overlap(geometry, pose, buffer, filterData, &QueryFilter))
|
if (!scenePhysX->Scene->overlap(geometry, pose, buffer, filterData, &QueryFilter))
|
||||||
return false;
|
return false;
|
||||||
@@ -1553,7 +1583,7 @@ bool PhysicsBackend::OverlapSphere(void* scene, const Vector3& center, const flo
|
|||||||
bool PhysicsBackend::OverlapCapsule(void* scene, const Vector3& center, const float radius, const float height, Array<PhysicsColliderActor*>& results, const Quaternion& rotation, uint32 layerMask, bool hitTriggers)
|
bool PhysicsBackend::OverlapCapsule(void* scene, const Vector3& center, const float radius, const float height, Array<PhysicsColliderActor*>& results, const Quaternion& rotation, uint32 layerMask, bool hitTriggers)
|
||||||
{
|
{
|
||||||
SCENE_QUERY_SETUP_OVERLAP();
|
SCENE_QUERY_SETUP_OVERLAP();
|
||||||
const PxTransform pose(C2P(center), C2P(rotation));
|
const PxTransform pose(C2P(center - scenePhysX->Origin), C2P(rotation));
|
||||||
const PxCapsuleGeometry geometry(radius, height * 0.5f);
|
const PxCapsuleGeometry geometry(radius, height * 0.5f);
|
||||||
if (!scenePhysX->Scene->overlap(geometry, pose, buffer, filterData, &QueryFilter))
|
if (!scenePhysX->Scene->overlap(geometry, pose, buffer, filterData, &QueryFilter))
|
||||||
return false;
|
return false;
|
||||||
@@ -1565,7 +1595,7 @@ bool PhysicsBackend::OverlapConvex(void* scene, const Vector3& center, const Col
|
|||||||
{
|
{
|
||||||
CHECK_RETURN(convexMesh && convexMesh->GetOptions().Type == CollisionDataType::ConvexMesh, false)
|
CHECK_RETURN(convexMesh && convexMesh->GetOptions().Type == CollisionDataType::ConvexMesh, false)
|
||||||
SCENE_QUERY_SETUP_OVERLAP();
|
SCENE_QUERY_SETUP_OVERLAP();
|
||||||
const PxTransform pose(C2P(center), C2P(rotation));
|
const PxTransform pose(C2P(center - scenePhysX->Origin), C2P(rotation));
|
||||||
const PxConvexMeshGeometry geometry((PxConvexMesh*)convexMesh->GetConvex(), PxMeshScale(C2P(scale)));
|
const PxConvexMeshGeometry geometry((PxConvexMesh*)convexMesh->GetConvex(), PxMeshScale(C2P(scale)));
|
||||||
if (!scenePhysX->Scene->overlap(geometry, pose, buffer, filterData, &QueryFilter))
|
if (!scenePhysX->Scene->overlap(geometry, pose, buffer, filterData, &QueryFilter))
|
||||||
return false;
|
return false;
|
||||||
@@ -1604,6 +1634,9 @@ void PhysicsBackend::GetActorBounds(void* actor, BoundingBox& bounds)
|
|||||||
auto actorPhysX = (PxActor*)actor;
|
auto actorPhysX = (PxActor*)actor;
|
||||||
const float boundsScale = 1.02f;
|
const float boundsScale = 1.02f;
|
||||||
bounds = P2C(actorPhysX->getWorldBounds(boundsScale));
|
bounds = P2C(actorPhysX->getWorldBounds(boundsScale));
|
||||||
|
const Vector3 sceneOrigin = SceneOrigins[actorPhysX->getScene()];
|
||||||
|
bounds.Minimum += sceneOrigin;
|
||||||
|
bounds.Maximum += sceneOrigin;
|
||||||
}
|
}
|
||||||
|
|
||||||
int32 PhysicsBackend::GetRigidActorShapesCount(void* actor)
|
int32 PhysicsBackend::GetRigidActorShapesCount(void* actor)
|
||||||
@@ -1612,9 +1645,10 @@ int32 PhysicsBackend::GetRigidActorShapesCount(void* actor)
|
|||||||
return actorPhysX->getNbShapes();
|
return actorPhysX->getNbShapes();
|
||||||
}
|
}
|
||||||
|
|
||||||
void* PhysicsBackend::CreateRigidDynamicActor(IPhysicsActor* actor, const Vector3& position, const Quaternion& orientation)
|
void* PhysicsBackend::CreateRigidDynamicActor(IPhysicsActor* actor, const Vector3& position, const Quaternion& orientation, void* scene)
|
||||||
{
|
{
|
||||||
const PxTransform trans(C2P(position), C2P(orientation));
|
const Vector3 sceneOrigin = SceneOrigins[scene ? ( (ScenePhysX*)scene)->Scene : nullptr];
|
||||||
|
const PxTransform trans(C2P(position - sceneOrigin), C2P(orientation));
|
||||||
PxRigidDynamic* actorPhysX = PhysX->createRigidDynamic(trans);
|
PxRigidDynamic* actorPhysX = PhysX->createRigidDynamic(trans);
|
||||||
actorPhysX->userData = actor;
|
actorPhysX->userData = actor;
|
||||||
#if PHYSX_DEBUG_NAMING
|
#if PHYSX_DEBUG_NAMING
|
||||||
@@ -1626,9 +1660,10 @@ void* PhysicsBackend::CreateRigidDynamicActor(IPhysicsActor* actor, const Vector
|
|||||||
return actorPhysX;
|
return actorPhysX;
|
||||||
}
|
}
|
||||||
|
|
||||||
void* PhysicsBackend::CreateRigidStaticActor(IPhysicsActor* actor, const Vector3& position, const Quaternion& orientation)
|
void* PhysicsBackend::CreateRigidStaticActor(IPhysicsActor* actor, const Vector3& position, const Quaternion& orientation, void* scene)
|
||||||
{
|
{
|
||||||
const PxTransform trans(C2P(position), C2P(orientation));
|
const Vector3 sceneOrigin = SceneOrigins[scene ? ( (ScenePhysX*)scene)->Scene : nullptr];
|
||||||
|
const PxTransform trans(C2P(position - sceneOrigin), C2P(orientation));
|
||||||
PxRigidStatic* actorPhysX = PhysX->createRigidStatic(trans);
|
PxRigidStatic* actorPhysX = PhysX->createRigidStatic(trans);
|
||||||
actorPhysX->userData = actor;
|
actorPhysX->userData = actor;
|
||||||
#if PHYSX_DEBUG_NAMING
|
#if PHYSX_DEBUG_NAMING
|
||||||
@@ -1667,13 +1702,15 @@ void PhysicsBackend::GetRigidActorPose(void* actor, Vector3& position, Quaternio
|
|||||||
{
|
{
|
||||||
auto actorPhysX = (PxRigidActor*)actor;
|
auto actorPhysX = (PxRigidActor*)actor;
|
||||||
auto pose = actorPhysX->getGlobalPose();
|
auto pose = actorPhysX->getGlobalPose();
|
||||||
position = P2C(pose.p);
|
const Vector3 sceneOrigin = SceneOrigins[actorPhysX->getScene()];
|
||||||
|
position = P2C(pose.p) + sceneOrigin;
|
||||||
orientation = P2C(pose.q);
|
orientation = P2C(pose.q);
|
||||||
}
|
}
|
||||||
|
|
||||||
void PhysicsBackend::SetRigidActorPose(void* actor, const Vector3& position, const Quaternion& orientation, bool kinematic, bool wakeUp)
|
void PhysicsBackend::SetRigidActorPose(void* actor, const Vector3& position, const Quaternion& orientation, bool kinematic, bool wakeUp)
|
||||||
{
|
{
|
||||||
const PxTransform trans(C2P(position), C2P(orientation));
|
const Vector3 sceneOrigin = SceneOrigins[((PxActor*)actor)->getScene()];
|
||||||
|
const PxTransform trans(C2P(position - sceneOrigin), C2P(orientation));
|
||||||
if (kinematic)
|
if (kinematic)
|
||||||
{
|
{
|
||||||
auto actorPhysX = (PxRigidDynamic*)actor;
|
auto actorPhysX = (PxRigidDynamic*)actor;
|
||||||
@@ -1852,7 +1889,8 @@ void PhysicsBackend::AddRigidDynamicActorForce(void* actor, const Vector3& force
|
|||||||
void PhysicsBackend::AddRigidDynamicActorForceAtPosition(void* actor, const Vector3& force, const Vector3& position, ForceMode mode)
|
void PhysicsBackend::AddRigidDynamicActorForceAtPosition(void* actor, const Vector3& force, const Vector3& position, ForceMode mode)
|
||||||
{
|
{
|
||||||
auto actorPhysX = (PxRigidDynamic*)actor;
|
auto actorPhysX = (PxRigidDynamic*)actor;
|
||||||
PxRigidBodyExt::addForceAtPos(*actorPhysX, C2P(force), C2P(position), static_cast<PxForceMode::Enum>(mode));
|
const Vector3 sceneOrigin = SceneOrigins[actorPhysX->getScene()];
|
||||||
|
PxRigidBodyExt::addForceAtPos(*actorPhysX, C2P(force), C2P(position - sceneOrigin), static_cast<PxForceMode::Enum>(mode));
|
||||||
}
|
}
|
||||||
|
|
||||||
void PhysicsBackend::AddRigidDynamicActorTorque(void* actor, const Vector3& torque, ForceMode mode)
|
void PhysicsBackend::AddRigidDynamicActorTorque(void* actor, const Vector3& torque, ForceMode mode)
|
||||||
@@ -1907,7 +1945,8 @@ void PhysicsBackend::GetShapePose(void* shape, Vector3& position, Quaternion& or
|
|||||||
auto shapePhysX = (PxShape*)shape;
|
auto shapePhysX = (PxShape*)shape;
|
||||||
PxRigidActor* actorPhysX = shapePhysX->getActor();
|
PxRigidActor* actorPhysX = shapePhysX->getActor();
|
||||||
PxTransform pose = actorPhysX->getGlobalPose().transform(shapePhysX->getLocalPose());
|
PxTransform pose = actorPhysX->getGlobalPose().transform(shapePhysX->getLocalPose());
|
||||||
position = P2C(pose.p);
|
const Vector3 sceneOrigin = SceneOrigins[actorPhysX->getScene()];
|
||||||
|
position = P2C(pose.p) + sceneOrigin;
|
||||||
orientation = P2C(pose.q);
|
orientation = P2C(pose.q);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2015,10 +2054,11 @@ float PhysicsBackend::ComputeShapeSqrDistanceToPoint(void* shape, const Vector3&
|
|||||||
bool PhysicsBackend::RayCastShape(void* shape, const Vector3& position, const Quaternion& orientation, const Vector3& origin, const Vector3& direction, float& resultHitDistance, float maxDistance)
|
bool PhysicsBackend::RayCastShape(void* shape, const Vector3& position, const Quaternion& orientation, const Vector3& origin, const Vector3& direction, float& resultHitDistance, float maxDistance)
|
||||||
{
|
{
|
||||||
auto shapePhysX = (PxShape*)shape;
|
auto shapePhysX = (PxShape*)shape;
|
||||||
const PxTransform trans(C2P(position), C2P(orientation));
|
const Vector3 sceneOrigin = SceneOrigins[shapePhysX->getActor() ? shapePhysX->getActor()->getScene() : nullptr];
|
||||||
|
const PxTransform trans(C2P(position - sceneOrigin), C2P(orientation));
|
||||||
const PxHitFlags hitFlags = (PxHitFlags)0;
|
const PxHitFlags hitFlags = (PxHitFlags)0;
|
||||||
PxRaycastHit hit;
|
PxRaycastHit hit;
|
||||||
if (PxGeometryQuery::raycast(C2P(origin), C2P(direction), shapePhysX->getGeometry().any(), trans, maxDistance, hitFlags, 1, &hit) != 0)
|
if (PxGeometryQuery::raycast(C2P(origin - sceneOrigin), C2P(direction), shapePhysX->getGeometry().any(), trans, maxDistance, hitFlags, 1, &hit) != 0)
|
||||||
{
|
{
|
||||||
resultHitDistance = hit.distance;
|
resultHitDistance = hit.distance;
|
||||||
return true;
|
return true;
|
||||||
@@ -2029,12 +2069,14 @@ bool PhysicsBackend::RayCastShape(void* shape, const Vector3& position, const Qu
|
|||||||
bool PhysicsBackend::RayCastShape(void* shape, const Vector3& position, const Quaternion& orientation, const Vector3& origin, const Vector3& direction, RayCastHit& hitInfo, float maxDistance)
|
bool PhysicsBackend::RayCastShape(void* shape, const Vector3& position, const Quaternion& orientation, const Vector3& origin, const Vector3& direction, RayCastHit& hitInfo, float maxDistance)
|
||||||
{
|
{
|
||||||
auto shapePhysX = (PxShape*)shape;
|
auto shapePhysX = (PxShape*)shape;
|
||||||
const PxTransform trans(C2P(position), C2P(orientation));
|
const Vector3 sceneOrigin = SceneOrigins[shapePhysX->getActor() ? shapePhysX->getActor()->getScene() : nullptr];
|
||||||
|
const PxTransform trans(C2P(position - sceneOrigin), C2P(orientation));
|
||||||
const PxHitFlags hitFlags = PxHitFlag::ePOSITION | PxHitFlag::eNORMAL | PxHitFlag::eFACE_INDEX | PxHitFlag::eUV;
|
const PxHitFlags hitFlags = PxHitFlag::ePOSITION | PxHitFlag::eNORMAL | PxHitFlag::eFACE_INDEX | PxHitFlag::eUV;
|
||||||
PxRaycastHit hit;
|
PxRaycastHit hit;
|
||||||
if (PxGeometryQuery::raycast(C2P(origin), C2P(direction), shapePhysX->getGeometry().any(), trans, maxDistance, hitFlags, 1, &hit) == 0)
|
if (PxGeometryQuery::raycast(C2P(origin - sceneOrigin), C2P(direction), shapePhysX->getGeometry().any(), trans, maxDistance, hitFlags, 1, &hit) == 0)
|
||||||
return false;
|
return false;
|
||||||
P2C(hit, hitInfo);
|
P2C(hit, hitInfo);
|
||||||
|
hitInfo.Point += sceneOrigin;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2390,10 +2432,11 @@ float PhysicsBackend::GetD6JointSwingZ(void* joint)
|
|||||||
void* PhysicsBackend::CreateController(void* scene, IPhysicsActor* actor, PhysicsColliderActor* collider, float contactOffset, const Vector3& position, float slopeLimit, int32 nonWalkableMode, JsonAsset* material, float radius, float height, float stepOffset, void*& shape)
|
void* PhysicsBackend::CreateController(void* scene, IPhysicsActor* actor, PhysicsColliderActor* collider, float contactOffset, const Vector3& position, float slopeLimit, int32 nonWalkableMode, JsonAsset* material, float radius, float height, float stepOffset, void*& shape)
|
||||||
{
|
{
|
||||||
auto scenePhysX = (ScenePhysX*)scene;
|
auto scenePhysX = (ScenePhysX*)scene;
|
||||||
|
const Vector3 sceneOrigin = SceneOrigins[scenePhysX->Scene];
|
||||||
PxCapsuleControllerDesc desc;
|
PxCapsuleControllerDesc desc;
|
||||||
desc.userData = actor;
|
desc.userData = actor;
|
||||||
desc.contactOffset = Math::Max(contactOffset, ZeroTolerance);
|
desc.contactOffset = Math::Max(contactOffset, ZeroTolerance);
|
||||||
desc.position = PxExtendedVec3(position.X, position.Y, position.Z);
|
desc.position = PxExtendedVec3(position.X - sceneOrigin.X, position.Y - sceneOrigin.Y, position.Z - sceneOrigin.Z);
|
||||||
desc.slopeLimit = Math::Cos(slopeLimit * DegreesToRadians);
|
desc.slopeLimit = Math::Cos(slopeLimit * DegreesToRadians);
|
||||||
desc.nonWalkableMode = static_cast<PxControllerNonWalkableMode::Enum>(nonWalkableMode);
|
desc.nonWalkableMode = static_cast<PxControllerNonWalkableMode::Enum>(nonWalkableMode);
|
||||||
desc.climbingMode = PxCapsuleClimbingMode::eEASY;
|
desc.climbingMode = PxCapsuleClimbingMode::eEASY;
|
||||||
@@ -2465,13 +2508,15 @@ void PhysicsBackend::SetControllerUpDirection(void* controller, const Vector3& v
|
|||||||
Vector3 PhysicsBackend::GetControllerPosition(void* controller)
|
Vector3 PhysicsBackend::GetControllerPosition(void* controller)
|
||||||
{
|
{
|
||||||
auto controllerPhysX = (PxCapsuleController*)controller;
|
auto controllerPhysX = (PxCapsuleController*)controller;
|
||||||
return P2C(controllerPhysX->getPosition());
|
const Vector3 origin = SceneOrigins[controllerPhysX->getScene()];
|
||||||
|
return P2C(controllerPhysX->getPosition()) + origin;
|
||||||
}
|
}
|
||||||
|
|
||||||
void PhysicsBackend::SetControllerPosition(void* controller, const Vector3& value)
|
void PhysicsBackend::SetControllerPosition(void* controller, const Vector3& value)
|
||||||
{
|
{
|
||||||
auto controllerPhysX = (PxCapsuleController*)controller;
|
auto controllerPhysX = (PxCapsuleController*)controller;
|
||||||
controllerPhysX->setPosition(PxExtendedVec3(value.X, value.Y, value.Z));
|
const Vector3 sceneOrigin = SceneOrigins[controllerPhysX->getScene()];
|
||||||
|
controllerPhysX->setPosition(PxExtendedVec3(value.X - sceneOrigin.X, value.Y - sceneOrigin.Y, value.Z - sceneOrigin.Z));
|
||||||
}
|
}
|
||||||
|
|
||||||
int32 PhysicsBackend::MoveController(void* controller, void* shape, const Vector3& displacement, float minMoveDistance, float deltaTime)
|
int32 PhysicsBackend::MoveController(void* controller, void* shape, const Vector3& displacement, float minMoveDistance, float deltaTime)
|
||||||
|
|||||||
@@ -384,12 +384,12 @@ void PhysicsScene::SetGravity(const Vector3& value)
|
|||||||
PhysicsBackend::SetSceneGravity(_scene, value);
|
PhysicsBackend::SetSceneGravity(_scene, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
Vector3 PhysicsScene::GetGravity()
|
Vector3 PhysicsScene::GetGravity() const
|
||||||
{
|
{
|
||||||
return PhysicsBackend::GetSceneGravity(_scene);
|
return PhysicsBackend::GetSceneGravity(_scene);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool PhysicsScene::GetEnableCCD()
|
bool PhysicsScene::GetEnableCCD() const
|
||||||
{
|
{
|
||||||
return PhysicsBackend::GetSceneEnableCCD(_scene);
|
return PhysicsBackend::GetSceneEnableCCD(_scene);
|
||||||
}
|
}
|
||||||
@@ -409,6 +409,15 @@ void PhysicsScene::SetBounceThresholdVelocity(float value)
|
|||||||
PhysicsBackend::SetSceneBounceThresholdVelocity(_scene, value);
|
PhysicsBackend::SetSceneBounceThresholdVelocity(_scene, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void PhysicsScene::SetOrigin(const Vector3& value)
|
||||||
|
{
|
||||||
|
if (_origin != value)
|
||||||
|
{
|
||||||
|
PhysicsBackend::SetSceneOrigin(_scene, _origin, value);
|
||||||
|
_origin = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
bool PhysicsScene::Init(const StringView& name, const PhysicsSettings& settings)
|
bool PhysicsScene::Init(const StringView& name, const PhysicsSettings& settings)
|
||||||
{
|
{
|
||||||
if (_scene)
|
if (_scene)
|
||||||
|
|||||||
@@ -94,6 +94,7 @@ public:
|
|||||||
static void SetSceneEnableCCD(void* scene, bool value);
|
static void SetSceneEnableCCD(void* scene, bool value);
|
||||||
static float GetSceneBounceThresholdVelocity(void* scene);
|
static float GetSceneBounceThresholdVelocity(void* scene);
|
||||||
static void SetSceneBounceThresholdVelocity(void* scene, float value);
|
static void SetSceneBounceThresholdVelocity(void* scene, float value);
|
||||||
|
static void SetSceneOrigin(void* scene, const Vector3& oldOrigin, const Vector3& newOrigin);
|
||||||
static void AddSceneActor(void* scene, void* actor);
|
static void AddSceneActor(void* scene, void* actor);
|
||||||
static void RemoveSceneActor(void* scene, void* actor);
|
static void RemoveSceneActor(void* scene, void* actor);
|
||||||
static void AddSceneActorAction(void* scene, void* actor, ActionType action);
|
static void AddSceneActorAction(void* scene, void* actor, ActionType action);
|
||||||
@@ -132,8 +133,8 @@ public:
|
|||||||
static void SetActorFlags(void* actor, ActorFlags value);
|
static void SetActorFlags(void* actor, ActorFlags value);
|
||||||
static void GetActorBounds(void* actor, BoundingBox& bounds);
|
static void GetActorBounds(void* actor, BoundingBox& bounds);
|
||||||
static int32 GetRigidActorShapesCount(void* actor);
|
static int32 GetRigidActorShapesCount(void* actor);
|
||||||
static void* CreateRigidDynamicActor(IPhysicsActor* actor, const Vector3& position, const Quaternion& orientation);
|
static void* CreateRigidDynamicActor(IPhysicsActor* actor, const Vector3& position, const Quaternion& orientation, void* scene);
|
||||||
static void* CreateRigidStaticActor(IPhysicsActor* actor, const Vector3& position, const Quaternion& orientation);
|
static void* CreateRigidStaticActor(IPhysicsActor* actor, const Vector3& position, const Quaternion& orientation, void* scene);
|
||||||
static RigidDynamicFlags GetRigidDynamicActorFlags(void* actor);
|
static RigidDynamicFlags GetRigidDynamicActorFlags(void* actor);
|
||||||
static void SetRigidDynamicActorFlags(void* actor, RigidDynamicFlags value);
|
static void SetRigidDynamicActorFlags(void* actor, RigidDynamicFlags value);
|
||||||
static void GetRigidActorPose(void* actor, Vector3& position, Quaternion& orientation);
|
static void GetRigidActorPose(void* actor, Vector3& position, Quaternion& orientation);
|
||||||
|
|||||||
@@ -28,6 +28,7 @@ private:
|
|||||||
String _name;
|
String _name;
|
||||||
bool _autoSimulation = true;
|
bool _autoSimulation = true;
|
||||||
bool _isDuringSimulation = false;
|
bool _isDuringSimulation = false;
|
||||||
|
Vector3 _origin = Vector3::Zero;
|
||||||
void* _scene = nullptr;
|
void* _scene = nullptr;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
@@ -59,7 +60,7 @@ public:
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the current gravity force.
|
/// Gets the current gravity force.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
API_PROPERTY() Vector3 GetGravity();
|
API_PROPERTY() Vector3 GetGravity() const;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Sets the current gravity force.
|
/// Sets the current gravity force.
|
||||||
@@ -69,7 +70,7 @@ public:
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the CCD feature enable flag.
|
/// Gets the CCD feature enable flag.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
API_PROPERTY() bool GetEnableCCD();
|
API_PROPERTY() bool GetEnableCCD() const;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Sets the CCD feature enable flag.
|
/// Sets the CCD feature enable flag.
|
||||||
@@ -86,6 +87,19 @@ public:
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
API_PROPERTY() void SetBounceThresholdVelocity(float value);
|
API_PROPERTY() void SetBounceThresholdVelocity(float value);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the current scene origin that defines the center of the simulation (in world). Can be used to run physics simulation relative to the camera.
|
||||||
|
/// </summary>
|
||||||
|
API_PROPERTY() FORCE_INLINE Vector3 GetOrigin() const
|
||||||
|
{
|
||||||
|
return _origin;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Sets the current scene origin that defines the center of the simulation (in world). Can be used to run physics simulation relative to the camera.
|
||||||
|
/// </summary>
|
||||||
|
API_PROPERTY() void SetOrigin(const Vector3& value);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Initializes the scene.
|
/// Initializes the scene.
|
||||||
|
|||||||
@@ -12,6 +12,7 @@
|
|||||||
#include "Engine/Level/Actors/EnvironmentProbe.h"
|
#include "Engine/Level/Actors/EnvironmentProbe.h"
|
||||||
#include "Engine/Level/Actors/SkyLight.h"
|
#include "Engine/Level/Actors/SkyLight.h"
|
||||||
#include "Engine/Level/SceneQuery.h"
|
#include "Engine/Level/SceneQuery.h"
|
||||||
|
#include "Engine/Level/LargeWorlds.h"
|
||||||
#include "Engine/ContentExporters/AssetExporters.h"
|
#include "Engine/ContentExporters/AssetExporters.h"
|
||||||
#include "Engine/Serialization/FileWriteStream.h"
|
#include "Engine/Serialization/FileWriteStream.h"
|
||||||
#include "Engine/Engine/Time.h"
|
#include "Engine/Engine/Time.h"
|
||||||
@@ -430,12 +431,11 @@ bool fixFarPlaneTreeExecute(Actor* actor, const Vector3& position, float& farPla
|
|||||||
if (auto* pointLight = dynamic_cast<PointLight*>(actor))
|
if (auto* pointLight = dynamic_cast<PointLight*>(actor))
|
||||||
{
|
{
|
||||||
const Real dst = Vector3::Distance(pointLight->GetPosition(), position) + pointLight->GetScaledRadius();
|
const Real dst = Vector3::Distance(pointLight->GetPosition(), position) + pointLight->GetScaledRadius();
|
||||||
if (dst > farPlane)
|
if (dst > farPlane && dst * 0.5f < farPlane)
|
||||||
{
|
{
|
||||||
farPlane = (float)dst;
|
farPlane = (float)dst;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -480,7 +480,8 @@ void ProbesRenderer::onRender(RenderTask* task, GPUContext* context)
|
|||||||
SceneQuery::TreeExecute<const Vector3&, float&>(f, position, farPlane);
|
SceneQuery::TreeExecute<const Vector3&, float&>(f, position, farPlane);
|
||||||
|
|
||||||
// Setup view
|
// Setup view
|
||||||
_task->View.SetUpCube(nearPlane, farPlane, position);
|
LargeWorlds::UpdateOrigin(_task->View.Origin, position);
|
||||||
|
_task->View.SetUpCube(nearPlane, farPlane, position - _task->View.Origin);
|
||||||
}
|
}
|
||||||
else if (_current.Type == EntryType::SkyLight)
|
else if (_current.Type == EntryType::SkyLight)
|
||||||
{
|
{
|
||||||
@@ -494,7 +495,8 @@ void ProbesRenderer::onRender(RenderTask* task, GPUContext* context)
|
|||||||
// TODO: use setLowerHemisphereToBlack feature for SkyLight?
|
// TODO: use setLowerHemisphereToBlack feature for SkyLight?
|
||||||
|
|
||||||
// Setup view
|
// Setup view
|
||||||
_task->View.SetUpCube(nearPlane, farPlane, position);
|
LargeWorlds::UpdateOrigin(_task->View.Origin, position);
|
||||||
|
_task->View.SetUpCube(nearPlane, farPlane, position - _task->View.Origin);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Disable actor during baking (it cannot influence own results)
|
// Disable actor during baking (it cannot influence own results)
|
||||||
|
|||||||
@@ -415,7 +415,7 @@ void ReflectionsPass::Render(RenderContext& renderContext, GPUTextureView* light
|
|||||||
if (!probe->HasProbeLoaded())
|
if (!probe->HasProbeLoaded())
|
||||||
continue;
|
continue;
|
||||||
float probeRadius = probe->GetScaledRadius();
|
float probeRadius = probe->GetScaledRadius();
|
||||||
Vector3 probePosition = probe->GetPosition(); // TODO: large-worlds
|
Float3 probePosition = probe->GetPosition() - renderContext.View.Origin;
|
||||||
|
|
||||||
// Get distance from view center to light center less radius (check if view is inside a sphere)
|
// Get distance from view center to light center less radius (check if view is inside a sphere)
|
||||||
const float sphereModelScale = 2.0f;
|
const float sphereModelScale = 2.0f;
|
||||||
@@ -430,7 +430,7 @@ void ReflectionsPass::Render(RenderContext& renderContext, GPUTextureView* light
|
|||||||
Matrix::Multiply(world, view.ViewProjection(), wvp);
|
Matrix::Multiply(world, view.ViewProjection(), wvp);
|
||||||
|
|
||||||
// Pack probe properties buffer
|
// Pack probe properties buffer
|
||||||
probe->SetupProbeData(&data.PData);
|
probe->SetupProbeData(renderContext, &data.PData);
|
||||||
Matrix::Transpose(wvp, data.WVP);
|
Matrix::Transpose(wvp, data.WVP);
|
||||||
|
|
||||||
// Render reflections
|
// Render reflections
|
||||||
|
|||||||
@@ -2113,9 +2113,9 @@ void TerrainPatch::CreateCollision()
|
|||||||
PhysicsBackend::SetShapeLocalPose(_physicsShape, Vector3(0, _yOffset * terrainTransform.Scale.Y, 0), Quaternion::Identity);
|
PhysicsBackend::SetShapeLocalPose(_physicsShape, Vector3(0, _yOffset * terrainTransform.Scale.Y, 0), Quaternion::Identity);
|
||||||
|
|
||||||
// Create static actor
|
// Create static actor
|
||||||
_physicsActor = PhysicsBackend::CreateRigidStaticActor(nullptr, terrainTransform.LocalToWorld(_offset), terrainTransform.Orientation);
|
|
||||||
PhysicsBackend::AttachShape(_physicsShape, _physicsActor);
|
|
||||||
void* scene = _terrain->GetPhysicsScene()->GetPhysicsScene();
|
void* scene = _terrain->GetPhysicsScene()->GetPhysicsScene();
|
||||||
|
_physicsActor = PhysicsBackend::CreateRigidStaticActor(nullptr, terrainTransform.LocalToWorld(_offset), terrainTransform.Orientation, scene);
|
||||||
|
PhysicsBackend::AttachShape(_physicsShape, _physicsActor);
|
||||||
PhysicsBackend::AddSceneActor(scene, _physicsActor);
|
PhysicsBackend::AddSceneActor(scene, _physicsActor);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -113,22 +113,21 @@ void SpriteRender::Draw(RenderContext& renderContext)
|
|||||||
auto model = _quadModel.As<Model>();
|
auto model = _quadModel.As<Model>();
|
||||||
if (model->GetLoadedLODs() == 0)
|
if (model->GetLoadedLODs() == 0)
|
||||||
return;
|
return;
|
||||||
auto& view = renderContext.View;
|
const auto& view = renderContext.View;
|
||||||
Matrix m1, m2, m3, world;
|
Matrix m1, m2, m3, world;
|
||||||
Matrix::Scaling(_size.X, _size.Y, 1.0f, m2);
|
Matrix::Scaling(_size.X, _size.Y, 1.0f, m2);
|
||||||
Matrix::RotationY(PI, m3);
|
Matrix::RotationY(PI, m3);
|
||||||
Matrix::Multiply(m2, m3, m1);
|
Matrix::Multiply(m2, m3, m1);
|
||||||
// TODO: large-worlds
|
|
||||||
if (FaceCamera)
|
if (FaceCamera)
|
||||||
{
|
{
|
||||||
Matrix::Billboard(_transform.Translation, view.Position, Vector3::Up, view.Direction, m2);
|
Matrix::Billboard(_transform.Translation - view.Origin, view.Position, Vector3::Up, view.Direction, m2);
|
||||||
Matrix::Multiply(m1, m2, m3);
|
Matrix::Multiply(m1, m2, m3);
|
||||||
Matrix::Scaling(_transform.Scale, m1);
|
Matrix::Scaling(_transform.Scale, m1);
|
||||||
Matrix::Multiply(m1, m3, world);
|
Matrix::Multiply(m1, m3, world);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
_transform.GetWorld(m2);
|
view.GetWorldMatrix(_transform, m2);
|
||||||
Matrix::Multiply(m1, m2, world);
|
Matrix::Multiply(m1, m2, world);
|
||||||
}
|
}
|
||||||
model->LODs[0].Draw(renderContext, _materialInstance, world, GetStaticFlags(), false, DrawModes, GetPerInstanceRandom());
|
model->LODs[0].Draw(renderContext, _materialInstance, world, GetStaticFlags(), false, DrawModes, GetPerInstanceRandom());
|
||||||
|
|||||||
@@ -56,7 +56,7 @@ public:
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the text.
|
/// Gets the text.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
API_PROPERTY(Attributes="EditorOrder(0), EditorDisplay(\"Text\")")
|
API_PROPERTY(Attributes="EditorOrder(0), MultilineText, EditorDisplay(\"Text\")")
|
||||||
const LocalizedString& GetText() const;
|
const LocalizedString& GetText() const;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|||||||
@@ -17,25 +17,21 @@ namespace FlaxEngine
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// The screen space rendering mode that places UI elements on the screen rendered on top of the scene. If the screen is resized or changes resolution, the Canvas will automatically change size to match this.
|
/// The screen space rendering mode that places UI elements on the screen rendered on top of the scene. If the screen is resized or changes resolution, the Canvas will automatically change size to match this.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[Tooltip("The screen space rendering mode that places UI elements on the screen rendered on top of the scene. If the screen is resized or changes resolution, the Canvas will automatically change size to match this.")]
|
|
||||||
ScreenSpace = 0,
|
ScreenSpace = 0,
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The camera space rendering mode that places Canvas in a given distance in front of a specified Camera. The UI elements are rendered by this camera, which means that the Camera settings affect the appearance of the UI. If the Camera is set to Perspective, the UI elements will be rendered with perspective, and the amount of perspective distortion can be controlled by the Camera Field of View. If the screen is resized, changes resolution, or the camera frustum changes, the Canvas will automatically change size to match as well.
|
/// The camera space rendering mode that places Canvas in a given distance in front of a specified Camera. The UI elements are rendered by this camera, which means that the Camera settings affect the appearance of the UI. If the Camera is set to Perspective, the UI elements will be rendered with perspective, and the amount of perspective distortion can be controlled by the Camera Field of View. If the screen is resized, changes resolution, or the camera frustum changes, the Canvas will automatically change size to match as well.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[Tooltip("The camera space rendering mode that places Canvas in a given distance in front of a specified Camera. The UI elements are rendered by this camera, which means that the Camera settings affect the appearance of the UI. If the Camera is set to Perspective, the UI elements will be rendered with perspective, and the amount of perspective distortion can be controlled by the Camera Field of View. If the screen is resized, changes resolution, or the camera frustum changes, the Canvas will automatically change size to match as well.")]
|
|
||||||
CameraSpace = 1,
|
CameraSpace = 1,
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The world space rendering mode that places Canvas as any other object in the scene. The size of the Canvas can be set manually using its Transform, and UI elements will render in front of or behind other objects in the scene based on 3D placement. This is useful for UIs that are meant to be a part of the world. This is also known as a 'diegetic interface'.
|
/// The world space rendering mode that places Canvas as any other object in the scene. The size of the Canvas can be set manually using its Transform, and UI elements will render in front of or behind other objects in the scene based on 3D placement. This is useful for UIs that are meant to be a part of the world. This is also known as a 'diegetic interface'.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[Tooltip("The world space rendering mode that places Canvas as any other object in the scene. The size of the Canvas can be set manually using its Transform, and UI elements will render in front of or behind other objects in the scene based on 3D placement. This is useful for UIs that are meant to be a part of the world. This is also known as a 'diegetic interface'.")]
|
|
||||||
WorldSpace = 2,
|
WorldSpace = 2,
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The world space rendering mode that places Canvas as any other object in the scene and orients it to face the camera. The size of the Canvas can be set manually using its Transform, and UI elements will render in front of or behind other objects in the scene based on 3D placement. This is useful for UIs that are meant to be a part of the world. This is also known as a 'diegetic interface'.
|
/// The world space rendering mode that places Canvas as any other object in the scene and orients it to face the camera. The size of the Canvas can be set manually using its Transform, and UI elements will render in front of or behind other objects in the scene based on 3D placement. This is useful for UIs that are meant to be a part of the world. This is also known as a 'diegetic interface'.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[Tooltip("The world space rendering mode that places Canvas as any other object in the scene and orients canvas to face the camera. The size of the Canvas can be set manually using its Transform, and UI elements will render in front of or behind other objects in the scene based on 3D placement. This is useful for UIs that are meant to be a part of the world. This is also known as a 'diegetic interface'.")]
|
|
||||||
WorldSpaceFaceCamera = 3,
|
WorldSpaceFaceCamera = 3,
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -63,13 +59,15 @@ namespace FlaxEngine
|
|||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public override void Render(GPUContext context, ref RenderContext renderContext, GPUTexture input, GPUTexture output)
|
public override void Render(GPUContext context, ref RenderContext renderContext, GPUTexture input, GPUTexture output)
|
||||||
{
|
{
|
||||||
if (renderContext.View.Frustum.Contains(Canvas.Bounds.GetBoundingBox()) == ContainmentType.Disjoint)
|
var bounds = Canvas.Bounds;
|
||||||
|
bounds.Transformation.Translation -= renderContext.View.Origin;
|
||||||
|
if (renderContext.View.Frustum.Contains(bounds.GetBoundingBox()) == ContainmentType.Disjoint)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
Profiler.BeginEventGPU("UI Canvas");
|
Profiler.BeginEventGPU("UI Canvas");
|
||||||
|
|
||||||
// Calculate rendering matrix (world*view*projection)
|
// Calculate rendering matrix (world*view*projection)
|
||||||
Canvas.GetWorldMatrix(out Matrix worldMatrix);
|
Canvas.GetWorldMatrix(renderContext.View.Origin, out Matrix worldMatrix);
|
||||||
Matrix.Multiply(ref worldMatrix, ref renderContext.View.View, out Matrix viewMatrix);
|
Matrix.Multiply(ref worldMatrix, ref renderContext.View.View, out Matrix viewMatrix);
|
||||||
Matrix.Multiply(ref viewMatrix, ref renderContext.View.Projection, out Matrix viewProjectionMatrix);
|
Matrix.Multiply(ref viewMatrix, ref renderContext.View.Projection, out Matrix viewProjectionMatrix);
|
||||||
|
|
||||||
@@ -352,25 +350,37 @@ namespace FlaxEngine
|
|||||||
/// <param name="world">The world.</param>
|
/// <param name="world">The world.</param>
|
||||||
public void GetWorldMatrix(out Matrix world)
|
public void GetWorldMatrix(out Matrix world)
|
||||||
{
|
{
|
||||||
|
GetWorldMatrix(Vector3.Zero, out world);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the world matrix used to transform the GUI from the local space to the world space. Handles canvas rendering mode
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="viewOrigin">The view origin (when using relative-to-camera rendering).</param>
|
||||||
|
/// <param name="world">The world.</param>
|
||||||
|
public void GetWorldMatrix(Vector3 viewOrigin, out Matrix world)
|
||||||
|
{
|
||||||
|
var transform = Transform;
|
||||||
|
Float3 translation = transform.Translation - viewOrigin;
|
||||||
|
|
||||||
#if FLAX_EDITOR
|
#if FLAX_EDITOR
|
||||||
// Override projection for editor preview
|
// Override projection for editor preview
|
||||||
if (_editorTask)
|
if (_editorTask)
|
||||||
{
|
{
|
||||||
if (_renderMode == CanvasRenderMode.WorldSpace)
|
if (_renderMode == CanvasRenderMode.WorldSpace)
|
||||||
{
|
{
|
||||||
GetLocalToWorldMatrix(out world);
|
Matrix.Transformation(ref transform.Scale, ref transform.Orientation, ref translation, out world);
|
||||||
}
|
}
|
||||||
else if (_renderMode == CanvasRenderMode.WorldSpaceFaceCamera)
|
else if (_renderMode == CanvasRenderMode.WorldSpaceFaceCamera)
|
||||||
{
|
{
|
||||||
var view = _editorTask.View;
|
var view = _editorTask.View;
|
||||||
var transform = Transform;
|
|
||||||
Matrix.Translation(_guiRoot.Width * -0.5f, _guiRoot.Height * -0.5f, 0, out var m1);
|
Matrix.Translation(_guiRoot.Width * -0.5f, _guiRoot.Height * -0.5f, 0, out var m1);
|
||||||
Matrix.Scaling(ref transform.Scale, out var m2);
|
Matrix.Scaling(ref transform.Scale, out var m2);
|
||||||
Matrix.Multiply(ref m1, ref m2, out var m3);
|
Matrix.Multiply(ref m1, ref m2, out var m3);
|
||||||
Quaternion.Euler(180, 180, 0, out var quat);
|
Quaternion.Euler(180, 180, 0, out var quat);
|
||||||
Matrix.RotationQuaternion(ref quat, out m2);
|
Matrix.RotationQuaternion(ref quat, out m2);
|
||||||
Matrix.Multiply(ref m3, ref m2, out m1);
|
Matrix.Multiply(ref m3, ref m2, out m1);
|
||||||
m2 = Matrix.Transformation(Float3.One, Quaternion.FromDirection(-view.Direction), transform.Translation);
|
m2 = Matrix.Transformation(Float3.One, Quaternion.FromDirection(-view.Direction), translation);
|
||||||
Matrix.Multiply(ref m1, ref m2, out world);
|
Matrix.Multiply(ref m1, ref m2, out world);
|
||||||
}
|
}
|
||||||
else if (_renderMode == CanvasRenderMode.CameraSpace)
|
else if (_renderMode == CanvasRenderMode.CameraSpace)
|
||||||
@@ -384,7 +394,7 @@ namespace FlaxEngine
|
|||||||
Matrix.Translation(_guiRoot.Width / -2.0f, _guiRoot.Height / -2.0f, 0, out world);
|
Matrix.Translation(_guiRoot.Width / -2.0f, _guiRoot.Height / -2.0f, 0, out world);
|
||||||
Matrix.RotationYawPitchRoll(Mathf.Pi, Mathf.Pi, 0, out var tmp2);
|
Matrix.RotationYawPitchRoll(Mathf.Pi, Mathf.Pi, 0, out var tmp2);
|
||||||
Matrix.Multiply(ref world, ref tmp2, out var tmp1);
|
Matrix.Multiply(ref world, ref tmp2, out var tmp1);
|
||||||
var viewPos = (Float3)view.Position; // TODO: large-worlds
|
Float3 viewPos = view.Position - viewOrigin;
|
||||||
var viewRot = view.Direction != Float3.Up ? Quaternion.LookRotation(view.Direction, Float3.Up) : Quaternion.LookRotation(view.Direction, Float3.Right);
|
var viewRot = view.Direction != Float3.Up ? Quaternion.LookRotation(view.Direction, Float3.Up) : Quaternion.LookRotation(view.Direction, Float3.Right);
|
||||||
var viewUp = Float3.Up * viewRot;
|
var viewUp = Float3.Up * viewRot;
|
||||||
var viewForward = view.Direction;
|
var viewForward = view.Direction;
|
||||||
@@ -407,19 +417,18 @@ namespace FlaxEngine
|
|||||||
if (_renderMode == CanvasRenderMode.WorldSpace || (_renderMode == CanvasRenderMode.WorldSpaceFaceCamera && !camera))
|
if (_renderMode == CanvasRenderMode.WorldSpace || (_renderMode == CanvasRenderMode.WorldSpaceFaceCamera && !camera))
|
||||||
{
|
{
|
||||||
// In 3D world
|
// In 3D world
|
||||||
GetLocalToWorldMatrix(out world);
|
Matrix.Transformation(ref transform.Scale, ref transform.Orientation, ref translation, out world);
|
||||||
}
|
}
|
||||||
else if (_renderMode == CanvasRenderMode.WorldSpaceFaceCamera)
|
else if (_renderMode == CanvasRenderMode.WorldSpaceFaceCamera)
|
||||||
{
|
{
|
||||||
// In 3D world face camera
|
// In 3D world face camera
|
||||||
var transform = Transform;
|
|
||||||
Matrix.Translation(_guiRoot.Width * -0.5f, _guiRoot.Height * -0.5f, 0, out var m1);
|
Matrix.Translation(_guiRoot.Width * -0.5f, _guiRoot.Height * -0.5f, 0, out var m1);
|
||||||
Matrix.Scaling(ref transform.Scale, out var m2);
|
Matrix.Scaling(ref transform.Scale, out var m2);
|
||||||
Matrix.Multiply(ref m1, ref m2, out var m3);
|
Matrix.Multiply(ref m1, ref m2, out var m3);
|
||||||
Quaternion.Euler(180, 180, 0, out var quat);
|
Quaternion.Euler(180, 180, 0, out var quat);
|
||||||
Matrix.RotationQuaternion(ref quat, out m2);
|
Matrix.RotationQuaternion(ref quat, out m2);
|
||||||
Matrix.Multiply(ref m3, ref m2, out m1);
|
Matrix.Multiply(ref m3, ref m2, out m1);
|
||||||
m2 = Matrix.Transformation(Vector3.One, Quaternion.FromDirection(-camera.Direction), transform.Translation);
|
m2 = Matrix.Transformation(Vector3.One, Quaternion.FromDirection(-camera.Direction), translation);
|
||||||
Matrix.Multiply(ref m1, ref m2, out world);
|
Matrix.Multiply(ref m1, ref m2, out world);
|
||||||
}
|
}
|
||||||
else if (_renderMode == CanvasRenderMode.CameraSpace && camera)
|
else if (_renderMode == CanvasRenderMode.CameraSpace && camera)
|
||||||
@@ -446,7 +455,7 @@ namespace FlaxEngine
|
|||||||
Matrix.Multiply(ref world, ref tmp2, out tmp1);
|
Matrix.Multiply(ref world, ref tmp2, out tmp1);
|
||||||
|
|
||||||
// In front of the camera
|
// In front of the camera
|
||||||
var viewPos = (Float3)camera.Position; // TODO: large-worlds
|
Float3 viewPos = camera.Position - viewOrigin;
|
||||||
var viewRot = camera.Orientation;
|
var viewRot = camera.Orientation;
|
||||||
var viewUp = Float3.Up * viewRot;
|
var viewUp = Float3.Up * viewRot;
|
||||||
var viewForward = Float3.Forward * viewRot;
|
var viewForward = Float3.Forward * viewRot;
|
||||||
|
|||||||
Reference in New Issue
Block a user