public override bool Equals(object obj)
        {
            SortableVertex o = obj as SortableVertex;

            if (o == null)
            {
                return(false);
            }

            return(gridIndex == o.gridIndex && x == o.x);
        }
 public int compareTo(SortableVertex o)
 {
     if (gridIndex != o.gridIndex) {
         return gridIndex - o.gridIndex;
     } else if (x < o.x) {
         return -1;
     } else if (x > o.x) {
         return 1;
     } else {
         return 0;
     }
 }
        public int CompareTo(object obj)
        {
            if (obj == null)
            {
                return(1);
            }

            SortableVertex other = obj as SortableVertex;

            if (other != null)
            {
                return(compareTo(other));
            }
            else
            {
                throw new ArgumentException("Object is not a SortableVertex");
            }
        }
        public SortableVertex[] sortVertices(Grid grid, float[] v)
        {
            // Prepare sort vertex array
            int vc = v.Length / Mesh.CTM_POSITION_ELEMENT_COUNT;

            SortableVertex[] sortVertices = new SortableVertex[vc];
            for (int i = 0; i < vc; ++i)
            {
                // Store vertex properties in the sort vertex array
                float[] point = new float[] { v [i * 3], v [i * 3 + 1], v [i * 3 + 2] };
                int     p2g   = pointToGridIdx(grid, point);
                sortVertices [i] = new SortableVertex(v [i * 3], p2g, i);
            }

            // Sort vertices. The elements are first sorted by their grid indices, and
            // scondly by their x coordinates.
            Array.Sort(sortVertices);
            return(sortVertices);
        }
 public int compareTo(SortableVertex o)
 {
     if (gridIndex != o.gridIndex)
     {
         return(gridIndex - o.gridIndex);
     }
     else if (x < o.x)
     {
         return(-1);
     }
     else if (x > o.x)
     {
         return(1);
     }
     else
     {
         return(0);
     }
 }
Beispiel #6
0
        /**
         * Re-index all indices, based on the sorted vertices.
         */
        private int[] reIndexIndices(SortableVertex[] sortVertices, int[] indices)
        {
            // Create temporary lookup-array, O(n)
            int[] indexLUT = new int[sortVertices.Length];
            int[] newIndices = new int[indices.Length];

            for (int i = 0; i < sortVertices.Length; ++i) {
                indexLUT [sortVertices [i].originalIndex] = i;
            }

            // Convert old indices to new indices, O(n)
            for (int i = 0; i < indices.Length; ++i) {
                newIndices [i] = indexLUT [indices [i]];
            }

            return newIndices;
        }
Beispiel #7
0
        /**
         * Calculate various forms of derivatives in order to reduce data entropy.
         */
        private int[] makeVertexDeltas(float[] vertices, SortableVertex[] sortVertices, Grid grid)
        {
            int vc = sortVertices.Length;

            // Vertex scaling factor
            float scale = 1.0f / vertexPrecision;

            float prevGridIndex = 0x7fffffff;
            int prevDeltaX = 0;
            int[] intVertices = new int[vc * Mesh.CTM_POSITION_ELEMENT_COUNT];
            for (int i = 0; i < vc; ++i) {
                // Get grid box origin
                int gridIdx = sortVertices [i].gridIndex;
                float[] gridOrigin = CommonAlgorithm.gridIdxToPoint (grid, gridIdx);

                // Get old vertex coordinate index (before vertex sorting)
                int oldIdx = sortVertices [i].originalIndex;

                // Store delta to the grid box origin in the integer vertex array. For the
                // X axis (which is sorted) we also do the delta to the previous coordinate
                // in the box.
                int deltaX = (int)Math.Floor (scale * (vertices [oldIdx * 3] - gridOrigin [0]) + 0.5f);
                if (gridIdx == prevGridIndex) {
                    intVertices [i * 3] = deltaX - prevDeltaX;
                } else {
                    intVertices [i * 3] = deltaX;
                }

                intVertices [i * 3 + 1] = (int)Math.Floor (scale * (vertices [oldIdx * 3 + 1] - gridOrigin [1]) + 0.5f);
                intVertices [i * 3 + 2] = (int)Math.Floor (scale * (vertices [oldIdx * 3 + 2] - gridOrigin [2]) + 0.5f);

                prevGridIndex = gridIdx;
                prevDeltaX = deltaX;
            }

            return intVertices;
        }
Beispiel #8
0
        /**
         * Calculate various forms of derivatives in order to reduce data entropy.
         */
        private int[] makeUVCoordDeltas(AttributeData map, SortableVertex[] sortVertices)
        {
            // UV coordinate scaling factor
            float scale = 1.0f / map.precision;
            int vc = sortVertices.Length;
            int prevU = 0, prevV = 0;
            int[] intUVCoords = new int[vc * Mesh.CTM_UV_ELEMENT_COUNT];
            for (int i = 0; i < vc; ++i) {
                // Get old UV coordinate index (before vertex sorting)
                int oldIdx = sortVertices [i].originalIndex;

                // Convert to fixed point
                int u = (int)Math.Floor (scale * map.values [oldIdx * 2] + 0.5f);
                int v = (int)Math.Floor (scale * map.values [oldIdx * 2 + 1] + 0.5f);

                // Calculate delta and store it in the converted array. NOTE: Here we rely
                // on the fact that vertices are sorted, and usually close to each other,
                // which means that UV coordinates should also be close to each other...
                intUVCoords [i * 2] = u - prevU;
                intUVCoords [i * 2 + 1] = v - prevV;

                prevU = u;
                prevV = v;
            }
            return intUVCoords;
        }
