Ejemplo n.º 1
0
        //---------------------------------------------------------------
        #endregion
        //---------------------------------------------------------------

        //---------------------------------------------------------------
        #region Methods
        //---------------------------------------------------------------
        /// <summary>
        /// Creates a deep-copy of the current <see cref="IGraphicsStream"/>.
        /// </summary>
        /// <returns>A deep-copy of the current <see cref="IGraphicsStream"/>.</returns>
        public override IGraphicsStream Clone()
        {
            IGraphicsStream stream = new TangentStream(this.Size);

            stream.Copy(this);
            return(stream);
        }
Ejemplo n.º 2
0
        /// <summary>
        /// calculate tangent, normal and binormal stream
        /// Triangle list is assumed for indices format
        /// there will be a more sophisticated version of this functions for SubSets, which will
        /// have much similiarity to NVidias MeshMender
        /// </summary>
        /// <param name="positions">stream containing vertex positions</param>
        /// <param name="textures">stream containing texture coordinates</param>
        /// <param name="indices">stream containing indices</param>
        /// <returns></returns>
        public static IGraphicsStream[] CalcTangentSpaceStreams(VertexStreams.PositionStream positions,
                                                                VertexStreams.TextureStream textures,
                                                                VertexStreams.IndexStream indices)
        {
            // create ret streams
            VertexStreams.NormalStream   normal   = new VertexStreams.NormalStream(positions.Size);
            VertexStreams.TangentStream  tangent  = new VertexStreams.TangentStream(positions.Size);
            VertexStreams.BinormalStream binormal = new VertexStreams.BinormalStream(positions.Size);

            for (int i = 0; i < indices.Size / 3; i++)
            {
                // prepare data
                Vector3  s   = Vector3.Zero;
                Vector3  t   = Vector3.Zero;
                Triangle tri = indices.GetTriangle(i);

                // calculate s.X and t.X
                Vector3 a = new Vector3(positions[tri.B].X - positions[tri.A].X,
                                        textures[tri.B].X - textures[tri.A].X,
                                        textures[tri.B].Y - textures[tri.A].Y);
                Vector3 b = new Vector3(positions[tri.C].X - positions[tri.A].X,
                                        textures[tri.C].X - textures[tri.A].X,
                                        textures[tri.C].Y - textures[tri.A].Y);
                Vector3 axb = Vector3.Cross(a, b);
                if (Basic.Abs(axb.X) > float.Epsilon)
                {
                    s.X = -axb.Y / axb.X;
                    t.X = -axb.Z / axb.X;
                }

                // calculate s.Y and t.Y
                a.X = positions[tri.B].Y - positions[tri.A].Y;
                b.X = positions[tri.C].Y - positions[tri.A].Y;
                axb = Vector3.Cross(a, b);
                if (Basic.Abs(axb.X) > float.Epsilon)
                {
                    s.Y = -axb.Y / axb.X;
                    t.Y = -axb.Z / axb.X;
                }

                // calculate s.Z and t.Z
                a.X = positions[tri.B].Z - positions[tri.A].Z;
                b.X = positions[tri.C].Z - positions[tri.A].Z;
                axb = Vector3.Cross(a, b);
                if (Basic.Abs(axb.X) > float.Epsilon)
                {
                    s.Z = -axb.Y / axb.X;
                    t.Z = -axb.Z / axb.X;
                }

                // normalize and calculate normal vector
                s.Normalize();
                t.Normalize();

                // swap t if normal vector of texture space triangle has a negative z direction
                if (axb.X < float.Epsilon)
                {
                    t = -t;
                }
                Vector3 sxt = Vector3.Unit(Vector3.Cross(s, t));

                // add s, t, sxt into the streams
                // to get the average value - in a later version I will add functionality
                // to duplicate vertices if the results for one vertex are too different
                // (like the NVidia MeshMender does ...)
                tangent[tri.A] += s;
                tangent[tri.B] += s;
                tangent[tri.C] += s;

                binormal[tri.A] += t;
                binormal[tri.B] += t;
                binormal[tri.C] += t;

                normal[tri.A] += sxt;
                normal[tri.B] += sxt;
                normal[tri.C] += sxt;
            }

            // so last but not least renormalize the summed vectors
            for (int i = 0; i < positions.Size; i++)
            {
                tangent[i].Normalize();
                binormal[i].Normalize();
                normal[i].Normalize();
            }
            return(new IGraphicsStream[] { tangent, binormal, normal });
        }