/// <summary>
 /// Store the vertex into the cache for later retrieval.
 /// </summary>
 /// <param name="vertexIndex">The index associated with this vertex.</param>
 /// <param name="point">The location of the point on the square: an int from 0 to 7.</param>
 /// <param name="x">Location in the current row of squares.</param>
 public void CacheVertex(VertexIndex vertexIndex, int point, int x)
 {
     if (point < perSquareCacheSize)
     {
         currentRow[point, x] = vertexIndex;
     }
 }
예제 #2
0
        // Token: 0x0600003A RID: 58 RVA: 0x000030B8 File Offset: 0x000012B8
        private static IEnumerable <UVSetTagg> createUVSetTaggs(LOD src)
        {
            int nFaces = src.Faces.Length;
            int num3;

            for (int i = 0; i < src.UVSets.Length; i = num3)
            {
                UVSetTagg uvsetTagg = new UVSetTagg();
                uvsetTagg.Name    = "#UVSet#";
                uvsetTagg.uvSetNr = (uint)i;
                uvsetTagg.faceUVs = new float[nFaces][, ];
                float[] uvdata = src.UVSets[i].UVData;
                uint    num    = 4u;
                for (int j = 0; j < nFaces; j++)
                {
                    Polygon polygon = src.Faces[j];
                    int     num2    = polygon.VertexIndices.Length;
                    uvsetTagg.faceUVs[j] = new float[num2, 2];
                    for (int k = 0; k < num2; k++)
                    {
                        VertexIndex vi = polygon.VertexIndices[num2 - 1 - k];
                        uvsetTagg.faceUVs[j][k, 0] = uvdata[vi * 2];
                        uvsetTagg.faceUVs[j][k, 1] = uvdata[vi * 2 + 1];
                        num += 8u;
                    }
                }
                uvsetTagg.DataSize = num;
                yield return(uvsetTagg);

                num3 = i + 1;
            }
            yield break;
        }
예제 #3
0
 /// <summary>
 /// Store the vertex into the cache for later retrieval.
 /// </summary>
 /// <param name="vertexIndex">The index associated with this vertex.</param>
 /// <param name="point">The location of the point on the square: an int from 0 to 7.</param>
 /// <param name="x">Location in the current row.</param>
 public void CacheVertex(VertexIndex vertexIndex, int point, int x)
 {
     if (point < perSquareCacheSize)
     {
         int positionInRow = perSquareCacheSize * x + point;
         currentRow[positionInRow] = vertexIndex;
     }
 }
예제 #4
0
 public VertexLookup(int rowLength)
 {
     VertexIndex[] currentRow  = new VertexIndex[rowLength * perSquareCacheSize];
     VertexIndex[] previousRow = new VertexIndex[rowLength * perSquareCacheSize];
     for (int i = 0; i < currentRow.Length; i++)
     {
         currentRow[i]  = VertexIndex.VoidValue;
         previousRow[i] = VertexIndex.VoidValue;
     }
     this.currentRow  = currentRow;
     this.previousRow = previousRow;
 }
예제 #5
0
 /// <summary>
 /// Retrieve the vertex from the cache, if it exists.
 /// </summary>
 /// <param name="vertexIndex">The index associated with this vertex.</param>
 /// <param name="point">The location of the point on the square: an int from 0 to 7.</param>
 /// <param name="x">Location in the current row.</param>
 /// <returns>Bool representing whether the vertex was found.</returns>
 public bool TryGetCachedVertex(int point, int x, out VertexIndex vertexIndex)
 {
     vertexIndex = VertexIndex.VoidValue;
     if (IsPointOnBottomOfSquare(point))
     {
         vertexIndex = GetVertexFromBelow(point, x);
     }
     if (IsVertexIndexVoid(vertexIndex) && IsPointOnLeftOfSquare(point) && x > 0)
     {
         vertexIndex = GetVertexFromLeft(point, x);
     }
     return(!IsVertexIndexVoid(vertexIndex));
 }
        /// <summary>
        /// Retrieve the vertex from the cache, if it exists.
        /// </summary>
        /// <param name="vertexIndex">The index associated with this vertex.</param>
        /// <param name="point">The location of the point on the square: an int from 0 to 7.</param>
        /// <param name="x">Location in the current row.</param>
        /// <returns>Bool representing whether the vertex was found.</returns>
        public bool TryGetCachedVertex(int point, int x, out VertexIndex vertexIndex)
        {
            VertexIndex?index = null;

            if (isOnBottom[point])
            {
                index = previousRow[bottomOffset[point], x];
            }
            if (!index.HasValue && isOnLeft[point] && x > 0)
            {
                index = currentRow[leftOffset[point], x - 1];
            }
            vertexIndex = index.HasValue ? index.Value : (VertexIndex)0;
            return(index.HasValue);
        }
