public static GTreeInstance Create(int prototypeIndex)
        {
            GTreeInstance tree = new GTreeInstance();

            tree.PrototypeIndex = prototypeIndex;
            tree.Position       = Vector3.zero;
            tree.Rotation       = Quaternion.identity;
            tree.Scale          = Vector3.one;

            return(tree);
        }
Example #2
0
        private static void RenderTreesInstanced_NonInstanced(GStylizedTerrain t, Camera cam, List <int> flags, List <Vector3> worldPositions)
        {
            List <GTreePrototype> prototypes = t.TerrainData.Foliage.Trees.Prototypes;
            List <GTreeInstance>  instances  = t.TerrainData.Foliage.TreeInstances;
            int instanceCount = instances.Count;
            int subMeshCount  = 0;
            int materialCount = 0;
            int drawCallCount = 0;
            int d;

            for (int i = 0; i < instanceCount; ++i)
            {
                if (flags[i] != FLAG_NON_INSTANCED)
                {
                    continue;
                }
                GTreeInstance  tree  = instances[i];
                GTreePrototype proto = prototypes[tree.PrototypeIndex];
                subMeshCount  = proto.SharedMesh.subMeshCount;
                materialCount = proto.SharedMaterials.Length;
                drawCallCount = Mathf.Min(subMeshCount, materialCount);
                for (d = 0; d < drawCallCount; ++d)
                {
                    Graphics.DrawMesh(
                        proto.SharedMesh,
                        Matrix4x4.TRS(worldPositions[i] + Vector3.up * proto.PivotOffset, tree.Rotation * proto.BaseRotation, tree.Scale.Mul(proto.BaseScale)),
                        proto.SharedMaterials[d],
                        proto.Layer,
                        cam,  //camera
                        d,    //sub mesh index
                        null, //properties block
                        proto.ShadowCastingMode,
                        proto.ReceiveShadow,
                        null,  //probe anchor
                        LightProbeUsage.BlendProbes,
                        null); //proxy volume
                }
            }
        }
