Exemple #1
0
        private GameObject CreateLODModels()
        {
            GameObject  retn     = new GameObject("Detail Root");
            BoxCollider collider = retn.AddComponent <BoxCollider>();

            collider.size = model.GetBoundingBoxSize();

            for (int i = 0; i < model.DetailLevels; i++)
            {
                SubObject  subObject = model.GetDetailLevel(i);
                GameObject go        = CreateRenderableGameObject(subObject);
                go.transform.parent = retn.transform;
            }

            if (model.DetailLevels > 1)
            {
                LODGroup lodGroup = retn.AddComponent <LODGroup>();
                LOD[]    lods     = new LOD[model.DetailLevels];

                for (int i = 0; i < model.DetailLevels; i++)
                {
                    lods[i] = new LOD(1f / (i + 1), retn.transform.GetChild(i).GetComponents <Renderer>());
                }

                lodGroup.SetLODs(lods);
                lodGroup.RecalculateBounds();
            }

            return(retn);
        }
Exemple #2
0
    void Start()
    {
        group = gameObject.AddComponent <LODGroup>();
        LOD[] lods = new LOD[4];
        int   i    = 0;

        while (i < 4)
        {
            PrimitiveType primType = PrimitiveType.Cube;
            if (i == 1)
            {
                primType = PrimitiveType.Capsule;
            }
            if (i == 2)
            {
                primType = PrimitiveType.Sphere;
            }
            if (i == 3)
            {
                primType = PrimitiveType.Cylinder;
            }
            GameObject go = GameObject.CreatePrimitive(primType);
            go.transform.parent = gameObject.transform;
            Renderer[] renderers = new Renderer[1];
            renderers[0] = go.renderer;
            lods[i]      = new LOD(1.0F / (i + 1), renderers);
            i++;
        }
        group.SetLODS(lods);
        group.RecalculateBounds();
    }
Exemple #3
0
    void SetCullingPercents()
    {
        if (cullPercent > 1.0f)
        {
            cullPercent = 1.0f;
        }
        if (cullPercent < 0.0f)
        {
            cullPercent = 0.0f;
        }

        if (Selection.objects == null)
        {
            Debug.Log("Nothing Selected!");
            return;
        }

        foreach (GameObject g in Selection.objects)
        {
            if (g.GetComponent <LODGroup>() == null)
            {
                return;
            }
            LODGroup group = g.GetComponent <LODGroup>();

            LOD[]      lods      = group.GetLODs();
            Renderer[] renderers = lods[0].renderers;
            lods[0] = new LOD(cullPercent, renderers);
            group.SetLODs(lods);
            group.RecalculateBounds();
        }
    }
Exemple #4
0
        public static void ConfigureLODGroup(LODGroup lodGroup, LOD[] lodList)
        {
            if (EP.useEditorUndo)
            {
                Undo.RecordObject(lodGroup.gameObject, "Configure LODGroup");
            }

            // Configure all transition fractions
            for (int f = 0; f < lodList.Length; ++f)
            {
                lodList[f].screenRelativeTransitionHeight = screenRelativeTransitionHeight(f, lodList.Length);
            }

            // Configure crossfade relative to transition fractions
            // NOTE: Final transition is to culled rendering
            lodGroup.fadeMode           = LODFadeMode.CrossFade;
            lodGroup.animateCrossFading = false;
            for (int f = 0; f < lodList.Length; ++f)
            {
                var lastHeight = f - 1 >= 0 ? lodList[f - 1].screenRelativeTransitionHeight : 1f;
                var thisHeight = lodList[f].screenRelativeTransitionHeight;
                var nextHeight = f + 1 < lodList.Length ? lodList[f + 1].screenRelativeTransitionHeight : 0f;
                lodList[f].fadeTransitionWidth = fadeTransitionWidth * (thisHeight - nextHeight) / (lastHeight - thisHeight);
                // fadeTransitionWidth is entirely in this LoD, but is proportionate to the next LoD.
                // This is important for culling, which should not begin until within fadeTransitionWidth of the culling height
            }

            lodGroup.SetLODs(lodList);
            lodGroup.RecalculateBounds();
        }
Exemple #5
0
    static int RecalculateBounds(IntPtr L)
    {
        LuaScriptMgr.CheckArgsCount(L, 1);
        LODGroup obj = LuaScriptMgr.GetNetObject <LODGroup>(L, 1);

        obj.RecalculateBounds();
        return(0);
    }
Exemple #6
0
 public static void CalculateLODGroupBoundingBox(LODGroup group)
 {
     if (group == null)
     {
         throw new ArgumentNullException("group");
     }
     group.RecalculateBounds();
 }
Exemple #7
0
    void AddLODGroupForTransform(Transform target)
    {
        LODGroup lodGroup = target.gameObject.AddComponent <LODGroup>();

        LOD[] lods = LODChildCount(target);
        lodGroup.SetLODS(lods);
        lodGroup.RecalculateBounds();
    }
        //Install LOD information
        void InstallLods()
        {
            if (this.transform == null || this.transform.childCount == 0)
            {
                return;
            }
            Transform baseTurrel = this.transform.GetChild(0);

            if (baseTurrel != null)
            {
                LODGroup oldLod = baseTurrel.gameObject.GetComponent <LODGroup>();
                if (oldLod == null)
                {
                    LODGroup   lod   = baseTurrel.gameObject.AddComponent <LODGroup>();
                    Renderer[] rends = baseTurrel.gameObject.GetComponentsInChildren <Renderer>();
                    List <List <Renderer> > renderers = new List <List <Renderer> >();
                    for (int i = 0; i < rends.Length; i++)
                    {
                        string curName = rends[i].gameObject.name;
                        if (curName[curName.Length - 1] == ')')
                        {
                            string cuting = "(Clone)";
                            curName = curName.Replace(cuting, "");
                        }
                        int lodGroup = -1;
                        if (int.TryParse(curName[curName.Length - 1].ToString(), out lodGroup))
                        {
                            if (renderers.Count <= lodGroup + 1)
                            {
                                for (int j = 0; j < lodGroup + 1 - renderers.Count; j++)
                                {
                                    renderers.Add(new List <Renderer>());
                                }
                            }
                            renderers[lodGroup].Add(rends[i]);
                        }
                    }

                    LOD[] lods = new LOD[renderers.Count];
                    for (int i = 0; i < lods.Length; i++)
                    {
                        lods[i].renderers = renderers[i].ToArray();
                        float x = 10f / lods.Length * (i + 1);
                        if (i < lods.Length * 0.5f)
                        {
                            lods[i].screenRelativeTransitionHeight = (-1.5f * x + 10f) / 10f + 0.02f;
                        }
                        else
                        {
                            lods[i].screenRelativeTransitionHeight = (-0.5f * x + 5f) / 10f + 0.02f;
                        }
                    }

                    lod.SetLODs(lods);
                    lod.RecalculateBounds();
                }
            }
        }
Exemple #9
0
        public bool PostBuild(int lodIndex, Mesh visualMesh, Mesh collisionMesh, ChunkTriggerBounds bounds)
        {
            var hasVisualMesh = chunks[lodIndex].PostBuild(visualMesh, collisionMesh, bounds);

            if (LODCount > 1)
            {
                lodGroup.RecalculateBounds();
            }

            return(hasVisualMesh);
        }
            private void Update()
            {
                ReEnableForcedDisabledLOD();

                //If no LOD was rendered or culled (last LOD level), set controller LOD to lowest level
                if (_currentLODLevel == -1)
                {
                    if (_overrideController.OnLODLevelChanged(-1))
                    {
                        _LODGroup.RecalculateBounds();
                    }
                }
                else
                {
                    //Swith to avatar based on LOD
                    SwitchToAvatar(_overrideController.GetAvatar() ?? _origAvatar);

                    //Reset LOD level
                    _currentLODLevel = -1;
                }
            }
Exemple #11
0
    public void AddIt()
    {
        LODGroup lODGroup = this.gameObject.GetComponent <LODGroup>();

        LOD[] Lods = new LOD[1];

        // Fill up Renderer[] arrays.  This is the list of drawables per LOD level
        Lods[0].renderers = this.GetComponentsInChildren <Renderer>();

        // Make it live!
        lODGroup.SetLODS(Lods);
        lODGroup.RecalculateBounds();
    }
 static void AddMRLG()
 {
     GameObject[] gobs = Selection.gameObjects;
     foreach (GameObject gob in gobs)
     {
         LODGroup g    = gob.AddComponent <LODGroup> ();
         LOD[]    lods = new LOD[1];
         lods [0].screenRelativeTransitionHeight = 0.11f;
         lods [0].renderers = gob.GetComponentsInChildren <Renderer> ();
         g.SetLODs(lods);
         g.RecalculateBounds();
     }
 }
 private void ClearVisibility()
 {
     if (lodGroup != null)
     {
         lodGroup.localReferencePoint = Vector3.zero;
         lodGroup.RecalculateBounds();
         lodGroup = null;
     }
     if (renderers != null)
     {
         renderers.Clear();
     }
     localOccludee = new OccludeeSphere(-1);
 }