예제 #7
0
        /// <summary>
        /// Writes a Vertex Index into the data stream
        /// </summary>
        /// <param name="vertexIndex">The Vertex Index to write</param>
        public void WriteVertexIndex(VertexIndex vertexIndex)
        {
            short value = vertexIndex.index;

            if (vertexIndex.polyBoundary)
            {
                //if index is a polygon boundary (begin/end), set the highest bit
                // (using logical OR)
                // value  0000000000000111   = 7
                // mask   1000000000000000   = 0x8000 in hex
                // result 1000000000000111   = desired index value (-32761 in dec)
                value = (short)(value ^ 0x8000);
            }

            data.AddRange(BitConverter.GetBytes(value));
        }
예제 #8
0
        public IEnumerable <VertexIndex> FindNeighbours(VertexIndex a)
        {
            var indexOfA = this.TriangleIndicies.IndexOf(a);

            while (indexOfA != -1)
            {
                var verticeTripleIndex = (int)((indexOfA / 3.0).Floor() * 3);
                yield return(new VertexIndex(this.TriangleIndicies[verticeTripleIndex + 0]));

                yield return(new VertexIndex(this.TriangleIndicies[verticeTripleIndex + 1]));

                yield return(new VertexIndex(this.TriangleIndicies[verticeTripleIndex + 2]));

                indexOfA = this.TriangleIndicies.IndexOf(a, verticeTripleIndex + 3);                 // start search at next triple
            }
        }
예제 #9
0
        public VertexIndex[] Duplicate(VertexIndex[] duplicateVertices, params IBufferObject[] duplicateVbos)
        {
            var newExtrudedVertices = new VertexIndex[duplicateVertices.Length];

            // duplicate selected vertexes
            for (int i = 0; i < duplicateVertices.Length; i++)
            {
                newExtrudedVertices[i] = new VertexIndex(Vertices.Count);

                foreach (var vbo in duplicateVbos)
                {
                    vbo.Duplicate(duplicateVertices[i]);
                }
            }

            // if they are neighbouring, make face between them
            for (int a = 0; a < newExtrudedVertices.Length; a++)
            {
                for (int b = a; b < newExtrudedVertices.Length; b++)
                {
                    if (IsNeighbouring(duplicateVertices[a], duplicateVertices[b]))
                    {
                        //OVERKILL: to make sure skirts are visible we make both CW and CCW triangles

                        //CW vs CCW might actually depend on the order of array duplicateVertices

                        //CCW
                        AddTriangle(duplicateVertices[a], duplicateVertices[b], newExtrudedVertices[b]);
                        AddTriangle(duplicateVertices[a], newExtrudedVertices[b], newExtrudedVertices[a]);

                        //CW
                        AddTriangle(duplicateVertices[b], duplicateVertices[a], newExtrudedVertices[b]);
                        AddTriangle(duplicateVertices[a], newExtrudedVertices[a], newExtrudedVertices[b]);
                    }
                }
            }

            return(newExtrudedVertices);
        }