Example #3
0
        private void CreateStaticObstacles(GStylizedTerrain t)
        {
            if (t.TerrainData == null)
            {
                return;
            }
            if (t.TerrainData.Foliage.Trees == null)
            {
                return;
            }
            if (t.TerrainData.Foliage.Trees.Prototypes.Count == 0)
            {
                return;
            }

#if UNITY_EDITOR
            string title = "Creating static obstacles";
            string info  = t.name;
            GCommonGUI.CancelableProgressBar(title, info, 0);
#endif

            Vector3 terrainSize = new Vector3(
                t.TerrainData.Geometry.Width,
                t.TerrainData.Geometry.Height,
                t.TerrainData.Geometry.Length);

            Transform             root       = GUtilities.GetChildrenWithName(transform, string.Format("{0}_{1}", t.name, t.GetInstanceID()));
            List <GTreePrototype> prototypes = t.TerrainData.Foliage.Trees.Prototypes;

            GameObject[] templates = new GameObject[prototypes.Count];
            for (int i = 0; i < prototypes.Count; ++i)
            {
                if (!prototypes[i].IsValid)
                {
                    continue;
                }
                GameObject  template   = Instantiate(prototypes[i].Prefab) as GameObject;
                Component[] components = template.GetComponentsInChildren <Component>();
                for (int j = 0; j < components.Length; ++j)
                {
                    if (components[j] is Collider)
                    {
                        GUtilities.DestroyObject(components[j]);
                    }
                    if (components[j] is MeshRenderer)
                    {
                        MeshRenderer mr = components[j] as MeshRenderer;
                        mr.sharedMaterials   = new Material[] { GInternalMaterials.NavHelperDummyGameObjectMaterial };
                        mr.shadowCastingMode = UnityEngine.Rendering.ShadowCastingMode.Off;
                        mr.receiveShadows    = false;
                    }
                }
#if UNITY_EDITOR
                GameObjectUtility.SetStaticEditorFlags(template, StaticEditorFlags.NavigationStatic);
#endif
                template.name = prototypes[i].Prefab.name;
                templates[i]  = template;
            }

            List <GTreeInstance> instances = t.TerrainData.Foliage.TreeInstances;
            for (int i = 0; i < instances.Count; ++i)
            {
#if UNITY_EDITOR
                GCommonGUI.CancelableProgressBar(title, info, i * 1.0f / instances.Count);
#endif
                GTreeInstance tree = instances[i];
                if (templates[tree.PrototypeIndex] == null)
                {
                    continue;
                }

                GameObject g = Instantiate(templates[tree.PrototypeIndex]) as GameObject;
                g.transform.parent = root;

                Vector3 localPos = new Vector3(
                    tree.Position.x * terrainSize.x,
                    tree.Position.y * terrainSize.y,
                    tree.Position.z * terrainSize.z);
                Vector3 worldPos = t.transform.TransformPoint(localPos);
                g.transform.position   = worldPos;
                g.transform.rotation   = tree.Rotation;
                g.transform.localScale = tree.Scale;
                g.name = templates[tree.PrototypeIndex].name;
            }

            for (int i = 0; i < templates.Length; ++i)
            {
                GUtilities.DestroyGameobject(templates[i]);
            }
#if UNITY_EDITOR
            GCommonGUI.ClearProgressBar();
#endif
        }
        private void LateUpdate()
        {
            if (Terrain == null)
            {
                return;
            }
            if (Terrain.TerrainData == null)
            {
                return;
            }
            if (Terrain.TerrainData.Foliage.Trees == null)
            {
                return;
            }
            if (Terrain.TerrainData.Foliage.Trees.Prototypes.Count == 0)
            {
                return;
            }

            GameObject actualTarget = null;

            if (Target != null)
            {
                actualTarget = Target;
            }
            else if (Camera.main != null)
            {
                actualTarget = Camera.main.gameObject;
            }

            if (actualTarget == null)
            {
                return;
            }
            Vector3 terrainSize = new Vector3(
                Terrain.TerrainData.Geometry.Width,
                Terrain.TerrainData.Geometry.Height,
                Terrain.TerrainData.Geometry.Length);
            Vector3 targetLocalPos = Terrain.transform.InverseTransformPoint(actualTarget.transform.position);
            Vector3 treeLocalPos   = Vector3.zero;
            float   sqrDistance    = distance * distance;

            TreeInstances.Clear();
            List <GTreeInstance> instances = Terrain.TerrainData.Foliage.TreeInstances;

            for (int i = 0; i < instances.Count; ++i)
            {
                GTreeInstance tree = instances[i];
                treeLocalPos.Set(
                    tree.Position.x * terrainSize.x,
                    tree.Position.y * terrainSize.y,
                    tree.Position.z * terrainSize.z);
                if (Vector3.SqrMagnitude(targetLocalPos - treeLocalPos) <= sqrDistance)
                {
                    TreeInstances.Add(tree);
                }
            }

            Vector3 targetNormalizePos = Terrain.WorldPointToNormalized(actualTarget.transform.position);

            TreeInstances.Sort((t0, t1) =>
            {
                float d0 = Vector3.SqrMagnitude(targetNormalizePos - t0.Position);
                float d1 = Vector3.SqrMagnitude(targetNormalizePos - t1.Position);
                return(d0.CompareTo(d1));
            });

            List <GTreePrototype> prototypes = Terrain.TerrainData.Foliage.Trees.Prototypes;
            int colliderIndex = 0;

            for (int i = 0; i < TreeInstances.Count; ++i)
            {
                GTreeInstance  tree      = TreeInstances[i];
                GTreePrototype prototype = prototypes[tree.PrototypeIndex];
                if (!prototype.HasCollider)
                {
                    continue;
                }

                if (colliderIndex >= ColliderBudget)
                {
                    break;
                }
                CapsuleCollider col = GetCollider(colliderIndex);
                colliderIndex += 1;

                Vector3 localPos = new Vector3(
                    terrainSize.x * tree.Position.x,
                    terrainSize.y * tree.Position.y,
                    terrainSize.z * tree.Position.z);
                Vector3 worldPos = Terrain.transform.TransformPoint(localPos);
                col.transform.position   = worldPos;
                col.transform.rotation   = tree.Rotation;
                col.transform.localScale = tree.Scale;
                GTreeColliderInfo colliderInfo = prototype.ColliderInfo;
                col.center           = colliderInfo.Center;
                col.radius           = colliderInfo.Radius;
                col.height           = colliderInfo.Height;
                col.direction        = colliderInfo.Direction;
                col.gameObject.layer = prototype.Layer;
                col.gameObject.tag   = prototype.Prefab.tag;
                col.gameObject.SetActive(true);
            }

            for (int i = colliderIndex; i < ColliderBudget; ++i)
            {
                CapsuleCollider col = GetCollider(i);
                col.gameObject.SetActive(false);
            }
        }