Exemple #14
0
    void Start()
    {
        // Programmatically create a LOD group and add LOD levels.
        // Create a GUI that allows for forcing a specific LOD level.
        group = gameObject.GetComponent <LODGroup>();

        // Add 4 LOD levels
        LOD[] lods = new LOD[3];
        for (int i = 0; i < group.lodCount; i++)
        {
            PrimitiveType primType = PrimitiveType.Cube;
            switch (i)
            {
            case 1:
                primType = PrimitiveType.Capsule;
                break;

            case 2:
                primType = PrimitiveType.Sphere;
                break;

            case 3:
                primType = PrimitiveType.Cylinder;
                break;
            }
            GameObject go = GameObject.CreatePrimitive(primType);
            go.transform.parent = gameObject.transform;
            Renderer[] renderers = new Renderer[1];
            renderers[0] = go.GetComponent <Renderer>();
            float screenRelativeTransitionHeight = 1f;

            switch (i)
            {
            case 1:
                screenRelativeTransitionHeight = 0.25f;
                break;

            case 2:
                screenRelativeTransitionHeight = 0.05f;
                break;

            case 3:
                screenRelativeTransitionHeight = 0.02f;
                break;
            }
            lods[i] = new LOD(screenRelativeTransitionHeight, renderers);
        }
        group.SetLODs(lods);
        group.RecalculateBounds();
    }
        private void SavePrefabs(Mesh[,,] generatedMeshes, GrassBakeSettings grassBakeSettings, string path)
        {
            GameObject topParentObject = new GameObject();
            Vector2    tileSize        = grassBakeSettings.extents / grassBakeSettings.numTiles;

            for (int x = 0; x < generatedMeshes.GetLength(0); ++x)
            {
                for (int y = 0; y < generatedMeshes.GetLength(1); ++y)
                {
                    GameObject tileParentObject = new GameObject();
                    tileParentObject.transform.parent = topParentObject.transform;
                    tileParentObject.name             = "Tile" + x + y;

                    LODGroup lodGroup = tileParentObject.AddComponent <LODGroup>();
                    LOD[]    lods     = new LOD[generatedMeshes.GetLength(2)];

                    for (int i = 0; i < generatedMeshes.GetLength(2); ++i)
                    {
                        GameObject generatedGrass = new GameObject();
                        generatedGrass.name = "" + x + y + "_LOD" + i;
                        generatedGrass.transform.position = new Vector3(
                            x * tileSize.x - generatedMeshes.GetLength(0) * tileSize.x / 2f,
                            0f,
                            y * tileSize.y - generatedMeshes.GetLength(1) * tileSize.y / 2f);

                        MeshFilter meshFilter = generatedGrass.AddComponent <MeshFilter>();
                        meshFilter.sharedMesh = generatedMeshes[x, y, i];

                        MeshRenderer meshRenderer = generatedGrass.AddComponent <MeshRenderer>();
                        meshRenderer.sharedMaterial = grassBakeSettings.grassLODLevelSettings[i].grassMaterial;

                        generatedGrass.transform.parent = tileParentObject.transform;

                        Renderer[] renderers = new Renderer[1];
                        renderers[0] = meshRenderer;
                        lods[i]      = new LOD(grassBakeSettings.grassLODLevelSettings[i].lodPercent, renderers);
                    }

                    lodGroup.SetLODs(lods);
                    lodGroup.RecalculateBounds();
                }
            }

            PrefabUtility.SaveAsPrefabAsset(topParentObject, path);

            DestroyImmediate(topParentObject);

            AssetDatabase.SaveAssets();
        }
 static void AddBridgeLG()
 {
     GameObject[] gobs = Selection.gameObjects;
     foreach (GameObject gob in gobs)
     {
         Renderer        r    = gob.GetComponent <Renderer> ();
         LODGroup        g    = gob.AddComponent <LODGroup> ();
         List <Renderer> list = new List <Renderer> ();
         gob.GetComponentsInChildren <Renderer> (true, list);
         LOD[] lods = new LOD[1];
         lods [0].screenRelativeTransitionHeight = 0.4f;
         list.Remove(r);
         lods [0].renderers = list.ToArray();
         g.SetLODs(lods);
         g.RecalculateBounds();
     }
 }
    public static int RecalculateBounds(IntPtr l)
    {
        int result;

        try
        {
            LODGroup lodgroup = (LODGroup)LuaObject.checkSelf(l);
            lodgroup.RecalculateBounds();
            LuaObject.pushValue(l, true);
            result = 1;
        }
        catch (Exception e)
        {
            result = LuaObject.error(l, e);
        }
        return(result);
    }
Exemple #18
0
        bool IncludeLODGroup(LODGroup lodGroup, GDOC_ManagementMode mode, GDOC_UpdateMode movementMode = GDOC_UpdateMode.Static, GDOC_Occludee parentOccludee = null)
        {
            var e = lodGroup.gameObject.AddComponent <GDOC_Occludee>();

            lodGroup.RecalculateBounds();

            e.mode           = GDOC_OccludeeMode.MeshRendererGroup;
            e.movementMode   = movementMode;
            e.isTemporary    = true;
            e.managementMode = mode;

            e.GrabLODGroupRenderers();

            e.Init();

            e.isImportant = e.volumeSizeSqr > 2;

            AddOccludee(e, parentOccludee);

            return(false);
        }
Exemple #19
0
    void AddLODs()
    {
        if (cullPercent > 1.0f)
        {
            cullPercent = 1.0f;
        }
        if (cullPercent < 0.0f)
        {
            cullPercent = 0.0f;
        }

        if (Selection.objects == null)
        {
            Debug.Log("Nothing Selected!");
            return;
        }

        foreach (GameObject g in Selection.objects)
        {
            if (g.GetComponent <LODGroup>() == null)
            {
                g.AddComponent <LODGroup>();
            }
            else
            {
                return;
            }
            LODGroup group = g.GetComponent <LODGroup>();
            LOD[]    lods  = new LOD[1];

            //Renderer[] renderers = new Renderer[1];
            //renderers[0] = g.transform.GetComponent<Renderer>();
            Renderer[] renderers = g.transform.GetComponentsInChildren <Renderer>();

            lods[0] = new LOD(cullPercent, renderers);
            group.SetLODs(lods);
            group.RecalculateBounds();
        }
    }
Exemple #20
0
        public void MergeMeshes()
        {
            MeshFilter[]      meshFilters = GetComponentsInChildren <MeshFilter>();
            CombineInstance[] combine     = new CombineInstance[meshFilters.Length - 1];

            int index = 0;

            for (int i = 0; i < meshFilters.Length; i++)
            {
                if (meshFilters[i].sharedMesh != null)
                {
                    // if (meshFilters[i].sharedMesh == null) continue;
                    combine[index].mesh        = meshFilters[i].sharedMesh;
                    combine[index++].transform = meshFilters[i].transform.localToWorldMatrix;
                }
            }
            MeshFilter meshF = transform.GetComponent <MeshFilter>();

            meshF.sharedMesh      = new Mesh();
            meshF.sharedMesh.name = "lightpoles";
            meshF.sharedMesh.CombineMeshes(combine);
            meshF.sharedMesh.RecalculateBounds();
            if (lodGroup != null)
            {
                lodGroup.RecalculateBounds();
            }

            //    transform.gameObject.SetActive(true);
            foreach (Transform go in gameObject.transform.Cast <Transform>().Reverse())
            {
                DestroyImmediate(go.gameObject);
            }

            MeshCollider mColl = gameObject.GetComponent <MeshCollider>();

            mColl.sharedMesh = meshF.sharedMesh;
        }
Exemple #21
0
    void Start()
    {
        // Programmatically create a LOD group and add LOD levels.
        // Create a GUI that allows for forcing a specific LOD level.
        group = gameObject.AddComponent <LODGroup> ();

        // Add 4 LOD levels
        LOD[] lods = new LOD[4];
        for (int i = 0; i < 4; i++)
        {
            PrimitiveType primType = PrimitiveType.Cube;
            switch (i)
            {
            case 1:
                primType = PrimitiveType.Capsule;
                break;

            case 2:
                primType = PrimitiveType.Sphere;
                break;

            case 3:
                primType = PrimitiveType.Cylinder;
                break;
            }
            GameObject go = GameObject.CreatePrimitive(primType);
            go.transform.parent = gameObject.transform;
            Renderer[] renderers = new Renderer[1];
            renderers[0] = go.GetComponent <Renderer> ();
            float v = 1.0F / (i + 1);
            lods[i] = new LOD(v, renderers);
            Debug.Log(i + " screenrelative transition height: " + v);
        }
        group.SetLODs(lods);
        group.RecalculateBounds();
    }
