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); }
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); }
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; }
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); } } }