Skip to content

Commit

Permalink
[Rendering] Extended Picking in editor to write InstanceID
Browse files Browse the repository at this point in the history
  • Loading branch information
tebjan committed Jul 16, 2020
1 parent 24c97db commit 94e9ab1
Show file tree
Hide file tree
Showing 8 changed files with 61 additions and 14 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -478,6 +478,13 @@ private async Task Execute()
{
var entityPicked = Pick();
entityUnderMouse = entityPicked.Entity;

// Check for instancing
var instancingComponent = entityUnderMouse?.Get<InstancingComponent>();
if (instancingComponent != null && instancingComponent.Type is InstancingEntityTransform instancing)
{
entityUnderMouse = instancing.GetInstanceEntity(entityPicked.InstanceId) ?? entityUnderMouse;
}
}

// Ctrl + click on an empty area: do nothing
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,11 @@ public struct EntityPickingResult
/// </summary>
public int MaterialIndex;

/// <summary>
/// The instance index
/// </summary>
public int InstanceId;

/// <summary>
/// Gets the component.
/// </summary>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,26 +21,31 @@ namespace Stride.Assets.Presentation.SceneEditor
internal struct PickingObjectInfo
{
private const float MaxMaterialIndex = 1024;
private const float MaxInstancingId = 1024;

public float ModelComponentId;
public float MeshMaterialIndex;

public PickingObjectInfo(int componentId, int meshIndex, int materialIndex)
{
ModelComponentId = componentId;
MeshMaterialIndex = meshIndex + (materialIndex / MaxMaterialIndex); // Pack to: MeshIndex.MaterialIndex
MeshMaterialIndex = meshIndex + (Math.Min(materialIndex, MaxMaterialIndex - 1) / MaxMaterialIndex); // Pack to: MeshIndex.MaterialIndex
}

public EntityPickingResult GetResult(Dictionary<int, Entity> idToEntity)
{
var fraction = MeshMaterialIndex - Math.Floor(MeshMaterialIndex);
var integral = MeshMaterialIndex - fraction;
var mcFraction = ModelComponentId - Math.Floor(ModelComponentId);
var mcIntegral = ModelComponentId - mcFraction;

var mmiFraction = MeshMaterialIndex - Math.Floor(MeshMaterialIndex);
var mmiIntegral = MeshMaterialIndex - mmiFraction;

var result = new EntityPickingResult
{
ComponentId = (int)Math.Round(ModelComponentId),
MeshNodeIndex = (int)Math.Round(integral),
MaterialIndex = (int)Math.Round(fraction * MaxMaterialIndex),
ComponentId = (int)Math.Round(mcIntegral),
InstanceId = (int)Math.Round(mcFraction * MaxInstancingId),
MeshNodeIndex = (int)Math.Round(mmiIntegral),
MaterialIndex = (int)Math.Round(mmiFraction * MaxMaterialIndex),
};
idToEntity.TryGetValue(result.ComponentId, out result.Entity);
return result;
Expand Down
17 changes: 17 additions & 0 deletions sources/engine/Stride.Engine/Engine/InstancingEntiyTransform.cs
Original file line number Diff line number Diff line change
Expand Up @@ -28,5 +28,22 @@ public override void Update()
{
base.Update();
}

List<Entity> instanceEntities = new List<Entity>();

internal Entity GetInstanceEntity(int instanceId)
{
return instanceEntities[instanceId];
}

internal void ClearEntities()
{
instanceEntities.Clear();
}

internal void AddInstanceEntity(Entity entity)
{
instanceEntities.Add(entity);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -92,18 +92,24 @@ public override void Draw(RenderContext context)
}

// Build matrix array
foreach (var group in SingleInstanceGroups)
foreach (var item in SingleInstanceGroups)
{
var groupCount = group.Value.Components.Count;
var group = item.Value;
var groupCount = group.Components.Count;
var instancing = (InstancingEntityTransform)group.MasterInstancing.Key.Type;
instancing.ClearEntities();

var matrices = ArrayPool.Rent(groupCount);
for (int i = 0; i < groupCount; i++)
{
matrices[i] = group.Value.Components[i].Value.TransformComponent.WorldMatrix;
var data = group.Components[i].Value.TransformComponent;
matrices[i] = data.WorldMatrix;
instancing.AddInstanceEntity(data.Entity);
}

// Assign matrix array
((InstancingEntityTransform)group.Value.MasterInstancing.Key.Type).UpdateWorldMatrices(matrices, groupCount);
ManyInstancing.Add(group.Value.MasterInstancing);
instancing.UpdateWorldMatrices(matrices, groupCount);
ManyInstancing.Add(group.MasterInstancing);
}

// Process the components
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,9 @@ public struct InstancingData

public class InstancingRenderFeature : SubRenderFeature
{
[DataMemberIgnore]
public static readonly PropertyKey<Dictionary<ModelComponent, InstancingComponent>> ModelToInstancingMap = new PropertyKey<Dictionary<ModelComponent, InstancingComponent>>("InstancingRenderFeature.ModelToInstancingMap", typeof(InstancingRenderFeature));

private StaticObjectPropertyKey<InstancingData> renderObjectInstancingDataInfoKey;

private StaticObjectPropertyKey<RenderEffect> renderEffectKey;
Expand All @@ -41,6 +44,7 @@ protected override void InitializeCore()
/// <inheritdoc/>
public override void Extract()
{
var mapFound = Context.VisibilityGroup.Tags.TryGetValue(ModelToInstancingMap, out var modelToInstancingMap);
var renderObjectInstancingData = RootRenderFeature.RenderData.GetData(renderObjectInstancingDataInfoKey);

foreach (var objectNodeReference in RootRenderFeature.ObjectNodeReferences)
Expand All @@ -54,6 +58,8 @@ public override void Extract()
if (modelComponent == null)
continue;

// Better:
// modelToInstancingMap.TryGetValue(modelComponent, out var instancingComponent);
var instancingComponent = modelComponent.Entity.Get<InstancingComponent>();
if (instancingComponent == null)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ shader TransformationWAndVPInstanced : TransformationWAndVP, TransformationInsta
{
stage override void PreTransformPosition()
{
float4 posWS = mul(streams.Position, GetInstanceWorld());
streams.PositionWS = mul(posWS, Transformation.World);
streams.PositionWS = mul(streams.Position, GetInstanceWorld());
}
};
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,9 @@ namespace Stride.Rendering

stage override void PSMain()
{
streams.ColorTarget = PickingData;
float modelComponentId = PickingData.x + (min(streams.InstanceID, 1023.0) / 1024.0);
float meshMaterialIndex = PickingData.y;
streams.ColorTarget = float4(modelComponentId, meshMaterialIndex, 1, 1);
}
};
}

0 comments on commit 94e9ab1

Please sign in to comment.