Exemple #22
0
        private static void ParseFile_SceneShapesAttributes(XmlReader xml, ref I3DModel model, Entity part)
        {
            Entity.ShapeType type;
            if (!Enum.TryParse(xml.LocalName, out type))
            {
                throw new Exception($"Unrecognized shape type {xml.LocalName}");
            }
            part.Type = type;

            string name = ParseString(xml.GetAttribute("name"));

            //I3DTransform
            I3DTransform t = part.gameObject.AddComponent <I3DTransform>();

            t.Name            = name;
            t.Id              = ParseInt(xml.GetAttribute("nodeId"));
            t.IndexPath       = ""; //TODO: Make this
            t.Visibility      = ParseBool(xml.GetAttribute("visibility"), true);
            t.ClipDistance    = ParseInt(xml.GetAttribute("clipDistance"), 1000000);
            t.MinClipDistance = ParseInt(xml.GetAttribute("minClipDistance"));
            t.ObjectMask      = ParseInt(xml.GetAttribute("objectMask"), 0xffff);
            t.LOD             = ParseBool(xml.GetAttribute("lodDistance"));

            //Transform
            part.gameObject.transform.localPosition    = ParseVector3(xml.GetAttribute("translation"));
            part.gameObject.transform.localEulerAngles = ParseVector3(xml.GetAttribute("rotation"));
            Vector3 scale = xml.GetAttribute("scale") != null?ParseVector3(xml.GetAttribute("scale")) : Vector3.one;

            //scale.x *= -1;
            part.gameObject.transform.localScale = scale;

            //Rigidbody
            bool bStatic    = ParseBool(xml.GetAttribute("static"));
            bool bDynamic   = ParseBool(xml.GetAttribute("dynamic"));
            bool bKinematic = ParseBool(xml.GetAttribute("kinematic"));

            if (bStatic || bDynamic || bKinematic)
            {
                t.RigidBody = true;

                I3DRigidBody r = part.gameObject.AddComponent <I3DRigidBody>();
                if (bStatic)
                {
                    r.Type = RigidBodyType.Static;
                }
                else if (bDynamic)
                {
                    r.Type = RigidBodyType.Dynamic;
                }
                else
                {
                    r.Type = RigidBodyType.Kinematic;
                }

                r.Compound         = ParseBool(xml.GetAttribute("compound"));
                r.CompoundChild    = ParseBool(xml.GetAttribute("compoundChild"));
                r.Collision        = ParseBool(xml.GetAttribute("collision"), true);
                r.Trigger          = ParseBool(xml.GetAttribute("trigger"));
                r.CollisionMask    = ParseInt(xml.GetAttribute("collisionMask"));
                r.Restitution      = ParseFloat(xml.GetAttribute("restitution"));
                r.StaticFriction   = ParseFloat(xml.GetAttribute("staticFriction"), 0.5f);
                r.DynamicFriction  = ParseFloat(xml.GetAttribute("dynamicFriction"), 0.5f);
                r.LinearDamping    = ParseFloat(xml.GetAttribute("linearDamping"), 0.5f);
                r.AngularDamping   = ParseFloat(xml.GetAttribute("angularDamping"), 0.5f);
                r.Density          = ParseFloat(xml.GetAttribute("density"), 1);
                r.SolverIterations = ParseInt(xml.GetAttribute("solverIterationCount"), 4);
                //r.Mass = ParseFloat(xml.GetAttribute("mass"), 0.5f);
            }

            //Shape
            if (part.Type == Entity.ShapeType.Shape)
            {
                if (name.EndsWith("_lod0") || name.EndsWith("_lod1") || name.EndsWith("_lod2"))
                {
                    Transform parent   = part.transform.parent;
                    LODGroup  lodGroup = parent.GetComponent <LODGroup>();
                    if (lodGroup == null)
                    {
                        lodGroup = parent.gameObject.AddComponent <LODGroup>();
                        lodGroup.SetLODs(new LOD[] {});
                    }

                    int lodIndex = ParseInt(name.Substring(name.Length - 1));

                    LOD lod = new LOD {
                        renderers = new Renderer[] { part.GetComponent <MeshRenderer>() }
                    };

                    List <LOD> lods = lodGroup.GetLODs().ToList();

                    if (lodIndex > lods.Count)
                    {
                        lods.Add(lod);
                    }
                    else
                    {
                        lods.Insert(lodIndex, lod);
                    }

                    // Update the transition point for all LODs
                    float lodGap = 1f / lods.Count;
                    for (int i = 0; i < lods.Count; i++)
                    {
                        lods[i] = new LOD((lods.Count - i - 1) * lodGap, lods[i].renderers);
                    }

                    lodGroup.SetLODs(lods.ToArray());
                    lodGroup.RecalculateBounds();
                }

                Shape s = part.gameObject.AddComponent <Shape>();
                s.ID               = ParseInt(xml.GetAttribute("shapeId"));
                s.CastShadows      = ParseBool(xml.GetAttribute("castsShadows"));
                s.ReceiveShadows   = ParseBool(xml.GetAttribute("receiveShadows"));
                s.NonRenderable    = ParseBool(xml.GetAttribute("nonRenderable"));
                s.BuildNavMeshMask = ParseInt(xml.GetAttribute("buildNavMeshMask"));
                s._Materials       = Shape.ParseMaterialString(ParseString(xml.GetAttribute("materialIds")));

                part.Shape = s;

                //Assign the shape object according to ID
                foreach (I3DShapeData sh in model.ShapeDatas)
                {
                    if (part.Shape.ID != sh.ID)
                    {
                        continue;
                    }

                    part.Shape.ID   = sh.ID;
                    part.Shape.Name = sh.Name;
                    part.Shape.Mesh = sh.Mesh;

                    part.GetComponent <MeshFilter>().mesh = sh.Mesh;
                    break;
                }

                //Assign material according to ID
                part.Shape.Materials = new I3DMaterial[part.Shape._Materials.Length];

                for (int i = 0; i < part.Shape._Materials.Length; i++)
                {
                    int shapeMatId = part.Shape._Materials[i];
                    foreach (I3DMaterial mat in model.Materials)
                    {
                        if (mat.Id != shapeMatId)
                        {
                            continue;
                        }

                        part.Shape.Materials[i] = mat;
                    }
                }
            }
            else if (part.Type == Entity.ShapeType.TerrainTransformGroup)
            {
                int heightMapId = ParseInt(xml.GetAttribute("heightMapId"));
                //int patchSize = ParseInt(xml.GetAttribute("patchSize"));
                float heightScale   = ParseFloat(xml.GetAttribute("heightScale"));
                float unitsPerPixel = ParseFloat(xml.GetAttribute("unitsPerPixel"));

                I3DFile heightMapFile = model.GetFile(heightMapId);
                if (heightMapFile != null)
                {
                    I3DTerrain i3DTerrain = part.gameObject.AddComponent <I3DTerrain>();
                    i3DTerrain.AlphaWidth             = ParseInt(xml.GetAttribute("lodTextureSize"));
                    i3DTerrain.AlphaHeight            = ParseInt(xml.GetAttribute("lodTextureSize"));
                    i3DTerrain.Terrain                = part.gameObject.AddComponent <Terrain>();
                    i3DTerrain.TerrainData            = new TerrainData();
                    i3DTerrain.TerrainCollider        = part.gameObject.AddComponent <TerrainCollider>();
                    i3DTerrain.HeightMapScale         = heightScale;
                    i3DTerrain.HeightMapUnitsPerPixel = unitsPerPixel;
                    i3DTerrain.HeightMap              = TextureLoader.GetTexture(heightMapFile.AbsolutePath);

                    i3DTerrain.BuildHeightmap();
                }
            }
            else if (part.Type == Entity.ShapeType.Layer)
            {
                I3DFile detailMapFile = model.GetFile(ParseInt(xml.GetAttribute("detailMapId"))); // Detail map = diffuse texture
                I3DFile normalMapFile = model.GetFile(ParseInt(xml.GetAttribute("normalMapId"))); // Normal map = normal texture
                I3DFile weightMapFile = model.GetFile(ParseInt(xml.GetAttribute("weightMapId"))); // Weight map = splat map?
                //I3DFile distanceMapFile = model.GetFile(ParseInt(xml.GetAttribute("distanceMapId"))); // Distance map = low-res diffuse texture

                int unitSize = ParseInt(xml.GetAttribute("unitSize"));
                //int distanceMapUnitSize = ParseInt(xml.GetAttribute("distanceMapUnitSize")); // Unknown

                SplatPrototype splat = new SplatPrototype
                {
                    texture    = TextureLoader.GetTexture(detailMapFile.AbsolutePath),
                    normalMap  = TextureLoader.GetTexture(normalMapFile.AbsolutePath),
                    tileSize   = new Vector2(unitSize, unitSize),
                    tileOffset = Vector2.zero
                };

                I3DTerrain i3Dterrain = part.GetComponentInParent <I3DTerrain>();
                i3Dterrain.Layers.Add(new I3DTerrainLayer
                {
                    Priority   = ParseInt(xml.GetAttribute("priority")),
                    Attributes = ParseVector4(xml.GetAttribute("attributes")),
                    SplatMap   = splat,
                    Weights    = I3DTerrainUtil.Parse8BitMap(TextureLoader.GetTexture(weightMapFile.AbsolutePath))
                });
            }
        }
