Skip to content

Commit

Permalink
Merge pull request #614 from FUSEEProjectTeam/feature/612-visibility-…
Browse files Browse the repository at this point in the history
…tester-honors-transform

Feature/612 visibility tester honors transform
  • Loading branch information
wrestledBearOnce authored Sep 6, 2022
2 parents 08b1c2c + 57b4476 commit 5f7fe79
Show file tree
Hide file tree
Showing 9 changed files with 72 additions and 36 deletions.
6 changes: 3 additions & 3 deletions src/Engine/Core/Effects/SurfaceEffectPointCloud.cs
Original file line number Diff line number Diff line change
Expand Up @@ -190,7 +190,7 @@ private static List<string> CalculateVaryings(bool doRenderInstanced)
else
{
return new List<string>() {
$"mat4 mv = FUSEE_V * {UniformNameDeclarations.InstanceModelMat};",
$"mat4 mv = FUSEE_V * FUSEE_M * {UniformNameDeclarations.InstanceModelMat};",

//assumption: position x and y are in range [-0.5, 0.5].
$"{VaryingNameDeclarations.PointCoord} = vec2(0.5) / {UniformNameDeclarations.Vertex}.xy;",
Expand All @@ -208,14 +208,14 @@ private static List<string> CalculateVaryings(bool doRenderInstanced)
" // Fixed pixel size",
" case 0:",
" {",
$" sizeInPx = (billboardHeight / (2.0 * slope * z)) * float({UniformNameDeclarations.ViewportPx});",
$" sizeInPx = (billboardHeight / (2.0 * slope * z)) * float({UniformNameDeclarations.ViewportPx}.y);",
" break;",
" }",
" //Fixed world size",
" case 1:",
" {",
" //In this scenario the PointSize is the given point radius in world space - the point size in pixel will shrink if the camera moves farther away", "",
$" sizeInPx = (billboardHeight / (2.0 * slope)) * float({UniformNameDeclarations.ViewportPx});",
$" sizeInPx = (billboardHeight / (2.0 * slope)) * float({UniformNameDeclarations.ViewportPx}.y);",
" break;",
" }",
"}",
Expand Down
6 changes: 6 additions & 0 deletions src/Engine/Core/SceneRendererForward.cs
Original file line number Diff line number Diff line change
Expand Up @@ -282,6 +282,9 @@ public virtual void SetContext(RenderContext rc)
}
}

/// <summary>
/// Updates the state in each registered <see cref="IRendererModule"/>.
/// </summary>
protected void NotifyStateChanges()
{
foreach (var module in VisitorModules)
Expand All @@ -290,6 +293,9 @@ protected void NotifyStateChanges()
}
}

/// <summary>
/// Updates the camera in each registered <see cref="IRendererModule"/>.
/// </summary>
protected void NotifyCameraChanges(Camera cam)
{
foreach (var module in VisitorModules)
Expand Down
6 changes: 3 additions & 3 deletions src/PointCloud/Common/Assets/PointCloudInstanced.vert
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ in mat4 fuInstanceModelMat;

void main(void)
{
mat4 mv = FUSEE_V * fuInstanceModelMat;
mat4 mv = FUSEE_V * FUSEE_M * fuInstanceModelMat;

//vColor = fuInstanceColor;

Expand Down Expand Up @@ -52,7 +52,7 @@ void main(void)
case 1:
{
//In this scenario the PointSize is the given point radius in world space - the point size in pixel will shrink if the camera moves farther away" "",
sizeInPx = (billboardHeight / (2.0 * slope)) * float(FUSEE_ViewportPx);
sizeInPx = (billboardHeight / (2.0 * slope)) * float(FUSEE_ViewportPx);
break;
}
}
Expand All @@ -62,5 +62,5 @@ void main(void)
+ vec4(fuVertex.x, fuVertex.y, 0.0, 0.0)
* vec4(scaleFactor, scaleFactor, 1.0, 1.0);

gl_Position = FUSEE_P * FUSEE_M * vViewPos;
gl_Position = FUSEE_P * vViewPos;
}
4 changes: 2 additions & 2 deletions src/PointCloud/Common/IPointCloudImp.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
using Fusee.Engine.Core;
using Fusee.Math.Core;
using System;
using System.Collections.Generic;