예제 #10
0
        /// <summary>
        /// Find the direction vector for a vertex by taking the average direction vector of the faces the vertex belongs to
        /// </summary>
        /// <param name="vertex">Vertex in a mesh</param>
        /// <param name="mesh">Mesh which vertex is a part of.</param>
        /// <returns>Normal/Direction vector for vertex</returns>
        public Vector3 FindVertexNormal(VertexIndex vertex, CVMesh mesh)
        {
            mesh.Faces = Extensions.ToFaces(mesh.TriangleIndeces);
            int            index       = vertex.Index;
            List <Vector3> faceNormals = new List <Vector3>();

            for (int i = 0; i < mesh.Faces.Count; i++)
            {
                Face f = mesh.Faces[i];
                if (f.index1 == index || f.index2 == index || f.index3 == index)
                {
                    faceNormals.Add(GetFaceNormal(i, mesh));
                }
            }
            if (faceNormals.Count == 0)
            {
                return new Vector3 {
                           X = 0, Y = 0, Z = 1
                }
            }
            ;
            return(Extensions.Normalize(Extensions.AvgVector(faceNormals)));
        }
예제 #11
0
        /// <summary>
        /// Initializes a new instance of the <see cref="SEGM"/> class.
        /// </summary>
        /// <param name="from">The <see cref="BaseChunk" /> to use for creating this Chunk. The given data will be interpreted respectively.</param>
        public SEGM(BaseChunk from) : base(from)
        {
            List <Vector3> verts   = new List <Vector3>();
            List <Vector3> normals = new List <Vector3>();
            List <Vector2> uvs     = new List <Vector2>();

            Polygon currentPoly = new Polygon(vertices);
            bool    lastBoundry = false;

            while (!EndOfData)
            {
                BaseChunk nextChunk = ReadChunk();
                int       count     = 0;

                switch (nextChunk.ChunkName)
                {
                case "MATI":
                    matIndex = nextChunk.ReadInt32();
                    break;

                case "POSL":
                    count = nextChunk.ReadInt32();
                    for (int i = 0; i < count; i++)
                    {
                        verts.Add(nextChunk.ReadVector3());
                    }
                    break;

                case "NRML":
                    count = nextChunk.ReadInt32();
                    for (int i = 0; i < count; i++)
                    {
                        normals.Add(nextChunk.ReadVector3());
                    }
                    break;

                case "UV0L":
                    count = nextChunk.ReadInt32();
                    for (int i = 0; i < count; i++)
                    {
                        uvs.Add(nextChunk.ReadVector2());
                    }
                    break;

                case "STRP":
                    count = nextChunk.ReadInt32();
                    for (int i = 0; i < count; i++)
                    {
                        VertexIndex next = nextChunk.ReadVertexIndex();

                        if (next.polyBoundary && !lastBoundry)
                        {
                            //polygon finished, add to buffer
                            if (currentPoly.VertexIndices.Count > 0)
                            {
                                polygons.Add(currentPoly);
                            }

                            //start new polygon
                            currentPoly = new Polygon(vertices);

                            //write first index value to polygon
                            currentPoly.VertexIndices.Add(next.index);
                        }
                        else
                        {
                            if (currentPoly != null)
                            {
                                currentPoly.VertexIndices.Add(next.index);
                            }
                            else
                            {
                                //this should never happen
                                Log.Add("Warning: Lone Vertex in Strip Buffer!", LogType.Warning);
                            }
                        }

                        lastBoundry = next.polyBoundary;
                    }
                    break;
                }
            }

            if (uvs.Count > 0)
            {
                hasUVs = true;
            }

            for (int i = 0; i < verts.Count; i++)
            {
                //since uv coordinates are optional, deliver empty ones if non existent
                Vector2 uv = (i < uvs.Count) ? uvs[i] : new Vector2();

                vertices.Add(new Vertex(verts[i], normals[i], uv));
            }

            //Add last Polygon
            if (currentPoly != null && currentPoly.VertexIndices.Count > 0)
            {
                polygons.Add(currentPoly);
            }
        }