Exemple #23
0
        public void MergeMeshes()
        {
            // else Debug.LogWarning("Please assign rooftop material in CS Rooftops Component");


            MeshFilter[] meshFilters = rooftopHolder.GetComponentsInChildren <MeshFilter>();



            CombineInstance[] combine = new CombineInstance[meshFilters.Length - 1];



            int index = 0;

            for (int i = 0; i < meshFilters.Length; i++)
            {
                if (meshFilters[i].sharedMesh != null)
                {
                    // if (meshFilters[i].sharedMesh == null) continue;
                    combine[index].mesh        = meshFilters[i].sharedMesh;
                    combine[index++].transform = meshFilters[i].transform.localToWorldMatrix;
                }
            }
            MeshFilter meshF = rooftopHolder.transform.GetComponent <MeshFilter>();

            meshF.sharedMesh = new Mesh();
            meshF.sharedMesh.CombineMeshes(combine);

            ///assign new color


            //    Mesh newMesh = new Mesh();
            //    newMesh.vertices = meshF.sharedMesh.vertices;
            //    newMesh.normals = meshF.sharedMesh.normals;
            //    newMesh.uv = meshF.sharedMesh.uv;
            //    newMesh.colors = new Color[meshF.sharedMesh.vertices.Length];
            //    newMesh.triangles = meshF.sharedMesh.triangles;
            //    for (int v = 0; v < newMesh.colors.Length; v++)
            //    {
            //        newMesh.colors[v] = new Color(0, 0, 1, 0);
            //    }

            //meshF.sharedMesh = newMesh;



            meshF.sharedMesh.RecalculateBounds();

            if (lodComponent != null)
            {
                lodComponent.RecalculateBounds();
            }

            foreach (Transform go in rooftopHolder.transform.Cast <Transform>().Reverse())
            {
                DestroyImmediate(go.gameObject);
            }

            if (rooftopHolder.GetComponent <MeshRenderer>() == null)
            {
                rh = rooftopHolder.AddComponent <MeshRenderer>() as MeshRenderer;
                rh = rooftopHolder.GetComponent <MeshRenderer>();
                rh.sharedMaterial = greebleMat;
            }
            rh = rooftopHolder.GetComponent <MeshRenderer>();
            rh.sharedMaterial = greebleMat;
            Renderer[] renderers = new Renderer[1];
            LOD[]      lod       = new LOD[1];
            renderers[0] = rooftopHolder.GetComponent <Renderer>();
            lod[0]       = new LOD(lodDistance, renderers);
            lodComponent.SetLODs(lod);
            if (animateLodFade)
            {
                lodComponent.fadeMode = LODFadeMode.CrossFade;
            }
            else
            {
                lodComponent.fadeMode = LODFadeMode.None;
            }
            lodComponent.animateCrossFading = animateLodFade;

            //if (meshF.sharedMesh.vertices.Length < 3)
            //{
            //    DestroyImmediate(rooftopHolder);
            //    noMesh = true;
            //}
            //else noMesh = false;
        }