Example #5
0
        private static void RenderTreesNonInstanced(GStylizedTerrain t, Camera cam)
        {
            if (t.TerrainData.Foliage.Trees == null ||
                t.TerrainData.Foliage.Trees.Prototypes.Count == 0)
            {
                return;
            }
            List <GTreePrototype> prototypes = t.TerrainData.Foliage.Trees.Prototypes;
            List <GTreeInstance>  instances  = t.TerrainData.Foliage.TreeInstances;
            int prototypeCount = prototypes.Count;
            int instanceCount  = instances.Count;

            bool[] prototypeValidation   = new bool[prototypeCount];
            int[]  prototypeSubMeshCount = new int[prototypeCount];
            for (int pIndex = 0; pIndex < prototypeCount; ++pIndex)
            {
                prototypeValidation[pIndex]   = prototypes[pIndex].IsValid;
                prototypeSubMeshCount[pIndex] = prototypeValidation[pIndex] ? prototypes[pIndex].SharedMesh.subMeshCount : 0;

                if (prototypeValidation[pIndex] == true &&
                    prototypes[pIndex].Billboard != null &&
                    prototypes[pIndex].Billboard.material != null)
                {
                    try
                    {
                        Material mat = prototypes[pIndex].Billboard.material;
                        mat.SetVectorArray(IMAGE_TEXCOORDS_PROPERTY, prototypes[pIndex].Billboard.GetImageTexCoords());
                        mat.SetInt(IMAGE_COUNT_PROPERTY, prototypes[pIndex].Billboard.imageCount);
                    }
                    catch { }
                }
            }

            Quaternion billboardShadowCasterRotation = Quaternion.identity;

            Light[] directionalLights = Light.GetLights(LightType.Directional, 0);
            Light   firstDirLight     = null;

            if (directionalLights.Length > 0)
            {
                firstDirLight = directionalLights[0];
                billboardShadowCasterRotation = Quaternion.Euler(0, firstDirLight.transform.root.eulerAngles.y, 0);
            }

            float   sqrBillboardStart = t.TerrainData.Rendering.BillboardStart * t.TerrainData.Rendering.BillboardStart;
            float   sqrTreeDistance   = t.TerrainData.Rendering.TreeDistance * t.TerrainData.Rendering.TreeDistance;
            float   sqrDistance       = 0;
            Vector3 dimension         = new Vector3(
                t.TerrainData.Geometry.Width,
                t.TerrainData.Geometry.Height,
                t.TerrainData.Geometry.Length);
            Vector3        localPos          = Vector3.zero;
            Vector3        worldPos          = Vector3.zero;
            int            prototypeMaxIndex = prototypeCount - 1;
            GTreePrototype p             = null;
            int            subMeshCount  = 0;
            int            materialCount = 0;
            int            drawCallCount = 0;
            int            i             = 0;
            int            d             = 0;
            Vector3        camLocalPos   = t.transform.InverseTransformPoint(cam.transform.position);

            for (i = 0; i < instanceCount; ++i)
            {
                GTreeInstance tree = instances[i];
                if (tree.PrototypeIndex < 0 || tree.PrototypeIndex > prototypeMaxIndex)
                {
                    continue;
                }
                if (!prototypeValidation[tree.PrototypeIndex])
                {
                    continue;
                }
                localPos.Set(
                    tree.Position.x * dimension.x,
                    tree.Position.y * dimension.y,
                    tree.Position.z * dimension.z);

                sqrDistance = Vector3.SqrMagnitude(localPos - camLocalPos);
                if (sqrDistance > sqrTreeDistance)
                {
                    continue;
                }

                worldPos = t.transform.TransformPoint(localPos);
                p        = prototypes[tree.PrototypeIndex];

                if (sqrDistance < sqrBillboardStart)
                {
                    subMeshCount  = prototypeSubMeshCount[tree.PrototypeIndex];
                    materialCount = p.SharedMaterials.Length;
                    drawCallCount = Mathf.Min(subMeshCount, materialCount);
                    for (d = 0; d < drawCallCount; ++d)
                    {
                        Graphics.DrawMesh(
                            p.SharedMesh,
                            Matrix4x4.TRS(worldPos + Vector3.up * p.PivotOffset, p.BaseRotation * tree.Rotation, tree.Scale.Mul(p.BaseScale)),
                            p.SharedMaterials[d],
                            p.Layer,
                            cam,  //camera
                            d,    //sub mesh index
                            null, //properties block
                            p.ShadowCastingMode,
                            p.ReceiveShadow,
                            null,  //probe anchor
                            LightProbeUsage.BlendProbes,
                            null); //proxy volume
                    }
                }
                else
                {
                    if (p.Billboard == null)
                    {
                        continue;
                    }
                    if (p.Billboard.material == null)
                    {
                        continue;
                    }
                    Vector3 lookDir = cam.transform.position - worldPos;
                    lookDir.y = 0;
                    Quaternion rotation      = Quaternion.LookRotation(-lookDir, Vector3.up);
                    Mesh       billboardMesh = ResourceManager.GetBillboardMesh(p.Billboard);
                    Graphics.DrawMesh(
                        billboardMesh,
                        Matrix4x4.TRS(worldPos + Vector3.up * p.PivotOffset, rotation, tree.Scale),
                        p.Billboard.material,
                        p.Layer,
                        cam,   //camera
                        0,     //sub mesh index
                        null,  //properties block
                        ShadowCastingMode.Off,
                        false, //receive shadow
                        null,  //probe anchor
                        LightProbeUsage.BlendProbes,
                        null); //proxy volume

                    if (p.ShadowCastingMode == ShadowCastingMode.Off)
                    {
                        continue;
                    }
                    if (firstDirLight == null)
                    {
                        continue;
                    }

                    Graphics.DrawMesh(
                        billboardMesh,
                        Matrix4x4.TRS(worldPos + Vector3.up * p.PivotOffset, billboardShadowCasterRotation, tree.Scale),
                        p.Billboard.material,
                        p.Layer,
                        cam,   //camera
                        0,     //sub mesh index
                        null,  //properties block
                        ShadowCastingMode.ShadowsOnly,
                        false, //receive shadow
                        null,  //probe anchor
                        LightProbeUsage.Off,
                        null); //proxy volume
                }
            }
        }
