Merge remote-tracking branch 'origin/master' into 1.11
# Conflicts: # Source/Engine/Level/Actors/Sky.cpp
This commit is contained in:
@@ -93,6 +93,7 @@ void MultiBlendBucketInit(AnimGraphInstanceData::Bucket& bucket)
|
||||
void BlendPoseBucketInit(AnimGraphInstanceData::Bucket& bucket)
|
||||
{
|
||||
bucket.BlendPose.TransitionPosition = 0.0f;
|
||||
bucket.BlendPose.BlendPoseIndex = -1;
|
||||
bucket.BlendPose.PreviousBlendPoseIndex = -1;
|
||||
}
|
||||
|
||||
|
||||
@@ -239,7 +239,8 @@ public:
|
||||
struct BlendPoseBucket
|
||||
{
|
||||
float TransitionPosition;
|
||||
int32 PreviousBlendPoseIndex;
|
||||
int16 BlendPoseIndex;
|
||||
int16 PreviousBlendPoseIndex;
|
||||
};
|
||||
|
||||
struct StateMachineBucket
|
||||
@@ -810,6 +811,7 @@ public:
|
||||
{
|
||||
// Copy the node transformations
|
||||
Platform::MemoryCopy(dstNodes->Nodes.Get(), srcNodes->Nodes.Get(), sizeof(Transform) * _skeletonNodesCount);
|
||||
dstNodes->RootMotion = srcNodes->RootMotion;
|
||||
|
||||
// Copy the animation playback state
|
||||
dstNodes->Position = srcNodes->Position;
|
||||
|
||||
@@ -676,9 +676,12 @@ Variant AnimGraphExecutor::Blend(AnimGraphNode* node, const Value& poseA, const
|
||||
if (!ANIM_GRAPH_IS_VALID_PTR(poseB))
|
||||
nodesB = GetEmptyNodes();
|
||||
|
||||
const Transform* srcA = nodesA->Nodes.Get();
|
||||
const Transform* srcB = nodesB->Nodes.Get();
|
||||
Transform* dst = nodes->Nodes.Get();
|
||||
for (int32 i = 0; i < nodes->Nodes.Count(); i++)
|
||||
{
|
||||
Transform::Lerp(nodesA->Nodes[i], nodesB->Nodes[i], alpha, nodes->Nodes[i]);
|
||||
Transform::Lerp(srcA[i], srcB[i], alpha, dst[i]);
|
||||
}
|
||||
Transform::Lerp(nodesA->RootMotion, nodesB->RootMotion, alpha, nodes->RootMotion);
|
||||
nodes->Position = Math::Lerp(nodesA->Position, nodesB->Position, alpha);
|
||||
@@ -1263,21 +1266,7 @@ void AnimGraphExecutor::ProcessGroupAnimation(Box* boxBase, Node* nodeBase, Valu
|
||||
{
|
||||
const auto valueA = tryGetValue(node->GetBox(1), Value::Null);
|
||||
const auto valueB = tryGetValue(node->GetBox(2), Value::Null);
|
||||
const auto nodes = node->GetNodes(this);
|
||||
|
||||
auto nodesA = static_cast<AnimGraphImpulse*>(valueA.AsPointer);
|
||||
auto nodesB = static_cast<AnimGraphImpulse*>(valueB.AsPointer);
|
||||
if (!ANIM_GRAPH_IS_VALID_PTR(valueA))
|
||||
nodesA = GetEmptyNodes();
|
||||
if (!ANIM_GRAPH_IS_VALID_PTR(valueB))
|
||||
nodesB = GetEmptyNodes();
|
||||
|
||||
for (int32 i = 0; i < nodes->Nodes.Count(); i++)
|
||||
{
|
||||
Transform::Lerp(nodesA->Nodes[i], nodesB->Nodes[i], alpha, nodes->Nodes[i]);
|
||||
}
|
||||
Transform::Lerp(nodesA->RootMotion, nodesB->RootMotion, alpha, nodes->RootMotion);
|
||||
value = nodes;
|
||||
value = Blend(node, valueA, valueB, alpha, AlphaBlendMode::Linear);
|
||||
}
|
||||
|
||||
break;
|
||||
@@ -1758,35 +1747,38 @@ void AnimGraphExecutor::ProcessGroupAnimation(Box* boxBase, Node* nodeBase, Valu
|
||||
// [2]: int Pose Count
|
||||
// [3]: AlphaBlendMode Mode
|
||||
|
||||
// Prepare
|
||||
auto& bucket = context.Data->State[node->BucketIndex].BlendPose;
|
||||
const int32 poseIndex = (int32)tryGetValue(node->GetBox(1), node->Values[0]);
|
||||
const int16 poseIndex = (int32)tryGetValue(node->GetBox(1), node->Values[0]);
|
||||
const float blendDuration = (float)tryGetValue(node->GetBox(2), node->Values[1]);
|
||||
const int32 poseCount = Math::Clamp(node->Values[2].AsInt, 0, MaxBlendPoses);
|
||||
const AlphaBlendMode mode = (AlphaBlendMode)node->Values[3].AsInt;
|
||||
|
||||
// Skip if nothing to blend
|
||||
if (poseCount == 0 || poseIndex < 0 || poseIndex >= poseCount)
|
||||
{
|
||||
break;
|
||||
|
||||
// Check if swap transition end points
|
||||
if (bucket.PreviousBlendPoseIndex == poseIndex && bucket.BlendPoseIndex != poseIndex && bucket.TransitionPosition >= ANIM_GRAPH_BLEND_THRESHOLD)
|
||||
{
|
||||
bucket.TransitionPosition = blendDuration - bucket.TransitionPosition;
|
||||
Swap(bucket.BlendPoseIndex, bucket.PreviousBlendPoseIndex);
|
||||
}
|
||||
|
||||
// Check if transition is not active (first update, pose not changing or transition ended)
|
||||
bucket.TransitionPosition += context.DeltaTime;
|
||||
bucket.BlendPoseIndex = poseIndex;
|
||||
if (bucket.PreviousBlendPoseIndex == -1 || bucket.PreviousBlendPoseIndex == poseIndex || bucket.TransitionPosition >= blendDuration || blendDuration <= ANIM_GRAPH_BLEND_THRESHOLD)
|
||||
{
|
||||
bucket.TransitionPosition = 0.0f;
|
||||
bucket.BlendPoseIndex = poseIndex;
|
||||
bucket.PreviousBlendPoseIndex = poseIndex;
|
||||
value = tryGetValue(node->GetBox(FirstBlendPoseBoxIndex + poseIndex), Value::Null);
|
||||
value = tryGetValue(node->GetBox(FirstBlendPoseBoxIndex + bucket.BlendPoseIndex), Value::Null);
|
||||
break;
|
||||
}
|
||||
ASSERT(bucket.PreviousBlendPoseIndex >= 0 && bucket.PreviousBlendPoseIndex < poseCount);
|
||||
|
||||
// Blend two animations
|
||||
{
|
||||
const float alpha = bucket.TransitionPosition / blendDuration;
|
||||
const auto valueA = tryGetValue(node->GetBox(FirstBlendPoseBoxIndex + bucket.PreviousBlendPoseIndex), Value::Null);
|
||||
const auto valueB = tryGetValue(node->GetBox(FirstBlendPoseBoxIndex + poseIndex), Value::Null);
|
||||
const auto valueB = tryGetValue(node->GetBox(FirstBlendPoseBoxIndex + bucket.BlendPoseIndex), Value::Null);
|
||||
value = Blend(node, valueA, valueB, alpha, mode);
|
||||
}
|
||||
|
||||
|
||||
@@ -63,9 +63,16 @@ void BoundingFrustum::SetMatrix(const Matrix& matrix)
|
||||
|
||||
Plane BoundingFrustum::GetPlane(int32 index) const
|
||||
{
|
||||
if (index > 5)
|
||||
return Plane();
|
||||
return _planes[index];
|
||||
switch (index)
|
||||
{
|
||||
case 0: return _pLeft;
|
||||
case 1: return _pRight;
|
||||
case 2: return _pTop;
|
||||
case 3: return _pBottom;
|
||||
case 4: return _pNear;
|
||||
case 5: return _pFar;
|
||||
default: return Plane();
|
||||
}
|
||||
}
|
||||
|
||||
static Vector3 Get3PlanesInterPoint(const Plane& p1, const Plane& p2, const Plane& p3)
|
||||
|
||||
@@ -182,7 +182,7 @@ namespace FlaxEngine
|
||||
/// <summary>
|
||||
/// Returns one of the 6 planes related to this frustum.
|
||||
/// </summary>
|
||||
/// <param name="index">Plane index where 0 fro Left, 1 for Right, 2 for Top, 3 for Bottom, 4 for Near, 5 for Far</param>
|
||||
/// <param name="index">Plane index where 0 for Left, 1 for Right, 2 for Top, 3 for Bottom, 4 for Near, 5 for Far</param>
|
||||
/// <returns>The frustum plane.</returns>
|
||||
public Plane GetPlane(int index)
|
||||
{
|
||||
|
||||
@@ -148,13 +148,13 @@ public:
|
||||
Plane GetPlane(int32 index) const;
|
||||
|
||||
/// <summary>
|
||||
/// Gets the the 8 corners of the frustum: Near1 (near right down corner), Near2 (near right top corner), Near3 (near Left top corner), Near4 (near Left down corner), Far1 (far right down corner), Far2 (far right top corner), Far3 (far left top corner), Far4 (far left down corner).
|
||||
/// Gets the 8 corners of the frustum: Near1 (near right down corner), Near2 (near right top corner), Near3 (near Left top corner), Near4 (near Left down corner), Far1 (far right down corner), Far2 (far right top corner), Far3 (far left top corner), Far4 (far left down corner).
|
||||
/// </summary>
|
||||
/// <param name="corners">The corners.</param>
|
||||
void GetCorners(Float3 corners[8]) const;
|
||||
|
||||
/// <summary>
|
||||
/// Gets the the 8 corners of the frustum: Near1 (near right down corner), Near2 (near right top corner), Near3 (near Left top corner), Near4 (near Left down corner), Far1 (far right down corner), Far2 (far right top corner), Far3 (far left top corner), Far4 (far left down corner).
|
||||
/// Gets the 8 corners of the frustum: Near1 (near right down corner), Near2 (near right top corner), Near3 (near Left top corner), Near4 (near Left down corner), Far1 (far right down corner), Far2 (far right top corner), Far3 (far left top corner), Far4 (far left down corner).
|
||||
/// </summary>
|
||||
/// <param name="corners">The corners.</param>
|
||||
void GetCorners(Double3 corners[8]) const;
|
||||
|
||||
@@ -265,6 +265,14 @@ public:
|
||||
return Projection.M44 >= 1.0f;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Determines whether view Origin has been moved in this frame. Old history buffers/data might be invalid.
|
||||
/// </summary>
|
||||
FORCE_INLINE bool IsOriginTeleport() const
|
||||
{
|
||||
return Origin != PrevOrigin;
|
||||
}
|
||||
|
||||
public:
|
||||
// Ignore deprecation warnings in defaults
|
||||
PRAGMA_DISABLE_DEPRECATION_WARNINGS
|
||||
|
||||
@@ -21,7 +21,8 @@
|
||||
#endif
|
||||
|
||||
GPU_CB_STRUCT(Data {
|
||||
Matrix WVP;
|
||||
Matrix WorldViewProjection;
|
||||
Matrix InvViewProjection;
|
||||
Float3 ViewOffset;
|
||||
float Padding;
|
||||
ShaderGBufferData GBuffer;
|
||||
@@ -30,8 +31,6 @@ GPU_CB_STRUCT(Data {
|
||||
|
||||
Sky::Sky(const SpawnParams& params)
|
||||
: Actor(params)
|
||||
, _psSky(nullptr)
|
||||
, _psFog(nullptr)
|
||||
{
|
||||
_drawNoCulling = 1;
|
||||
_drawCategory = SceneRendering::PreRender;
|
||||
@@ -51,7 +50,6 @@ Sky::Sky(const SpawnParams& params)
|
||||
Sky::~Sky()
|
||||
{
|
||||
SAFE_DELETE_GPU_RESOURCE(_psSky);
|
||||
SAFE_DELETE_GPU_RESOURCE(_psFog);
|
||||
}
|
||||
|
||||
void Sky::InitConfig(ShaderAtmosphericFogData& config) const
|
||||
@@ -90,7 +88,7 @@ void Sky::Draw(RenderContext& renderContext)
|
||||
if (HasContentLoaded() && EnumHasAnyFlags(renderContext.View.Flags, ViewFlags::Sky))
|
||||
{
|
||||
// Ensure to have pipeline state cache created
|
||||
if (_psSky == nullptr || _psFog == nullptr)
|
||||
if (_psSky == nullptr)
|
||||
{
|
||||
const auto shader = _shader->GetShader();
|
||||
|
||||
@@ -112,21 +110,6 @@ void Sky::Draw(RenderContext& renderContext)
|
||||
LOG(Warning, "Cannot create graphics pipeline state object for '{0}'.", ToString());
|
||||
}
|
||||
}
|
||||
if (_psFog == nullptr)
|
||||
{
|
||||
_psFog = GPUDevice::Instance->CreatePipelineState();
|
||||
|
||||
GPUPipelineState::Description psDesc = GPUPipelineState::Description::DefaultFullscreenTriangle;
|
||||
psDesc.PS = shader->GetPS("PS_Fog");
|
||||
psDesc.DepthWriteEnable = false;
|
||||
psDesc.DepthClipEnable = false;
|
||||
psDesc.BlendMode = BlendingMode::Additive;
|
||||
|
||||
if (_psFog->Init(psDesc))
|
||||
{
|
||||
LOG(Warning, "Cannot create graphics pipeline state object for '{0}'.", ToString());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Register for the sky and fog pass
|
||||
@@ -138,7 +121,6 @@ void Sky::Draw(RenderContext& renderContext)
|
||||
|
||||
void Sky::Serialize(SerializeStream& stream, const void* otherObj)
|
||||
{
|
||||
// Base
|
||||
Actor::Serialize(stream, otherObj);
|
||||
|
||||
SERIALIZE_GET_OTHER_OBJ(Sky);
|
||||
@@ -151,7 +133,6 @@ void Sky::Serialize(SerializeStream& stream, const void* otherObj)
|
||||
|
||||
void Sky::Deserialize(DeserializeStream& stream, ISerializeModifier* modifier)
|
||||
{
|
||||
// Base
|
||||
Actor::Deserialize(stream, modifier);
|
||||
|
||||
DESERIALIZE_MEMBER(Sun, SunLight);
|
||||
@@ -172,40 +153,7 @@ bool Sky::IntersectsItself(const Ray& ray, Real& distance, Vector3& normal)
|
||||
|
||||
void Sky::DrawFog(GPUContext* context, RenderContext& renderContext, GPUTextureView* output)
|
||||
{
|
||||
// Get precomputed cache and bind it to the pipeline
|
||||
AtmosphereCache cache;
|
||||
if (!AtmospherePreCompute::GetCache(&cache))
|
||||
return;
|
||||
PROFILE_GPU_CPU("Sky Fog");
|
||||
context->BindSR(4, cache.Transmittance);
|
||||
context->BindSR(5, cache.Irradiance);
|
||||
context->BindSR(6, cache.Inscatter->ViewVolume());
|
||||
|
||||
// Bind GBuffer inputs
|
||||
context->BindSR(0, renderContext.Buffers->GBuffer0);
|
||||
context->BindSR(1, renderContext.Buffers->GBuffer1);
|
||||
context->BindSR(2, renderContext.Buffers->GBuffer2);
|
||||
context->BindSR(3, renderContext.Buffers->DepthBuffer);
|
||||
|
||||
// Setup constants data
|
||||
Data data;
|
||||
GBufferPass::SetInputs(renderContext.View, data.GBuffer);
|
||||
data.ViewOffset = renderContext.View.Origin + GetPosition();
|
||||
InitConfig(data.Fog);
|
||||
data.Fog.AtmosphericFogSunPower *= SunLight ? SunLight->Brightness : 1.0f;
|
||||
bool useSpecularLight = EnumHasAnyFlags(renderContext.View.Flags, ViewFlags::SpecularLight);
|
||||
if (!useSpecularLight)
|
||||
{
|
||||
data.Fog.AtmosphericFogSunDiscScale = 0;
|
||||
}
|
||||
|
||||
// Bind pipeline
|
||||
auto cb = _shader->GetShader()->GetCB(0);
|
||||
context->UpdateCB(cb, &data);
|
||||
context->BindCB(0, cb);
|
||||
context->SetState(_psFog);
|
||||
context->SetRenderTarget(output);
|
||||
context->DrawFullscreenTriangle();
|
||||
MISSING_CODE("sky fog");
|
||||
}
|
||||
|
||||
bool Sky::IsDynamicSky() const
|
||||
@@ -231,14 +179,14 @@ void Sky::ApplySky(GPUContext* context, RenderContext& renderContext, const Matr
|
||||
// Setup constants data
|
||||
Matrix m;
|
||||
Data data;
|
||||
Matrix::Multiply(world, renderContext.View.Frustum.GetMatrix(), m);
|
||||
Matrix::Transpose(m, data.WVP);
|
||||
Matrix::Multiply(world, renderContext.View.ViewProjection(), m);
|
||||
Matrix::Transpose(m, data.WorldViewProjection);
|
||||
Matrix::Transpose(renderContext.View.IVP, data.InvViewProjection);
|
||||
GBufferPass::SetInputs(renderContext.View, data.GBuffer);
|
||||
data.ViewOffset = renderContext.View.Origin + GetPosition();
|
||||
InitConfig(data.Fog);
|
||||
//data.Fog.AtmosphericFogSunPower *= SunLight ? SunLight->Brightness : 1.0f;
|
||||
bool useSpecularLight = EnumHasAnyFlags(renderContext.View.Flags, ViewFlags::SpecularLight);
|
||||
if (!useSpecularLight)
|
||||
if (EnumHasNoneFlags(renderContext.View.Flags, ViewFlags::SpecularLight))
|
||||
{
|
||||
// Hide sun disc if specular light is disabled
|
||||
data.Fog.AtmosphericFogSunDiscScale = 0;
|
||||
@@ -253,11 +201,8 @@ void Sky::ApplySky(GPUContext* context, RenderContext& renderContext, const Matr
|
||||
|
||||
void Sky::EndPlay()
|
||||
{
|
||||
// Cleanup
|
||||
SAFE_DELETE_GPU_RESOURCE(_psSky);
|
||||
SAFE_DELETE_GPU_RESOURCE(_psFog);
|
||||
|
||||
// Base
|
||||
Actor::EndPlay();
|
||||
}
|
||||
|
||||
@@ -268,7 +213,6 @@ void Sky::OnEnable()
|
||||
GetSceneRendering()->AddViewportIcon(this);
|
||||
#endif
|
||||
|
||||
// Base
|
||||
Actor::OnEnable();
|
||||
}
|
||||
|
||||
@@ -279,13 +223,11 @@ void Sky::OnDisable()
|
||||
#endif
|
||||
GetSceneRendering()->RemoveActor(this, _sceneRenderingKey);
|
||||
|
||||
// Base
|
||||
Actor::OnDisable();
|
||||
}
|
||||
|
||||
void Sky::OnTransformChanged()
|
||||
{
|
||||
// Base
|
||||
Actor::OnTransformChanged();
|
||||
|
||||
_box = BoundingBox(_transform.Translation);
|
||||
|
||||
@@ -20,8 +20,7 @@ class FLAXENGINE_API Sky : public Actor, public IAtmosphericFogRenderer, public
|
||||
DECLARE_SCENE_OBJECT(Sky);
|
||||
private:
|
||||
AssetReference<Shader> _shader;
|
||||
GPUPipelineState* _psSky;
|
||||
GPUPipelineState* _psFog;
|
||||
GPUPipelineState* _psSky = nullptr;
|
||||
int32 _sceneRenderingKey = -1;
|
||||
|
||||
public:
|
||||
@@ -57,7 +56,6 @@ private:
|
||||
void OnShaderReloading(Asset* obj)
|
||||
{
|
||||
_psSky = nullptr;
|
||||
_psFog = nullptr;
|
||||
}
|
||||
#endif
|
||||
void InitConfig(ShaderAtmosphericFogData& config) const;
|
||||
|
||||
@@ -19,6 +19,7 @@
|
||||
#include "Engine/Content/Content.h"
|
||||
#include "Engine/Content/Assets/Model.h"
|
||||
#include "Engine/Level/Actors/Decal.h"
|
||||
#include "Engine/Level/Actors/Sky.h"
|
||||
#include "Engine/Engine/Engine.h"
|
||||
|
||||
GPU_CB_STRUCT(GBufferPassData {
|
||||
@@ -416,8 +417,17 @@ void GBufferPass::DrawSky(RenderContext& renderContext, GPUContext* context)
|
||||
|
||||
// Calculate sphere model transform to cover far plane
|
||||
Matrix m1, m2;
|
||||
Matrix::Scaling(renderContext.View.Far / ((float)box.GetSize().Y * 0.5f) * 0.95f, m1); // Scale to fit whole view frustum
|
||||
Matrix::CreateWorld(renderContext.View.Position, Float3::Up, Float3::Backward, m2); // Rotate sphere model
|
||||
float size = renderContext.View.Far;
|
||||
Float3 origin = renderContext.View.Position;
|
||||
if (dynamic_cast<Sky*>(renderContext.List->Sky)) // TODO: refactor sky rendering (eg. let sky draw with custom projection)
|
||||
{
|
||||
BoundingSphere frustumBounds;
|
||||
renderContext.View.CullingFrustum.GetSphere(frustumBounds);
|
||||
origin = frustumBounds.Center;
|
||||
size = frustumBounds.Radius;
|
||||
}
|
||||
Matrix::Scaling(size / ((float)box.GetSize().Y * 0.5f) * 0.95f, m1); // Scale to fit whole view frustum
|
||||
Matrix::CreateWorld(origin, Float3::Up, Float3::Backward, m2); // Rotate sphere model
|
||||
m1 *= m2;
|
||||
|
||||
// Draw sky
|
||||
|
||||
@@ -357,8 +357,6 @@ void RenderInner(SceneRenderTask* task, RenderContext& renderContext, RenderCont
|
||||
const bool isGBufferDebug = GBufferPass::IsDebugView(renderContext.View.Mode);
|
||||
{
|
||||
PROFILE_CPU_NAMED("Setup");
|
||||
if (renderContext.View.Origin != renderContext.View.PrevOrigin)
|
||||
renderContext.Task->CameraCut(); // Cut any temporal effects on rendering origin change
|
||||
const int32 screenWidth = renderContext.Buffers->GetWidth();
|
||||
const int32 screenHeight = renderContext.Buffers->GetHeight();
|
||||
setup.UpscaleLocation = renderContext.Task->UpscaleLocation;
|
||||
|
||||
@@ -167,7 +167,7 @@ bool VolumetricFogPass::Init(RenderContext& renderContext, GPUContext* context,
|
||||
(float)_cache.GridSizeZ);
|
||||
auto& fogData = renderContext.Buffers->VolumetricFogData;
|
||||
fogData.MaxDistance = options.Distance;
|
||||
if (renderContext.Task->IsCameraCut)
|
||||
if (renderContext.Task->IsCameraCut || renderContext.View.IsOriginTeleport())
|
||||
_cache.HistoryWeight = 0.0f;
|
||||
|
||||
// Init data (partial, without directional light or sky light data);
|
||||
@@ -301,7 +301,7 @@ void VolumetricFogPass::Render(RenderContext& renderContext)
|
||||
PROFILE_GPU_CPU("Volumetric Fog");
|
||||
|
||||
// TODO: test exponential depth distribution (should give better quality near the camera)
|
||||
// TODO: use tiled light culling and render unshadowed lights in single pass
|
||||
// TODO: use tiled light culling and render shadowed/unshadowed lights in single pass
|
||||
|
||||
// Try to get shadows atlas
|
||||
GPUTexture* shadowMap;
|
||||
|
||||
@@ -859,9 +859,7 @@ void Terrain::OnEnable()
|
||||
{
|
||||
auto patch = _patches[i];
|
||||
if (patch->_physicsActor)
|
||||
{
|
||||
PhysicsBackend::AddSceneActor(scene, patch->_physicsActor);
|
||||
}
|
||||
}
|
||||
|
||||
// Base
|
||||
@@ -880,9 +878,7 @@ void Terrain::OnDisable()
|
||||
{
|
||||
auto patch = _patches[i];
|
||||
if (patch->_physicsActor)
|
||||
{
|
||||
PhysicsBackend::RemoveSceneActor(scene, patch->_physicsActor);
|
||||
}
|
||||
}
|
||||
|
||||
// Base
|
||||
|
||||
@@ -2230,7 +2230,8 @@ void TerrainPatch::DestroyCollision()
|
||||
|
||||
void* scene = _terrain->GetPhysicsScene()->GetPhysicsScene();
|
||||
PhysicsBackend::RemoveCollider(_terrain);
|
||||
PhysicsBackend::RemoveSceneActor(scene, _physicsActor);
|
||||
if (_terrain->IsDuringPlay() && _terrain->IsActiveInHierarchy())
|
||||
PhysicsBackend::RemoveSceneActor(scene, _physicsActor);
|
||||
PhysicsBackend::DestroyActor(_physicsActor);
|
||||
PhysicsBackend::DestroyShape(_physicsShape);
|
||||
PhysicsBackend::DestroyObject(_physicsHeightField);
|
||||
|
||||
@@ -181,8 +181,8 @@ namespace FlaxEngine.GUI
|
||||
ImageColor = style.BorderSelected * 1.2f;
|
||||
BorderColor = style.BorderNormal;
|
||||
BorderColorHighlighted = style.BorderSelected;
|
||||
CheckedImage = new SpriteBrush(style.CheckBoxTick);
|
||||
IntermediateImage = new SpriteBrush(style.CheckBoxIntermediate);
|
||||
CheckedImage = style.CheckBoxTick.IsValid ? new SpriteBrush(style.CheckBoxTick) : new SolidColorBrush(style.Foreground);
|
||||
IntermediateImage = style.CheckBoxIntermediate.IsValid ? new SpriteBrush(style.CheckBoxIntermediate) : new SolidColorBrush(style.ForegroundGrey);
|
||||
|
||||
CacheBox();
|
||||
}
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
#include "Engine/Content/AssetsContainer.h"
|
||||
#include "Engine/Animations/Curve.h"
|
||||
|
||||
#define SHADER_GRAPH_MAX_CALL_STACK 100
|
||||
#define SHADER_GRAPH_MAX_CALL_STACK 50
|
||||
|
||||
enum class MaterialSceneTextures;
|
||||
template<class BoxType>
|
||||
|
||||
Reference in New Issue
Block a user