namespace Fusee.PointCloud.Common
Expand Down Expand Up @@ -60,7 +59,8 @@ public float UpdateRate
/// <param name="viewportHeight">The current viewport height.</param>
/// <param name="renderFrustum">The current viewport width.</param>
/// <param name="camPos">The current camera position in world coordinates.</param>
public void Update(float fov, int viewportHeight, FrustumF renderFrustum, float3 camPos);
/// <param name="modelMat">The model matrix of the SceneNode the PointCloud(Component) is part of.</param>
public void Update(float fov, int viewportHeight, FrustumF renderFrustum, float3 camPos, float4x4 modelMat);
}

/// <summary>
Expand Down
30 changes: 26 additions & 4 deletions src/PointCloud/Core/PointCloudOctant.cs
Original file line number Diff line number Diff line change
Expand Up @@ -86,13 +86,17 @@ public PointCloudOctant(double3 center, double size, OctantId octId, PointCloudO
/// <param name="camPos">Position of the camera.</param>
/// <param name="screenHeight">Hight of the canvas.</param>
/// <param name="fov">Field of view.</param>
public void ComputeScreenProjectedSize(double3 camPos, int screenHeight, float fov)
public void ComputeScreenProjectedSize(double3 camPos, int screenHeight, float fov, float3 translation, float3 scale)
{
var distance = (Center - camPos).Length;
if (Center == camPos)
var translatedCenter = Center + new double3(translation);
var scaledRad = Size / 2f * new double3(scale);
var distance = (translatedCenter - camPos).Length;
if (translatedCenter == camPos)
distance = 0.0001f;
var slope = (float)System.Math.Tan(fov / 2d);
ProjectedScreenSize = screenHeight / 2d * Size / (slope * distance);

var maxRad = System.Math.Max(System.Math.Max(scaledRad.x, scaledRad.y), scaledRad.z);
ProjectedScreenSize = screenHeight / 2d * maxRad / (slope * distance);
}

/// <summary>
Expand All @@ -104,6 +108,24 @@ public IEmptyOctant<double3, double> CreateChild(int atPosInParent)
throw new System.NotImplementedException();
}

/// <summary>
/// Checks if this Octant lies within or intersects a Frustum.
/// Returns true if one of the Frustum planes is intersecting this octant.
/// </summary>
/// <param name="frustum">The frustum to test against.</param>
/// <returns>false if fully outside, true if inside or intersecting.</returns>
public bool InsideOrIntersectingFrustum(FrustumF frustum, float3 translation, float3 scale)
{
var translatedCenter = new float3(Center) + translation;
var scaledSize = new float3((float)Size) * scale;
return frustum.Near.InsideOrIntersecting(translatedCenter, scaledSize) &
frustum.Far.InsideOrIntersecting(translatedCenter, scaledSize) &
frustum.Left.InsideOrIntersecting(translatedCenter, scaledSize) &
frustum.Right.InsideOrIntersecting(translatedCenter, scaledSize) &
frustum.Top.InsideOrIntersecting(translatedCenter, scaledSize) &
frustum.Bottom.InsideOrIntersecting(translatedCenter, scaledSize);
}

/// <summary>
/// Checks if this Octant lies within or intersects a Frustum.
/// Returns true if one of the Frustum planes is intersecting this octant.
Expand Down
12 changes: 3 additions & 9 deletions src/PointCloud/Core/Scene/PointCloudRenderModule.cs
Original file line number Diff line number Diff line change
Expand Up @@ -41,10 +41,7 @@ public void UpdateContext(RenderContext rc)
if (rc == null)
throw new ArgumentNullException(nameof(rc));

if (rc != _rc)
{
_rc = rc;
}
_rc = rc;
}