Example #6
0
        private static void RenderTreesInstanced_InstancedBillboard(GStylizedTerrain t, Camera cam, List <int> flags, List <Vector3> worldPositions)
        {
            List <GTreePrototype> prototypes = t.TerrainData.Foliage.Trees.Prototypes;
            List <GTreeInstance>  instances  = t.TerrainData.Foliage.TreeInstances;
            int prototypeCount     = prototypes.Count;
            int instanceCount      = instances.Count;
            int batchInstanceCount = 0;

            Light[] directionalLights = Light.GetLights(LightType.Directional, 0);
            Light   firstDirLight     = null;

            if (directionalLights.Length > 0)
            {
                firstDirLight = directionalLights[0];
            }
            Quaternion billboardShadowCasterRotation = Quaternion.Euler(0, firstDirLight.transform.root.eulerAngles.y, 0);

            for (int p = 0; p < prototypeCount; ++p)
            {
                for (int i = 0; i <= instanceCount; ++i)
                {
                    //render batch
                    if ((instanceCount == i ||
                         batchInstanceCount == MAX_INSTANCE_PER_BATCH) &&
                        batchInstanceCount > 0)
                    {
                        Mesh billboardMesh = ResourceManager.GetBillboardMesh(prototypes[p].Billboard);
                        Graphics.DrawMeshInstanced(
                            billboardMesh,
                            0,     //submesh index
                            prototypes[p].Billboard.material,
                            batchMatrices,
                            batchInstanceCount,
                            null,     //properties
                            ShadowCastingMode.Off,
                            false,    //receive shadow
                            prototypes[p].Layer,
                            cam,
                            LightProbeUsage.BlendProbes,
                            null);     //proxy volume

                        if (prototypes[p].ShadowCastingMode == ShadowCastingMode.Off)
                        {
                            continue;
                        }
                        if (firstDirLight == null)
                        {
                            continue;
                        }

                        Graphics.DrawMeshInstanced(
                            billboardMesh,
                            0,     //submesh index
                            prototypes[p].Billboard.material,
                            batchMatricesShadowCaster,
                            batchInstanceCount,
                            null,     //properties
                            ShadowCastingMode.ShadowsOnly,
                            false,    //receive shadow
                            prototypes[p].Layer,
                            cam,
                            LightProbeUsage.BlendProbes,
                            null);     //proxy volume

                        batchInstanceCount = 0;
                    }

                    if (instanceCount == i)
                    {
                        break;
                    }

                    if (flags[i] != FLAG_INSTANCED_BILLBOARD)
                    {
                        continue;
                    }
                    GTreeInstance tree = instances[i];
                    if (tree.PrototypeIndex != p)
                    {
                        continue;
                    }

                    Vector3 lookDir = cam.transform.position - worldPositions[i];
                    lookDir.y = 0;
                    Quaternion rotation = Quaternion.LookRotation(-lookDir, Vector3.up);
                    batchMatrices[batchInstanceCount]             = Matrix4x4.TRS(worldPositions[i] + Vector3.up * prototypes[p].PivotOffset, rotation, tree.Scale);
                    batchMatricesShadowCaster[batchInstanceCount] = Matrix4x4.TRS(worldPositions[i] + Vector3.up * prototypes[p].PivotOffset, billboardShadowCasterRotation, tree.Scale);
                    batchInstanceCount += 1;
                }
            }
        }