Exemple #24
0
        public static void CreateFileForResult(List <Core_Voxel.Result> resultList, Shader[] shaders, string[] shaderKeywords, Vector2[] shaderRemaps, float scale, Vector3 pivot)
        {
            var diffuseShader = shaders[0];

            for (int index = 0; index < resultList.Count; index++)
            {
                var  result     = resultList[index];
                bool lod        = result.VoxelModels.Length > 1;
                bool isRig      = !lod && result.IsRigged;
                int  realLodNum = result.IsRigged ? 1 : result.VoxelModels.Length;

                var         root         = new GameObject(result.FileName).transform;
                var         meshs        = new List <Mesh>();
                var         materialsMap = new Dictionary <Texture2D, Material[]>();
                Transform[] lodRoots     = new Transform[realLodNum];
                for (int lodIndex = 0; lodIndex < realLodNum; lodIndex++)
                {
                    var voxelModel = result.VoxelModels[lodIndex];
                    var model      = CreateModelFrom(voxelModel.RootNode, voxelModel.Materials, root, pivot, ref meshs, ref materialsMap, isRig, result.WithAvatar, shaders, shaderKeywords, shaderRemaps, scale);
                    model.name         = string.Format("Root{0}", lod ? "_lod " + lodIndex.ToString() : "");
                    lodRoots[lodIndex] = model;

                    // Rig
                    if (isRig)
                    {
                        Vector3 halfModelSize = voxelModel.ModelSize[0] * 0.5f;
                        halfModelSize.x = Mathf.Floor(halfModelSize.x);
                        halfModelSize.y = Mathf.Floor(halfModelSize.y);
                        halfModelSize.z = Mathf.Floor(halfModelSize.z);

                        var skinMR = model.GetComponent <SkinnedMeshRenderer>();
                        if (skinMR)
                        {
                            Vector3 rootBoneOffset = halfModelSize * scale;
                            var     boneTFList     = new List <Transform>();
                            if (voxelModel.RootBones != null)
                            {
                                for (int i = 0; i < voxelModel.RootBones.Length; i++)
                                {
                                    var boneTF = CreateBoneTransform(voxelModel.RootBones[i], model, scale, ref boneTFList);
                                    if (boneTF)
                                    {
                                        boneTF.localPosition -= rootBoneOffset;
                                    }
                                }
                            }

                            skinMR.bones    = boneTFList.ToArray();
                            skinMR.rootBone = model;

                            // Bind Poses
                            var poses = new Matrix4x4[boneTFList.Count];
                            for (int i = 0; i < boneTFList.Count; i++)
                            {
                                poses[i] = boneTFList[i].worldToLocalMatrix * model.localToWorldMatrix;
                            }
                            skinMR.sharedMesh.bindposes = poses;
                        }

                        // Foot Fix
                        model.localPosition = (halfModelSize - voxelModel.FootPoints[lodIndex]) * scale;
                    }
                }



                // Lod
                if (lod)
                {
                    LODGroup group = root.gameObject.AddComponent <LODGroup>();
                    LOD[]    lods  = new LOD[realLodNum];
                    for (int i = 0; i < realLodNum; i++)
                    {
                        lods[i] = new LOD(
                            i == realLodNum - 1 ? 0.001f : GetLodRant(result.VoxelModels[i].MaxModelBounds, i),
                            lodRoots[i].GetComponentsInChildren <MeshRenderer>(true)
                            );
                    }
#if UNITY_5_0 || UNITY_5_1 || UNITY_4
                    group.SetLODS(lods);
                    group.RecalculateBounds();
#else
                    group.SetLODs(lods);
                    group.RecalculateBounds();
#endif
                }
                else if (!isRig && root.childCount > 0)
                {
                    var newRoot = root.GetChild(0);
                    newRoot.name = root.name;
                    root         = newRoot;
                }



                // File
                string path = Util.CombinePaths(
                    result.ExportRoot,
                    result.ExportSubRoot,
                    result.FileName + result.Extension
                    );
                path = Util.FixPath(path);
                string parentPath = Util.GetParentPath(path);
                Util.CreateFolder(parentPath);

                if (result.Extension == ".prefab")
                {
                    Object prefab;

                    if (Util.FileExists(path))
                    {
                        prefab = AssetDatabase.LoadAssetAtPath <Object>(path);
                        if (prefab as GameObject)
                        {
                            var group = (prefab as GameObject).GetComponent <LODGroup>();
                            if (group)
                            {
                                Object.DestroyImmediate(group, true);
                            }
                        }
                        Object[] things = AssetDatabase.LoadAllAssetRepresentationsAtPath(path);
                        foreach (Object o in things)
                        {
                            Object.DestroyImmediate(o, true);
                        }
                    }
                    else
                    {
#if UNITY_4 || UNITY_5 || UNITY_2017 || UNITY_2018_1 || UNITY_2018_2
                        prefab = PrefabUtility.CreateEmptyPrefab(path);
#else   // 2018.3+
                        var tempObject = new GameObject();
                        prefab = PrefabUtility.SaveAsPrefabAsset(tempObject, path);
                        Object.DestroyImmediate(tempObject, false);
#endif
                    }

                    if (prefab)
                    {
                        // Assets
                        for (int i = 0; i < meshs.Count; i++)
                        {
                            meshs[i].name = GetIndexedName("Mesh", i, meshs.Count);
                            AssetDatabase.AddObjectToAsset(meshs[i], path);
                        }
                        int currentIndex = 0;
                        foreach (var textureMat in materialsMap)
                        {
                            textureMat.Key.name = GetIndexedName("Texture", currentIndex, materialsMap.Count);
                            AssetDatabase.AddObjectToAsset(textureMat.Key, path);
                            var mats = textureMat.Value;
                            for (int i = 0; i < mats.Length; i++)
                            {
                                mats[i].name = GetIndexedName("Material", currentIndex, materialsMap.Count) + "_" + i.ToString();
                                AssetDatabase.AddObjectToAsset(mats[i], path);
                            }
                            currentIndex++;
                        }

                        // Avatar
                        if (isRig && result.WithAvatar)
                        {
                            var avatar = GetVoxelAvatarInRoot(root);
                            if (avatar)
                            {
                                avatar.name = result.FileName;
                                AssetDatabase.AddObjectToAsset(avatar, path);

                                // Animator
                                var ani = root.GetComponent <Animator>();
                                if (!ani)
                                {
                                    ani = root.gameObject.AddComponent <Animator>();
                                }
                                ani.avatar = avatar;
                            }
                            else
                            {
                                Debug.LogWarning("[Voxel to Unity] Failed to get avatar from the prefab. Use \"+ Human Bones\" button in rig editor to create bones and don\'t change their names and layout.");
                            }
                        }
                        // Prefab
#if UNITY_4 || UNITY_5 || UNITY_2017 || UNITY_2018_1 || UNITY_2018_2
                        PrefabUtility.ReplacePrefab(root.gameObject, prefab, ReplacePrefabOptions.ReplaceNameBased);
#else  // 2018.3+
                        prefab = PrefabUtility.SaveAsPrefabAsset(root.gameObject, path);
#endif
                    }
                }
                else                     // Obj

                {
                    string objFolderPath     = Util.CombinePaths(parentPath, result.FileName);
                    string textureFolderPath = Util.CombinePaths(objFolderPath, "Textures");
                    Util.CreateFolder(objFolderPath);

                    VoxelPostprocessor.TheShader = diffuseShader;

                    // Assets
                    var model = result.VoxelModels[0];
                    for (int modelIndex = 0; modelIndex < model.Meshs.Length; modelIndex++)
                    {
                        string modelIndexedName = GetIndexedName(result.FileName, modelIndex, model.Meshs.Length);
                        string modelPathRoot    = Util.CombinePaths(objFolderPath, modelIndexedName);

                        // Texture
                        string texturePath = Util.CombinePaths(textureFolderPath, modelIndexedName + ".png");
                        texturePath = Util.FixPath(texturePath);
                        var texture = model.Textures[modelIndex];
                        Util.ByteToFile(texture.EncodeToPNG(), texturePath);
                        VoxelPostprocessor.AddTexture(texturePath);

                        // Meshs
                        var uMesh = model.Meshs[modelIndex];
                        for (int i = 0; i < uMesh.Count; i++)
                        {
                            uMesh[i].name = GetIndexedName("Mesh", i, uMesh.Count);
                            string obj     = Util.GetObj(uMesh[i]);
                            string objPath = GetIndexedName(modelPathRoot, i, uMesh.Count) + ".obj";

                            bool hasObjBefore = Util.FileExists(objPath);

                            Util.Write(obj, objPath);
                            VoxelPostprocessor.AddObj(objPath, texturePath);

                            if (hasObjBefore)
                            {
                                AssetDatabase.ImportAsset(Util.FixedRelativePath(objPath), ImportAssetOptions.ForceUpdate);
                            }
                        }
                    }
                }


                // Delete Objects
                if (root.parent)
                {
                    Object.DestroyImmediate(root.parent.gameObject, false);
                }
                else
                {
                    Object.DestroyImmediate(root.gameObject, false);
                }
            }
            AssetDatabase.Refresh(ImportAssetOptions.ForceUpdate);
            AssetDatabase.SaveAssets();
            Resources.UnloadUnusedAssets();

            EditorApplication.delayCall += VoxelPostprocessor.ClearAsset;
        }
    public void SaveAsPrefab(bool groupedSave = false)
    {
        string name = gameObject.name;
        string path = saveTreeFolder;

        if (string.IsNullOrEmpty(path))
        {
            return;
        }

        bool replacePrefab = false;

        if (!System.IO.Directory.Exists(path))
        {
            EditorUtility.DisplayDialog("Invalid Path", "The path is not valid, you can chose it with the find folder button", "Ok");
            return;
        }
        if (AssetDatabase.LoadAssetAtPath(path + "/" + name + ".prefab", typeof(GameObject))) // Overriding prefab dialog
        {
            if (EditorUtility.DisplayDialog("Are you sure?", "The prefab already exists. Do you want to overwrite it?", "Yes", "No"))
            {
                FileUtil.DeleteFileOrDirectory(Path.Combine(path, name + "_meshes"));
                AssetDatabase.Refresh();
                replacePrefab = true;
            }
            else
            {
                name += "_1";
            }
        }

        Mesh[] meshes       = new Mesh[4];
        string meshesFolder = AssetDatabase.CreateFolder(path, name + "_meshes");

        meshesFolder = AssetDatabase.GUIDToAssetPath(meshesFolder) + Path.DirectorySeparatorChar;
        Material[] materials  = SaveMaterials(meshesFolder);
        GameObject TreeObject = new GameObject(name);                 // Tree game object
        LODGroup   group      = TreeObject.AddComponent <LODGroup>(); // LOD Group

        group.fadeMode = LODFadeMode.CrossFade;
        int lodNumber = 4; // Creating LODs

        LOD[] lods = new LOD[lodNumber + 1];

        // Generating Billboard
        Lod = 3;
        GenerateTree(true);
        GameObject billboard = CreateBillboard(meshesFolder, name);

        Renderer[] bill_re = new Renderer[1] {
            billboard.GetComponent <MeshRenderer>()
        };
        lods[lodNumber] = new LOD(.01f, bill_re);


        for (int lod = lodNumber - 1; lod > -1; lod--)                                 // create and save all LOD meshes
        {
            string meshPath = meshesFolder + name + "_LOD" + lod.ToString() + ".mesh"; //updating path for each LOD
            Lod = lod;
            Mesh mesh = GenerateTree(ao: true);
            meshes[lod] = mesh;
            AssetDatabase.CreateAsset(mesh, meshPath);
        }

        for (int i = 0; i < lodNumber; i++) // assigning lod meshes to LOD array
        {
            GameObject go = new GameObject(name + "_LOD" + i.ToString());
            go.transform.parent = TreeObject.transform;
            MeshFilter mf = go.AddComponent <MeshFilter>();
            mf.mesh = meshes[i];
            Renderer[] re = new Renderer[1] {
                go.AddComponent <MeshRenderer>()
            };                                                      // the renderer to put in LODs
            re[0].sharedMaterials = materials;
            float t = Mathf.Pow((i + 1) * 1f / (lodNumber + 1), 1); // float between 0 and 1 following f(x) = pow(x, n)
            lods[i] = new LOD((1 - t) * 0.9f + t * .01f, re);       // assigning renderer
            lods[i].fadeTransitionWidth = 0.25f;
        }

        billboard.transform.parent = TreeObject.transform; // making billboard child of tree object


        group.SetLODs(lods); // assigning LODs to lod group
        group.RecalculateBounds();

        string prefabPath = path + "/" + name + ".prefab";

        TreeObject.AddComponent <MtreeWind>();

        Object prefab;

        if (replacePrefab)
        {
            Object targetPrefab = AssetDatabase.LoadAssetAtPath(path + "/" + name + ".prefab", typeof(GameObject));
            prefab = PrefabUtility.ReplacePrefab(TreeObject, targetPrefab, ReplacePrefabOptions.ConnectToPrefab);
        }
        else
        {
            prefab = PrefabUtility.CreatePrefab(prefabPath, TreeObject, ReplacePrefabOptions.ConnectToPrefab);
        }

        AssetDatabase.SaveAssets();
        DestroyImmediate(TreeObject);

        if (!groupedSave)
        {
            // select newly created prefab in folder
            Selection.activeObject = prefab;
            // Also flash the folder yellow to highlight it
            EditorGUIUtility.PingObject(prefab);
            EditorUtility.DisplayDialog("Prefab saved !", "The prefab is saved, you can now delete the tree and use the prefab instead", "Ok");
        }
    }
        public void MergeMeshes()
        {
            // else Debug.LogWarning("Please assign rooftop material in CS Rooftops Component");
            rooftopHolder[iteration].transform.localScale = new Vector3(1, 1, 1);
            MeshFilter[]      meshFilters = rooftopHolder[iteration].GetComponentsInChildren <MeshFilter>();
            CombineInstance[] combine     = new CombineInstance[meshFilters.Length];

            int index = 0;

            for (int x = 0; x < meshFilters.Length; x++)
            {
                if (meshFilters[x].sharedMesh != null)
                {
                    // if (meshFilters[i].sharedMesh == null) continue;
                    combine[index].mesh        = meshFilters[x].sharedMesh;
                    combine[index++].transform = meshFilters[x].transform.localToWorldMatrix;
                }
            }
            MeshFilter meshF = rooftopHolder[iteration].transform.GetComponent <MeshFilter>();

            meshF.sharedMesh = new Mesh();
            meshF.sharedMesh.CombineMeshes(combine);
            meshF.sharedMesh.RecalculateBounds();

            if (lodComponent != null)
            {
                lodComponent.RecalculateBounds();
            }

            foreach (Transform go in rooftopHolder[iteration].transform.Cast <Transform>().Reverse())
            {
                DestroyImmediate(go.gameObject);
            }

            if (rooftopHolder[iteration].GetComponent <MeshRenderer>() == null)
            {
                rh = rooftopHolder[iteration].AddComponent <MeshRenderer>() as MeshRenderer;
                rh = rooftopHolder[iteration].GetComponent <MeshRenderer>();
                rh.sharedMaterial = greebleMat[iteration];
            }
            rh = rooftopHolder[iteration].GetComponent <MeshRenderer>();
            rh.sharedMaterial = greebleMat[iteration];
            Renderer[] renderers = new Renderer[1];
            LOD[]      lod       = new LOD[1];
            renderers[0] = rooftopHolder[iteration].GetComponent <Renderer>();
            lod[0]       = new LOD(lodDistance, renderers);
            lodComponent.SetLODs(lod);
            if (animateLodFade)
            {
                lodComponent.fadeMode = LODFadeMode.CrossFade;
            }
            else
            {
                lodComponent.fadeMode = LODFadeMode.None;
            }
            lodComponent.animateCrossFading = animateLodFade;

            rooftopHolder[iteration].transform.position   = gameObject.transform.position;
            rooftopHolder[iteration].transform.rotation   = gameObject.transform.rotation;
            rooftopHolder[iteration].transform.localScale = new Vector3(1, bmComponent.scale, 1);
        }
