예제 #1
0
        internal static bool ShouldHaveFoliage(this MeshId meshId)
        {
            int partsNum = MyMeshes.GetLodMesh(meshId, 0).Info.PartsNum;

            bool shouldHaveFoliage = false;

            for (int partIndex = 0; partIndex < partsNum; ++partIndex)
            {
                var triple = MyMeshes.GetVoxelPart(meshId, partIndex).Info.MaterialTriple;

                if (triple.I0 >= 0 && MyVoxelMaterials1.Table[triple.I0].HasFoliage)
                {
                    shouldHaveFoliage = true;
                    break;
                }
                if (triple.I1 >= 0 && MyVoxelMaterials1.Table[triple.I1].HasFoliage)
                {
                    shouldHaveFoliage = true;
                    break;
                }
                if (triple.I2 >= 0 && MyVoxelMaterials1.Table[triple.I2].HasFoliage)
                {
                    shouldHaveFoliage = true;
                    break;
                }
            }
            return(shouldHaveFoliage);
        }
예제 #2
0
        internal bool ShouldHaveFoliage()
        {
            var  mesh              = Owner.GetRenderable().GetModel();
            int  voxelLod          = MyMeshes.GetVoxelInfo(mesh).Lod;
            bool voxelMeshNotReady = voxelLod > LodLimit;

            if (voxelMeshNotReady)
            {
                return(false);
            }

            int partsNum;

            if (MyMeshes.IsMergedVoxelMesh(mesh))
            {
                partsNum = MyMeshes.GetMergedLodMesh(mesh, 0).Info.PartsNum;
            }
            else
            {
                partsNum = MyMeshes.GetLodMesh(mesh, 0).Info.PartsNum;
            }

            // only stream stones for lod0
            if (voxelLod > 0)
            {
                bool allStone = true;
                for (int i = 0; i < partsNum; i++)
                {
                    var triple = MyMeshes.GetVoxelPart(mesh, i).Info.MaterialTriple;
                    if (triple.I0 != -1 && MyVoxelMaterials1.Table[triple.I0].HasFoliage && MyVoxelMaterials1.Table[triple.I0].FoliageType == 0)
                    {
                        allStone = false;
                        break;
                    }
                    if (triple.I1 != -1 && MyVoxelMaterials1.Table[triple.I1].HasFoliage && MyVoxelMaterials1.Table[triple.I1].FoliageType == 0)
                    {
                        allStone = false;
                        break;
                    }
                    if (triple.I2 != -1 && MyVoxelMaterials1.Table[triple.I2].HasFoliage && MyVoxelMaterials1.Table[triple.I2].FoliageType == 0)
                    {
                        allStone = false;
                        break;
                    }
                }
                if (allStone)
                {
                    return(false);
                }
            }

            return(true);
        }
