/// <summary> /// Renders a polygon from a given set of unique vertex coordinates. Triangles are defined by their /// indices and the tex coords are parallel to the vertex list. /// </summary> public static void AddTriangles(IReadOnlyList <int> indices, IReadOnlyList <Vector2> vertices, ref PolyMaterial mat, MatrixD[] matrixRef) { var bbPool = instance.bbPoolBack; var bbDataBack = instance.flatTriangleList; var bbBuf = instance.bbBuf; var matList = instance.matrixBuf; var matTable = instance.matrixTable; // Find matrix index in table or add it int matrixID; if (!matTable.TryGetValue(matrixRef, out matrixID)) { matrixID = matList.Count; matList.Add(matrixRef[0]); matTable.Add(matrixRef, matrixID); } // Get triangle count, ensure enough billboards are in the pool and add them to the // render queue before writing QB data to buffer int triangleCount = indices.Count / 3, bbRemaining = bbPool.Count - bbDataBack.Count, bbToAdd = Math.Max(triangleCount - bbRemaining, 0); instance.AddNewBB(bbToAdd); for (int i = bbDataBack.Count; i < triangleCount + bbDataBack.Count; i++) { bbBuf.Add(bbPool[i]); } MyTransparentGeometry.AddBillboards(bbBuf, false); bbBuf.Clear(); bbDataBack.EnsureCapacity(bbDataBack.Count + triangleCount); for (int i = 0; i < indices.Count; i += 3) { var bb = new FlatTriangleBillboardData { Item1 = BlendTypeEnum.PostPP, Item2 = new Vector2I(bbDataBack.Count, matrixID), Item3 = mat.textureID, Item4 = new MyTuple <Vector4, BoundingBox2?>(mat.bbColor, null), Item5 = new MyTuple <Vector2, Vector2, Vector2> ( mat.texCoords[indices[i]], mat.texCoords[indices[i + 1]], mat.texCoords[indices[i + 2]] ), Item6 = new MyTuple <Vector2, Vector2, Vector2> ( vertices[indices[i]], vertices[indices[i + 1]], vertices[indices[i + 2]] ), }; bbDataBack.Add(bb); } }
/// <summary> /// Queues a quad billboard for rendering /// </summary> public static void AddQuad(ref FlatQuad quad, ref BoundedQuadMaterial mat, MatrixD[] matrixRef, BoundingBox2?mask = null) { var bbPool = instance.bbPoolBack; var bbDataBack = instance.flatTriangleList; var matList = instance.matrixBuf; var matTable = instance.matrixTable; // Find matrix index in table or add it int matrixID; if (!matTable.TryGetValue(matrixRef, out matrixID)) { matrixID = matList.Count; matList.Add(matrixRef[0]); matTable.Add(matrixRef, matrixID); } // Mask bounding check. Null mask if not intersecting. BoundingBox2? maskBox = mask; ContainmentType containment = ContainmentType.Contains; if (maskBox != null) { BoundingBox2 bounds = new BoundingBox2(quad.Point2, quad.Point0); maskBox.Value.Contains(ref bounds, out containment); if (containment == ContainmentType.Contains) { maskBox = null; } } if (containment != ContainmentType.Disjoint) { int indexL = bbDataBack.Count, indexR = bbDataBack.Count + 1; var bbL = new FlatTriangleBillboardData { Item1 = BlendTypeEnum.PostPP, Item2 = new Vector2I(bbDataBack.Count, matrixID), Item3 = mat.textureID, Item4 = new MyTuple <Vector4, BoundingBox2?>(mat.bbColor, maskBox), Item5 = new MyTuple <Vector2, Vector2, Vector2> ( new Vector2(mat.texBounds.Max.X, mat.texBounds.Min.Y), // 1 mat.texBounds.Max, // 0 new Vector2(mat.texBounds.Min.X, mat.texBounds.Max.Y) // 3 ), Item6 = new MyTuple <Vector2, Vector2, Vector2> ( quad.Point0, quad.Point1, quad.Point2 ), }; var bbR = new FlatTriangleBillboardData { Item1 = BlendTypeEnum.PostPP, Item2 = new Vector2I(bbDataBack.Count + 1, matrixID), Item3 = mat.textureID, Item4 = new MyTuple <Vector4, BoundingBox2?>(mat.bbColor, maskBox), Item5 = new MyTuple <Vector2, Vector2, Vector2> ( new Vector2(mat.texBounds.Max.X, mat.texBounds.Min.Y), // 1 new Vector2(mat.texBounds.Min.X, mat.texBounds.Max.Y), // 3 mat.texBounds.Min // 2 ), Item6 = new MyTuple <Vector2, Vector2, Vector2> ( quad.Point0, quad.Point2, quad.Point3 ), }; bbDataBack.Add(bbL); bbDataBack.Add(bbR); if (indexR >= bbPool.Count) { instance.AddNewBB(indexR - (bbPool.Count - 1)); } MyTransparentGeometry.AddBillboard(bbPool[indexL], false); MyTransparentGeometry.AddBillboard(bbPool[indexR], false); } }
/// <summary> /// Adds a list of textured quads in one batch using QuadBoard data /// </summary> public static void AddQuads(IReadOnlyList <BoundedQuadBoard> quads, MatrixD[] matrixRef, BoundingBox2?mask = null, Vector2 offset = default(Vector2), float scale = 1f) { var bbPool = instance.bbPoolBack; var bbDataBack = instance.flatTriangleList; var bbBuf = instance.bbBuf; var matList = instance.matrixBuf; var matTable = instance.matrixTable; // Find matrix index in table or add it int matrixID; if (!matTable.TryGetValue(matrixRef, out matrixID)) { matrixID = matList.Count; matList.Add(matrixRef[0]); matTable.Add(matrixRef, matrixID); } int triangleCount = quads.Count * 2, bbCountStart = bbDataBack.Count; bbDataBack.EnsureCapacity(bbDataBack.Count + triangleCount); for (int i = 0; i < quads.Count; i++) { BoundedQuadBoard boundedQB = quads[i]; BoundedQuadMaterial mat = boundedQB.quadBoard.materialData; Vector2 size = boundedQB.bounds.Size * scale, center = offset + boundedQB.bounds.Center * scale; BoundingBox2 bounds = BoundingBox2.CreateFromHalfExtent(center, .5f * size); BoundingBox2? maskBox = mask; ContainmentType containment = ContainmentType.Contains; if (maskBox != null) { maskBox.Value.Contains(ref bounds, out containment); if (containment == ContainmentType.Contains) { maskBox = null; } } if (containment != ContainmentType.Disjoint) { var bbL = new FlatTriangleBillboardData { Item1 = BlendTypeEnum.PostPP, Item2 = new Vector2I(bbDataBack.Count, matrixID), Item3 = mat.textureID, Item4 = new MyTuple <Vector4, BoundingBox2?>(mat.bbColor, maskBox), Item5 = new MyTuple <Vector2, Vector2, Vector2> ( new Vector2(mat.texBounds.Max.X, mat.texBounds.Min.Y), // 1 mat.texBounds.Max, // 0 new Vector2(mat.texBounds.Min.X, mat.texBounds.Max.Y) // 3 ), Item6 = new MyTuple <Vector2, Vector2, Vector2> ( bounds.Max, new Vector2(bounds.Max.X, bounds.Min.Y), bounds.Min ), }; var bbR = new FlatTriangleBillboardData { Item1 = BlendTypeEnum.PostPP, Item2 = new Vector2I(bbDataBack.Count + 1, matrixID), Item3 = mat.textureID, Item4 = new MyTuple <Vector4, BoundingBox2?>(mat.bbColor, maskBox), Item5 = new MyTuple <Vector2, Vector2, Vector2> ( new Vector2(mat.texBounds.Max.X, mat.texBounds.Min.Y), // 1 new Vector2(mat.texBounds.Min.X, mat.texBounds.Max.Y), // 3 mat.texBounds.Min // 2 ), Item6 = new MyTuple <Vector2, Vector2, Vector2> ( bounds.Max, bounds.Min, new Vector2(bounds.Min.X, bounds.Max.Y) ), }; bbDataBack.Add(bbL); bbDataBack.Add(bbR); } } // Add more billboards to pool as needed then queue them for rendering int bbToAdd = Math.Max(bbDataBack.Count - bbPool.Count, 0); instance.AddNewBB(bbToAdd); for (int i = bbCountStart; i < bbDataBack.Count; i++) { bbBuf.Add(bbPool[i]); } MyTransparentGeometry.AddBillboards(bbBuf, false); bbBuf.Clear(); }