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 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); } } } }