예제 #3
0
        internal unsafe void FillStreams()
        {
            bool alreadyFilled = m_streams != null && m_streams.Count > 0;

            if (alreadyFilled)
            {
                return;
            }

            var mesh = Owner.GetRenderable().GetModel();

            int voxelLod = MyMeshes.GetVoxelInfo(mesh).Lod;

            if (!Owner.IsVisible)
            {
                return;
            }

            int partsNum;

            if (MyMeshes.IsMergedVoxelMesh(mesh))
            {
                partsNum = MyMeshes.GetMergedLodMesh(mesh, 0).Info.PartsNum;
            }
            else
            {
                partsNum = MyMeshes.GetLodMesh(mesh, 0).Info.PartsNum;
            }

            m_streams = new Dictionary <int, MyFoliageStream>();

            // analyze
            for (int partIndex = 0; partIndex < partsNum; ++partIndex)
            {
                var partInfo = MyMeshes.GetVoxelPart(mesh, partIndex).Info;
                var triple   = partInfo.MaterialTriple;

                if (triple.I0 != -1 && MyVoxelMaterials1.Table[triple.I0].HasFoliage)
                {
                    PrepareStream(triple.I0, partInfo.IndexCount / 3, voxelLod);
                }
                if (triple.I1 != -1 && MyVoxelMaterials1.Table[triple.I1].HasFoliage)
                {
                    PrepareStream(triple.I1, partInfo.IndexCount / 3, voxelLod);
                }
                if (triple.I2 != -1 && MyVoxelMaterials1.Table[triple.I2].HasFoliage)
                {
                    PrepareStream(triple.I2, partInfo.IndexCount / 3, voxelLod);
                }
            }

            // prepare
            foreach (var stream in m_streams.Values)
            {
                stream.AllocateStreamOutBuffer(sizeof(Vector3) + sizeof(uint));
            }

            // analyze
            for (int partIndex = 0; partIndex < partsNum; partIndex++)
            {
                var partInfo = MyMeshes.GetVoxelPart(mesh, partIndex).Info;
                var triple   = partInfo.MaterialTriple;

                if (triple.I0 != -1 && MyVoxelMaterials1.Table[triple.I0].HasFoliage)
                {
                    FillStreamWithTerrainBatch(triple.I0, 0,
                                               partInfo.IndexCount, partInfo.StartIndex, 0);
                }
                if (triple.I1 != -1 && MyVoxelMaterials1.Table[triple.I1].HasFoliage)
                {
                    FillStreamWithTerrainBatch(triple.I1, 1,
                                               partInfo.IndexCount, partInfo.StartIndex, 0);
                }
                if (triple.I2 != -1 && MyVoxelMaterials1.Table[triple.I2].HasFoliage)
                {
                    FillStreamWithTerrainBatch(triple.I2, 2,
                                               partInfo.IndexCount, partInfo.StartIndex, 0);
                }
            }
        }
        private void CreateRenderableProxyForPart(int lodIndex, int objectConstantsSize, int proxyIndex, int partIndex, bool shadowsOnly)
        {
            MyRenderLod lod       = m_lods[lodIndex];
            var         partId    = MyMeshes.GetVoxelPart(Mesh, partIndex);
            var         technique = partId.Info.MaterialTriple.IsMultimaterial() && !shadowsOnly ? MyVoxelMesh.MULTI_MATERIAL_TAG : MyVoxelMesh.SINGLE_MATERIAL_TAG;

            MyRenderableProxy renderableProxy = lod.RenderableProxies[proxyIndex];

            renderableProxy.WorldMatrix = Owner.WorldMatrix;
            //lod.RenderableProxies[p].ObjectData.LocalMatrix = m_owner.WorldMatrix;

            renderableProxy.NonVoxelObjectData = MyObjectDataNonVoxel.Invalid;
            renderableProxy.VoxelCommonObjectData.VoxelOffset         = m_voxelOffset;
            renderableProxy.VoxelCommonObjectData.MassiveCenterRadius = Vector4.Zero; // Set in UpdateLodState
            renderableProxy.VoxelCommonObjectData.VoxelScale          = m_voxelScale;

            MyStringId shaderMaterial = MyStringId.GetOrCompute(MapTechniqueToShaderMaterial(technique));

            Mesh.AssignLodMeshToProxy(renderableProxy);
            AssignShadersToProxy(renderableProxy, shaderMaterial, lod.VertexLayout1, lod.VertexShaderFlags | MapTechniqueToShaderMaterialFlags(technique) | MyShaderUnifiedFlags.DITHERED);

            var partInfo = partId.Info;

            MyDrawSubmesh drawSubmesh;

            if (shadowsOnly)
            {
                drawSubmesh = new MyDrawSubmesh
                {
                    BaseVertex   = 0,
                    StartIndex   = 0,
                    IndexCount   = Mesh.GetIndexCount(),
                    BonesMapping = null,
                    MaterialId   = MyVoxelMaterials1.GetMaterialProxyId(partId.Info.MaterialTriple),
                    Flags        = MyDrawSubmesh.MySubmeshFlags.Depth
                };
            }
            else
            {
                drawSubmesh = new MyDrawSubmesh
                {
                    BaseVertex   = partInfo.BaseVertex,
                    StartIndex   = partInfo.StartIndex,
                    IndexCount   = partInfo.IndexCount,
                    BonesMapping = null,
                    MaterialId   = MyVoxelMaterials1.GetMaterialProxyId(partId.Info.MaterialTriple),
                    Flags        = MyDrawSubmesh.MySubmeshFlags.Gbuffer | MyDrawSubmesh.MySubmeshFlags.Forward
                };
            }

            lod.RenderableProxies[proxyIndex].DrawSubmesh      = drawSubmesh;
            lod.RenderableProxies[proxyIndex].SkinningMatrices = null;

            lod.RenderableProxies[proxyIndex].ObjectBuffer  = MyCommon.GetObjectCB(objectConstantsSize);
            lod.RenderableProxies[proxyIndex].InstanceCount = m_instanceCount;
            lod.RenderableProxies[proxyIndex].StartInstance = m_startInstance;
            lod.RenderableProxies[proxyIndex].Flags         = MapTechniqueToRenderableFlags(technique) | m_additionalFlags;
            lod.RenderableProxies[proxyIndex].Type          = MapTechniqueToMaterialType(technique);
            lod.RenderableProxies[proxyIndex].Parent        = this;
            lod.RenderableProxies[proxyIndex].Lod           = 0;
            lod.RenderableProxies[proxyIndex].Instancing    = m_instancing;

            AnyDrawOutsideViewDistance |= lod.RenderableProxies[proxyIndex].Flags.HasFlags(MyRenderableProxyFlags.DrawOutsideViewDistance);

            ulong sortingKey = 0;

            My64BitValueHelper.SetBits(ref sortingKey, 36, 2, (ulong)lod.RenderableProxies[proxyIndex].Type);
            My64BitValueHelper.SetBits(ref sortingKey, 32, 4, (ulong)drawSubmesh.MaterialId.Index);
            My64BitValueHelper.SetBits(ref sortingKey, 26, 6, (ulong)MyShaderMaterial.GetID(MapTechniqueToShaderMaterial(technique)));
            My64BitValueHelper.SetBits(ref sortingKey, 22, 4, (ulong)m_voxelLod);
            My64BitValueHelper.SetBits(ref sortingKey, 16, 6, (ulong)lod.VertexShaderFlags);
            //My64BitValueHelper.SetBits(ref sortingKey, 14, 6, (ulong)lod.VertexLayout1.Index);
            //My64BitValueHelper.SetBits(ref sortingKey, 0, 14, (ulong)m_owner.ID);

            lod.SortingKeys[proxyIndex] = sortingKey;
        }
        private void CreateRenderableProxyForPart(MyRenderLod lod, int objectConstantsSize, int proxyIndex, int partIndex, bool shadowsOnly)
        {
            var partId    = MyMeshes.GetVoxelPart(Mesh, partIndex);
            var technique = partId.Info.MaterialTriple.IsMultimaterial() ? MyVoxelMesh.MULTI_MATERIAL_TAG : MyVoxelMesh.SINGLE_MATERIAL_TAG;

            if (shadowsOnly)
            {
                technique = MyVoxelMesh.SINGLE_MATERIAL_TAG;
            }

            lod.RenderableProxies[proxyIndex].WorldMatrix = Owner.WorldMatrix;
            //lod.RenderableProxies[p].ObjectData.LocalMatrix = m_owner.WorldMatrix;

            lod.RenderableProxies[proxyIndex].NonVoxelObjectData = MyObjectDataNonVoxel.Invalid;
            lod.RenderableProxies[proxyIndex].VoxelCommonObjectData.VoxelOffset         = m_voxelOffset;
            lod.RenderableProxies[proxyIndex].VoxelCommonObjectData.MassiveCenterRadius = Vector4.Zero; // Set in UpdateLodState
            lod.RenderableProxies[proxyIndex].VoxelCommonObjectData.VoxelScale          = m_voxelScale;


            AssignLodMeshToProxy(Mesh, lod.RenderableProxies[proxyIndex]);
            lod.RenderableProxies[proxyIndex].DepthShaders = MyMaterialShaders.Get(
                X.TEXT(MapTechniqueToShaderMaterial(technique)),
                X.TEXT(MyGeometryRenderer.DEFAULT_DEPTH_PASS),
                lod.VertexLayout1,
                lod.VertexShaderFlags | MyShaderUnifiedFlags.DEPTH_ONLY | MapTechniqueToShaderMaterialFlags(technique) | MyShaderUnifiedFlags.DITHERED);
            lod.RenderableProxies[proxyIndex].Shaders = MyMaterialShaders.Get(
                X.TEXT(MapTechniqueToShaderMaterial(technique)),
                X.TEXT(MyGeometryRenderer.DEFAULT_OPAQUE_PASS),
                lod.VertexLayout1,
                lod.VertexShaderFlags | MapTechniqueToShaderMaterialFlags(technique) | MyShaderUnifiedFlags.DITHERED);
            lod.RenderableProxies[proxyIndex].ForwardShaders = MyMaterialShaders.Get(
                X.TEXT(MapTechniqueToShaderMaterial(technique)),
                X.TEXT(MyGeometryRenderer.DEFAULT_FORWARD_PASS),
                lod.VertexLayout1,
                lod.VertexShaderFlags | MapTechniqueToShaderMaterialFlags(technique) | MyShaderUnifiedFlags.DITHERED);

            var partInfo = partId.Info;

            MyDrawSubmesh drawSubmesh;

            if (shadowsOnly)
            {
                MyMeshBuffers buffers;
                if (MyMeshes.IsMergedVoxelMesh(Mesh))
                {
                    buffers = MyMeshes.GetMergedLodMesh(Mesh, 0).Buffers;
                }
                else
                {
                    buffers = MyMeshes.GetLodMesh(Mesh, 0).Buffers;
                }

                drawSubmesh = new MyDrawSubmesh
                {
                    BaseVertex   = 0,
                    StartIndex   = 0,
                    IndexCount   = buffers.IB.Capacity,
                    BonesMapping = null,
                    MaterialId   = MyVoxelMaterials1.GetMaterialProxyId(partId.Info.MaterialTriple),
                    Flags        = MyDrawSubmesh.MySubmeshFlags.Depth
                };
            }
            else
            {
                drawSubmesh = new MyDrawSubmesh
                {
                    BaseVertex   = partInfo.BaseVertex,
                    StartIndex   = partInfo.StartIndex,
                    IndexCount   = partInfo.IndexCount,
                    BonesMapping = null,
                    MaterialId   = MyVoxelMaterials1.GetMaterialProxyId(partId.Info.MaterialTriple),
                    Flags        = MyDrawSubmesh.MySubmeshFlags.Gbuffer | MyDrawSubmesh.MySubmeshFlags.Forward
                };
            }

            lod.RenderableProxies[proxyIndex].DrawSubmesh      = drawSubmesh;
            lod.RenderableProxies[proxyIndex].SkinningMatrices = null;

            lod.RenderableProxies[proxyIndex].ObjectBuffer  = MyCommon.GetObjectCB(objectConstantsSize);
            lod.RenderableProxies[proxyIndex].InstanceCount = m_instanceCount;
            lod.RenderableProxies[proxyIndex].StartInstance = m_startInstance;
            lod.RenderableProxies[proxyIndex].Flags         = MapTechniqueToRenderableFlags(technique) | m_additionalFlags;
            lod.RenderableProxies[proxyIndex].Type          = MapTechniqueToMaterialType(technique);
            lod.RenderableProxies[proxyIndex].Parent        = this;
            lod.RenderableProxies[proxyIndex].Lod           = 0;
            lod.RenderableProxies[proxyIndex].Instancing    = m_instancing;

            AnyDrawOutsideViewDistance |= lod.RenderableProxies[proxyIndex].Flags.HasFlags(MyRenderableProxyFlags.DrawOutsideViewDistance);

            ulong sortingKey = 0;

            My64BitValueHelper.SetBits(ref sortingKey, 36, 2, (ulong)lod.RenderableProxies[proxyIndex].Type);
            My64BitValueHelper.SetBits(ref sortingKey, 32, 4, (ulong)drawSubmesh.MaterialId.Index);
            My64BitValueHelper.SetBits(ref sortingKey, 26, 6, (ulong)MyShaderMaterial.GetID(MapTechniqueToShaderMaterial(technique)));
            My64BitValueHelper.SetBits(ref sortingKey, 22, 4, (ulong)m_voxelLod);
            My64BitValueHelper.SetBits(ref sortingKey, 16, 6, (ulong)lod.VertexShaderFlags);
            //My64BitValueHelper.SetBits(ref sortingKey, 14, 6, (ulong)lod.VertexLayout1.Index);
            //My64BitValueHelper.SetBits(ref sortingKey, 0, 14, (ulong)m_owner.ID);

            lod.SortingKeys[proxyIndex] = sortingKey;
        }
