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); } }
/** * 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; }
/** * 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; }
/** * 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; }
/** * 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; }
/** * 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; }
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; }