Exemple #27
0
    void Mesh()
    {
        counting = 0;
        canMerge = false;
        int numOfseObjList = 0;

        totalcount = dataDic.Count;
        foreach (string key in dataDic.Keys)
        {
            counting++;
            UpdateProgress();
            if (showList.Count > 0 && showList[numOfseObjList] == false)
            {
                numOfseObjList++;
                continue;
            }
            numOfseObjList++;
            if (polyMergeCountDic[key] > 65000)
            {
                continue;
            }
            NewFolder(meshContainsName, key);
            LOD[] lods     = new LOD[dataDic[key].Count];
            int   lodCount = 0;
            int   merCoung = 0;
            foreach (MergeData m in dataDic[key])
            {
                //Mesh
                for (int i = 0; i < m._matLists.Count; i++)
                {
                    subMeshList = m._subMeshLists[i];
                    string     header       = meshContainsName;
                    GameObject mergedObject = new GameObject(header + "_" + m._objectLists[i][0].name + "_" + m._matLists[i][0].name, typeof(MeshFilter), typeof(MeshRenderer));
                    Mesh       combinedMesh = CombineSubmeshes(subMeshList, mergedObject);

                    if (m._tranMeshColLists.Count != 0)
                    {
                        int mesColCou = 0;
                        for (int t = 0; t < m._tranMeshColLists.Count; t++)
                        {
                            GameObject addMesh = new GameObject(m._meshColLists[t].name + "_" + mesColCou);
                            mesColCou++;
                            MeshCollider mc = addMesh.AddComponent <MeshCollider> ();
                            mc.sharedMesh = m._meshColLists[t];
                            addMesh.transform.position   = m._tranMeshColLists[t].transform.position;
                            addMesh.transform.rotation   = m._tranMeshColLists[t].transform.rotation;
                            addMesh.transform.localScale = m._tranMeshColLists[t].localScale;
                            addMesh.transform.SetParent(mergedObject.transform);
                        }
                    }

                    AssetDatabase.CreateAsset(combinedMesh, filePath + "/" + header + "_" + m._objectLists[i][0].name + "_" + m._matLists[i][0].name + ".asset");
                    mergedObject.GetComponent <MeshFilter>().mesh = combinedMesh;
                    mergedObject.GetComponent <MeshRenderer>().sharedMaterials = m._matLists[i].ToArray();
                    lodList.Add(mergedObject);

                    Renderer[] renderers = new Renderer[1];
                    renderers[0]   = mergedObject.GetComponent <Renderer>();
                    lods[lodCount] = new LOD(1.0f / (lodCount + 2f), renderers);
                    lodCount++;
                }
            }
            string     m_header     = meshContainsName;
            GameObject newMergedObj = new GameObject(m_header + "_" + key);
            foreach (GameObject n in lodList)
            {
                n.transform.SetParent(newMergedObj.transform);
            }

            if (lodGroup)
            {
                LODGroup lodObj = newMergedObj.AddComponent <LODGroup> ();
                lodObj.SetLODs(lods);
                lodObj.RecalculateBounds();
                for (int n = lodObj.GetLODs().Count() - 1; n >= 0; n--)
                {
                    if (lodObj.GetLODs()[n].renderers.Length == 0)
                    {
                        List <LOD> _lodObj = lodObj.GetLODs().ToList();
                        _lodObj.RemoveAt(n);
                        lodObj.SetLODs(_lodObj.ToArray());
                    }
                }
                if (lodRTH.ContainsKey(key))
                {
                    lods = lodObj.GetLODs();
                    for (int u = 0; u < lodRTH[key].Count; u++)
                    {
                        lods [u].screenRelativeTransitionHeight = lodRTH [key] [u];
                    }
                    lodObj.SetLODs(lods);
                }
            }

            PrefabUtility.CreatePrefab(filePath + "/" + m_header + "_" + key + ".prefab", (GameObject)newMergedObj, ReplacePrefabOptions.ConnectToPrefab);
            lodList.Clear();
        }
    }
        public void CreateWMOObject()
        {
            if (terrainHandler.working)
            {
                WMO.WMOStruct data        = WMO.AllWMOData.Dequeue();
                GameObject    WMOinstance = new GameObject();

                terrainHandler.LoadedWMOIds[data.fileDataId] = WMOinstance;

                int nGroups = data.Info.nGroups;
                for (int g = 0; g < nGroups; g++)
                {
                    // group object //
                    GameObject GroupInstance = new GameObject();
                    GroupInstance.isStatic = true;
                    GroupInstance.transform.SetParent(terrainHandler.LoadedWMOIds[data.fileDataId].transform);
                    GroupInstance.name = data.groupsData[g].groupName;

                    LODGroup   Lodgroup  = GroupInstance.AddComponent <LODGroup>();
                    LOD[]      lods      = new LOD[1];
                    Renderer[] renderers = new Renderer[data.groupsData[g].nBatches];

                    // Batches //
                    for (int bn = 0; bn < data.groupsData[g].nBatches; bn++)
                    {
                        ////////////////////////////////
                        #region object

                        GameObject BatchInstance = new GameObject();
                        BatchInstance.isStatic = true;
                        BatchInstance.transform.SetParent(GroupInstance.transform);
                        BatchInstance.name = bn.ToString();
                        BatchInstance.transform.transform.eulerAngles = new Vector3(BatchInstance.transform.transform.eulerAngles.x, BatchInstance.transform.transform.eulerAngles.y - 180, GroupInstance.transform.transform.eulerAngles.z);

                        #endregion
                        ////////////////////////////////

                        ////////////////////////////////
                        #region mesh

                        BatchInstance.AddComponent <MeshRenderer>();
                        BatchInstance.GetComponent <MeshRenderer>().shadowCastingMode = UnityEngine.Rendering.ShadowCastingMode.TwoSided;
                        renderers[bn] = BatchInstance.GetComponent <MeshRenderer>();
                        BatchInstance.AddComponent <MeshFilter>();
                        Mesh bmesh = new Mesh();

                        uint batchVertSize = data.groupsData[g].batch_MaxIndex[bn] - data.groupsData[g].batch_MinIndex[bn] + 1;

                        Vector3[]  batchVertices      = new Vector3[batchVertSize];
                        Vector2[]  batchUVs           = new Vector2[batchVertSize];
                        Vector3[]  batchNormals       = new Vector3[batchVertSize];
                        Color32[]  batchVertexColors  = new Color32[batchVertSize];
                        List <int> batchTrianglesList = new List <int>();
                        int[]      batchTriangles;

                        int  arrayPosition     = 0;
                        uint batch_startVertex = data.groupsData[g].batch_MinIndex[bn];
                        uint batch_endVertex   = data.groupsData[g].batch_MaxIndex[bn];
                        for (uint v = batch_startVertex; v <= batch_endVertex; v++)
                        {
                            batchVertices[arrayPosition] = data.groupsData[g].vertices[v];
                            batchUVs[arrayPosition]      = data.groupsData[g].UVs[v];
                            batchNormals[arrayPosition]  = data.groupsData[g].normals[v];
                            if (!data.groupsData[g].flags.Hasvertexolors)
                            {
                                batchVertexColors[arrayPosition] = new Color32(127, 127, 127, 127);
                            }
                            else
                            {
                                batchVertexColors[arrayPosition] = data.groupsData[g].vertexColors[(int)v];
                            }
                            arrayPosition++;
                        }

                        uint batch_startIndex = data.groupsData[g].batch_StartIndex[bn];
                        uint batch_nIndices   = data.groupsData[g].batch_Count[bn];
                        for (uint idx = batch_startIndex; idx <= batch_startIndex + batch_nIndices - 2; idx = idx + 3)
                        {
                            uint in1 = data.groupsData[g].triangles[idx + 0];
                            uint in2 = data.groupsData[g].triangles[idx + 1];
                            uint in3 = data.groupsData[g].triangles[idx + 2];
                            int  a   = (int)(in1 - batch_startVertex);
                            int  b   = (int)(in2 - batch_startVertex);
                            int  c   = (int)(in3 - batch_startVertex);

                            batchTrianglesList.Add(a);
                            batchTrianglesList.Add(b);
                            batchTrianglesList.Add(c);
                        }
                        batchTrianglesList.Reverse();
                        batchTriangles = batchTrianglesList.ToArray();

                        bmesh.vertices  = batchVertices;
                        bmesh.uv        = batchUVs;
                        bmesh.normals   = batchNormals;
                        bmesh.triangles = batchTriangles;
                        bmesh.colors32  = batchVertexColors;
                        BatchInstance.GetComponent <MeshFilter>().mesh             = bmesh;
                        BatchInstance.GetComponent <MeshRenderer>().sharedMaterial = missingMaterial;

                        #endregion
                        ////////////////////////////////

                        ////////////////////////////////
                        #region material

                        uint TextureFileDataId = data.texturePaths[data.materials[data.groupsData[g].batchMaterialIDs[bn]].TextureId1];
                        BatchInstance.GetComponent <Renderer>().material = WMOmaterials[(int)data.materials[data.groupsData[g].batchMaterialIDs[bn]].ShaderType];

                        ////////////////////////////////
                        #region Set Fragment Shader

                        WMOFragmentShader shader = data.materials[data.groupsData[g].batchMaterialIDs[bn]].ShaderType;
                        switch (shader)
                        {
                        case WMOFragmentShader.Diffuse:
                        {
                            BatchInstance.GetComponent <Renderer>().material.SetFloat("_ShaderDiffuse", 1.0f);
                            break;
                        }

                        case WMOFragmentShader.Specular:
                        {
                            BatchInstance.GetComponent <Renderer>().material.SetFloat("_ShaderSpecular", 1.0f);
                            break;
                        }

                        case WMOFragmentShader.Metal:
                        {
                            BatchInstance.GetComponent <Renderer>().material.SetFloat("_ShaderMetal", 1.0f);
                            break;
                        }

                        case WMOFragmentShader.Env:
                        {
                            BatchInstance.GetComponent <Renderer>().material.SetFloat("_ShaderEnv", 1.0f);
                            break;
                        }

                        case WMOFragmentShader.Opaque:
                        {
                            BatchInstance.GetComponent <Renderer>().material.SetFloat("_ShaderOpaque", 1.0f);
                            BatchInstance.GetComponent <Renderer>().material.SetFloat("_AlphaToMask", 1.0f);
                            break;
                        }

                        default:
                        {
                            BatchInstance.GetComponent <Renderer>().material.SetFloat("_ShaderDiffuse", 1.0f);
                            break;
                        }
                        }


                        #endregion
                        ////////////////////////////////

                        ////////////////////////////////
                        #region Set Material Flags

                        // F_UNCULLED //
                        int Culling = 2; // on (only front)
                        if (data.materials[data.groupsData[g].batchMaterialIDs[bn]].flags.F_UNCULLED)
                        {
                            Culling = 0; // off (both sides_
                        }
                        BatchInstance.GetComponent <Renderer>().material.SetFloat("F_UNCULLED", Culling);
                        // F_UNLIT //
                        if (data.materials[data.groupsData[g].batchMaterialIDs[bn]].flags.F_UNLIT)
                        {
                            BatchInstance.GetComponent <Renderer>().material.EnableKeyword("F_UNLIT");
                        }
                        //BatchInstance.GetComponent<Renderer>().material.SetFloat("_F_UNLIT", data.materials[data.groupsData[g].batchMaterialIDs[bn]].flags.F_UNLIT ? 1 : 0);
                        // F_UNFOGGED //
                        BatchInstance.GetComponent <Renderer>().material.SetFloat("_F_UNFOGGED", data.materials[data.groupsData[g].batchMaterialIDs[bn]].flags.F_UNFOGGED ? 1 : 0);

                        #endregion
                        ////////////////////////////////

                        ////////////////////////////////
                        #region Set Blending Mode

                        // set default blend: One Zero, basicly off
                        UnityEngine.Rendering.BlendMode source      = UnityEngine.Rendering.BlendMode.One;
                        UnityEngine.Rendering.BlendMode destination = UnityEngine.Rendering.BlendMode.Zero;

                        BlendingMode blending = data.materials[data.groupsData[g].batchMaterialIDs[bn]].BlendMode;

                        switch (blending)
                        {
                        case BlendingMode.Opaque:
                        {
                            source      = UnityEngine.Rendering.BlendMode.One;
                            destination = UnityEngine.Rendering.BlendMode.Zero;
                            break;
                        }

                        case BlendingMode.AlphaKey:
                        {
                            source      = UnityEngine.Rendering.BlendMode.One;
                            destination = UnityEngine.Rendering.BlendMode.Zero;
                            break;
                        }

                        case BlendingMode.Alpha:
                        {
                            source      = UnityEngine.Rendering.BlendMode.SrcAlpha;
                            destination = UnityEngine.Rendering.BlendMode.OneMinusSrcAlpha;
                            break;
                        }

                        case BlendingMode.Additive:
                        {
                            source      = UnityEngine.Rendering.BlendMode.One;
                            destination = UnityEngine.Rendering.BlendMode.One;
                            break;
                        }

                        case BlendingMode.Modulate:
                        {
                            source      = UnityEngine.Rendering.BlendMode.DstColor;
                            destination = UnityEngine.Rendering.BlendMode.Zero;
                            break;
                        }

                        case BlendingMode.Modulate2x:
                        {
                            source      = UnityEngine.Rendering.BlendMode.DstColor;
                            destination = UnityEngine.Rendering.BlendMode.SrcColor;
                            break;
                        }

                        case BlendingMode.ModulateAdditive:
                        {
                            source      = UnityEngine.Rendering.BlendMode.DstColor;
                            destination = UnityEngine.Rendering.BlendMode.One;
                            break;
                        }

                        default:
                        {
                            Debug.Log("BlendMode To Add: " + blending.ToString() + " Texture Used: " + TextureFileDataId);
                            source      = UnityEngine.Rendering.BlendMode.One;
                            destination = UnityEngine.Rendering.BlendMode.Zero;
                            break;
                        }
                        }
                        BatchInstance.GetComponent <Renderer>().material.SetInt("MySrcMode", (int)source);
                        BatchInstance.GetComponent <Renderer>().material.SetInt("MyDstMode", (int)destination);

                        #endregion
                        ////////////////////////////////

                        ////////////////////////////////
                        #region Assign Textures

                        if (LoadedWMOTextures.ContainsKey(TextureFileDataId))
                        {
                            BatchInstance.GetComponent <Renderer>().material.SetTexture("_MainTex", LoadedWMOTextures[TextureFileDataId]);
                        }
                        else
                        {
                            try
                            {
                                Texture2Ddata tdata = data.textureData[TextureFileDataId];
                                Texture2D     tex   = new Texture2D(tdata.width, tdata.height, tdata.textureFormat, tdata.hasMipmaps);
                                tex.LoadRawTextureData(tdata.TextureData);
                                tex.Apply();
                                LoadedWMOTextures[TextureFileDataId] = tex;
                                BatchInstance.GetComponent <Renderer>().material.SetTexture("_MainTex", tex);
                            }
                            catch (Exception ex)
                            {
                                Debug.Log("Error: Loading RawTextureData @ WMOhandler");
                                Debug.LogException(ex);
                            }
                        }
                        #endregion
                        ////////////////////////////////

                        #endregion
                        ////////////////////////////////
                    }

                    lods[0] = new LOD(.1f, renderers);
                    Lodgroup.SetLODs(lods);
                    Lodgroup.animateCrossFading = true;
                    Lodgroup.fadeMode           = LODFadeMode.SpeedTree;
                    Lodgroup.RecalculateBounds();
                }

                terrainHandler.LoadedWMOIds[data.fileDataId].transform.position   = data.position;
                terrainHandler.LoadedWMOIds[data.fileDataId].transform.rotation   = data.rotation;
                terrainHandler.LoadedWMOIds[data.fileDataId].transform.localScale = data.scale;
                if (data.uniqueID != -1)
                {
                    if (terrainHandler.ADTBlockWMOParents[data.uniqueID] != null)
                    {
                        terrainHandler.LoadedWMOIds[data.fileDataId].transform.SetParent(terrainHandler.ADTBlockWMOParents[data.uniqueID].transform);
                    }
                    else
                    {
                        Destroy(terrainHandler.LoadedWMOIds[data.fileDataId]);
                    }
                }
                terrainHandler.LoadedWMOIds[data.fileDataId].name = data.Info.wmoID.ToString();

                terrainHandler.frameBusy = false;
            }
        }
