Example #1
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 #2
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)
                };
            }
        }