/// <summary>
Expand All @@ -56,10 +53,7 @@ public void UpdateState(RendererState state)
if (state == null)
throw new ArgumentNullException(nameof(state));

if (state != _state)
{
_state = state;
}
_state = state;
}

/// <summary>
Expand Down Expand Up @@ -110,7 +104,7 @@ public void RenderPointCloud(PointCloudComponent pointCloud)
else if (pointCloud.Camera == _camera)
{
var fov = (float)_rc.ViewportWidth / _rc.ViewportHeight;
pointCloud.PointCloudImp.Update(fov, _rc.ViewportHeight, _rc.RenderFrustum, _rc.InvView.Column4.xyz);
pointCloud.PointCloudImp.Update(fov, _rc.ViewportHeight, _rc.RenderFrustum, _rc.InvView.Column4.xyz, _rc.Model);
}

switch (pointCloud.RenderMode)
Expand Down
33 changes: 23 additions & 10 deletions src/PointCloud/Core/VisibilityTester.cs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
using Fusee.Base.Core;
using Fusee.Engine.Core;
using Fusee.Math.Core;
using Fusee.PointCloud.Common;
Expand All @@ -21,10 +22,25 @@ public class VisibilityTester
/// </summary>
public float Fov { get; set; }

/// <summary>
/// Model matrix of the SceneNode the point cloud (component) is part of.
/// </summary>
public float4x4 Model { get; set; } = float4x4.Identity;

/// <summary>
/// Current camera position - set by the SceneRenderer if a PointCloud Component is visited.
/// </summary>
public float3 CamPos { get; set; }
public float3 CamPos
{
get => _camPos;
set
{
_camPos = value;
_camPosD = new double3(_camPos.x, _camPos.y, _camPos.z);
}
}
private float3 _camPos;


/// <summary>
/// Current height of the viewport - set by the SceneRenderer if a PointCloud Component is visited.
Expand Down Expand Up @@ -81,7 +97,6 @@ public float MinProjSizeModifier
private readonly SortedDictionary<double, PointCloudOctant> _visibleNodesOrderedByProjectionSize;