Example #7
0
        private static void RenderTreesInstanced_Instanced(GStylizedTerrain t, Camera cam, List <int> flags, List <Vector3> worldPositions)
        {
            List <GTreePrototype> prototypes = t.TerrainData.Foliage.Trees.Prototypes;
            List <GTreeInstance>  instances  = t.TerrainData.Foliage.TreeInstances;
            int prototypeCount     = prototypes.Count;
            int instanceCount      = instances.Count;
            int subMeshCount       = 0;
            int materialCount      = 0;
            int drawCallCount      = 0;
            int batchInstanceCount = 0;

            for (int p = 0; p < prototypeCount; ++p)
            {
                for (int i = 0; i <= instanceCount; ++i)
                {
                    //render batch
                    if ((instanceCount == i ||
                         batchInstanceCount == MAX_INSTANCE_PER_BATCH) &&
                        batchInstanceCount > 0)
                    {
                        subMeshCount  = prototypes[p].SharedMesh.subMeshCount;
                        materialCount = prototypes[p].SharedMaterials.Length;
                        drawCallCount = Mathf.Min(subMeshCount, materialCount);

                        for (int d = 0; d < drawCallCount; ++d)
                        {
                            Graphics.DrawMeshInstanced(
                                prototypes[p].SharedMesh,
                                d,
                                prototypes[p].SharedMaterials[d],
                                batchMatrices,
                                batchInstanceCount,
                                null, //properties
                                prototypes[p].ShadowCastingMode,
                                prototypes[p].ReceiveShadow,
                                prototypes[p].Layer,
                                cam,
                                LightProbeUsage.BlendProbes,
                                null); //proxy volume
                        }
                        batchInstanceCount = 0;
                    }

                    if (instanceCount == i)
                    {
                        break;
                    }

                    if (flags[i] != FLAG_INSTANCED)
                    {
                        continue;
                    }
                    GTreeInstance tree = instances[i];
                    if (tree.PrototypeIndex != p)
                    {
                        continue;
                    }
                    batchMatrices[batchInstanceCount] = Matrix4x4.TRS(
                        worldPositions[i] + Vector3.up * prototypes[p].PivotOffset,
                        tree.Rotation * prototypes[p].BaseRotation,
                        tree.Scale.Mul(prototypes[p].BaseScale));
                    batchInstanceCount += 1;
                }
            }
        }
