/// <summary> /// Gets static geometry. /// </summary> /// <returns>Static geometry builder.</returns> public StaticGeometryBuilder GetStaticGeometry() { // Create builder StaticGeometryBuilder builder = new StaticGeometryBuilder(core.GraphicsDevice); // Convert vertices to required format List <VertexPositionNormalTextureBump> vertices = new List <VertexPositionNormalTextureBump>(primitive.Vertices.Count); foreach (var vertex in primitive.Vertices) { vertices.Add(new VertexPositionNormalTextureBump( vertex.Position, vertex.Normal, Vector2.Zero, Vector3.Zero, Vector3.Zero)); } // Add geometry StaticGeometryBuilder.BatchData batchData = new StaticGeometryBuilder.BatchData { Vertices = vertices, Indices = primitive.Indices, }; builder.AddToBuilder((uint)MaterialManager.NullTextureKey, batchData, this.Matrix); return(builder); }
/// <summary> /// Add billboard to collection. /// </summary> /// <param name="archive">Texture archive.</param> /// <param name="record">Texture index.</param> /// <param name="position">Position relative to parent entity.</param> public void AddBillboard(int archive, int record, Vector3 position) { MaterialManager.TextureCreateFlags flags = MaterialManager.TextureCreateFlags.Dilate | MaterialManager.TextureCreateFlags.PreMultiplyAlpha | MaterialManager.TextureCreateFlags.MipMaps; // Load flat BaseMaterialEffect material; Vector2 startSize, finalSize; LoadDaggerfallFlat(archive, record, flags, out material, out startSize, out finalSize); // Calcuate final position Vector3 finalPosition = new Vector3(position.X, -position.Y + (finalSize.Y / 2) - 4, -position.Z); // Information about the billboard is packed into unused parts of the vertex format. // This allows us to send a huge static batch of billboards and correctly position, rotate, and scale // each one for the camera. for (int i = 0; i < 4; i++) { billboardVertices[i].Tangent = finalPosition; billboardVertices[i].Binormal = new Vector3(finalSize.X, finalSize.Y, 0); } // Add to batch staticGeometry.AddToBuilder(material.ID, billboardVertices, billboardIndices, Matrix.Identity); }
/// <summary> /// Adds exterior ground tiles to the batch. /// </summary> /// <param name="blockData">Block data.</param> private void AddRMBGroundTiles(ref DFBlock blockData) { // Make ground slightly lower to minimise depth-fighting on ground aligned polygons const float groundHeight = 0f; // Corner positions Vector3 topLeftPos, topRightPos, bottomLeftPos, bottomRightPos; Vector2 topLeftUV, topRightUV, bottomLeftUV, bottomRightUV; // Create vertices. These will be updated for each tile based on position and UV orientation. VertexPositionNormalTextureBump[] vertices = new VertexPositionNormalTextureBump[4]; // Create indices. These are the same for every tile. int[] indices = new int[] { 0, 1, 2, 1, 3, 2 }; // Loop through tiles int tileCount = 16; float tileDimension = 256.0f * ModelManager.GlobalScale; for (int y = 0; y < tileCount; y++) { for (int x = 0; x < tileCount; x++) { // Get source tile data DFBlock.RmbGroundTiles tile = blockData.RmbBlock.FldHeader.GroundData.GroundTiles[x, y]; // Set random terrain marker back to grass int textureRecord = (tile.TextureRecord > 55) ? 2 : tile.TextureRecord; // Create material BaseMaterialEffect material = core.ModelManager.CreateModelMaterial( (int)DFLocation.ClimateTextureSet.Exterior_Terrain, textureRecord); material.SamplerState0 = SamplerState.AnisotropicClamp; // Create vertices for this quad topLeftPos = new Vector3(x * tileDimension, groundHeight, y * tileDimension); topRightPos = new Vector3(topLeftPos.X + tileDimension, groundHeight, topLeftPos.Z); bottomLeftPos = new Vector3(topLeftPos.X, groundHeight, topLeftPos.Z + tileDimension); bottomRightPos = new Vector3(topLeftPos.X + tileDimension, groundHeight, topLeftPos.Z + tileDimension); // Set UVs if (tile.IsRotated && !tile.IsFlipped) { // Rotate only topLeftUV = new Vector2(1, 0); topRightUV = new Vector2(1, 1); bottomLeftUV = new Vector2(0, 0); bottomRightUV = new Vector2(0, 1); } else if (tile.IsFlipped && !tile.IsRotated) { // Flip only topLeftUV = new Vector2(1, 1); topRightUV = new Vector2(0, 1); bottomLeftUV = new Vector2(1, 0); bottomRightUV = new Vector2(0, 0); } else if (tile.IsRotated && tile.IsRotated) { // Rotate and flip topLeftUV = new Vector2(0, 1); topRightUV = new Vector2(0, 0); bottomLeftUV = new Vector2(1, 1); bottomRightUV = new Vector2(1, 0); } else { // No rotate or flip topLeftUV = new Vector2(0, 0); topRightUV = new Vector2(1, 0); bottomLeftUV = new Vector2(0, 1); bottomRightUV = new Vector2(1, 1); } // Set vertices vertices[0] = new VertexPositionNormalTextureBump(topLeftPos, Vector3.Up, topLeftUV, Vector3.Zero, Vector3.Zero); vertices[1] = new VertexPositionNormalTextureBump(topRightPos, Vector3.Up, topRightUV, Vector3.Zero, Vector3.Zero); vertices[2] = new VertexPositionNormalTextureBump(bottomLeftPos, Vector3.Up, bottomLeftUV, Vector3.Zero, Vector3.Zero); vertices[3] = new VertexPositionNormalTextureBump(bottomRightPos, Vector3.Up, bottomRightUV, Vector3.Zero, Vector3.Zero); // Add to builder staticGeometry.AddToBuilder(material.ID, vertices, indices, Matrix.Identity); } } }