public static BillboardAsset CreateBillboardAsset(GBillboardCreatorArgs args) { BillboardAsset billboard = new BillboardAsset(); billboard.SetVertices(args.Vertices); billboard.SetIndices(Triangulate(args.Vertices)); billboard.width = args.Width; billboard.height = args.Height; billboard.bottom = args.Bottom; Vector4[] texcoords = new Vector4[args.Row * args.Column]; Vector2 imageSize = new Vector2(1f / args.Column, 1f / args.Row); Vector2 imageTopLeft = new Vector2(0, 0); for (int y = 0; y < args.Row; ++y) { for (int x = 0; x < args.Column; ++x) { imageTopLeft = new Vector2(x * imageSize.x, y * imageSize.y); texcoords[GUtilities.To1DIndex(x, y, args.Column)] = new Vector4(imageTopLeft.x, imageTopLeft.y, imageSize.x, imageSize.y); } } billboard.SetImageTexCoords(texcoords); billboard.name = args.Target.name + "_Billboard"; return(billboard); }
private void DoRenderPreview(bool shaded) { BillboardAsset billboardAsset = this.target as BillboardAsset; Bounds bounds = new Bounds(new Vector3(0f, (this.m_Height.floatValue + this.m_Bottom.floatValue) * 0.5f, 0f), new Vector3(this.m_Width.floatValue, this.m_Height.floatValue, this.m_Width.floatValue)); float magnitude = bounds.extents.magnitude; float num = 8f * magnitude; Quaternion quaternion = Quaternion.Euler(-this.m_PreviewDir.y, -this.m_PreviewDir.x, 0f); this.m_PreviewUtility.m_Camera.transform.rotation = quaternion; this.m_PreviewUtility.m_Camera.transform.position = quaternion * (-Vector3.forward * num); this.m_PreviewUtility.m_Camera.nearClipPlane = num - magnitude * 1.1f; this.m_PreviewUtility.m_Camera.farClipPlane = num + magnitude * 1.1f; this.m_PreviewUtility.m_Light[0].intensity = 1.4f; this.m_PreviewUtility.m_Light[0].transform.rotation = quaternion * Quaternion.Euler(40f, 40f, 0f); this.m_PreviewUtility.m_Light[1].intensity = 1.4f; Color ambient = new Color(0.1f, 0.1f, 0.1f, 0f); InternalEditorUtility.SetCustomLighting(this.m_PreviewUtility.m_Light, ambient); if (shaded) { billboardAsset.MakeRenderMesh(this.m_ShadedMesh, 1f, 1f, 0f); billboardAsset.MakeMaterialProperties(this.m_ShadedMaterialProperties, this.m_PreviewUtility.m_Camera); ModelInspector.RenderMeshPreviewSkipCameraAndLighting(this.m_ShadedMesh, bounds, this.m_PreviewUtility, billboardAsset.material, null, this.m_ShadedMaterialProperties, new Vector2(0f, 0f), -1); } else { billboardAsset.MakePreviewMesh(this.m_GeometryMesh); ModelInspector.RenderMeshPreviewSkipCameraAndLighting(this.m_GeometryMesh, bounds, this.m_PreviewUtility, this.m_GeometryMaterial, this.m_WireframeMaterial, null, new Vector2(0f, 0f), -1); } InternalEditorUtility.RemoveCustomLighting(); }
// Make a mesh out of the BillboardAsset that is suitable for previewing the geometry. // The vertices are expanded and made double-face. private void MakePreviewMesh(Mesh mesh, BillboardAsset billboard) { float width = billboard.width; float height = billboard.height; float bottom = billboard.bottom; mesh.SetVertices(Enumerable.Repeat( billboard.GetVertices().Select(v => new Vector3( (v.x - 0.5f) * width, v.y * height + bottom, 0)), // Repeat the sequence twice 2).SelectMany(s => s).ToList()); // (0,0,1) for the front-facing vertices and (0,0,-1) for the back-facing vertices mesh.SetNormals( Enumerable.Repeat(Vector3.forward, billboard.vertexCount).Concat( Enumerable.Repeat(-Vector3.forward, billboard.vertexCount)).ToList()); // make a new triangle list with second half triangles flipped var indices = new int[billboard.indexCount * 2]; var billboardIndices = billboard.GetIndices(); for (int i = 0; i < billboard.indexCount / 3; ++i) { indices[i * 3 + 0] = billboardIndices[i * 3 + 0]; indices[i * 3 + 1] = billboardIndices[i * 3 + 1]; indices[i * 3 + 2] = billboardIndices[i * 3 + 2]; indices[i * 3 + 0 + billboard.indexCount] = billboardIndices[i * 3 + 2]; indices[i * 3 + 1 + billboard.indexCount] = billboardIndices[i * 3 + 1]; indices[i * 3 + 2 + billboard.indexCount] = billboardIndices[i * 3 + 0]; } mesh.SetTriangles(indices, 0); }
private Mesh CreateBillboardMesh(BillboardAsset billboard) { Mesh m = new Mesh(); Vector2[] uvs = billboard.GetVertices(); Vector3[] vertices = new Vector3[billboard.vertexCount]; for (int i = 0; i < vertices.Length; ++i) { vertices[i] = new Vector3( (uvs[i].x - 0.5f) * billboard.width, uvs[i].y * billboard.height + billboard.bottom, 0); } ushort[] tris = billboard.GetIndices(); int[] trisInt = new int[tris.Length]; for (int i = 0; i < trisInt.Length; ++i) { trisInt[i] = tris[i]; } m.vertices = vertices; m.uv = uvs; m.triangles = trisInt; m.name = billboard.name; return(m); }
public static void vCreateNew_BillbardAsset_FromObjects(this GameObject obj, string directory, string billBoardAssetExtendname = "", bool applyNewToObj = true) { BillboardRenderer billboardRenderer = obj.GetComponentInChildren <BillboardRenderer>(); if (billboardRenderer != null) { if (billboardRenderer.billboard == null) { Debug.Log("Billboard is Null"); return; } BillboardAsset newBillboardAsset = new BillboardAsset(); newBillboardAsset.width = billboardRenderer.billboard.width; newBillboardAsset.height = billboardRenderer.billboard.height; newBillboardAsset.bottom = billboardRenderer.billboard.bottom; newBillboardAsset.material = billboardRenderer.sharedMaterial; string billboardAssetPath = directory + "/" + obj.name + billBoardAssetExtendname + "_Billboard.asset"; AssetDatabase.CreateAsset(newBillboardAsset, billboardAssetPath); AssetDatabase.Refresh(); if (applyNewToObj) { billboardRenderer.billboard = newBillboardAsset; } } }
// Make a mesh out of the BillboardAsset that is used for rendering by SpeedTree billboard shader. // Vertices are expanded by the shader therefore the mesh vertices are not used (filled by zeroes). internal static void MakeRenderMesh(Mesh mesh, BillboardAsset billboard) { mesh.SetVertices(Enumerable.Repeat(Vector3.zero, billboard.vertexCount).ToList()); mesh.SetColors(Enumerable.Repeat(Color.black, billboard.vertexCount).ToList()); mesh.SetUVs(0, billboard.GetVertices().ToList()); mesh.SetUVs(1, Enumerable.Repeat(new Vector4(1.0f, 1.0f, 0.0f, 0.0f), billboard.vertexCount).ToList()); mesh.SetTriangles(billboard.GetIndices().Select(v => (int)v).ToList(), 0); }
private void MakeRenderMesh(Mesh mesh, BillboardAsset billboard) { mesh.SetVertices(Enumerable.Repeat <Vector3>(Vector3.zero, billboard.vertexCount).ToList <Vector3>()); mesh.SetColors(Enumerable.Repeat <Color>(Color.black, billboard.vertexCount).ToList <Color>()); mesh.SetUVs(0, billboard.GetVertices().ToList <Vector2>()); mesh.SetUVs(1, Enumerable.Repeat <Vector4>(new Vector4(1f, 1f, 0f, 0f), billboard.vertexCount).ToList <Vector4>()); mesh.SetTriangles((from v in billboard.GetIndices() select(int) v).ToList <int>(), 0); }
private BillboardAsset CreateUnityBillboardAsset(string folder, string assetName, string assetPath) { var shaderBillboard = Shader.Find("G2Studios/Imposter/UnityBillboard"); BillboardRendererMaterial = new Material(shaderBillboard); BillboardRendererMaterial.SetTexture("_ImposterBaseTex", BaseTexture); BillboardRendererMaterial.SetTexture("_ImposterWorldNormalDepthTex", PackTexture); BillboardRendererMaterial.SetFloat("_ImposterFrames", Frames); BillboardRendererMaterial.SetFloat("_ImposterSize", Radius); BillboardRendererMaterial.SetVector("_ImposterOffset", Offset); BillboardRendererMaterial.SetFloat("_ImposterFullSphere", IsHalf ? 0f : 1f); BillboardRendererMaterial.name = assetName + "_BR"; EditorUtility.SetDirty(BillboardRendererMaterial); AssetDatabase.CreateAsset(BillboardRendererMaterial, folder + "/" + assetName + "_Imposter_BillboardMat.mat"); BillboardAsset = new BillboardAsset { material = BillboardRendererMaterial }; BillboardAsset.SetVertices(new Vector2[] { new Vector2(0.5f, 0.5f), new Vector2(0.0f, 0.0f), new Vector2(1.0f, 0.0f), new Vector2(1.0f, 1.0f), new Vector2(0.0f, 1.0f) }); BillboardAsset.SetIndices(new ushort[] { 2, 1, 0, 3, 2, 0, 4, 3, 0, 1, 4, 0 }); BillboardAsset.SetImageTexCoords(new Vector4[] { new Vector4(0.5f, 0.5f, 0f, 0f), new Vector4(0.0f, 0.0f, 0f, 0f), new Vector4(1.0f, 0.0f, 0f, 0f), new Vector4(1.0f, 1.0f, 0f, 0f), new Vector4(0.0f, 1.0f, 0f, 0f) }); BillboardAsset.width = Radius; BillboardAsset.height = Radius; BillboardAsset.bottom = Radius * 0.5f; BillboardAsset.name = "BillboardAsset"; EditorUtility.SetDirty(BillboardAsset); AssetDatabase.AddObjectToAsset(BillboardAsset, assetPath); return(BillboardAsset); }
public void UpdateBillboardMesh(BillboardAsset billboard) { if (BillboardMeshes.ContainsKey(billboard) && BillboardMeshes[billboard] != null) { GUtilities.DestroyObject(BillboardMeshes[billboard]); BillboardMeshes.Remove(billboard); } Mesh m = CreateBillboardMesh(billboard); BillboardMeshes.Add(billboard, m); }
public static Mesh GetMesh(BillboardAsset billboard) { if (!BillboardMeshes.ContainsKey(billboard)) { BillboardMeshes.Add(billboard, null); } if (BillboardMeshes[billboard] == null) { Mesh m = CreateMesh(billboard); BillboardMeshes[billboard] = m; } return(BillboardMeshes[billboard]); }
public Mesh GetBillboardMesh(BillboardAsset billboard) { if (BillboardMeshes.ContainsKey(billboard) && BillboardMeshes[billboard] != null) { return(BillboardMeshes[billboard]); } else if (BillboardMeshes.ContainsKey(billboard) && BillboardMeshes[billboard] == null) { BillboardMeshes.Remove(billboard); } Mesh m = CreateBillboardMesh(billboard); BillboardMeshes.Add(billboard, m); return(m); }
public static int get_material(IntPtr l) { int result; try { BillboardAsset billboardAsset = (BillboardAsset)LuaObject.checkSelf(l); LuaObject.pushValue(l, true); LuaObject.pushValue(l, billboardAsset.material); result = 2; } catch (Exception e) { result = LuaObject.error(l, e); } return(result); }
public static int constructor(IntPtr l) { int result; try { BillboardAsset o = new BillboardAsset(); LuaObject.pushValue(l, true); LuaObject.pushValue(l, o); result = 2; } catch (Exception e) { result = LuaObject.error(l, e); } return(result); }
public static int set_material(IntPtr l) { int result; try { BillboardAsset billboardAsset = (BillboardAsset)LuaObject.checkSelf(l); Material material; LuaObject.checkType <Material>(l, 2, out material); billboardAsset.material = material; LuaObject.pushValue(l, true); result = 1; } catch (Exception e) { result = LuaObject.error(l, e); } return(result); }
public static int set_bottom(IntPtr l) { int result; try { BillboardAsset billboardAsset = (BillboardAsset)LuaObject.checkSelf(l); float bottom; LuaObject.checkType(l, 2, out bottom); billboardAsset.bottom = bottom; LuaObject.pushValue(l, true); result = 1; } catch (Exception e) { result = LuaObject.error(l, e); } return(result); }
private void MakePreviewMesh(Mesh mesh, BillboardAsset billboard) { float width = billboard.width; float height = billboard.height; float bottom = billboard.bottom; mesh.SetVertices(Enumerable.Repeat <IEnumerable <Vector3> >(from v in billboard.GetVertices() select new Vector3((v.x - 0.5f) * width, v.y * height + bottom, 0f), 2).SelectMany((IEnumerable <Vector3> s) => s).ToList <Vector3>()); mesh.SetNormals(Enumerable.Repeat <Vector3>(Vector3.forward, billboard.vertexCount).Concat(Enumerable.Repeat <Vector3>(-Vector3.forward, billboard.vertexCount)).ToList <Vector3>()); int[] array = new int[billboard.indexCount * 2]; ushort[] indices = billboard.GetIndices(); for (int i = 0; i < billboard.indexCount / 3; i++) { array[i * 3] = (int)indices[i * 3]; array[i * 3 + 1] = (int)indices[i * 3 + 1]; array[i * 3 + 2] = (int)indices[i * 3 + 2]; array[i * 3 + billboard.indexCount] = (int)indices[i * 3 + 2]; array[i * 3 + 1 + billboard.indexCount] = (int)indices[i * 3 + 1]; array[i * 3 + 2 + billboard.indexCount] = (int)indices[i * 3]; } mesh.SetTriangles(array, 0); }
public static int SetImageTexCoords(IntPtr l) { int result; try { int total = LuaDLL.lua_gettop(l); if (LuaObject.matchType(l, total, 2, typeof(List <Vector4>))) { BillboardAsset billboardAsset = (BillboardAsset)LuaObject.checkSelf(l); List <Vector4> imageTexCoords; LuaObject.checkType <List <Vector4> >(l, 2, out imageTexCoords); billboardAsset.SetImageTexCoords(imageTexCoords); LuaObject.pushValue(l, true); result = 1; } else if (LuaObject.matchType(l, total, 2, typeof(Vector4[]))) { BillboardAsset billboardAsset2 = (BillboardAsset)LuaObject.checkSelf(l); Vector4[] imageTexCoords2; LuaObject.checkArray <Vector4>(l, 2, out imageTexCoords2); billboardAsset2.SetImageTexCoords(imageTexCoords2); LuaObject.pushValue(l, true); result = 1; } else { LuaObject.pushValue(l, false); LuaDLL.lua_pushstring(l, "No matched override function SetImageTexCoords to call"); result = 2; } } catch (Exception e) { result = LuaObject.error(l, e); } return(result); }
public static int GetImageTexCoords(IntPtr l) { int result; try { int num = LuaDLL.lua_gettop(l); if (num == 2) { BillboardAsset billboardAsset = (BillboardAsset)LuaObject.checkSelf(l); List <Vector4> imageTexCoords; LuaObject.checkType <List <Vector4> >(l, 2, out imageTexCoords); billboardAsset.GetImageTexCoords(imageTexCoords); LuaObject.pushValue(l, true); result = 1; } else if (num == 1) { BillboardAsset billboardAsset2 = (BillboardAsset)LuaObject.checkSelf(l); Vector4[] imageTexCoords2 = billboardAsset2.GetImageTexCoords(); LuaObject.pushValue(l, true); LuaObject.pushValue(l, imageTexCoords2); result = 2; } else { LuaObject.pushValue(l, false); LuaDLL.lua_pushstring(l, "No matched override function GetImageTexCoords to call"); result = 2; } } catch (Exception e) { result = LuaObject.error(l, e); } return(result); }
public void ExtractXMLTreePrototypeData() { TreeSystemPrototypeData[] data = m_ManagedPrototypes; for (int i = 0; i < data.Length; i++) { TreeSystemPrototypeData d = data[i]; if (d.m_TreePrototype == null) { Debug.LogError("Nothing set for data at index: " + i); continue; } // Get the protorype's billboard asset BillboardRenderer bill = d.m_TreePrototype.GetComponentInChildren <BillboardRenderer>(); if (bill == null) { Debug.LogError("Prototype: " + d.m_TreePrototype.name + " does not contain a billboard renderer! Items without billboard renderers are not supported at the moment!"); continue; } BillboardAsset billAsset = bill.billboard; // Set sizes d.m_Size = new Vector3(billAsset.width, billAsset.height, billAsset.bottom); Vector4[] uvs = billAsset.GetImageTexCoords(); // Ussualy 16 d.m_VertBillboardUVs = new Vector2[uvs.Length * 4]; // Just set the first UV's just to have something d.m_HorzBillboardUVs = new Vector2[4]; for (int uvIdx = 0, billUv = 0; uvIdx < uvs.Length; uvIdx++, billUv += 4) { Vector4 extract = uvs[uvIdx]; if (uvIdx == 0) { d.m_HorzBillboardUVs[0] = new Vector2(extract.x, extract.y); d.m_HorzBillboardUVs[1] = new Vector2(extract.x, extract.y) + new Vector2(0, Mathf.Abs(extract.w)); d.m_HorzBillboardUVs[2] = new Vector2(extract.x, extract.y) + new Vector2(-extract.z, Mathf.Abs(extract.w)); d.m_HorzBillboardUVs[3] = new Vector2(extract.x, extract.y) + new Vector2(-extract.z, 0); } // We are rotated if (extract.w < 0) { d.m_VertBillboardUVs[billUv + 0] = new Vector2(extract.x, extract.y); d.m_VertBillboardUVs[billUv + 1] = new Vector2(extract.x, extract.y) + new Vector2(0, Mathf.Abs(extract.w)); d.m_VertBillboardUVs[billUv + 2] = new Vector2(extract.x, extract.y) + new Vector2(-extract.z, Mathf.Abs(extract.w)); d.m_VertBillboardUVs[billUv + 3] = new Vector2(extract.x, extract.y) + new Vector2(-extract.z, 0); } else { d.m_VertBillboardUVs[billUv + 0] = new Vector2(extract.x, extract.y); d.m_VertBillboardUVs[billUv + 1] = new Vector2(extract.x, extract.y) + new Vector2(extract.z, 0); d.m_VertBillboardUVs[billUv + 2] = new Vector2(extract.x, extract.y) + new Vector2(extract.z, extract.w); d.m_VertBillboardUVs[billUv + 3] = new Vector2(extract.x, extract.y) + new Vector2(0, extract.w); } } Vector4 size = d.m_Size; size.w = 1; // Create the material with the texture references Material billboardMaterialBatch = new Material(m_BillboardShaderBatch); billboardMaterialBatch.SetTexture("_MainTex", bill.billboard.material.GetTexture("_MainTex")); billboardMaterialBatch.SetTexture("_BumpMap", bill.billboard.material.GetTexture("_BumpMap")); billboardMaterialBatch.SetVector("_Size", size); // Replace, don't delete // AssetDatabase.DeleteAsset(m_DataStorePath + "/" + d.m_TreePrototype.name + "_Mat.mat"); AssetDatabase.CreateAsset(billboardMaterialBatch, m_DataStorePath + "/" + d.m_TreePrototype.name + "_Bill_Batch_Mat.mat"); // Set the material d.m_BillboardBatchMaterial = billboardMaterialBatch; // Set billboard data TreeSystem.SetMaterialBillProps(d, d.m_BillboardBatchMaterial); } AssetDatabase.Refresh(); }
private BillboardAsset CreateUnityBillboardAsset(string folder, string assetName, string assetPath) { //shader for unity billboards (billboardRenderer and BillboardAsset) var shaderBillboard = Shader.Find("XRA/IMP/UnityBillboard"); //billboardRenderer material BillboardRendererMaterial = new Material(shaderBillboard); BillboardRendererMaterial.SetTexture("_ImposterBaseTex", BaseTexture); BillboardRendererMaterial.SetTexture("_ImposterWorldNormalDepthTex", PackTexture); BillboardRendererMaterial.SetFloat("_ImposterFrames", Frames); BillboardRendererMaterial.SetFloat("_ImposterSize", Radius); BillboardRendererMaterial.SetVector("_ImposterOffset", Offset); BillboardRendererMaterial.SetFloat("_ImposterFullSphere", IsHalf ? 0f : 1f); BillboardRendererMaterial.name = assetName + "_BR"; EditorUtility.SetDirty(BillboardRendererMaterial); //create material AssetDatabase.CreateAsset(BillboardRendererMaterial, folder + "/" + assetName + "_Imposter_BillboardMat.mat"); //TODO billboard renderer support //create billboard BillboardAsset = new BillboardAsset { //for billboardRenderer use an alternative shader material = BillboardRendererMaterial }; //billboard renderer vertices must be within 0 to 1 range //and only vector2 so we need to swwap the Y Z in shader //in shader (*2-1)*0.5 to get back to original //also doesnt accept vertex normals BillboardAsset.SetVertices(new Vector2[] { new Vector2(0.5f, 0.5f), new Vector2(0.0f, 0.0f), new Vector2(1.0f, 0.0f), new Vector2(1.0f, 1.0f), new Vector2(0.0f, 1.0f) }); BillboardAsset.SetIndices(new ushort[] { 2, 1, 0, 3, 2, 0, 4, 3, 0, 1, 4, 0 }); BillboardAsset.SetImageTexCoords(new Vector4[] { new Vector4(0.5f, 0.5f, 0f, 0f), new Vector4(0.0f, 0.0f, 0f, 0f), new Vector4(1.0f, 0.0f, 0f, 0f), new Vector4(1.0f, 1.0f, 0f, 0f), new Vector4(0.0f, 1.0f, 0f, 0f) }); BillboardAsset.width = Radius; BillboardAsset.height = Radius; BillboardAsset.bottom = Radius * 0.5f; BillboardAsset.name = "BillboardAsset"; EditorUtility.SetDirty(BillboardAsset); AssetDatabase.AddObjectToAsset(BillboardAsset, assetPath); return(BillboardAsset); }
public static void ExtractBillboardData(BillboardRenderer billboardData, FoliageTypeSpeedTreeData data) { BillboardAsset billAsset = billboardData.billboard; Vector4 size = new Vector4(billAsset.width, billAsset.height, billAsset.bottom, 1); // UV Extraction Vector4[] uvs = billAsset.GetImageTexCoords(); Vector2[] vertBillUV = new Vector2[uvs.Length * 4]; Vector2[] horzBillUV = new Vector2[4]; // Build the UV's for (int uvIdx = 0, billUv = 0; uvIdx < uvs.Length; uvIdx++, billUv += 4) { Vector4 extract = uvs[uvIdx]; if (uvIdx == 0) { horzBillUV[0] = new Vector2(extract.x, extract.y); horzBillUV[1] = new Vector2(extract.x, extract.y) + new Vector2(0, Mathf.Abs(extract.w)); horzBillUV[2] = new Vector2(extract.x, extract.y) + new Vector2(-extract.z, Mathf.Abs(extract.w)); horzBillUV[3] = new Vector2(extract.x, extract.y) + new Vector2(-extract.z, 0); } // We are rotated if (extract.w < 0) { vertBillUV[billUv + 0] = new Vector2(extract.x, extract.y); vertBillUV[billUv + 1] = new Vector2(extract.x, extract.y) + new Vector2(0, Mathf.Abs(extract.w)); vertBillUV[billUv + 2] = new Vector2(extract.x, extract.y) + new Vector2(-extract.z, Mathf.Abs(extract.w)); vertBillUV[billUv + 3] = new Vector2(extract.x, extract.y) + new Vector2(-extract.z, 0); } else { vertBillUV[billUv + 0] = new Vector2(extract.x, extract.y); vertBillUV[billUv + 1] = new Vector2(extract.x, extract.y) + new Vector2(extract.z, 0); vertBillUV[billUv + 2] = new Vector2(extract.x, extract.y) + new Vector2(extract.z, extract.w); vertBillUV[billUv + 3] = new Vector2(extract.x, extract.y) + new Vector2(0, extract.w); } } // Build the UVs ready for the shader Vector4[] UV_U = new Vector4[8]; Vector4[] UV_V = new Vector4[8]; Vector2[] uv = vertBillUV; for (int i = 0; i < 8; i++) { // 4 by 4 elements UV_U[i].x = uv[4 * i + 0].x; UV_U[i].y = uv[4 * i + 1].x; UV_U[i].z = uv[4 * i + 2].x; UV_U[i].w = uv[4 * i + 3].x; UV_V[i].x = uv[4 * i + 0].y; UV_V[i].y = uv[4 * i + 1].y; UV_V[i].z = uv[4 * i + 2].y; UV_V[i].w = uv[4 * i + 3].y; } // Assign the data data.m_Size = size; data.m_VertBillboardU = UV_U; data.m_VertBillboardV = UV_V; data.m_BillboardRenderer = billboardData; data.m_BillboardMaterial = GenerateBillboardMaterial(data); }
void BakeBillboard() { BillboardAsset billboard = new BillboardAsset(); billboard.material = m_material; Vector4[] texCoords = new Vector4[8]; ushort[] indices = new ushort[6]; Vector2[] vertices = new Vector2[4]; //float height = 0.3333f * ratio; //float offsetY = 0.3333f * (1 - ratio) / 2; //height = 0.3333f; //offset = 0; texCoords[0].Set(0.3333f + offsetU, 0 + offsetV, sizeU, sizeV); texCoords[1].Set(0.6667f + offsetU, 0 + offsetV, sizeU, sizeV); texCoords[2].Set(0.0f + offsetU, 0.3333f + offsetV, sizeU, sizeV); texCoords[3].Set(0.3333f + offsetU, 0.3333f + offsetV, sizeU, sizeV); texCoords[4].Set(0.6667f + offsetU, 0.3333f + offsetV, sizeU, sizeV); texCoords[5].Set(0.0f + offsetU, 0.6667f + offsetV, sizeU, sizeV); texCoords[6].Set(0.3333f + offsetU, 0.6667f + offsetV, sizeU, sizeV); texCoords[7].Set(0.6667f + offsetU, 0.6667f + offsetV, sizeU, sizeV); ratio = sizeV / sizeU; //indices[0] = 0; //indices[1] = 3; //indices[2] = 1; //indices[3] = 3; //indices[4] = 4; //indices[5] = 1; //indices[6] = 1; //indices[7] = 4; //indices[8] = 5; //indices[9] = 1; //indices[10] = 5; //indices[11] = 2; indices[0] = 0; indices[1] = 3; indices[2] = 1; indices[3] = 2; indices[4] = 3; indices[5] = 0; //vertices[0].Set(0.47093f, 1); //vertices[1].Set(0.037790697f, 0.498547f); //vertices[2].Set(0.037790697f, 0.020348798f); //vertices[3].Set(0.58906996f, 1); //vertices[4].Set(0.95930207f, 0.498547f); //vertices[5].Set(0.95930207f, 0.020348798f); vertices[0].Set(0, 1); vertices[1].Set(0, 0); vertices[2].Set(1, 1); vertices[3].Set(1, 0); billboard.SetImageTexCoords(texCoords); billboard.SetIndices(indices); billboard.SetVertices(vertices); //billboard.width = 19.03616f; //billboard.height = 19.58068f; //billboard.bottom = -1.814002f; billboard.width = width; billboard.height = width * ratio; billboard.bottom = 0; if (m_outputFile != null) { EditorUtility.CopySerialized(billboard, m_outputFile); } else { string path; path = AssetDatabase.GetAssetPath(m_material); path = path.Remove(path.Length - (m_material.name.Length + 4)); AssetDatabase.CreateAsset(billboard, path + "resource/BillboardAsset.asset"); } }
public void Save(string assetPath, string assetName, bool createBillboardAsset = false) { var lastSlash = assetPath.LastIndexOf("/", StringComparison.Ordinal); var folder = assetPath.Substring(0, lastSlash); EditorUtility.SetDirty(this); BaseTexture.name = "ImposterBase"; var baseTexPath = WriteTexture(BaseTexture, folder, assetName); PackTexture.name = "ImposterPack"; var normTexPath = WriteTexture(PackTexture, folder, assetName); AssetDatabase.Refresh(); var importer = AssetImporter.GetAtPath(baseTexPath) as TextureImporter; if (importer != null) { importer.textureType = TextureImporterType.Default; importer.maxTextureSize = AtlasResolution; importer.alphaSource = TextureImporterAlphaSource.FromInput; importer.alphaIsTransparency = false; importer.sRGBTexture = false; importer.SaveAndReimport(); BaseTexture = AssetDatabase.LoadAssetAtPath <Texture2D>(baseTexPath); } importer = AssetImporter.GetAtPath(normTexPath) as TextureImporter; if (importer != null) { importer.textureType = TextureImporterType.Default; importer.maxTextureSize = AtlasResolution; importer.alphaSource = TextureImporterAlphaSource.FromInput; importer.alphaIsTransparency = false; importer.sRGBTexture = false; importer.SaveAndReimport(); PackTexture = AssetDatabase.LoadAssetAtPath <Texture2D>(normTexPath); } var shader = Shader.Find("G2Studios/Imposter/Standard"); Material = new Material(shader); Material.SetTexture("_ImposterBaseTex", BaseTexture); Material.SetTexture("_ImposterWorldNormalDepthTex", PackTexture); Material.SetFloat("_ImposterFrames", Frames); Material.SetFloat("_ImposterSize", Radius); Material.SetVector("_ImposterOffset", Offset); Material.SetFloat("_ImposterFullSphere", IsHalf ? 0f : 1f); Material.name = assetName; EditorUtility.SetDirty(Material); //create material AssetDatabase.CreateAsset(Material, folder + "/" + assetName + "_Imposter_Mat.mat"); //mesh (not for billboardAsset) Mesh = MeshSetup(); Mesh.name = "ImposterQuad_" + Radius.ToString("F1"); AssetDatabase.AddObjectToAsset(Mesh, assetPath); if (createBillboardAsset) { BillboardAsset = CreateUnityBillboardAsset(folder, assetName, assetPath); } AssetDatabase.SaveAssets(); }
private void SaveAssets() { string folder = EditorUtility.OpenFolderPanel("Select Folder", "Assets/", ""); if (string.IsNullOrEmpty(folder)) { return; } try { GAnalytics.Record(GAnalytics.BILLBOARD_SAVE); EditorUtility.DisplayProgressBar("Saving", "Saving assets...", 1f); GBillboardCreatorArgs args = ConstructArgs(); BillboardAsset billboard = GBillboardCreator.CreateBillboardAsset(args); Texture2D atlas = GBillboardCreator.RenderAtlas(args); Texture2D normal = GBillboardCreator.RenderNormal(args); string billboardPath = Path.Combine(FileUtil.GetProjectRelativePath(folder), billboard.name + ".asset"); BillboardAsset billboardAsset = AssetDatabase.LoadAssetAtPath <BillboardAsset>(billboardPath); if (billboardAsset == null) { AssetDatabase.CreateAsset(billboard, billboardPath); billboardAsset = billboard; } else { billboardAsset.SetVertices(billboard.GetVertices()); billboardAsset.SetIndices(billboard.GetIndices()); billboardAsset.SetImageTexCoords(billboard.GetImageTexCoords()); billboardAsset.width = billboard.width; billboardAsset.height = billboard.height; billboardAsset.bottom = billboard.bottom; billboardAsset.name = billboard.name; } string atlasPath = Path.Combine(FileUtil.GetProjectRelativePath(folder), atlas.name + ".png"); byte[] atlasData = atlas.EncodeToPNG(); File.WriteAllBytes(atlasPath, atlasData); GUtilities.DestroyObject(atlas); string normalPath = Path.Combine(FileUtil.GetProjectRelativePath(folder), normal.name + ".png"); byte[] normalData = normal.EncodeToPNG(); File.WriteAllBytes(normalPath, normalData); GUtilities.DestroyObject(normal); AssetDatabase.Refresh(); TextureImporter atlasImporter = AssetImporter.GetAtPath(atlasPath) as TextureImporter; atlasImporter.wrapMode = TextureWrapMode.Clamp; atlasImporter.alphaIsTransparency = true; atlasImporter.SaveAndReimport(); atlas = AssetDatabase.LoadAssetAtPath <Texture2D>(atlasPath); TextureImporter normalImporter = AssetImporter.GetAtPath(normalPath) as TextureImporter; normalImporter.textureType = TextureImporterType.NormalMap; normalImporter.wrapMode = TextureWrapMode.Clamp; normalImporter.SaveAndReimport(); normal = AssetDatabase.LoadAssetAtPath <Texture2D>(normalPath); Material mat = null; if (GCommon.CurrentRenderPipeline == GRenderPipelineType.Universal) { mat = Object.Instantiate(GGriffinSettings.Instance.TerrainDataDefault.Foliage.TreeBillboardMaterialURP); } else if (GCommon.CurrentRenderPipeline == GRenderPipelineType.Lightweight) { mat = Object.Instantiate(GGriffinSettings.Instance.TerrainDataDefault.Foliage.TreeBillboardMaterialLWRP); } else { mat = Object.Instantiate(GGriffinSettings.Instance.TerrainDataDefault.Foliage.TreeBillboardMaterial); } if (mat != null) { if (mat.HasProperty("_MainTex")) { mat.SetTexture("_MainTex", atlas); } if (mat.HasProperty("_BumpMap")) { mat.SetTexture("_BumpMap", normal); } mat.name = args.Target.name + "_BillboardMaterial"; string matPath = Path.Combine(FileUtil.GetProjectRelativePath(folder), mat.name + ".mat"); AssetDatabase.CreateAsset(mat, matPath); billboardAsset.material = mat; } AssetDatabase.Refresh(); } catch (System.Exception e) { Debug.LogError(e.ToString()); } EditorUtility.ClearProgressBar(); }
void OnWizardCreate() { //function to execute on submit BillboardAsset billboard = new BillboardAsset(); billboard.material = m_material; Vector4[] texCoords = new Vector4[totalImageCount]; ushort[] indices = new ushort[12]; Vector2[] vertices = new Vector2[6]; //make texture to save at end var texture = new Texture2D(atlasPixelWidth, atlasPixelHeight, TextureFormat.ARGB32, false); //make render texture to copy to texture and assign it to camera //renderCamera.targetTexture = RenderTexture.GetTemporary(atlasPixelWidth / atlasColumnImageCount, atlasPixelHeight / atlasRowImageCount, 16); renderCamera.targetTexture = RenderTexture.GetTemporary(atlasPixelWidth, atlasPixelHeight, 16); var renderTex = renderCamera.targetTexture; renderCamera.targetTexture = renderTex; //reset rotation, but camera should be on local +x axis from rotating object toRotateCamera.transform.eulerAngles = Vector3.zero; int imageAt = 0; for (int j = 0; j < atlasRowImageCount; j++) { for (int i = 0; i < atlasColumnImageCount; i++) { //i is x, j is y if (imageAt < totalImageCount) { //atla them left-right, top-bottom, 0,0 is bottom left float xRatio = (float)i / atlasColumnImageCount; float yRatio = (float)(atlasRowImageCount - j - 1) / atlasRowImageCount; //starts at viewing from +x, and rotates camera clockwise around object, uses amount of vertices set (later down) to tell how many angles to view from texCoords[imageAt].Set(xRatio, yRatio, 1f / atlasColumnImageCount, 1f / atlasRowImageCount); imageAt++; //set rect of where to render texture to renderCamera.rect = new Rect(xRatio, yRatio, 1f / atlasColumnImageCount, 1f / atlasRowImageCount); renderCamera.Render(); //read pixels on rec //Rect rec = new Rect(xRatio * atlasPixelWidth, yRatio * atlasPixelHeight, (float)1 / atlasColumnImageCount * atlasPixelWidth, (float)1 / atlasRowImageCount * atlasPixelHeight); //texture.ReadPixels(rec, i / atlasColumnImageCount * atlasPixelWidth, (atlasRowImageCount - j - 1) / atlasRowImageCount * atlasPixelHeight); toRotateCamera.transform.eulerAngles += Vector3.up * (360 / totalImageCount); } } } toRotateCamera.transform.eulerAngles = Vector3.zero; renderCamera.rect = new Rect(0, 0, 1, 1); RenderTexture pastActive = RenderTexture.active; RenderTexture.active = renderTex; texture.ReadPixels(new Rect(0, 0, atlasPixelWidth, atlasPixelHeight), 0, 0); RenderTexture.active = pastActive; texture.Apply(); //make basic box out of four trinagles, to be able to pinch the top/bottom/middle to cut extra transparent pixels //still not sure how this works but it connects vertices to make the mesh indices[0] = 4; indices[1] = 3; indices[2] = 0; indices[3] = 1; indices[4] = 4; indices[5] = 0; indices[6] = 5; indices[7] = 4; indices[8] = 1; indices[9] = 2; indices[10] = 5; indices[11] = 1; //set vertices positions on mesh vertices[0].Set(-botWidth / 2 + 0.5f, 0); vertices[1].Set(-midWidth / 2 + 0.5f, 0.5f); vertices[2].Set(-topWidth / 2 + 0.5f, 1); vertices[3].Set(botWidth / 2 + 0.5f, 0); vertices[4].Set(midWidth / 2 + 0.5f, 0.5f); vertices[5].Set(topWidth / 2 + 0.5f, 1); //assign data billboard.SetImageTexCoords(texCoords); billboard.SetIndices(indices); billboard.SetVertices(vertices); billboard.width = objectWidth; billboard.height = objectHeight; billboard.bottom = bottomOffset; //save assets string path; int nameLength = AssetDatabase.GetAssetPath(m_material).Length; //take out ".mat" prefix path = AssetDatabase.GetAssetPath(m_material).Substring(0, nameLength - 4) + ".asset"; AssetDatabase.CreateAsset(billboard, path); path = AssetDatabase.GetAssetPath(m_material).Substring(0, nameLength - 4) + ".png"; byte[] byteArray = texture.EncodeToPNG(); System.IO.File.WriteAllBytes(path, byteArray); Debug.Log("BILLBOARD ASSET COMPLETED: File saved to " + path + ",\n if pressing save in editor breaks billboard, manually assign texture to material"); if (optionalBillboardRenderer != null) { optionalBillboardRenderer.billboard = billboard; } //cleanup / qol things RenderTexture.ReleaseTemporary(renderTex); renderCamera.targetTexture = null; m_material.SetTexture("_MainTex", texture); AssetDatabase.Refresh(); }
public void ExtractXMLTreePrototypeData() { TreeSystemPrototypeData[] data = m_ManagedPrototypes; for (int i = 0; i < data.Length; i++) { TreeSystemPrototypeData d = data[i]; if (d.m_TreePrototype == null) { Log.e("Nothing set for data at index: " + i); continue; } // Get the protorype's billboard asset BillboardRenderer bill = d.m_TreePrototype.GetComponentInChildren <BillboardRenderer>(); BillboardAsset billAsset = bill.billboard; // Set sizes d.m_Size = new Vector3(billAsset.width, billAsset.height, billAsset.bottom); // Parse the XML if (!d.m_TreeBillboardData && m_UseXMLData) { Debug.LogError("We are using XML data and we don't have any custom XML data! Switch 'UseXMLData' off!"); continue; } if (m_UseXMLData) { XmlDocument doc = new XmlDocument(); doc.LoadXml(d.m_TreeBillboardData.text); if (doc["SpeedTreeRaw"]["Billboards"]["Vertical"] == null || doc["SpeedTreeRaw"]["Billboards"]["Horizontal"] == null) { Debug.Log("Missing tree XML data for: " + d.m_TreePrototype.name); } else { // Should be multiple of 4 d.m_VertBillboardUVs = ExtractBillboards(doc["SpeedTreeRaw"]["Billboards"]["Vertical"], true).ToArray(); d.m_HorzBillboardUVs = ExtractBillboards(doc["SpeedTreeRaw"]["Billboards"]["Horizontal"], false).ToArray(); } } else { // TODO: support for non-XML Vector4[] uvs = billAsset.GetImageTexCoords(); // Ussualy 16 d.m_VertBillboardUVs = new Vector2[uvs.Length * 4]; // Just set the first UV's just to have something d.m_HorzBillboardUVs = new Vector2[4]; for (int uvIdx = 0, billUv = 0; uvIdx < uvs.Length; uvIdx++, billUv += 4) { Vector4 extract = uvs[uvIdx]; if (uvIdx == 0) { d.m_HorzBillboardUVs[0] = new Vector2(extract.x, extract.y); d.m_HorzBillboardUVs[1] = new Vector2(extract.x, extract.y) + new Vector2(0, Mathf.Abs(extract.w)); d.m_HorzBillboardUVs[2] = new Vector2(extract.x, extract.y) + new Vector2(-extract.z, Mathf.Abs(extract.w)); d.m_HorzBillboardUVs[3] = new Vector2(extract.x, extract.y) + new Vector2(-extract.z, 0); } // We are rotated if (extract.w < 0) { d.m_VertBillboardUVs[billUv + 0] = new Vector2(extract.x, extract.y); d.m_VertBillboardUVs[billUv + 1] = new Vector2(extract.x, extract.y) + new Vector2(0, Mathf.Abs(extract.w)); d.m_VertBillboardUVs[billUv + 2] = new Vector2(extract.x, extract.y) + new Vector2(-extract.z, Mathf.Abs(extract.w)); d.m_VertBillboardUVs[billUv + 3] = new Vector2(extract.x, extract.y) + new Vector2(-extract.z, 0); } else { d.m_VertBillboardUVs[billUv + 0] = new Vector2(extract.x, extract.y); d.m_VertBillboardUVs[billUv + 1] = new Vector2(extract.x, extract.y) + new Vector2(extract.z, 0); d.m_VertBillboardUVs[billUv + 2] = new Vector2(extract.x, extract.y) + new Vector2(extract.z, extract.w); d.m_VertBillboardUVs[billUv + 3] = new Vector2(extract.x, extract.y) + new Vector2(0, extract.w); } } } Vector4 size = d.m_Size; size.w = 1; // Create the material with the texture references Material billboardMaterialBatch = new Material(m_BillboardShaderBatch); billboardMaterialBatch.SetTexture("_MainTex", bill.billboard.material.GetTexture("_MainTex")); billboardMaterialBatch.SetTexture("_BumpMap", bill.billboard.material.GetTexture("_BumpMap")); billboardMaterialBatch.SetVector("_Size", size); Material billboardMaterialMaster = new Material(m_BillboardShaderMaster); billboardMaterialMaster.SetTexture("_MainTex", bill.billboard.material.GetTexture("_MainTex")); billboardMaterialMaster.SetTexture("_BumpMap", bill.billboard.material.GetTexture("_BumpMap")); billboardMaterialMaster.SetVector("_Size", size); // Replace, don't delete // AssetDatabase.DeleteAsset(m_DataStorePath + "/" + d.m_TreePrototype.name + "_Mat.mat"); AssetDatabase.CreateAsset(billboardMaterialBatch, m_DataStorePath + "/" + d.m_TreePrototype.name + "_Bill_Batch_Mat.mat"); AssetDatabase.CreateAsset(billboardMaterialMaster, m_DataStorePath + "/" + d.m_TreePrototype.name + "_Bill_Master_Mat.mat"); // Set the material d.m_BillboardBatchMaterial = billboardMaterialBatch; d.m_BillboardMasterMaterial = billboardMaterialMaster; // Set billboard data TreeSystem.SetMaterialBillProps(d, d.m_BillboardBatchMaterial); TreeSystem.SetMaterialBillProps(d, d.m_BillboardMasterMaterial); } AssetDatabase.Refresh(); }
private void DrawInstanced(int prototypeIndex) { GTreePrototype proto = prototypes[prototypeIndex]; Mesh mesh = proto.sharedMesh; Material[] materials = proto.sharedMaterials; int submeshCount = prototypeCache[prototypeIndex].subMeshCount; int drawCount = Mathf.Min(submeshCount, materials.Length); Mesh billboardMesh = null; Material billboardMaterial = null; BillboardAsset billboard = proto.billboard; if (billboard != null) { billboardMesh = GBillboardUtilities.GetMesh(billboard); billboardMaterial = billboard.material; } bool canDrawInstanced = prototypeCache[prototypeIndex].canDrawInstanced; bool canDrawBillboardInstanced = prototypeCache[prototypeIndex].canDrawBillboardInstanced; batchInstanceCount = 0; billboardBatchInstanceCount = 0; int count = instancePrototypeIndices.Length; for (int i = 0; i <= count; ++i) { if (i == count || batchInstanceCount == BATCH_MAX_INSTANCE_COUNT) { if (canDrawInstanced) { for (int d = 0; d < drawCount; ++d) { Graphics.DrawMeshInstanced( mesh, d, materials[d], batchContainer, batchInstanceCount, null, proto.shadowCastingMode, proto.receiveShadow, proto.layer, camera, LightProbeUsage.BlendProbes); } batchInstanceCount = 0; } } if (i == count || billboardBatchInstanceCount == BATCH_MAX_INSTANCE_COUNT) { if (billboard != null && canDrawBillboardInstanced) { Graphics.DrawMeshInstanced( billboardMesh, 0, billboardMaterial, billboardBatchContainer, billboardBatchInstanceCount, null, proto.billboardShadowCastingMode, proto.BillboardReceiveShadow, proto.layer, camera, LightProbeUsage.BlendProbes); billboardBatchInstanceCount = 0; } } if (i == count) { break; } if (instanceCullResults[i] == CULLED) { continue; } if (instancePrototypeIndices[i] != prototypeIndex) { continue; } if (instanceCullResults[i] == VISIBLE) { if (canDrawInstanced) { batchContainer[batchInstanceCount] = instanceTransforms[i]; batchInstanceCount += 1; } else { for (int d = 0; d < drawCount; ++d) { Graphics.DrawMesh( mesh, instanceTransforms[i], materials[d], proto.layer, camera, d, null, proto.shadowCastingMode, proto.receiveShadow, null, LightProbeUsage.BlendProbes, null); } } } else if (instanceCullResults[i] == BILLBOARD && billboard != null) { if (canDrawBillboardInstanced) { billboardBatchContainer[billboardBatchInstanceCount] = instanceTransforms[i]; billboardBatchInstanceCount += 1; } else { Graphics.DrawMesh( billboardMesh, instanceTransforms[i], billboardMaterial, proto.layer, camera, 0, null, proto.billboardShadowCastingMode, proto.BillboardReceiveShadow, null, LightProbeUsage.BlendProbes, null); } } } }
private void MakePreviewMesh(Mesh mesh, BillboardAsset billboard) {