Example #8
0
        private static void RenderTreesInstanced_NonInstancedBillboard(GStylizedTerrain t, Camera cam, List <int> flags, List <Vector3> worldPositions)
        {
            List <GTreePrototype> prototypes = t.TerrainData.Foliage.Trees.Prototypes;
            List <GTreeInstance>  instances  = t.TerrainData.Foliage.TreeInstances;
            int instanceCount = instances.Count;

            Light[] directionalLights = Light.GetLights(LightType.Directional, 0);
            Light   firstDirLight     = null;

            if (directionalLights.Length > 0)
            {
                firstDirLight = directionalLights[0];
            }
            Quaternion billboardShadowCasterRotation = Quaternion.Euler(0, firstDirLight.transform.root.eulerAngles.y, 0);

            for (int i = 0; i < instanceCount; ++i)
            {
                if (flags[i] != FLAG_NON_INSTANCED_BILLBOARD)
                {
                    continue;
                }
                GTreeInstance  tree  = instances[i];
                GTreePrototype proto = prototypes[tree.PrototypeIndex];

                Vector3 lookDir = cam.transform.position - worldPositions[i];
                lookDir.y = 0;
                Quaternion rotation      = Quaternion.LookRotation(-lookDir, Vector3.up);
                Mesh       billboardMesh = ResourceManager.GetBillboardMesh(proto.Billboard);
                Graphics.DrawMesh(
                    billboardMesh,
                    Matrix4x4.TRS(worldPositions[i] + Vector3.up * proto.PivotOffset, rotation, instances[i].Scale),
                    proto.Billboard.material,
                    proto.Layer,
                    cam,   //camera
                    0,     //sub mesh index
                    null,  //properties block
                    ShadowCastingMode.Off,
                    false, //receive shadow
                    null,  //probe anchor
                    LightProbeUsage.BlendProbes,
                    null); //proxy volume

                if (proto.ShadowCastingMode == ShadowCastingMode.Off)
                {
                    continue;
                }
                if (firstDirLight == null)
                {
                    continue;
                }

                Graphics.DrawMesh(
                    billboardMesh,
                    Matrix4x4.TRS(worldPositions[i], billboardShadowCasterRotation, instances[i].Scale),
                    proto.Billboard.material,
                    proto.Layer,
                    cam,   //camera
                    0,     //sub mesh index
                    null,  //properties block
                    ShadowCastingMode.ShadowsOnly,
                    false, //receive shadow
                    null,  //probe anchor
                    LightProbeUsage.Off,
                    null); //proxy volume
            }
        }