private double3 _camPosD;
private float _fov;
private float _minProjSizeModifier = 0.1f;
private readonly TriggerPointLoading _triggerPointLoading;
private float _deltaTimeSinceLastUpdate;
Expand All @@ -105,10 +120,7 @@ public VisibilityTester(IPointCloudOctree octree, TriggerPointLoading tryAddPoin
/// </summary>
public void Update()
{
_camPosD = new double3(CamPos.x, CamPos.y, CamPos.z);
_fov = Fov;

SetMinScreenProjectedSize(_camPosD, _fov);
SetMinScreenProjectedSize(_camPosD, Fov);

if (_deltaTimeSinceLastUpdate < UpdateRate)
_deltaTimeSinceLastUpdate += Time.DeltaTime;
Expand All @@ -129,7 +141,6 @@ private void DetermineVisibility()
NumberOfVisiblePoints = 0;
_visibleNodesOrderedByProjectionSize.Clear();
VisibleNodes.Clear();

DetermineVisibilityForNode((PointCloudOctant)Octree.Root);

while (_visibleNodesOrderedByProjectionSize.Count > 0 && NumberOfVisiblePoints <= PointThreshold)
Expand Down Expand Up @@ -161,12 +172,14 @@ private void DetermineVisibilityForChildren(PointCloudOctant node)

private void DetermineVisibilityForNode(PointCloudOctant node)
{
var scale = float3.One; //Model.Scale()
var translation = Model.Translation();
// gets pixel radius of the node
node.ComputeScreenProjectedSize(_camPosD, ViewportHeight, _fov);
node.ComputeScreenProjectedSize(_camPosD, ViewportHeight, Fov, translation, scale);

//If node does not intersect the viewing frustum or is smaller than the minimal projected size:
//Return -> will not be added to _visibleNodesOrderedByProjectionSize -> traversal of this branch stops.
if (!node.InsideOrIntersectingFrustum(RenderFrustum) || node.ProjectedScreenSize < _minScreenProjectedSize)
if (!node.InsideOrIntersectingFrustum(RenderFrustum, translation, scale) || node.ProjectedScreenSize < _minScreenProjectedSize)
{
return;
}
Expand All @@ -178,7 +191,7 @@ private void DetermineVisibilityForNode(PointCloudOctant node)

private void SetMinScreenProjectedSize(double3 camPos, float fov)
{
((PointCloudOctant)Octree.Root).ComputeScreenProjectedSize(camPos, ViewportHeight, fov);
((PointCloudOctant)Octree.Root).ComputeScreenProjectedSize(camPos, ViewportHeight, fov, Model.Translation(), float3.One);
_minScreenProjectedSize = ((PointCloudOctant)Octree.Root).ProjectedScreenSize * _minProjSizeModifier;
}
}
Expand Down
5 changes: 3 additions & 2 deletions src/PointCloud/Potree/Potree2Cloud.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
using Fusee.Math.Core;
using Fusee.PointCloud.Common;
using Fusee.PointCloud.Core;
using System;
using System.Collections.Generic;

namespace Fusee.PointCloud.Potree
Expand Down Expand Up @@ -105,7 +104,8 @@ public Potree2Cloud(PointCloudDataHandlerBase<GpuMesh> dataHandler, IPointCloudO
/// <param name="viewportHeight">The viewport height.</param>
/// <param name="renderFrustum">The camera's frustum.</param>
/// <param name="camPos">The camera position in world coordinates.</param>
public void Update(float fov, int viewportHeight, FrustumF renderFrustum, float3 camPos)
/// /// <param name="modelMat">The model matrix of the SceneNode the PointCloud(Component) is part of.</param>
public void Update(float fov, int viewportHeight, FrustumF renderFrustum, float3 camPos, float4x4 modelMat)
{
DataHandler.ProcessDisposeQueue();

Expand All @@ -121,6 +121,7 @@ public void Update(float fov, int viewportHeight, FrustumF renderFrustum, float3
VisibilityTester.ViewportHeight = viewportHeight;
VisibilityTester.Fov = fov;
VisibilityTester.CamPos = camPos;
VisibilityTester.Model = modelMat;

VisibilityTester.Update();

Expand Down
6 changes: 3 additions & 3 deletions src/PointCloud/Potree/Potree2CloudInstanced.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
using Fusee.Math.Core;
using Fusee.PointCloud.Common;
using Fusee.PointCloud.Core;
using System;
using System.Collections.Generic;

namespace Fusee.PointCloud.Potree
Expand Down Expand Up @@ -85,7 +84,6 @@ public float UpdateRate

private readonly GetInstanceData _getInstanceData;
private bool _doUpdate = true;
private bool _disposed;

/// <summary>
/// Creates a new instance of type <see cref="PointCloud"/>
Expand All @@ -106,7 +104,8 @@ public Potree2CloudInstanced(PointCloudDataHandlerBase<InstanceData> dataHandler
/// <param name="viewportHeight">The viewport height.</param>
/// <param name="renderFrustum">The camera's frustum.</param>
/// <param name="camPos">The camera position in world coordinates.</param>
public void Update(float fov, int viewportHeight, FrustumF renderFrustum, float3 camPos)
/// <param name="modelMat">The model matrix of the SceneNode the PointCloud(Component) is part of.</param>
public void Update(float fov, int viewportHeight, FrustumF renderFrustum, float3 camPos, float4x4 modelMat)
{
DataHandler.ProcessDisposeQueue();

Expand All @@ -122,6 +121,7 @@ public void Update(float fov, int viewportHeight, FrustumF renderFrustum, float3
VisibilityTester.ViewportHeight = viewportHeight;
VisibilityTester.Fov = fov;
VisibilityTester.CamPos = camPos;
VisibilityTester.Model = modelMat;

VisibilityTester.Update();

Expand Down

0 comments on commit 5f7fe79

Please sign in to comment.