129 lines
4.7 KiB
C#
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);
|
|
}
|
|
}
|
|
}
|
|
}
|