예제 #6
0
        internal void FillStreams()
        {
            var mesh = m_owner.GetRenderable().GetModel();


            bool voxelMeshNotReady = m_owner.m_visible == false || MyMeshes.GetVoxelInfo(mesh).Lod > 4;
            bool alreadyFilled     = m_streams != null;

            if (voxelMeshNotReady || alreadyFilled)
            {
                return;
            }

            m_streams = new Dictionary <int, MyFoliageStream>();

            // cleanup
            foreach (var kv in m_streams)
            {
                kv.Value.ResetAllocationSize();
            }

            var lodMesh = MyMeshes.GetLodMesh(mesh, 0);
            // analyze
            var voxelLod = MyMeshes.GetVoxelInfo(mesh).Lod;

            for (int i = 0; i < lodMesh.Info.PartsNum; i++)
            {
                var partInfo = MyMeshes.GetVoxelPart(mesh, i).Info;
                var triple   = partInfo.MaterialTriple;

                if (triple.I0 != -1 && MyVoxelMaterials1.Table[triple.I0].HasFoliage)
                {
                    PrepareStream(triple.I0, partInfo.IndexCount / 3, voxelLod);
                }
                if (triple.I1 != -1 && MyVoxelMaterials1.Table[triple.I1].HasFoliage)
                {
                    PrepareStream(triple.I1, partInfo.IndexCount / 3, voxelLod);
                }
                if (triple.I2 != -1 && MyVoxelMaterials1.Table[triple.I2].HasFoliage)
                {
                    PrepareStream(triple.I2, partInfo.IndexCount / 3, voxelLod);
                }
            }

            // prepare
            foreach (var kv in m_streams)
            {
                kv.Value.AllocateStreamOutBuffer();
            }

            // analyze
            for (int i = 0; i < lodMesh.Info.PartsNum; i++)
            {
                var partInfo = MyMeshes.GetVoxelPart(mesh, i).Info;
                var triple   = partInfo.MaterialTriple;

                if (triple.I0 != -1 && MyVoxelMaterials1.Table[triple.I0].HasFoliage)
                {
                    FillStreamWithTerrainBatch(triple.I0, 0,
                                               partInfo.IndexCount, partInfo.StartIndex, 0);// kv.Value.vertexOffset);
                }
                if (triple.I1 != -1 && MyVoxelMaterials1.Table[triple.I1].HasFoliage)
                {
                    FillStreamWithTerrainBatch(triple.I1, 1,
                                               partInfo.IndexCount, partInfo.StartIndex, 0);//kv.Value.vertexOffset);
                }
                if (triple.I2 != -1 && MyVoxelMaterials1.Table[triple.I2].HasFoliage)
                {
                    FillStreamWithTerrainBatch(triple.I2, 2,
                                               partInfo.IndexCount, partInfo.StartIndex, 0);//kv.Value.vertexOffset);
                }
            }
        }