예제 #12
0
        /// <summary>
        /// Writes the complete data stream new from scratch.
        /// Every Chunk inheriting from this must override this function
        /// </summary>
        public override void WriteData()
        {
            base.WriteData();

            WriteHeader("MATI");
            WriteInt32(4);
            WriteInt32(Owner.Materials.FindIndex(mat => mat == Material));

            WriteHeader("POSL");
            WriteInt32(vertices.Count * 12 + 4);    //float 4 bytes * vector3, 3 floats  =  12 bytes per Position
            WriteInt32(vertices.Count);             //first integer indicates number of vertices that follow
            foreach (Vertex vert in vertices)
            {
                WriteVector3(vert.position);
            }

            WriteHeader("NRML");
            WriteInt32(vertices.Count * 12 + 4);
            WriteInt32(vertices.Count);
            foreach (Vertex vert in vertices)
            {
                WriteVector3(vert.normal);
            }

            if (hasUVs)
            {
                WriteHeader("UV0L");
                WriteInt32(vertices.Count * 8 + 4);
                WriteInt32(vertices.Count);
                foreach (Vertex vert in vertices)
                {
                    WriteVector2(vert.uvCoordinate);
                }
            }

            //Write Polygon Strips
            WriteHeader("STRP");

            //lets build up an index buffer from our stored polygons
            List <VertexIndex> vertexBuffer = new List <VertexIndex>();

            foreach (Polygon poly in polygons)
            {
                for (int i = 0; i < poly.VertexIndices.Count; i++)
                {
                    VertexIndex vertInd = new VertexIndex {
                        index = poly.VertexIndices[i]
                    };

                    //the first two indices are always tagged as begin/end
                    if (i == 0 || i == 1)
                    {
                        vertInd.polyBoundary = true;
                    }

                    vertexBuffer.Add(vertInd);
                }
            }

            WriteInt32(vertexBuffer.Count * 2 + 4);
            WriteInt32(vertexBuffer.Count);

            foreach (VertexIndex vertInd in vertexBuffer)
            {
                WriteVertexIndex(vertInd);
            }

            WriteChunkLength();
        }
 public VertexIndex(int index) : base(dataSize, index)
 {
     _inst = this;
 }
예제 #14
0
 public bool IsNeighbouring(VertexIndex a, VertexIndex b)
 {
     return(FindNeighbours(a).Contains(b));
 }
예제 #15
0
 public void AddTriangle(VertexIndex a, VertexIndex b, VertexIndex c)
 {
     this.TriangleIndicies.Add(a);
     this.TriangleIndicies.Add(b);
     this.TriangleIndicies.Add(c);
 }
예제 #16
0
 public void Duplicate(VertexIndex index)
 {
     Add(this[index.Index]);
 }
예제 #17
0
 bool IsVertexIndexVoid(VertexIndex index)
 {
     return(index == VertexIndex.VoidValue);
 }
예제 #18
0
 public bool Equals(VertexIndex other)
 {
     return(VertexIndexInPart == other.VertexIndexInPart &&
            PartIndex == other.PartIndex);
 }
예제 #19
0
        /***************************************************/
        /**** Public Methods                            ****/
        /***************************************************/

        public static Mesh MergedVertices(this Mesh mesh, double tolerance = Tolerance.Distance) //TODO: use the point matrix
        {
            List <Face>        faces    = mesh.Faces.Select(x => x.Clone() as Face).ToList();
            List <VertexIndex> vertices = mesh.Vertices.Select((x, i) => new VertexIndex(x.Clone() as Point, i)).ToList();

            foreach (Face face in faces)
            {
                vertices[face.A].Faces.Add(face);
                vertices[face.B].Faces.Add(face);
                vertices[face.C].Faces.Add(face);

                if (face.IsQuad())
                {
                    vertices[face.A].Faces.Add(face);
                }
            }

            vertices.Sort(delegate(VertexIndex v1, VertexIndex v2)
            {
                return(v1.Location.SquareDistance(Point.Origin).CompareTo(v2.Location.SquareDistance(Point.Origin)));
            });


            List <int> culledIndices = new List <int>();
            double     sqTol         = tolerance * tolerance;

            for (int i = 0; i < vertices.Count; i++)
            {
                double distance = vertices[i].Location.Distance(Point.Origin);
                int    j        = i + 1;
                while (j < vertices.Count && Math.Abs(vertices[j].Location.Distance(Point.Origin) - distance) < tolerance)
                {
                    VertexIndex v2 = vertices[j];
                    if (vertices[i].Location.SquareDistance(vertices[j].Location) < sqTol)
                    {
                        SetFaceIndex(v2.Faces, vertices[j].Index, vertices[i].Index);
                        culledIndices.Add(vertices[j].Index);
                        v2.Index = vertices[i].Index;
                        break;
                    }
                    j++;
                }
            }

            for (int i = 0; i < faces.Count; i++)
            {
                for (int k = 0; k < culledIndices.Count; k++)
                {
                    if (faces[i].A > culledIndices[k])
                    {
                        faces[i].A--;
                    }
                    if (faces[i].B > culledIndices[k])
                    {
                        faces[i].B--;
                    }
                    if (faces[i].C > culledIndices[k])
                    {
                        faces[i].C--;
                    }
                    if (faces[i].D > culledIndices[k])
                    {
                        faces[i].D--;
                    }
                }
            }

            return(new Mesh {
                Vertices = vertices.Select(x => x.Location).ToList(), Faces = faces
            });
        }
