Example #1
0
        /// <summary>
        /// Function to build the plane vertices.
        /// </summary>
        /// <param name="buffer">Buffer to populate.</param>
        /// <param name="size">The width and height of the plane.</param>
        /// <param name="textureCoordinates">The texture coordinates to apply to the plane.</param>
        /// <param name="columns">The number of columns to subdivide by.</param>
        /// <param name="rows">The number of rows to subdivide by.</param>
        private unsafe void GetVertices(Vertex3D *buffer, Vector2 size, RectangleF textureCoordinates, int columns, int rows)
        {
            float columnWidth  = 1.0f / columns;
            float columnHeight = 1.0f / rows;

            var vertexNormal = -Vector3.UnitZ;

            Vector3.TransformNormal(ref vertexNormal, ref _orientation, out vertexNormal);

            for (int y = 0; y <= rows; ++y)
            {
                for (int x = 0; x <= columns; ++x)
                {
                    var vertexPos = new Vector3(((x * columnWidth) - 0.5f) * size.X,
                                                ((y * columnHeight) - 0.5f) * size.Y,
                                                0);

                    Vector3.TransformCoordinate(ref vertexPos, ref _orientation, out vertexPos);

                    *(buffer++) = new Vertex3D
                    {
                        Position =
                            new Vector4(vertexPos,
                                        1.0f),
                        Normal = vertexNormal,
                        UV     = new Vector2((x * (textureCoordinates.Width / columns)) + textureCoordinates.X,
                                             (1.0f - (y * (textureCoordinates.Height / rows))) + textureCoordinates.Y)
                    };
                }
            }
        }
Example #2
0
        /// <summary>
        /// Function to build the plane vertices.
        /// </summary>
        /// <param name="buffer">Buffer to populate.</param>
        /// <param name="up">Up vector for orientation.</param>
        /// <param name="normal">The face normal.</param>
        /// <param name="size">The width and height of the plane.</param>
        /// <param name="textureCoordinates">The texture coordinates to apply to the plane.</param>
        /// <param name="columns">The number of columns to subdivide by.</param>
        /// <param name="rows">The number of rows to subdivide by.</param>
        private unsafe void GetVertices(Vertex3D *buffer, Vector3 up, Vector3 normal, Vector3 size, RectangleF textureCoordinates, int columns, int rows)
        {
            float   columnWidth  = 1.0f / columns;
            float   columnHeight = 1.0f / rows;
            Matrix  rotation     = Matrix.Identity;
            Vector3 translate;
            Vector3 transformNormal;

            Vector3 orientVector;

            Vector3.Cross(ref normal, ref up, out orientVector);
            Vector3.Multiply(ref normal, 0.5f, out translate);

            rotation.Row1 = orientVector;
            rotation.Row2 = up;
            rotation.Row3 = normal;
            rotation.Row4 = new Vector4(translate, 1);

            Vector3.TransformCoordinate(ref normal, ref _orientation, out transformNormal);
            Vector3.Normalize(ref transformNormal, out transformNormal);

            for (int y = 0; y <= rows; ++y)
            {
                for (int x = 0; x <= columns; ++x)
                {
                    var vertexPos = new Vector3(((x * columnWidth) - 0.5f) * size.X,
                                                ((y * columnHeight) - 0.5f) * size.Y,
                                                0);

                    Vector3.TransformCoordinate(ref vertexPos, ref rotation, out vertexPos);
                    Vector3.TransformCoordinate(ref vertexPos, ref _orientation, out vertexPos);

                    *(buffer++) = new Vertex3D
                    {
                        Position =
                            new Vector4(vertexPos,
                                        1.0f),
                        Normal = transformNormal,
                        UV     = new Vector2((x * (textureCoordinates.Width / columns)) + textureCoordinates.X,
                                             (1.0f - (y * (textureCoordinates.Height / rows))) + textureCoordinates.Y)
                    };
                }
            }
        }
Example #3
0
        /// <summary>
        /// Function to create the vertex data for the sphere.
        /// </summary>
        /// <param name="vertexData">Pointer to the buffer that will hold the vertex data.</param>
        /// <param name="indexData">Pointer to the buffer that will hold the index data.</param>
        /// <param name="radius">Radius of the sphere.</param>
        /// <param name="textureCoordinates">Texture coordinates for the sphere.</param>
        /// <param name="ringCount">Number of rings in the sphere.</param>
        /// <param name="segmentCount">Number of segments in the sphere.</param>
        private unsafe void GetVertices(Vertex3D *vertexData,
                                        int *indexData,
                                        void *normalData,
                                        float radius,
                                        RectangleF textureCoordinates,
                                        int ringCount,
                                        int segmentCount)
        {
            int   index          = 0;                                           // Current index.
            float deltaRingAngle = ((float)System.Math.PI) / ringCount;
            float deltaSegAngle  = (((float)System.Math.PI) * 2.0f) / segmentCount;
            var   linePtStart    = (Vector4 *)normalData;

            Radius = radius;

            // Build our sphere.
            for (int ring = 0; ring <= ringCount; ring++)
            {
                float ringAngle = ring * deltaRingAngle;
                radius = ringAngle.Sin() * 0.5f * Radius;
                float radiusY = ringAngle.Cos() * Radius * 0.5f;

                for (int segment = 0; segment <= segmentCount; segment++)
                {
                    var   textureDelta = new Vector2(1.0f - segment / (float)segmentCount, ring / (float)ringCount);
                    float segmentAngle = deltaSegAngle * segment;

                    var position = new Vector3(radius * segmentAngle.Sin(), radiusY, radius * segmentAngle.Cos());

                    Vector3 normal;

                    Vector3.Multiply(ref position, 2.0f, out normal);
                    Vector3.TransformCoordinate(ref position, ref _orientation, out position);
                    Vector3.TransformCoordinate(ref normal, ref _orientation, out normal);
                    normal.Normalize();

                    *(linePtStart++) = new Vector4(position, 1.0f);
                    *(linePtStart++) = new Vector4(position + (normal * 0.05f), 1.0f);

                    // Create the vertex.
                    textureDelta.X *= textureCoordinates.Width;
                    textureDelta.Y *= textureCoordinates.Height;
                    textureDelta.X += textureCoordinates.X;
                    textureDelta.Y += textureCoordinates.Y;

                    *(vertexData++) = new Vertex3D
                    {
                        Position = new Vector4(position, 1.0f),
                        UV       = textureDelta,
                        Normal   = normal
                    };

                    // Add the indices and skip the last ring.
                    if (ring == ringCount)
                    {
                        continue;
                    }

                    *(indexData++) = (index + segmentCount + 1);
                    *(indexData++) = index;
                    *(indexData++) = (index + segmentCount);

                    *(indexData++) = (index + segmentCount + 1);
                    *(indexData++) = (index + 1);
                    *(indexData++) = index;
                    index++;
                }
            }
        }