Example #9
0
        private static void PreprocessRendering(GStylizedTerrain t, Camera cam, List <int> flags, List <Vector3> worldPositions)
        {
            flags.Clear();
            worldPositions.Clear();

            List <GTreePrototype> prototypes = t.TerrainData.Foliage.Trees.Prototypes;
            List <GTreeInstance>  instances  = t.TerrainData.Foliage.TreeInstances;
            int prototypeCount = prototypes.Count;
            int instanceCount  = instances.Count;

            bool[] prototypeValidation = new bool[prototypeCount];
            for (int pIndex = 0; pIndex < prototypeCount; ++pIndex)
            {
                prototypeValidation[pIndex] = prototypes[pIndex].IsValid;
            }

            float   sqrTreeDistance      = t.TerrainData.Rendering.TreeDistance * t.TerrainData.Rendering.TreeDistance;
            float   sqrBillboardDistance = t.TerrainData.Rendering.BillboardStart * t.TerrainData.Rendering.BillboardStart;
            float   sqrDistance          = 0;
            Bounds  bound       = new Bounds();
            Vector3 boundSize   = Vector3.zero;
            Vector3 boundCenter = Vector3.zero;
            Vector3 dimension   = new Vector3(
                t.TerrainData.Geometry.Width,
                t.TerrainData.Geometry.Height,
                t.TerrainData.Geometry.Length);
            Vector3 localPos = Vector3.zero;
            Vector3 worldPos = Vector3.zero;
            bool    isInstancingEnabledForAllSharedMaterials = true;

            frustumPlanes = GeometryUtility.CalculateFrustumPlanes(cam);

            for (int i = 0; i < instanceCount; ++i)
            {
                GTreeInstance tree = instances[i];
                //invalid prototype index
                if (tree.PrototypeIndex < 0 || tree.PrototypeIndex >= prototypeCount)
                {
                    flags.Add(FLAG_CULLED);
                    worldPositions.Add(Vector3.zero);
                    continue;
                }

                if (prototypeValidation[tree.PrototypeIndex] == false)
                {
                    flags.Add(FLAG_CULLED);
                    worldPositions.Add(Vector3.zero);
                    continue;
                }

                GTreePrototype proto = prototypes[tree.PrototypeIndex];
                //cull layer
                if (cam.cullingMask >= 0 && (cam.cullingMask & (1 << proto.Layer)) == 0)
                {
                    flags.Add(FLAG_CULLED);
                    worldPositions.Add(Vector3.zero);
                    continue;
                }

                localPos.Set(
                    dimension.x * tree.Position.x,
                    dimension.y * tree.Position.y,
                    dimension.z * tree.Position.z);
                worldPos    = t.transform.TransformPoint(localPos);
                sqrDistance = Vector3.SqrMagnitude(worldPos - cam.transform.position);

                //cull distance
                if (sqrDistance > sqrTreeDistance)
                {
                    flags.Add(FLAG_CULLED);
                    worldPositions.Add(Vector3.zero);
                    continue;
                }

                //cull frustum
                boundSize.Set(
                    proto.SharedMesh.bounds.size.x * tree.Scale.x,
                    proto.SharedMesh.bounds.size.y * tree.Scale.y,
                    proto.SharedMesh.bounds.size.z * tree.Scale.z);
                boundCenter  = worldPos;
                bound.size   = boundSize;
                bound.center = boundCenter;

                if (!GeometryUtility.TestPlanesAABB(frustumPlanes, bound))
                {
                    flags.Add(FLAG_CULLED);
                    worldPositions.Add(Vector3.zero);
                    continue;
                }

                //cull no billboard
                if (sqrDistance >= sqrBillboardDistance &&
                    (proto.Billboard == null || proto.Billboard.material == null))
                {
                    flags.Add(FLAG_CULLED);
                    worldPositions.Add(Vector3.zero);
                    continue;
                }

                //the object will be rendered
                worldPositions.Add(worldPos);

                //determine render mode
                if (sqrDistance >= sqrBillboardDistance)
                {
                    if (proto.Billboard.material.enableInstancing)
                    {
                        flags.Add(FLAG_INSTANCED_BILLBOARD);
                    }
                    else
                    {
                        flags.Add(FLAG_NON_INSTANCED_BILLBOARD);
                    }
                }
                else
                {
                    isInstancingEnabledForAllSharedMaterials = true;
                    for (int mIndex = 0; mIndex < proto.SharedMaterials.Length; ++mIndex)
                    {
                        if (!proto.SharedMaterials[mIndex].enableInstancing)
                        {
                            isInstancingEnabledForAllSharedMaterials = false;
                            break;
                        }
                    }

                    if (isInstancingEnabledForAllSharedMaterials)
                    {
                        flags.Add(FLAG_INSTANCED);
                    }
                    else
                    {
                        flags.Add(FLAG_NON_INSTANCED);
                    }
                }
            }
        }
Example #10
0
 public int GetTreeMemStats()
 {
     return(TreeInstances.Count * GTreeInstance.GetStructSize());
 }