Beispiel #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 void GetVertices(GorgonNativeBuffer <Vertex3D> vertexData,
                                 GorgonNativeBuffer <int> indexData,
                                 float radius,
                                 RectangleF textureCoordinates,
                                 int ringCount,
                                 int segmentCount)
        {
            int   index          = 0; // Current index.
            int   vertexOffset   = 0;
            int   indexOffset    = 0;
            float deltaRingAngle = ((float)System.Math.PI) / ringCount;
            float deltaSegAngle  = (((float)System.Math.PI) * 2.0f) / segmentCount;

            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 DX.Vector2(1.0f - (segment / (float)segmentCount), ring / (float)ringCount);
                    float segmentAngle = deltaSegAngle * segment;

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


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

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

                    vertexData[vertexOffset++] = new Vertex3D
                    {
                        Position = new DX.Vector4(position, 1.0f),
                        UV       = textureDelta,
                        Normal   = normal
                    };

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

                    indexData[indexOffset++] = (index + segmentCount + 1);
                    indexData[indexOffset++] = index;
                    indexData[indexOffset++] = (index + segmentCount);

                    indexData[indexOffset++] = (index + segmentCount + 1);
                    indexData[indexOffset++] = (index + 1);
                    indexData[indexOffset++] = index;
                    index++;
                }
            }
        }
Beispiel #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 void CalculateTangents(GorgonNativeBuffer <Vertex3D> vertexData, GorgonNativeBuffer <int> indexData)
        {
            var biTanData   = new DX.Vector3[VertexCount];
            var tanData     = new DX.Vector3[VertexCount];
            int indexOffset = 0;

            for (int i = 0; i < TriangleCount; ++i)
            {
                int index1 = indexData[indexOffset++];

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

                int index2 = indexData[indexOffset++];
                int index3 = indexData[indexOffset++];

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

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

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

                DX.Vector2.Subtract(ref vertex2.UV, ref vertex1.UV, out DX.Vector2 deltaUV1);
                DX.Vector2.Subtract(ref vertex3.UV, ref vertex1.UV, out DX.Vector2 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 DX.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 DX.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);

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

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

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


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

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

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