Exemplo n.º 1
0
        /// <summary>
        /// Expands the declaration of a mesh to include tangent and binormal information
        /// </summary>
        /// <param name="device">The <see cref="Device"/> containing the mesh</param>
        /// <param name="mesh">The mesh to be manipulated</param>
        /// <param name="hadNormals">Did the original declaration already contain normals?</param>
        /// <param name="hadTangents">Did the original declaration already contain tangents?</param>
        /// <returns><c>true</c> if the mesh declaration was expanded, <c>false</c> if the declaration didn't need to be changed</returns>
        private static bool ExpandDeclaration(Device device, ref Mesh mesh, out bool hadNormals, out bool hadTangents)
        {
            #region Sanity checks
            if (device == null)
            {
                throw new ArgumentNullException(nameof(device));
            }
            if (mesh == null)
            {
                throw new ArgumentNullException(nameof(mesh));
            }
            #endregion

            // Check if vertex declaration of mesh already is already ok
            var decl = mesh.GetDeclaration();
            if (CompareDecl(PositionNormalBinormalTangentTextured.GetVertexElements(), decl) ||
                CompareDecl(PositionNormalMultiTextured.GetVertexElements(), decl))
            {
                hadNormals  = true;
                hadTangents = true;
                return(false);
            }

            #region Find existing info
            hadNormals  = false;
            hadTangents = false;

            for (int i = 0; i < 6 && i < decl.Length; i++)
            {
                if (decl[i].Usage == DeclarationUsage.Normal)
                {
                    hadNormals = true;
                    break;
                }
                if (decl[i].Usage == DeclarationUsage.Tangent)
                {
                    hadTangents = true;
                    break;
                }
            }
            #endregion

            // Select the appropriate new vertex format
            decl = CompareDecl(PositionMultiTextured.GetVertexElements(), decl) ?
                   PositionNormalMultiTextured.GetVertexElements() : PositionNormalBinormalTangentTextured.GetVertexElements();

            // Clone the mesh to change the vertex format
            Mesh tempMesh = mesh.Clone(device, mesh.CreationOptions, decl);
            mesh.Dispose();
            mesh = tempMesh;

            return(true);
        }
Exemplo n.º 2
0
        private static PositionMultiTextured[] GenerateVertexes(Size size, float stretchH, float stretchV, ByteGrid heightMap, NibbleGrid textureMap, ByteVector4Grid occlusionIntervalMap)
        {
            var vertexes = new PositionMultiTextured[size.Width * size.Height];

#if NETFX4
            Parallel.For(0, size.Width, x =>
#else
            for (int x = 0; x < size.Width; x++)
#endif
            {
                for (int y = 0; y < size.Height; y++)
                {
                    #region Texture blending
                    var texWeights = new float[16];

                    // Perform integer division (texture map has 1/3 of height map accuracy) but keep remainders
                    int xRemainder;
                    int xCoord = Math.DivRem(x, 3, out xRemainder);
                    int yRemainder;
                    int yCoord = Math.DivRem(y, 3, out yRemainder);

                    // Use remainders to determine intermediate blending levels for vertexes
                    switch (xRemainder)
                    {
                        case 0:
                            TextureBlendHelper(textureMap, xCoord, yCoord, texWeights, 0.25f);
                            TextureBlendHelper(textureMap, xCoord - 1, yCoord, texWeights, 0.25f);
                            break;
                        case 1:
                            TextureBlendHelper(textureMap, xCoord, yCoord, texWeights, 0.5f);
                            break;
                        case 2:
                            TextureBlendHelper(textureMap, xCoord, yCoord, texWeights, 0.25f);
                            TextureBlendHelper(textureMap, xCoord + 1, yCoord, texWeights, 0.25f);
                            break;
                    }
                    switch (yRemainder)
                    {
                        case 0:
                            TextureBlendHelper(textureMap, xCoord, yCoord, texWeights, 0.25f);
                            TextureBlendHelper(textureMap, xCoord, yCoord - 1, texWeights, 0.25f);
                            break;
                        case 1:
                            TextureBlendHelper(textureMap, xCoord, yCoord, texWeights, 0.5f);
                            break;
                        case 2:
                            TextureBlendHelper(textureMap, xCoord, yCoord, texWeights, 0.25f);
                            TextureBlendHelper(textureMap, xCoord, yCoord + 1, texWeights, 0.25f);
                            break;
                    }
                    #endregion

                    var occlusionIntervals = occlusionIntervalMap?[x, y] ?? new ByteVector4(0, 255, 255, 255);

                    // Generate vertex using 2D coords, stretch factors (and tex-coords based on them)
                    // Map X = Engine +X
                    // Map Y = Engine -Z
                    // Map height = Engine +Y
                    vertexes[x + size.Width * y] = new PositionMultiTextured(
                        new Vector3(x * stretchH, heightMap[x, y] * stretchV, -y * stretchH),
                        x * stretchH / 500f, y * stretchH / 500f,
                        occlusionIntervals.ByteToAngle(),
                        texWeights, Color.White);
                }
            }