Beispiel #9
0
        /**
         * Convert the normals to a new coordinate system: magnitude, phi, theta
         * (relative to predicted smooth normals).
         */
        private int[] makeNormalDeltas(float[] vertices, float[] normals, int[] indices, SortableVertex[] sortVertices)
        {
            // Calculate smooth normals (Note: aVertices and aIndices use the sorted
            // index space, so smoothNormals will too)
            float[] smoothNormals = CommonAlgorithm.calcSmoothNormals (vertices, indices);

            // Normal scaling factor
            float scale = 1.0f / normalPrecision;

            int vc = vertices.Length / Mesh.CTM_POSITION_ELEMENT_COUNT;
            int[] intNormals = new int[vc * Mesh.CTM_NORMAL_ELEMENT_COUNT];
            for (int i = 0; i < vc; ++i) {
                // Get old normal index (before vertex sorting)
                int oldIdx = sortVertices [i].originalIndex;

                // Calculate normal magnitude (should always be 1.0 for unit length normals)
                float magn = (float)Math.Sqrt (normals [oldIdx * 3] * normals [oldIdx * 3]
                                          + normals [oldIdx * 3 + 1] * normals [oldIdx * 3 + 1]
                                          + normals [oldIdx * 3 + 2] * normals [oldIdx * 3 + 2]);
                if (magn < 1e-10f) {
                    magn = 1.0f;
                }

                // Invert magnitude if the normal is negative compared to the predicted
                // smooth normal
                if ((smoothNormals [i * 3] * normals [oldIdx * 3]
                     + smoothNormals [i * 3 + 1] * normals [oldIdx * 3 + 1]
                     + smoothNormals [i * 3 + 2] * normals [oldIdx * 3 + 2]) < 0.0f) {
                    magn = -magn;
                }

                // Store the magnitude in the first element of the three normal elements
                intNormals [i * 3] = (int)Math.Floor (scale * magn + 0.5f);

                // Normalize the normal (1 / magn) - and flip it if magn < 0
                magn = 1.0f / magn;
                float[] n = new float[3];
                for (int j = 0; j < 3; ++j) {
                    n [j] = normals [oldIdx * 3 + j] * magn;
                }

                // Convert the normal to angular representation (phi, theta) in a coordinate
                // system where the nominal (smooth) normal is the Z-axis
                float[] basisAxes = CommonAlgorithm.makeNormalCoordSys (smoothNormals, i * 3);
                float[] n2 = new float[3];
                for (int j = 0; j < 3; ++j) {
                    n2 [j] = basisAxes [j * 3] * n [0]
                            + basisAxes [j * 3 + 1] * n [1]
                            + basisAxes [j * 3 + 2] * n [2];
                }
                double phi, theta, thetaScale;
                if (n2 [2] >= 1.0f) {
                    phi = 0.0f;
                } else {
                    phi = Math.Acos (n2 [2]);
                }
                theta = Math.Atan2 (n2 [1], n2 [0]);

                // Round phi and theta (spherical coordinates) to integers. Note: We let the
                // theta resolution vary with the x/y circumference (roughly phi).
                int intPhi = (int)Math.Floor (phi * (scale / (0.5 * Math.PI)) + 0.5);
                if (intPhi == 0) {
                    thetaScale = 0.0;
                } else if (intPhi <= 4) {
                    thetaScale = 2.0 / Math.PI;
                } else {
                    thetaScale = intPhi / (2.0 * Math.PI);
                }
                intNormals [i * 3 + 1] = intPhi;
                intNormals [i * 3 + 2] = (int)Math.Floor ((theta + Math.PI) * thetaScale + 0.5f);
            }
            return intNormals;
        }
Beispiel #10
0
        /**
         * Calculate various forms of derivatives in order to reduce data entropy.
         */
        private int[] makeAttribDeltas(AttributeData map, SortableVertex[] sortVertices)
        {
            // Attribute scaling factor
            float scale = 1.0f / map.precision;

            int[] prev = new int[4];

            int vc = sortVertices.Length;
            int[] intAttribs = new int[vc * Mesh.CTM_ATTR_ELEMENT_COUNT];

            for (int i = 0; i < vc; ++i) {
                // Get old attribute index (before vertex sorting)
                int oldIdx = sortVertices [i].originalIndex;

                // Convert to fixed point, and calculate delta and store it in the converted
                // array. NOTE: Here we rely on the fact that vertices are sorted, and
                // usually close to each other, which means that attributes should also
                // be close to each other (and we assume that they somehow vary slowly with
                // the geometry)...

                for (int j = 0; j < 4; ++j) {
                    int value = (int)Math.Floor (scale * map.values [oldIdx * 4 + j] + 0.5f);
                    intAttribs [i * 4 + j] = value - prev [j];
                    prev [j] = value;
                }
            }
            return intAttribs;
        }
Beispiel #11
0
        public SortableVertex[] sortVertices(Grid grid, float[] v)
        {
            // Prepare sort vertex array
            int vc = v.Length / Mesh.CTM_POSITION_ELEMENT_COUNT;
            SortableVertex[] sortVertices = new SortableVertex[vc];
            for (int i = 0; i < vc; ++i) {
                // Store vertex properties in the sort vertex array
                float[] point = new float[]{v [i * 3], v [i * 3 + 1], v [i * 3 + 2]};
                int p2g = pointToGridIdx (grid, point);
                sortVertices [i] = new SortableVertex (v [i * 3], p2g, i);
            }

            // Sort vertices. The elements are first sorted by their grid indices, and
            // scondly by their x coordinates.
            Array.Sort (sortVertices);
            return sortVertices;
        }