예제 #1
0
        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);
        }
예제 #2
0
        public static void PrepareRenderTexture(ref RenderTexture rt, GBillboardCreatorArgs args)
        {
            int width  = args.Column * args.CellSize;
            int height = args.Row * args.CellSize;

            if (args.Mode == GBillboardRenderMode.Flipbook)
            {
                width  = args.CellSize;
                height = args.CellSize;
            }

            int depth = 16;
            RenderTextureFormat format = args.Mode == GBillboardRenderMode.Normal ? RenderTextureFormat.ARGBFloat : RenderTextureFormat.ARGB32;

            if (rt == null ||
                rt.width != width ||
                rt.height != height ||
                rt.depth != depth ||
                rt.format != format)
            {
                if (rt != null)
                {
                    rt.Release();
                }
                rt = new RenderTexture(width, height, depth, format, RenderTextureReadWrite.Linear);
            }
        }
예제 #3
0
        private void RenderPreview()
        {
            GBillboardCreatorArgs args = ConstructArgs();

            GBillboardCreator.PrepareRenderTexture(ref previewRt, args);
            GBillboardCreator.RenderPreview(previewRt, args);
        }
예제 #4
0
        private static void RenderPreviewFlipbook(RenderTexture rt, GBillboardCreatorArgs args)
        {
            Clear(rt, Color.clear);

            if (args.AtlasMaterial == null)
            {
                return;
            }
            args.Mode = GBillboardRenderMode.Flipbook;

            Camera cam = CreatePreviewCamera(args);

            cam.targetTexture = rt;
            GameObject g = CreatePreviewGameObject(cam.transform, args);

            int   imageCount = args.Row * args.Column;
            float angleStep  = 360f / imageCount;

            g.transform.rotation = Quaternion.Euler(0, args.CellIndex * angleStep, 0);
            cam.rect             = new Rect(0, 0, 1, 1);
            cam.Render();

            cam.targetTexture = null;
            GUtilities.DestroyGameobject(cam.gameObject);
            GUtilities.DestroyGameobject(g);
        }
예제 #5
0
        private GBillboardCreatorArgs ConstructArgs()
        {
            GBillboardCreatorArgs args = new GBillboardCreatorArgs();

            args.Mode           = mode;
            args.Target         = target;
            args.Row            = row;
            args.Column         = column;
            args.CellSize       = cellSize;
            args.CameraOffset   = cameraOffset;
            args.CameraSize     = cameraSize;
            args.AtlasMaterial  = atlasMaterial;
            args.NormalMaterial = normalMaterial;
            args.SrcColorProps  = srcColorProps;
            //args.DesColorProps = desColorProps;
            args.DesColorProps   = "_Color";
            args.SrcTextureProps = srcTextureProps;
            //args.DesTextureProps = desTextureProps;
            args.DesTextureProps = "_MainTex";
            args.CellIndex       = cellIndex % (args.Row * args.Column);
            args.Vertices        = vertices.ToArray();
            args.Width           = width;
            args.Height          = height;
            args.Bottom          = bottom;

            return(args);
        }
예제 #6
0
 public static void RenderPreview(RenderTexture rt, GBillboardCreatorArgs args)
 {
     if (args.Mode == GBillboardRenderMode.Atlas)
     {
         RenderPreviewAtlas(rt, args);
     }
     else if (args.Mode == GBillboardRenderMode.Normal)
     {
         RenderPreviewNormal(rt, args);
     }
     else if (args.Mode == GBillboardRenderMode.Flipbook)
     {
         RenderPreviewFlipbook(rt, args);
     }
 }
예제 #7
0
        public static Texture2D RenderNormal(GBillboardCreatorArgs args)
        {
            args.Mode = GBillboardRenderMode.Normal;
            RenderTexture rt = null;

            PrepareRenderTexture(ref rt, args);
            RenderPreviewNormal(rt, args);
            Texture2D atlas = new Texture2D(rt.width, rt.height, TextureFormat.ARGB32, true, true);

            GCommon.CopyFromRT(atlas, rt);
            rt.Release();
            GUtilities.DestroyObject(rt);
            atlas.name = args.Target.name + "_Normal";
            return(atlas);
        }
