142 lines
4.5 KiB
C#
142 lines
4.5 KiB
C#
|
using System;
|
||
|
using System.Runtime.InteropServices;
|
||
|
using Unity.Burst;
|
||
|
using Unity.Collections;
|
||
|
using Unity.Jobs;
|
||
|
using Unity.Mathematics;
|
||
|
using UnityEngine;
|
||
|
using UnityEngine.Rendering;
|
||
|
using Object = UnityEngine.Object;
|
||
|
using Random = UnityEngine.Random;
|
||
|
|
||
|
namespace ZC
|
||
|
{
|
||
|
public class PointsDrawer
|
||
|
{
|
||
|
private static readonly int id_properties = Shader.PropertyToID("_Properties");
|
||
|
private int population;
|
||
|
private float range;
|
||
|
private Mesh mesh;
|
||
|
private Material material;
|
||
|
|
||
|
private ComputeBuffer meshPropertiesBuffer;
|
||
|
private ComputeBuffer argsBuffer;
|
||
|
private NativeArray<MeshProperties> _properties;
|
||
|
|
||
|
[StructLayout(LayoutKind.Explicit, Size = 80)]
|
||
|
private struct MeshProperties
|
||
|
{
|
||
|
[FieldOffset(0)] public float4x4 mat;
|
||
|
[FieldOffset(64)] public float4 color;
|
||
|
|
||
|
public static int Size()
|
||
|
{
|
||
|
return sizeof(float) * 4 * 4 + sizeof(float) * 4;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
public void Setup(Mesh mesh, int population, float range, Material material)
|
||
|
{
|
||
|
this.mesh = mesh;
|
||
|
this.population = population;
|
||
|
this.range = range;
|
||
|
this.material = material;
|
||
|
|
||
|
InitializeBuffers();
|
||
|
}
|
||
|
|
||
|
private void InitializeBuffers()
|
||
|
{
|
||
|
// Argument buffer used by DrawMeshInstancedIndirect.
|
||
|
uint[] args = new uint[5] { 0, 0, 0, 0, 0 };
|
||
|
// Arguments for drawing mesh.
|
||
|
// 0 == number of triangle indices, 1 == population, others are only relevant if drawing submeshes.
|
||
|
args[0] = (uint)mesh.GetIndexCount(0);
|
||
|
args[1] = (uint)population;
|
||
|
args[2] = (uint)mesh.GetIndexStart(0);
|
||
|
args[3] = (uint)mesh.GetBaseVertex(0);
|
||
|
argsBuffer = new ComputeBuffer(1, args.Length * sizeof(uint), ComputeBufferType.IndirectArguments);
|
||
|
argsBuffer.SetData(args);
|
||
|
|
||
|
this._properties = new NativeArray<MeshProperties>(this.population, Allocator.Persistent);
|
||
|
|
||
|
meshPropertiesBuffer = new ComputeBuffer(population, MeshProperties.Size());
|
||
|
}
|
||
|
|
||
|
public void OnDispose()
|
||
|
{
|
||
|
if (meshPropertiesBuffer != null)
|
||
|
{
|
||
|
meshPropertiesBuffer.Release();
|
||
|
}
|
||
|
|
||
|
meshPropertiesBuffer = null;
|
||
|
|
||
|
if (argsBuffer != null)
|
||
|
{
|
||
|
argsBuffer.Release();
|
||
|
}
|
||
|
|
||
|
argsBuffer = null;
|
||
|
this._properties.Dispose();
|
||
|
}
|
||
|
|
||
|
|
||
|
public void Render(NativeArray<ZPointInfo> frames, int hitCount,Bounds bounds,quaternion quaternion, float3 position)
|
||
|
{
|
||
|
TransformJob job = new TransformJob()
|
||
|
{
|
||
|
properties = this._properties,
|
||
|
frames =frames,
|
||
|
hitCount =hitCount,
|
||
|
position =position,
|
||
|
quaternion =quaternion,
|
||
|
};
|
||
|
job.Schedule(_properties.Length, 1).Complete();
|
||
|
|
||
|
meshPropertiesBuffer.SetData(this._properties);
|
||
|
|
||
|
material.SetBuffer(id_properties, meshPropertiesBuffer);
|
||
|
|
||
|
Graphics.DrawMeshInstancedIndirect(mesh, 0, material, bounds, bufferWithArgs: argsBuffer,receiveShadows: false, castShadows: ShadowCastingMode.Off);
|
||
|
}
|
||
|
|
||
|
[BurstCompile]
|
||
|
struct TransformJob : IJobParallelFor
|
||
|
{
|
||
|
[ReadOnly]
|
||
|
public NativeArray<ZPointInfo> frames;
|
||
|
[ReadOnly]
|
||
|
public int hitCount;
|
||
|
[ReadOnly]
|
||
|
public float3 position;
|
||
|
[ReadOnly]
|
||
|
public quaternion quaternion;
|
||
|
|
||
|
public NativeArray<MeshProperties> properties;
|
||
|
|
||
|
public void Execute(int i)
|
||
|
{
|
||
|
MeshProperties props = new MeshProperties();
|
||
|
if(i>=hitCount)
|
||
|
{
|
||
|
props.color = math.float4(1,0,0,1);
|
||
|
properties[i] = props;
|
||
|
return;
|
||
|
}
|
||
|
var frame = this.frames[i];
|
||
|
float3 localPosition = frame.point - position;
|
||
|
localPosition = math.mul(math.inverse(this.quaternion), localPosition);
|
||
|
const float scale = 0.02f;
|
||
|
props.mat = math.float4x4(math.float3x3(
|
||
|
scale,0,0,
|
||
|
0,scale,0,
|
||
|
0,0,scale
|
||
|
),localPosition);
|
||
|
props.color = math.float4(1,1,1,1);
|
||
|
|
||
|
properties[i] = props;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|