Exemple #29
0
    public void SaveAsPrefab(bool groupedSave = false, bool usingHDRP = false)
    {
        var    oldMesh = filter.sharedMesh;
        string name    = gameObject.name;
        string path    = saveTreeFolder;

        if (string.IsNullOrEmpty(path))
        {
            return;
        }

        #if (UNITY_2017 || UNITY_2018_1 || UNITY_2018_2)
        bool replacePrefab = false;  //=> value never Used, taged by dan_wipf => used for unity up to 2018.2
        #endif

        if (!System.IO.Directory.Exists(path))
        {
            EditorUtility.DisplayDialog("Invalid Path", "The path is not valid, you can chose it with the find folder button", "Ok");
            return;
        }
        if (AssetDatabase.LoadAssetAtPath(path + "/" + name + ".prefab", typeof(GameObject))) // Overriding prefab dialog
        {
            if (EditorUtility.DisplayDialog("Are you sure?", "The prefab already exists. Do you want to overwrite it?", "Yes", "No"))
            {
                FileUtil.DeleteFileOrDirectory(Path.Combine(path, name + "_meshes"));
                #if (UNITY_2017 || UNITY_2018_1 || UNITY_2018_2)
                replacePrefab = true; //  => value never Used, taged by dan_wipf => used for unity up to 2018.2
                #endif
            }
            else
            {
                name += "_1";
            }
        }
        Mesh[] meshes       = new Mesh[LODs.Count];
        string meshesFolder = AssetDatabase.CreateFolder(path, name + "_meshes");
        meshesFolder = AssetDatabase.GUIDToAssetPath(meshesFolder) + Path.DirectorySeparatorChar;
        Material[] materials  = SaveMaterials(meshesFolder);
        GameObject TreeObject = new GameObject(name);                 // Tree game object
        LODGroup   group      = TreeObject.AddComponent <LODGroup>(); // LOD Group
        group.fadeMode = LODFadeMode.CrossFade;
        LOD[] lods = new LOD[LODs.Count + 1];

        // Generating Billboard
        LodIndex = LODs.Count - 1;
        GenerateTree(true);
        GameObject billboard = CreateBillboard(meshesFolder, name, usingHDRP);
        Renderer[] bill_re   = new Renderer[1] {
            billboard.GetComponent <MeshRenderer>()
        };
        lods[lods.Length - 1] = new LOD(.01f, bill_re);


        for (LodIndex = LODs.Count - 1; LodIndex >= 0; LodIndex--)               // create and save all LOD meshes
        {
            string meshPath = meshesFolder + name + "_LOD" + LodIndex + ".mesh"; //updating path for each LOD
            Mesh   mesh     = GenerateTree(instantAo: true);
            meshes[LodIndex] = mesh;
            AssetDatabase.CreateAsset(mesh, meshPath);
        }

        for (int i = 0; i < LODs.Count; i++) // assigning lod meshes to LOD array
        {
            GameObject go = new GameObject(name + "_LOD" + i.ToString());
            go.transform.parent = TreeObject.transform;
            MeshFilter mf = go.AddComponent <MeshFilter>();
            mf.mesh = meshes[i];
            Renderer[] re = new Renderer[1] {
                go.AddComponent <MeshRenderer>()
            };                                                       // the renderer to put in LODs
            re[0].sharedMaterials = materials;
            float t = Mathf.Pow((i + 1) * 1f / (LODs.Count + 1), 1); // float between 0 and 1 following f(x) = pow(x, n)
            lods[i] = new LOD((1 - t) * 0.9f + t * .01f, re);        // assigning renderer
            lods[i].fadeTransitionWidth = 0.25f;
        }

        billboard.transform.parent = TreeObject.transform; // making billboard child of tree object


        group.SetLODs(lods); // assigning LODs to lod group
        group.animateCrossFading = true;
        group.RecalculateBounds();

        string prefabPath = path + "/" + name + ".prefab";

        Object prefab;

        #if (UNITY_2017 || UNITY_2018_1 || UNITY_2018_2)
        if (replacePrefab)
        {
            Object targetPrefab = AssetDatabase.LoadAssetAtPath(path + "/" + name + ".prefab", typeof(GameObject));
            prefab = PrefabUtility.ReplacePrefab(TreeObject, targetPrefab, ReplacePrefabOptions.ConnectToPrefab);
        }
        else
        {
            prefab = PrefabUtility.CreatePrefab(prefabPath, TreeObject, ReplacePrefabOptions.ConnectToPrefab);
        }
        #else
        prefab = PrefabUtility.SaveAsPrefabAssetAndConnect(TreeObject, prefabPath, InteractionMode.AutomatedAction);
        #endif

        AssetDatabase.SaveAssets();
        DestroyImmediate(TreeObject);

        if (!groupedSave)
        {
            // select newly created prefab in folder
            Selection.activeObject = prefab;
            // Also flash the folder yellow to highlight it
            EditorGUIUtility.PingObject(prefab);
            EditorUtility.DisplayDialog("Prefab saved !", "The prefab is saved, you can now delete the tree and use the prefab instead", "Ok");
        }

        LodIndex          = 0;
        filter.sharedMesh = oldMesh;
    }
        public static void GenerateBillboards(Bounds bounds, FoliageCell cell, GameObject owner, List <FoliageInstance> trees, FoliageType type, bool addLodGroup, float screenFadeSize, bool animatedCrossFade)
        {
            int[] originalTriangles = m_SystemQuadTriangles;

            GameObject meshObj = new GameObject();

            // Mark object as static
#if UNITY_EDITOR
            GameObjectUtility.SetStaticEditorFlags(meshObj, StaticEditorFlags.OccludeeStatic | StaticEditorFlags.ReflectionProbeStatic);
#endif

            string name = string.Format("MeshCell[{0}_{1}]", cell.GetHashCode(), type.m_Prefab.name);

            Transform existing = owner.transform.Find(name);
            if (existing != null)
            {
#if UNITY_EDITOR
                if (UnityEditor.EditorApplication.isPlaying == false)
                {
                    Object.DestroyImmediate(existing.gameObject);
                }
                else
                {
                    Object.Destroy(existing.gameObject);
                }
#else
                Object.Destroy(existing.gameObject);
#endif
                existing = null;
            }

            meshObj.transform.SetParent(owner.transform);
            meshObj.name = name;

            var data = type.m_RuntimeData.m_SpeedTreeData;

            Vector3 worldScale = new Vector3(data.m_Size.x, data.m_Size.y, data.m_Size.x);

            // Set material
            MeshRenderer rend = meshObj.AddComponent <MeshRenderer>();
            rend.sharedMaterial = GenerateBillboardMaterial(type.m_RuntimeData.m_SpeedTreeData);

            MeshFilter filter = meshObj.AddComponent <MeshFilter>();

            Mesh treeMesh = new Mesh();
            treeMesh.name = meshObj.name;

            List <Vector4> m_TempWorldPositions = new List <Vector4>();
            List <Vector3> m_TempWorldScales    = new List <Vector3>();
            List <Vector3> m_TempQuadVertices   = new List <Vector3>();
            List <Vector4> m_TempQuadTangents   = new List <Vector4>();
            List <Vector3> m_TempQuadNormals    = new List <Vector3>();
            List <int>     m_TempQuadIndices    = new List <int>();

            for (int treeIndex = 0; treeIndex < trees.Count; treeIndex++)
            {
                Vector3 position = trees[treeIndex].m_Position;
                Vector3 scale    = trees[treeIndex].m_Scale;
                float   rot      = trees[treeIndex].m_Rotation.eulerAngles.y * Mathf.Deg2Rad;

                // Offset world position, by the grounding factor
                Vector3 instancePos = position;

                // Don't use this, but offset in shader, so that we can have that correct hue
                // instancePos.y += data.m_Size.z;

                // Scale by the world scale too so that we don't have to do an extra multip
                Vector3 instanceScale = scale;
                instanceScale.Scale(worldScale);

                // Add the world and scale data
                for (int index = 0; index < 4; index++)
                {
                    Vector4 posAndRot = instancePos;
                    posAndRot.w = rot;

                    m_TempWorldPositions.Add(posAndRot);
                    m_TempWorldScales.Add(instanceScale);
                }

                // Add stanard quad data
                m_TempQuadVertices.AddRange(m_SystemQuadVertices);
                m_TempQuadTangents.AddRange(m_SystemQuadTangents);
                m_TempQuadNormals.AddRange(m_SystemQuadNormals);

                // Calculate triangle indixes
                m_TempQuadIndices.AddRange(originalTriangles);
                for (int triIndex = 0; triIndex < 6; triIndex++)
                {
                    // Just add to the triangles the existing triangles + the new indices
                    m_TempQuadIndices[triIndex + 6 * treeIndex] = originalTriangles[triIndex] + 4 * treeIndex;
                }
            }

            treeMesh.Clear();

            // Set standard data
            treeMesh.SetVertices(m_TempQuadVertices);
            treeMesh.SetNormals(m_TempQuadNormals);
            treeMesh.SetTangents(m_TempQuadTangents);

            // Set the custom data
            treeMesh.SetUVs(1, m_TempWorldPositions);
            treeMesh.SetUVs(2, m_TempWorldScales);

            // Set triangles and do not calculate bounds
            treeMesh.SetTriangles(m_TempQuadIndices, 0, false);

            // Set the manually calculated bounds
            treeMesh.bounds = bounds;

            treeMesh.UploadMeshData(true);

            // Set the mesh
            filter.mesh = treeMesh;

            if (addLodGroup)
            {
                // Add the mesh' lod group
                LODGroup group = meshObj.AddComponent <LODGroup>();
                group.animateCrossFading = false;

                if (animatedCrossFade)
                {
                    group.fadeMode           = LODFadeMode.CrossFade;
                    group.animateCrossFading = true;
                }
                else
                {
                    group.fadeMode           = LODFadeMode.None;
                    group.animateCrossFading = false;
                }

                group.SetLODs(new LOD[] { new LOD(screenFadeSize, new Renderer[] { rend }) });
                group.RecalculateBounds();
            }

#if UNITY_EDITOR
            UnityEditor.SceneManagement.EditorSceneManager.MarkSceneDirty(meshObj.scene);
#endif
        }