예제 #8
0
        private void DrawUtilities()
        {
            string label = "Utilites";
            string id    = "billboardeditor-utilities";

            GEditorCommon.Foldout(label, false, id, () =>
            {
                Rect fitButtonRect = EditorGUILayout.GetControlRect();
                if (GUI.Button(fitButtonRect, "Fit Camera"))
                {
                    GBillboardCreatorArgs args = GBillboardCreator.FitCameraToTarget(ConstructArgs());
                    CopyArgs(args);
                }
            });
        }
예제 #9
0
        private void DrawTargetSettings()
        {
            string label = "Target";
            string id    = "billboardeditor-target";

            GEditorCommon.Foldout(label, false, id, () =>
            {
                EditorGUI.BeginChangeCheck();
                target = EditorGUILayout.ObjectField("Prefab", target, typeof(GameObject), true) as GameObject;
                if (EditorGUI.EndChangeCheck())
                {
                    GBillboardCreatorArgs args = GBillboardCreator.FitCameraToTarget(ConstructArgs());
                    CopyArgs(args);
                    RefreshMaterialPropsSuggestions();
                }
            });
        }
예제 #10
0
        private static Camera CreatePreviewCamera(GBillboardCreatorArgs args)
        {
            GameObject previewCam = new GameObject("~BillboardEditorCam");

            //previewCam.hideFlags = HideFlags.HideAndDontSave;
            previewCam.transform.position   = -Vector3.one * 10000;
            previewCam.transform.rotation   = Quaternion.identity;
            previewCam.transform.localScale = Vector3.one;

            Camera cam = previewCam.AddComponent <Camera>();

            cam.orthographic     = true;
            cam.orthographicSize = args.CameraSize;
            cam.clearFlags       = CameraClearFlags.SolidColor;
            cam.backgroundColor  = args.Mode == GBillboardRenderMode.Normal ? new Color(0.5f, 0.5f, 1f, 1f) : Color.clear;
            cam.depth            = -1000;
            cam.aspect           = 1;
            cam.enabled          = false;
            return(cam);
        }
예제 #11
0
        private static void RenderPreviewAtlas(RenderTexture rt, GBillboardCreatorArgs args)
        {
            Clear(rt, Color.clear);

            if (args.AtlasMaterial == null)
            {
                return;
            }
            args.Mode = GBillboardRenderMode.Atlas;

            Vector2       viewPortSize     = new Vector2(1f / args.Column, 1f / args.Row);
            Vector2       viewPortPosition = new Vector2(0, 0);
            RenderTexture tempRt           = new RenderTexture(Mathf.RoundToInt(viewPortSize.x * rt.width), Mathf.RoundToInt(viewPortSize.y * rt.height), 24, RenderTextureFormat.ARGB32, RenderTextureReadWrite.Linear);
            Camera        cam = CreatePreviewCamera(args);

            cam.targetTexture = tempRt;
            GameObject g = CreatePreviewGameObject(cam.transform, args);

            int   imageCount = args.Row * args.Column;
            float angleStep  = 360f / imageCount;

            for (int y = 0; y < args.Row; ++y)
            {
                for (int x = 0; x < args.Column; ++x)
                {
                    Clear(tempRt, Color.clear);
                    g.transform.rotation = Quaternion.Euler(0, GUtilities.To1DIndex(x, y, args.Column) * angleStep - 90, 0);
                    cam.Render();

                    viewPortPosition = new Vector2(x * viewPortSize.x, y * viewPortSize.y);
                    GCommon.DrawTexture(rt, tempRt, new Rect(viewPortPosition, viewPortSize), GInternalMaterials.UnlitTransparentMaterial);
                }
            }

            cam.targetTexture = null;
            GUtilities.DestroyGameobject(cam.gameObject);
            GUtilities.DestroyGameobject(g);
            tempRt.Release();
            GUtilities.DestroyObject(tempRt);
        }
예제 #12
0
 private void CopyArgs(GBillboardCreatorArgs args)
 {
     mode            = args.Mode;
     target          = args.Target;
     row             = args.Row;
     column          = args.Column;
     cellSize        = args.CellSize;
     cameraOffset    = args.CameraOffset;
     cameraSize      = args.CameraSize;
     atlasMaterial   = args.AtlasMaterial;
     normalMaterial  = args.NormalMaterial;
     srcColorProps   = args.SrcColorProps;
     desColorProps   = args.DesColorProps;
     srcTextureProps = args.SrcTextureProps;
     desTextureProps = args.DesTextureProps;
     cellIndex       = args.CellIndex;
     vertices        = new List <Vector2>(args.Vertices);
     width           = args.Width;
     height          = args.Height;
     bottom          = args.Bottom;
     tris            = GBillboardCreator.Triangulate(vertices.ToArray());
 }
