static void Gather() { // counting sorted billboards m_batches.Clear(); m_sortedNum = 0; PreGatherList(MyRenderProxy.BillboardsRead); PreGatherList(m_billboardsOnce); m_sortedBillboardsNum = m_sortedNum; m_unsorted = 0; m_sorted = 0; GatherList(MyRenderProxy.BillboardsRead); GatherList(m_billboardsOnce); Array.Sort(m_sortBuffer, 0, m_sortedNum); //Array.Reverse(m_sortBuffer, 0, m_sortedNum); //Array.Sort(m_sortBuffer, m_sortedNum, m_unsorted); var N = m_sorted + m_unsorted; var batch = new MyBillboardBatch(); //MyAssetTexture prevTexture = null; var prevTexId = TexId.NULL; int currentOffset = 0; if(N > 0) { var material = MyTransparentMaterials.GetMaterial(m_sortBuffer[0].Material); if(material.UseAtlas) { var item = m_atlasedTextures[material.Texture]; prevTexId = item.TextureId; } else { PreloadTexture(material.Texture); //prevTexture = MyTextureManager.GetTextureFast(material.Texture); prevTexId = MyTextures.GetTexture(material.Texture, MyTextureEnum.GUI, true); } } TexId batchTexId = TexId.NULL; MyTransparentMaterial prevMaterial = null; for(int i=0; i<N; i++) { var billboard = m_sortBuffer[i]; var material = MyTransparentMaterials.GetMaterial(billboard.Material); var billboardData = new MyBillboardData(); billboardData.CustomProjectionID = billboard.CustomViewProjection; billboardData.Color = billboard.Color; if (material.UseAtlas) { var atlasItem = m_atlasedTextures[material.Texture]; //billboardData.UvModifiers = new HalfVector4(atlasItem.UvOffsetScale); batchTexId = atlasItem.TextureId; } else { batchTexId = MyTextures.GetTexture(material.Texture, MyTextureEnum.GUI, true); } billboardData.Reflective = billboard.Reflectivity; Vector3D pos0 = billboard.Position0; Vector3D pos1 = billboard.Position1; Vector3D pos2 = billboard.Position2; Vector3D pos3 = billboard.Position3; if (billboard.ParentID != -1) { if (MyIDTracker<MyActor>.FindByID((uint)billboard.ParentID) != null) { var matrix = MyIDTracker<MyActor>.FindByID((uint)billboard.ParentID).WorldMatrix; Vector3D.Transform(ref pos0, ref matrix, out pos0); Vector3D.Transform(ref pos1, ref matrix, out pos1); Vector3D.Transform(ref pos2, ref matrix, out pos2); Vector3D.Transform(ref pos3, ref matrix, out pos3); } } if (billboard.CustomViewProjection != -1) { var billboardViewProjection = MyRenderProxy.BillboardsViewProjectionRead[billboard.CustomViewProjection]; //pos0 -= MyEnvironment.CameraPosition; //pos1 -= MyEnvironment.CameraPosition; //pos2 -= MyEnvironment.CameraPosition; //pos3 -= MyEnvironment.CameraPosition; } else { pos0 -= MyEnvironment.CameraPosition; pos1 -= MyEnvironment.CameraPosition; pos2 -= MyEnvironment.CameraPosition; pos3 -= MyEnvironment.CameraPosition; } var normal = Vector3.Cross(pos1 - pos0, pos2 - pos0); normal.Normalize(); billboardData.Normal = normal; m_vertexData[i * 4 + 0].Position = pos0; m_vertexData[i * 4 + 1].Position = pos1; m_vertexData[i * 4 + 2].Position = pos2; m_vertexData[i * 4 + 3].Position = pos3; var uv0 = new Vector2(material.UVOffset.X + billboard.UVOffset.X, material.UVOffset.Y + billboard.UVOffset.Y); var uv1 = new Vector2(material.UVOffset.X + material.UVSize.X + billboard.UVOffset.X, material.UVOffset.Y + billboard.UVOffset.Y); var uv2 = new Vector2(material.UVOffset.X + material.UVSize.X + billboard.UVOffset.X, material.UVOffset.Y + material.UVSize.Y + billboard.UVOffset.Y); var uv3 = new Vector2(material.UVOffset.X + billboard.UVOffset.X, material.UVOffset.Y + material.UVSize.Y + billboard.UVOffset.Y); if (material.UseAtlas) { var atlasItem = m_atlasedTextures[material.Texture]; uv0 = uv0 * new Vector2(atlasItem.UvOffsetScale.Z, atlasItem.UvOffsetScale.W) + new Vector2(atlasItem.UvOffsetScale.X, atlasItem.UvOffsetScale.Y); uv1 = uv1 * new Vector2(atlasItem.UvOffsetScale.Z, atlasItem.UvOffsetScale.W) + new Vector2(atlasItem.UvOffsetScale.X, atlasItem.UvOffsetScale.Y); uv2 = uv2 * new Vector2(atlasItem.UvOffsetScale.Z, atlasItem.UvOffsetScale.W) + new Vector2(atlasItem.UvOffsetScale.X, atlasItem.UvOffsetScale.Y); uv3 = uv3 * new Vector2(atlasItem.UvOffsetScale.Z, atlasItem.UvOffsetScale.W) + new Vector2(atlasItem.UvOffsetScale.X, atlasItem.UvOffsetScale.Y); } m_vertexData[i * 4 + 0].Texcoord = new HalfVector2(uv0); m_vertexData[i * 4 + 1].Texcoord = new HalfVector2(uv1); m_vertexData[i * 4 + 2].Texcoord = new HalfVector2(uv2); m_vertexData[i * 4 + 3].Texcoord = new HalfVector2(uv3); pos0.AssertIsValid(); pos1.AssertIsValid(); pos2.AssertIsValid(); pos3.AssertIsValid(); MyTriangleBillboard triBillboard = billboard as MyTriangleBillboard; if(triBillboard != null) { m_vertexData[i * 4 + 3].Position = pos2; // second triangle will die in rasterizer m_vertexData[i * 4 + 0].Texcoord = new HalfVector2(triBillboard.UV0); m_vertexData[i * 4 + 1].Texcoord = new HalfVector2(triBillboard.UV1); m_vertexData[i * 4 + 2].Texcoord = new HalfVector2(triBillboard.UV2); billboardData.Normal = triBillboard.Normal0; // pew pew pew :O } m_billboardData[i] = billboardData; bool closeBatch = (batchTexId != prevTexId) || ((i == m_sortedNum) && (i > 0)); if(closeBatch) { batch = new MyBillboardBatch(); batch.Offset = currentOffset; batch.Num = i - currentOffset; batch.Texture = prevTexId != TexId.NULL ? MyTextures.Views[prevTexId.Index] : null; batch.Lit = prevMaterial.CanBeAffectedByOtherLights; m_batches.Add(batch); currentOffset = i; } prevTexId = batchTexId; prevMaterial = material; } if(N > 0) { batch = new MyBillboardBatch(); batch.Offset = currentOffset; batch.Num = N - currentOffset; batch.Texture = prevTexId != TexId.NULL ? MyTextures.GetView(prevTexId) : null; batch.Lit = prevMaterial.CanBeAffectedByOtherLights; m_batches.Add(batch); } }
static void Gather() { // counting sorted billboards m_batches.Clear(); m_sortedNum = 0; PreGatherList(MyRenderProxy.BillboardsRead); PreGatherList(m_billboardsOnce); m_sortedBillboardsNum = m_sortedNum; m_unsorted = 0; m_sorted = 0; GatherList(MyRenderProxy.BillboardsRead); GatherList(m_billboardsOnce); Array.Sort(m_sortBuffer, 0, m_sortedNum); //Array.Reverse(m_sortBuffer, 0, m_sortedNum); //Array.Sort(m_sortBuffer, m_sortedNum, m_unsorted); var N = m_sorted + m_unsorted; var batch = new MyBillboardBatch(); //MyAssetTexture prevTexture = null; var prevTexId = TexId.NULL; int currentOffset = 0; if (N > 0) { var material = MyTransparentMaterials.GetMaterial(m_sortBuffer[0].Material); if (material.UseAtlas) { var item = m_atlasedTextures[material.Texture]; prevTexId = item.TextureId; } else { PreloadTexture(material.Texture); //prevTexture = MyTextureManager.GetTextureFast(material.Texture); prevTexId = MyTextures.GetTexture(material.Texture, MyTextureEnum.GUI, true); } } TexId batchTexId = TexId.NULL; MyTransparentMaterial prevMaterial = null; for (int i = 0; i < N; i++) { var billboard = m_sortBuffer[i]; var material = MyTransparentMaterials.GetMaterial(billboard.Material); var billboardData = new MyBillboardData(); billboardData.CustomProjectionID = billboard.CustomViewProjection; billboardData.Color = billboard.Color; if (material.UseAtlas) { var atlasItem = m_atlasedTextures[material.Texture]; //billboardData.UvModifiers = new HalfVector4(atlasItem.UvOffsetScale); batchTexId = atlasItem.TextureId; } else { batchTexId = MyTextures.GetTexture(material.Texture, MyTextureEnum.GUI, true); } billboardData.Reflective = billboard.Reflectivity; Vector3D pos0 = billboard.Position0; Vector3D pos1 = billboard.Position1; Vector3D pos2 = billboard.Position2; Vector3D pos3 = billboard.Position3; if (billboard.ParentID != -1) { if (MyIDTracker <MyActor> .FindByID((uint)billboard.ParentID) != null) { var matrix = MyIDTracker <MyActor> .FindByID((uint)billboard.ParentID).WorldMatrix; Vector3D.Transform(ref pos0, ref matrix, out pos0); Vector3D.Transform(ref pos1, ref matrix, out pos1); Vector3D.Transform(ref pos2, ref matrix, out pos2); Vector3D.Transform(ref pos3, ref matrix, out pos3); } } if (billboard.CustomViewProjection != -1) { var billboardViewProjection = MyRenderProxy.BillboardsViewProjectionRead[billboard.CustomViewProjection]; //pos0 -= MyEnvironment.CameraPosition; //pos1 -= MyEnvironment.CameraPosition; //pos2 -= MyEnvironment.CameraPosition; //pos3 -= MyEnvironment.CameraPosition; } else { pos0 -= MyEnvironment.CameraPosition; pos1 -= MyEnvironment.CameraPosition; pos2 -= MyEnvironment.CameraPosition; pos3 -= MyEnvironment.CameraPosition; } var normal = Vector3.Cross(pos1 - pos0, pos2 - pos0); normal.Normalize(); billboardData.Normal = normal; m_vertexData[i * 4 + 0].Position = pos0; m_vertexData[i * 4 + 1].Position = pos1; m_vertexData[i * 4 + 2].Position = pos2; m_vertexData[i * 4 + 3].Position = pos3; var uv0 = new Vector2(material.UVOffset.X + billboard.UVOffset.X, material.UVOffset.Y + billboard.UVOffset.Y); var uv1 = new Vector2(material.UVOffset.X + material.UVSize.X + billboard.UVOffset.X, material.UVOffset.Y + billboard.UVOffset.Y); var uv2 = new Vector2(material.UVOffset.X + material.UVSize.X + billboard.UVOffset.X, material.UVOffset.Y + material.UVSize.Y + billboard.UVOffset.Y); var uv3 = new Vector2(material.UVOffset.X + billboard.UVOffset.X, material.UVOffset.Y + material.UVSize.Y + billboard.UVOffset.Y); if (material.UseAtlas) { var atlasItem = m_atlasedTextures[material.Texture]; uv0 = uv0 * new Vector2(atlasItem.UvOffsetScale.Z, atlasItem.UvOffsetScale.W) + new Vector2(atlasItem.UvOffsetScale.X, atlasItem.UvOffsetScale.Y); uv1 = uv1 * new Vector2(atlasItem.UvOffsetScale.Z, atlasItem.UvOffsetScale.W) + new Vector2(atlasItem.UvOffsetScale.X, atlasItem.UvOffsetScale.Y); uv2 = uv2 * new Vector2(atlasItem.UvOffsetScale.Z, atlasItem.UvOffsetScale.W) + new Vector2(atlasItem.UvOffsetScale.X, atlasItem.UvOffsetScale.Y); uv3 = uv3 * new Vector2(atlasItem.UvOffsetScale.Z, atlasItem.UvOffsetScale.W) + new Vector2(atlasItem.UvOffsetScale.X, atlasItem.UvOffsetScale.Y); } m_vertexData[i * 4 + 0].Texcoord = new HalfVector2(uv0); m_vertexData[i * 4 + 1].Texcoord = new HalfVector2(uv1); m_vertexData[i * 4 + 2].Texcoord = new HalfVector2(uv2); m_vertexData[i * 4 + 3].Texcoord = new HalfVector2(uv3); pos0.AssertIsValid(); pos1.AssertIsValid(); pos2.AssertIsValid(); pos3.AssertIsValid(); MyTriangleBillboard triBillboard = billboard as MyTriangleBillboard; if (triBillboard != null) { m_vertexData[i * 4 + 3].Position = pos2; // second triangle will die in rasterizer m_vertexData[i * 4 + 0].Texcoord = new HalfVector2(triBillboard.UV0); m_vertexData[i * 4 + 1].Texcoord = new HalfVector2(triBillboard.UV1); m_vertexData[i * 4 + 2].Texcoord = new HalfVector2(triBillboard.UV2); billboardData.Normal = triBillboard.Normal0; // pew pew pew :O } m_billboardData[i] = billboardData; bool closeBatch = (batchTexId != prevTexId) || ((i == m_sortedNum) && (i > 0)); if (closeBatch) { batch = new MyBillboardBatch(); batch.Offset = currentOffset; batch.Num = i - currentOffset; batch.Texture = prevTexId != TexId.NULL ? MyTextures.Views[prevTexId.Index] : null; batch.Lit = prevMaterial.CanBeAffectedByOtherLights; m_batches.Add(batch); currentOffset = i; } prevTexId = batchTexId; prevMaterial = material; } if (N > 0) { batch = new MyBillboardBatch(); batch.Offset = currentOffset; batch.Num = N - currentOffset; batch.Texture = prevTexId != TexId.NULL ? MyTextures.GetView(prevTexId) : null; batch.Lit = prevMaterial.CanBeAffectedByOtherLights; m_batches.Add(batch); } }