コード例 #1
0
        /// <summary>
        /// Creates a new IndexStream object.
        /// </summary>
        /// <param name="indices">The list of indices.</param>
        /// <param name="maxIndex">The maximum index to handle (create IndexStream16 or IndexStream32).</param>
        /// <returns>The created indexStream.</returns>
        public static IndexStream Create(IList indices, int maxIndex)
        {
            IndexStream stream = IndexStream.Create(indices.Count, maxIndex);

            for (int i = 0; i < indices.Count; i++)
            {
                stream[i] = (int)indices[i];
            }
            return(stream);
        }
コード例 #2
0
 /// <summary>
 /// copies a source index stream into a certain location of a destination vertex stream
 /// </summary>
 /// <param name="source">index stream to take data from</param>
 /// <param name="sourceIndex">start index</param>
 /// <param name="dest">index to put data into</param>
 /// <param name="destIndex">start index</param>
 /// <param name="length">number of elements</param>
 /// <param name="vertexOffset">used if vertices are copied to another location</param>
 public static void Copy(IndexStream source, int sourceIndex,
                         IndexStream dest, int destIndex, int length, int vertexOffset)
 {
     if (source.GetType() != dest.GetType() || vertexOffset != 0)
     {
         for (int i = 0; i < length; i++)
         {
             dest[destIndex] = (ushort)(source[sourceIndex] + vertexOffset);
         }
     }
     else
     {
         Array.Copy(source.Data, sourceIndex, dest.Data, destIndex, length);
     }
 }
コード例 #3
0
        /// <summary>
        /// creates an indexed vertexUnit and the indexStream from the current vertexUnit
        /// </summary>
        /// <param name="vertexUnit">created vertexUnit</param>
        /// <param name="indexStream">created indexStream</param>
        public void Indexify(out VertexUnit vertexUnit, out VertexStreams.IndexStream indexStream)
        {
            object[]  currentVertex = new object[StreamCount];
            Hashtable vertices      = new Hashtable();
            int       vertexNum     = 0;
            int       currentIndex  = 0;

            indexStream = new VertexStreams.IndexStream16(Size);
            // TODO: Size is much too high for vertexUnit
            // calc real size
            vertexUnit = new VertexUnit(format, Size);

            for (int i = 0; i < Size; i++)
            {
                // fill vertex
                for (int j = 0; j < StreamCount; j++)
                {
                    currentVertex[j] = this[j].Data.GetValue(i);
                }

                // calc current index
                if (vertices.Contains(currentVertex))
                {
                    currentIndex = (int)vertices[currentVertex];
                }
                else
                {
                    vertices.Add(currentVertex, vertexNum);
                    currentIndex = vertexNum;
                    vertexNum++;
                    // add new vertex to new streams
                    for (int j = 0; j < StreamCount; j++)
                    {
                        vertexUnit[j].Data.SetValue(currentVertex[j], j);
                    }
                }

                indexStream[i] = currentIndex;
            }
        }
コード例 #4
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 });
        }