예제 #13
0
        public static GBillboardCreatorArgs FitCameraToTarget(GBillboardCreatorArgs args)
        {
            if (args.Target == null)
            {
                return(args);
            }
            Renderer[] renderers = args.Target.GetComponentsInChildren <Renderer>();

            if (renderers.Length > 0)
            {
                Bounds b = new Bounds();
                b.SetMinMax(
                    renderers[0].bounds.min,
                    renderers[0].bounds.max);
                for (int i = 1; i < renderers.Length; ++i)
                {
                    Bounds bi = renderers[i].bounds;
                    b.Encapsulate(bi.min);
                    b.Encapsulate(bi.max);
                }
                b.Encapsulate(args.Target.transform.position);

                Vector3 center = args.Target.transform.position;
                float   dWidth = 2 * Mathf.Max(
                    Vector3.Distance(center, new Vector3(b.min.x, center.y, b.min.z)),
                    Vector3.Distance(center, new Vector3(b.max.x, center.y, b.max.z)));
                float dHeight = b.size.y;
                float bottom  = b.min.y - center.y;
                args.CameraSize   = Mathf.Max(dWidth, dHeight) * 0.5f;
                args.CameraOffset = -(b.center - center) + Vector3.forward * dWidth * 2;

                args.Height = dHeight - bottom;
                args.Bottom = bottom;
                args.Width  = dHeight;
            }
            return(args);
        }
예제 #14
0
        private static GameObject CreatePreviewGameObject(Transform cameraTransform, GBillboardCreatorArgs args)
        {
            if (args.Target == null)
            {
                return(new GameObject("~EmptyBillboardCreatorTarget"));
            }
            GameObject g = GameObject.Instantiate(args.Target) as GameObject;

            g.name = "~BillboardCreatorTarget";
            //g.hideFlags = HideFlags.HideAndDontSave;
            g.transform.position   = cameraTransform.transform.TransformPoint(args.CameraOffset);
            g.transform.rotation   = cameraTransform.rotation;
            g.transform.localScale = Vector3.one;

            Material baseMaterial = args.Mode == GBillboardRenderMode.Normal ? args.NormalMaterial : args.AtlasMaterial;

            MeshRenderer[] renderers = g.GetComponentsInChildren <MeshRenderer>();
            for (int i = 0; i < renderers.Length; ++i)
            {
                Material[] sharedMaterials = renderers[i].sharedMaterials;
                for (int j = 0; j < sharedMaterials.Length; ++j)
                {
                    //Material mat = Object.Instantiate<Material>(baseMaterial);
                    Material mat = new Material(baseMaterial.shader);
                    mat.SetColor(args.DesColorProps, Color.white);
                    mat.SetTexture(args.DesTextureProps, null);
                    //mat.CopyPropertiesFromMaterial(sharedMaterials[j]);
                    try
                    {
                        if (sharedMaterials[j].HasProperty(args.SrcColorProps))
                        {
                            Color color = sharedMaterials[j].GetColor(args.SrcColorProps);
                            color.a = 1;
                            if (mat.HasProperty(args.DesColorProps))
                            {
                                mat.SetColor(args.DesColorProps, color);
                            }
                        }
                        else
                        {
                            if (mat.HasProperty(args.DesColorProps))
                            {
                                mat.SetColor(args.DesColorProps, Color.white);
                            }
                        }
                    }
                    catch { }

                    try
                    {
                        if (sharedMaterials[j].HasProperty(args.SrcTextureProps))
                        {
                            Texture tex = sharedMaterials[j].GetTexture(args.SrcTextureProps);
                            if (mat.HasProperty(args.DesTextureProps))
                            {
                                mat.SetTexture(args.DesTextureProps, tex);
                            }
                        }
                    }
                    catch { }

                    sharedMaterials[j] = mat;
                }
                renderers[i].sharedMaterials = sharedMaterials;
            }

            return(g);
        }
예제 #15
0
        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();
        }