Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add simple player simulation, fix terrain block search #2

Merged
merged 12 commits into from
Feb 20, 2024
Merged
Prev Previous commit
Next Next commit
Parallelize terrain lookup
  • Loading branch information
JerritEic committed Jan 27, 2024
commit e709f22c48509ba3a956bb6aa566b4b9a5166714
13 changes: 0 additions & 13 deletions Assets/Scenes/AuthoringScene/AuthoringScene.unity
Original file line number Diff line number Diff line change
Expand Up @@ -133,7 +133,6 @@ GameObject:
m_Component:
- component: {fileID: 176225509}
- component: {fileID: 176225510}
- component: {fileID: 176225512}
m_Layer: 0
m_Name: TerrainSpawner
m_TagString: Untagged
Expand Down Expand Up @@ -173,18 +172,6 @@ MonoBehaviour:
TerrainConfiguration: {fileID: 3194879136077857405, guid: b5e6d2c9e04e20ca7afceb12dff6319c,
type: 3}
TerrainMaterial: {fileID: 2100000, guid: b53eef138330bed4a8a6bd3b9a48b63e, type: 2}
--- !u!114 &176225512
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 176225508}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: c16549610bfe4458aa9389201d072bb6, type: 3}
m_Name:
m_EditorClassIdentifier:
--- !u!1 &1514283054
GameObject:
m_ObjectHideFlags: 0
Expand Down
2 changes: 1 addition & 1 deletion Assets/Scripts/Player/Emulation/PlayerSimulationSystem.cs
Original file line number Diff line number Diff line change
Expand Up @@ -895,7 +895,7 @@ private bool IsSolidBlock(int3 pos, NativeHashSet<int3> offsets, bool trueIfAny
BSI.offset = offset;

if (TerrainUtilities.GetBlockAtPositionByOffset(in BSI, ref BSO,
ref _terrainNeighborLookup, ref _terrainBlockLookup, debug))
in _terrainNeighborLookup, in _terrainBlockLookup, debug))
{
if (BSO.blockType != BlockType.Air)
{
Expand Down
187 changes: 149 additions & 38 deletions Assets/Scripts/Player/PlayerMovementSystem.cs

Large diffs are not rendered by default.

141 changes: 95 additions & 46 deletions Assets/Scripts/Player/PlayerSelectedBlockSystem.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,10 @@
using Opencraft.Terrain.Utilities;
using PolkaDOTS;
using Unity.Burst;
using Unity.Collections;
using Unity.Entities;
using Unity.Mathematics;
using Unity.Transforms;


namespace Opencraft.Player
Expand All @@ -21,6 +23,9 @@ public partial struct PlayerSelectedBlockSystem : ISystem
private static readonly int raycastLength = 5;
private static readonly float3 camOffset = new float3(0, Env.CAMERA_Y_OFFSET, 0);

// World generation information
private int _columnHeight;

// Reusable block search input/output structs
private TerrainUtilities.BlockSearchInput BSI;
private TerrainUtilities.BlockSearchOutput BSO;
Expand All @@ -32,8 +37,11 @@ public void OnCreate(ref SystemState state)
state.RequireForUpdate<PlayerComponent>();
state.RequireForUpdate<TerrainArea>();
state.RequireForUpdate<TerrainSpawner>();
state.RequireForUpdate<WorldParameters>();
_terrainBlockLookup = state.GetBufferLookup<TerrainBlocks>(true);
_terrainNeighborLookup = state.GetComponentLookup<TerrainNeighbors>(true);

_columnHeight = -1;

TerrainUtilities.BlockSearchInput.DefaultBlockSearchInput(ref BSI);
TerrainUtilities.BlockSearchOutput.DefaultBlockSearchOutput(ref BSO);
Expand All @@ -43,63 +51,104 @@ public void OnCreate(ref SystemState state)
public void OnUpdate(ref SystemState state)
{
state.CompleteDependency();

// Fetch world generation information from the WorldParameters singleton
if (_columnHeight == -1)
{
var worldParameters = SystemAPI.GetSingleton<WorldParameters>();
_columnHeight = worldParameters.ColumnHeight;
}

_terrainBlockLookup.Update(ref state);
_terrainNeighborLookup.Update(ref state);

foreach (var player in SystemAPI.Query<PlayerAspect>().WithAll<Simulate, PlayerInGame>())
{
player.SelectedBlock.blockLoc = new int3(-1);
player.SelectedBlock.terrainArea = Entity.Null;
player.SelectedBlock.neighborBlockLoc = new int3(-1);
player.SelectedBlock.neighborTerrainArea = Entity.Null;
new SetSelectedBlock()
{
columnHeight = _columnHeight,
raycastLength = raycastLength,
camOffset = camOffset,
terrainNeighborsLookup = _terrainNeighborLookup,
terrainBlockLookup = _terrainBlockLookup
}.ScheduleParallel();
}
}


[BurstCompile]
[WithAll(typeof(Simulate), typeof(PlayerInGame))]
public partial struct SetSelectedBlock : IJobEntity
{
public int columnHeight;

if (player.ContainingArea.Area == Entity.Null)
continue;

// Use player input Yaw/Pitch to calculate the camera direction on clients
var cameraRot = math.mul(quaternion.RotateY(player.Input.Yaw),
quaternion.RotateX(-player.Input.Pitch));
var direction = math.mul(cameraRot, math.forward());
//var cameraPos = player.Transform.ValueRO.Position + camOffset ;
Entity neighborTerrainArea = Entity.Null;
int3 neighborBlockLoc = new int3(-1);

public int raycastLength;

// Setup search inputs
TerrainUtilities.BlockSearchInput.DefaultBlockSearchInput(ref BSI);
BSI.basePos = NoiseUtilities.FastFloor(player.Transform.ValueRO.Position);
BSI.areaEntity = player.ContainingArea.Area;
BSI.terrainAreaPos = player.ContainingArea.AreaLocation;

// Step along a ray from the players position in the direction their camera is looking
for (int i = 0; i < raycastLength; i++)
public float3 camOffset;

[ReadOnly][NativeDisableParallelForRestriction] public ComponentLookup<TerrainNeighbors> terrainNeighborsLookup;
[ReadOnly][NativeDisableParallelForRestriction] public BufferLookup<TerrainBlocks> terrainBlockLookup;

// Reusable block search input/output structs
private TerrainUtilities.BlockSearchInput BSI;
private TerrainUtilities.BlockSearchOutput BSO;

public void Execute(Entity entity,
ref SelectedBlock selectedBlock,
in PlayerContainingArea playerContainingArea,
in PlayerInput playerInput,
in LocalTransform playerTransform)
{
selectedBlock.blockLoc = new int3(-1);
selectedBlock.terrainArea = Entity.Null;
selectedBlock.neighborBlockLoc = new int3(-1);
selectedBlock.neighborTerrainArea = Entity.Null;

if (playerContainingArea.Area == Entity.Null)
return;

// Use player input Yaw/Pitch to calculate the camera direction on clients
var cameraRot = math.mul(quaternion.RotateY(playerInput.Yaw),
quaternion.RotateX(-playerInput.Pitch));
var direction = math.mul(cameraRot, math.forward());
Entity neighborTerrainArea = Entity.Null;
int3 neighborBlockLoc = new int3(-1);


// Setup search inputs
TerrainUtilities.BlockSearchInput.DefaultBlockSearchInput(ref BSI);
BSI.basePos = NoiseUtilities.FastFloor(playerTransform.Position);
BSI.offset = int3.zero;
BSI.areaEntity = playerContainingArea.Area;
BSI.terrainAreaPos =playerContainingArea.AreaLocation;
BSI.columnHeight = columnHeight;

// Step along a ray from the players position in the direction their camera is looking
for (int i = 0; i < raycastLength; i++)
{
//float3 location = cameraPos + (direction * i);
TerrainUtilities.BlockSearchOutput.DefaultBlockSearchOutput(ref BSO);
BSI.basePos = NoiseUtilities.FastFloor(playerTransform.Position + camOffset + (direction * i));
if (TerrainUtilities.GetBlockAtPositionByOffset(in BSI, ref BSO,
in terrainNeighborsLookup, in terrainBlockLookup))
{
//float3 location = cameraPos + (direction * i);
TerrainUtilities.BlockSearchOutput.DefaultBlockSearchOutput(ref BSO);
BSI.offset = NoiseUtilities.FastFloor(camOffset + (direction * i));
if (TerrainUtilities.GetBlockAtPositionByOffset(in BSI, ref BSO,
ref _terrainNeighborLookup, ref _terrainBlockLookup))
if (BSO.blockType != BlockType.Air)
{
if (BSO.blockType != BlockType.Air)
{
// found selected block
player.SelectedBlock.blockLoc = BSO.localPos;
player.SelectedBlock.terrainArea = BSO.containingArea ;
// Set neighbor
player.SelectedBlock.neighborBlockLoc = neighborBlockLoc;
player.SelectedBlock.neighborTerrainArea = neighborTerrainArea;

break;
}
// If this block is air, still mark it as the neighbor
neighborTerrainArea = BSO.containingArea;
neighborBlockLoc = BSO.localPos;
// found selected block
selectedBlock.blockLoc = BSO.localPos;
selectedBlock.terrainArea = BSO.containingArea ;
// Set neighbor
selectedBlock.neighborBlockLoc = neighborBlockLoc;
selectedBlock.neighborTerrainArea = neighborTerrainArea;

break;
}

// If this block is air, still mark it as the neighbor
neighborTerrainArea = BSO.containingArea;
neighborBlockLoc = BSO.localPos;
}

}


}
}

}
2 changes: 1 addition & 1 deletion Assets/Scripts/Player/SetPlayerSpawnLocationSystem.cs
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ public void OnUpdate(ref SystemState state)

BSI.offset = new int3(0, -i, 0);

if (TerrainUtilities.GetBlockAtPositionByOffset(in BSI, ref BSO, ref _terrainNeighborLookup, ref _terrainBlockLookup)) {
if (TerrainUtilities.GetBlockAtPositionByOffset(in BSI, ref BSO, in _terrainNeighborLookup, in _terrainBlockLookup)) {
if (BSO.blockType != BlockType.Air) {
yVal = worldHeight - i + 1; // offset by +2 so player isn't stuck in a floor
break;
Expand Down
5 changes: 4 additions & 1 deletion Assets/Scripts/Rendering/TerrainMeshingSystem.cs
Original file line number Diff line number Diff line change
Expand Up @@ -132,10 +132,13 @@ public void Execute(int index)
TerrainNeighbors terrainNeighbor = terrainNeighbors[index];
TerrainArea terrainArea = terrainAreas[index];
// When area is remeshed, outline it in red
float3 terrainAreaLocation = terrainArea.location * Env.AREA_SIZE;
if (UseDebug)
{
float3 terrainAreaLocation = terrainArea.location * Env.AREA_SIZE;
TerrainUtilities.DebugDrawTerrainArea(in terrainAreaLocation, Color.red, 0.5f);
}


// Mesh object vertex data
Mesh.MeshData meshData = meshDataArray[index];
// The blocks in this chunk
Expand Down
4 changes: 2 additions & 2 deletions Assets/Scripts/Terrain/Utilities/TerrainUtilities.cs
Original file line number Diff line number Diff line change
Expand Up @@ -188,8 +188,8 @@ public static void DefaultBlockSearchOutput(ref BlockSearchOutput bso)
// Uses neighbor entity links to check block types via offset from an existing position with a given terrain area
// Returns true if the block exists and is not air
public static bool GetBlockAtPositionByOffset(in BlockSearchInput input, ref BlockSearchOutput output,
ref ComponentLookup<TerrainNeighbors> terrainNeighborsLookup,
ref BufferLookup<TerrainBlocks> terrainBlockLookup, bool debug = false)
in ComponentLookup<TerrainNeighbors> terrainNeighborsLookup,
in BufferLookup<TerrainBlocks> terrainBlockLookup, bool debug = false)
{
if (input.areaEntity == Entity.Null)
{
Expand Down
2 changes: 1 addition & 1 deletion Packages/PolkaDOTS