Exemplo 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 NormalStream(this.Size);

            stream.Copy(this);
            return(stream);
        }
Exemplo n.º 2
0
        /// <summary>
        /// compresses the normal stream and fills the current stream
        /// both streams have to be the same size
        /// </summary>
        /// <param name="stream"></param>
        public void CompressAndFill(NormalStream stream)
        {
            System.Diagnostics.Debug.Assert(stream.Size == this.Size);
            const float fracScale = 127.5f;

            for (int i = 0; i < stream.Size; i++)
            {
                Math.Vector3 vec = stream[i];
                IntData[i] = (((uint)(vec.X * fracScale + fracScale) * 1) +
                              ((uint)(vec.Y * fracScale + fracScale) * 256) +
                              ((uint)(vec.Z * fracScale + fracScale) * 65536));

                //16777216
            }
        }
Exemplo n.º 3
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 });
        }
Exemplo n.º 4
0
        /// <summary>
        /// create a compresses normal stream from an uncompressed stream
        /// </summary>
        /// <param name="stream">stream to compress</param>
        public static void From(NormalStream stream)
        {
            CompressedNormalStream compressed = new CompressedNormalStream(stream.Size);

            compressed.CompressAndFill(stream);
        }