Example #4
0
        /// <summary>
        /// Function to calculate tangent information for bump mapping.
        /// </summary>
        /// <param name="vertexData">Buffer holding the vertices.</param>
        /// <param name="indexData">Buffer holding the indices.</param>
        protected unsafe void CalculateTangents(Vertex3D *vertexData, int *indexData)
        {
            var biTanData = new Vector3[VertexCount];
            var tanData   = new Vector3[VertexCount];

            for (int i = 0; i < TriangleCount; ++i)
            {
                int index1 = *(indexData++);

                // If we hit a strip-restart index, then skip to the next index.
                if ((PrimitiveType == PrimitiveType.TriangleStrip) &&
                    (index1 < 0))
                {
                    index1 = *(indexData++);
                }

                int index2 = *(indexData++);
                int index3 = *(indexData++);

                Vertex3D vertex1 = vertexData[index1];
                Vertex3D vertex2 = vertexData[index2];
                Vertex3D vertex3 = vertexData[index3];

                Vector4 deltaPos1;
                Vector4.Subtract(ref vertex2.Position, ref vertex1.Position, out deltaPos1);

                Vector4 deltaPos2;
                Vector4.Subtract(ref vertex3.Position, ref vertex1.Position, out deltaPos2);

                Vector2 deltaUV1;
                Vector2.Subtract(ref vertex2.UV, ref vertex1.UV, out deltaUV1);
                Vector2 deltaUV2;
                Vector2.Subtract(ref vertex3.UV, ref vertex1.UV, out deltaUV2);

                float denom = (deltaUV1.X * deltaUV2.Y - deltaUV1.Y * deltaUV2.X);
                float r     = 0.0f;

                if (!denom.EqualsEpsilon(0))
                {
                    r = 1.0f / denom;
                }

                var tangent = new Vector3((deltaUV2.Y * deltaPos1.X - deltaUV1.Y * deltaPos2.X) * r,
                                          (deltaUV2.Y * deltaPos1.Y - deltaUV1.Y * deltaPos2.Y) * r,
                                          (deltaUV2.Y * deltaPos1.Z - deltaUV1.Y * deltaPos2.Z) * r);

                var biTangent = new Vector3((deltaUV1.X * deltaPos2.X - deltaUV2.X * deltaPos1.X) * r,
                                            (deltaUV1.X * deltaPos2.Y - deltaUV2.X * deltaPos1.Y) * r,
                                            (deltaUV1.X * deltaPos2.Z - deltaUV2.X * deltaPos1.Z) * r);

                Vector3.Add(ref tanData[index1], ref tangent, out tanData[index1]);
                Vector3.Add(ref tanData[index2], ref tangent, out tanData[index2]);
                Vector3.Add(ref tanData[index3], ref tangent, out tanData[index3]);

                Vector3.Add(ref biTanData[index1], ref biTangent, out biTanData[index1]);
                Vector3.Add(ref biTanData[index2], ref biTangent, out biTanData[index2]);
                Vector3.Add(ref biTanData[index3], ref biTangent, out biTanData[index3]);
            }

            for (int i = 0; i < VertexCount; ++i)
            {
                Vertex3D vertex = vertexData[i];

                Vector3 tangent;
                Vector3 cross;
                float   dot;

                Vector3.Dot(ref vertex.Normal, ref tanData[i], out dot);
                Vector3.Multiply(ref vertex.Normal, dot, out tangent);
                Vector3.Subtract(ref tanData[i], ref tangent, out tangent);
                Vector3.Normalize(ref tangent, out tangent);

                Vector3.Cross(ref vertex.Normal, ref tanData[i], out cross);
                Vector3.Dot(ref cross, ref biTanData[i], out dot);

                vertexData[i] = new Vertex3D
                {
                    Position = vertex.Position,
                    Normal   = vertex.Normal,
                    UV       = vertex.UV,
                    Tangent  = new Vector4(tangent, dot < 0.0f ? -1.0f : 1.0f)
                };
            }
        }