예제 #20
0
 // Token: 0x06000035 RID: 53 RVA: 0x00002CE4 File Offset: 0x00000EE4
 private static void ReconstructProxies(LOD src, out Dictionary <string, List <Conversion.PointWeight> > points, out Dictionary <string, List <int> > faces)
 {
     points = new Dictionary <string, List <Conversion.PointWeight> >(src.NamedSelections.Length * 2);
     faces  = new Dictionary <string, List <int> >(src.NamedSelections.Length * 2);
     for (int i = 0; i < src.Faces.Length; i++)
     {
         Polygon polygon = src.Faces[i];
         if (polygon.VertexIndices.Length == 3)
         {
             VertexIndex vi        = polygon.VertexIndices[0];
             VertexIndex vi2       = polygon.VertexIndices[1];
             VertexIndex vi3       = polygon.VertexIndices[2];
             Vector3P    vector3P  = src.Vertices[vi];
             Vector3P    vector3P2 = src.Vertices[vi2];
             Vector3P    vector3P3 = src.Vertices[vi3];
             float       num       = vector3P.Distance(vector3P2);
             float       num2      = vector3P.Distance(vector3P3);
             float       num3      = vector3P2.Distance(vector3P3);
             if (num > num2)
             {
                 Methods.Swap <Vector3P>(ref vector3P2, ref vector3P3);
                 Methods.Swap <float>(ref num, ref num2);
             }
             if (num > num3)
             {
                 Methods.Swap <Vector3P>(ref vector3P, ref vector3P3);
                 Methods.Swap <float>(ref num, ref num3);
             }
             if (num2 > num3)
             {
                 Methods.Swap <Vector3P>(ref vector3P, ref vector3P2);
                 Methods.Swap <float>(ref num2, ref num3);
             }
             Vector3P vector3P4 = vector3P;
             Vector3P vector3P5 = vector3P2 - vector3P;
             Vector3P vector3P6 = vector3P3 - vector3P;
             vector3P5.Normalize();
             vector3P6.Normalize();
             if (Methods.EqualsFloat(vector3P6 * vector3P5, 0f, 0.05f))
             {
                 for (int j = 0; j < src.Proxies.Length; j++)
                 {
                     Vector3P position = src.Proxies[j].transformation.Position;
                     Vector3P up       = src.Proxies[j].transformation.Orientation.Up;
                     Vector3P dir      = src.Proxies[j].transformation.Orientation.Dir;
                     if (vector3P4.Equals(position) && vector3P5.Equals(dir) && vector3P6.Equals(up))
                     {
                         Proxy  proxy = src.Proxies[j];
                         string name  = src.NamedSelections[proxy.namedSelectionIndex].Name;
                         if (!faces.ContainsKey(name))
                         {
                             faces[name]  = i.Yield <int>().ToList <int>();
                             points[name] = Methods.Yield <Conversion.PointWeight>(new Conversion.PointWeight[]
                             {
                                 new Conversion.PointWeight(vi, byte.MaxValue),
                                 new Conversion.PointWeight(vi2, byte.MaxValue),
                                 new Conversion.PointWeight(vi3, byte.MaxValue)
                             }).ToList <Conversion.PointWeight>();
                             break;
                         }
                     }
                 }
             }
         }
     }
 }