ThomagicRenderer/Runtime/BillboardDrawCall.cs

129 lines
4.7 KiB
C#

using System;
using System.Collections.Generic;
using UnityEngine;
namespace Assets.ThoMagic.Renderer
{
public class BillboardDrawCall : DrawCall
{
private static Mesh _billboardMesh;
private static Mesh GetBillboardMesh()
{
if (_billboardMesh == null)
{
_billboardMesh = new Mesh();
_billboardMesh.name = "Billboard Mesh";
_billboardMesh.vertices = new Vector3[6];
_billboardMesh.triangles = new int[6] {
0,
1,
2,
3,
4,
5
};
_billboardMesh.SetUVs(0,new Vector2[6]
{
new Vector2(0.0f, 0.0f),
new Vector2(0.0f, 1f),
new Vector2(1f, 1f),
new Vector2(0.0f, 0.0f),
new Vector2(1f, 1f),
new Vector2(1f, 0.0f)
});
_billboardMesh.SetUVs(1, new Vector4[6]
{
new Vector4(1f, 1f, 0.0f, 0.0f),
new Vector4(1f, 1f, 0.0f, 0.0f),
new Vector4(1f, 1f, 0.0f, 0.0f),
new Vector4(1f, 1f, 0.0f, 0.0f),
new Vector4(1f, 1f, 0.0f, 0.0f),
new Vector4(1f, 1f, 0.0f, 0.0f)
});
_billboardMesh.UploadMeshData(true);
}
return _billboardMesh;
}
public BillboardDrawCall(
int lodNr,
BillboardAsset billboardAsset,
Material material,
Matrix4x4 localToWorldMatrix,
uint baseIndirectArgsIndex,
List<GraphicsBuffer.IndirectDrawIndexedArgs> indirectDrawIndexedArgs,
in RenderParams renderParams)
: base(lodNr,
GetBillboardMesh(),
new Material[1]{ material },
localToWorldMatrix,
baseIndirectArgsIndex,
indirectDrawIndexedArgs,
in renderParams)
{
if (billboardAsset == null)
throw new ArgumentNullException(nameof(billboardAsset));
SetBillboardPerBatch(billboardAsset);
}
internal override void Dispose() {
UnityEngine.Object.Destroy(_billboardMesh);
base.Dispose();
}
public override void Draw(Camera camera, ObjectData obj, GraphicsBuffer indirectDrawIndexedArgs)
{
SetBillboardPerCamera(camera);
base.Draw(camera, obj, indirectDrawIndexedArgs);
}
private void SetBillboardPerCamera(Camera camera)
{
Vector3 position = camera.transform.position;
Vector3 vector3_1 = camera.transform.forward * -1f;
vector3_1.y = 0.0f;
vector3_1.Normalize();
Vector3 vector3_2 = camera.transform.right * -1f;
vector3_2.y = 0.0f;
vector3_2.Normalize();
float num1 = Mathf.Atan2(vector3_1.z, vector3_1.x);
float num2 = num1 + (num1 < 0.0f ? 6.283185f : 0.0f);
Vector4 vector4;
vector4.x = position.x;
vector4.y = position.y;
vector4.z = position.z;
vector4.w = num2;
for (int index = 0; index < RenderParams.Length; ++index)
{
RenderParams[index].matProps.SetVector("unity_BillboardNormal", vector3_1);
RenderParams[index].matProps.SetVector("unity_BillboardTangent", vector3_2);
RenderParams[index].matProps.SetVector("unity_BillboardCameraParams", vector4);
}
}
private void SetBillboardPerBatch(BillboardAsset asset)
{
Vector4 vector4_1 = Vector4.zero;
vector4_1.x = asset.imageCount;
vector4_1.y = 1.0f / (6.28318548202515f / asset.imageCount);
Vector4 vector4_2 = Vector4.zero;
vector4_2.x = asset.width;
vector4_2.y = asset.height;
vector4_2.z = asset.bottom;
Vector4[] imageTexCoords = asset.GetImageTexCoords();
for (int index = 0; index < RenderParams.Length; ++index)
{
RenderParams[index].matProps.SetVector("unity_BillboardInfo", vector4_1);
RenderParams[index].matProps.SetVector("unity_BillboardSize", vector4_2);
RenderParams[index].matProps.SetVectorArray("unity_BillboardImageTexCoords", imageTexCoords);
}
}
}
}