/*=========================================================================== * * Local Function - boolean l_ComputeDFUVMatrixXY (Matrix, Params); * * Computes the UV conversion parameters from the given input based on * the formula: * U = AX + BY + D * * Returns FALSE on any error. For use on faces with 0 Z-coordinates. * *=========================================================================*/ private bool l_ComputeDFUVMatrixXY(ref df3duvmatrix_t matrix, ref df3duvparams_lt param) { float determinant; float[] Xi = new float[3]; float[] Yi = new float[3]; float[] Zi = new float[3]; /* Compute the determinant of the coefficient matrix */ determinant = param.X[0] * param.Y[1] + param.Y[0] * param.X[2] + param.X[1] * param.Y[2] - param.Y[1] * param.X[2] - param.Y[0] * param.X[1] - param.X[0] * param.Y[2]; /* Check for a singular matrix indicating no valid solution */ if (determinant == 0) { return(false); } /* Compute parameters of the the inverted XYZ matrix */ Xi[0] = (param.Y[1] - param.Y[2]) / determinant; Xi[1] = (-param.X[1] + param.X[2]) / determinant; Xi[2] = (param.X[1] * param.Y[2] - param.X[2] * param.Y[1]) / determinant; Yi[0] = (-param.Y[0] + param.Y[2]) / determinant; Yi[1] = (param.X[0] - param.X[2]) / determinant; Yi[2] = (-param.X[0] * param.Y[2] + param.X[2] * param.Y[0]) / determinant; Zi[0] = (param.Y[0] - param.Y[1]) / determinant; Zi[1] = (-param.X[0] + param.X[1]) / determinant; Zi[2] = (param.X[0] * param.Y[1] - param.X[1] * param.Y[0]) / determinant; /* Compute the UV conversion parameters */ matrix.UA = (param.U[0] * Xi[0] + param.U[1] * Yi[0] + param.U[2] * Zi[0]); matrix.UB = (param.U[0] * Xi[1] + param.U[1] * Yi[1] + param.U[2] * Zi[1]); matrix.UC = (float)0.0; matrix.UD = (param.U[0] * Xi[2] + param.U[1] * Yi[2] + param.U[2] * Zi[2]);; matrix.VA = (param.V[0] * Xi[0] + param.V[1] * Yi[0] + param.V[2] * Zi[0]); matrix.VB = (param.V[0] * Xi[1] + param.V[1] * Yi[1] + param.V[2] * Zi[1]); matrix.VC = (float)0.0; matrix.VD = (param.V[0] * Xi[2] + param.V[1] * Yi[2] + param.V[2] * Zi[2]); return(true); }
/// <summary> /// Calculates absolute UV values for all points of a face. /// </summary> /// <param name="faceVertsIn">Source array of native point values.</param> /// <param name="faceVertsOut">Destination array for calculated UV values.</param> /// <returns>True if successful, otherwise false.</returns> public bool ComputeFaceUVCoordinates(ref DFPurePoint[] faceVertsIn, ref DFPurePoint[] faceVertsOut) { // Get first three vertices of ngon (these three vertices are always non-collinear) Vector3 P0 = new Vector3(faceVertsIn[0].x, faceVertsIn[0].y, faceVertsIn[0].z); Vector3 P1 = new Vector3(faceVertsIn[1].x, faceVertsIn[1].y, faceVertsIn[1].z); Vector3 P2 = new Vector3(faceVertsIn[2].x, faceVertsIn[2].y, faceVertsIn[2].z); // Create coplanar vectors from p1->p0 and p2->p0 Vector3 V0 = P1 - P0; Vector3 V1 = P2 - P0; // Orthogonalize V1 V1 = V1 - (V0 * (V1.DotProduct(V0) / (V0.DotProduct(V0)))); // Normalize both vectors V0.Normalize(); V1.Normalize(); // Compute first three vertices in 2D space DF2DPoint p0, p1, p2; p0.x = (Int32)P0.DotProduct(V0); p0.y = (Int32)P0.DotProduct(V1); p1.x = (Int32)P1.DotProduct(V0); p1.y = (Int32)P1.DotProduct(V1); p2.x = (Int32)P2.DotProduct(V0); p2.y = (Int32)P2.DotProduct(V1); // Initialise the params struct df3duvparams_lt Params = new df3duvparams_lt(); Params.X = new float[4]; Params.Y = new float[4]; Params.Z = new float[4]; Params.U = new float[4]; Params.V = new float[4]; // Initialise the conversion matrix df3duvmatrix_t Matrix = new df3duvmatrix_t(); Matrix.UA = 1.0f; Matrix.UB = 0.0f; Matrix.UC = 0.0f; Matrix.UD = 0.0f; Matrix.VA = 0.0f; Matrix.VB = 1.0f; Matrix.VC = 0.0f; Matrix.UD = 0.0f; // Store the first 3 points of texture coordinates Params.U[0] = faceVertsIn[0].u; Params.U[1] = faceVertsIn[1].u + Params.U[0]; Params.U[2] = faceVertsIn[2].u + Params.U[1]; Params.V[0] = faceVertsIn[0].v; Params.V[1] = faceVertsIn[1].v + Params.V[0]; Params.V[2] = faceVertsIn[2].v + Params.V[1]; // Get and store the 1st point coordinates in face Params.X[0] = p0.x; Params.Y[0] = p0.y; Params.Z[0] = 0; // Get and store the 2nd point coordinates in face Params.X[1] = p1.x; Params.Y[1] = p1.y; Params.Z[1] = 0; // Get and store the 3rd point coordinates in face Params.X[2] = p2.x; Params.Y[2] = p2.y; Params.Z[2] = 0; // Compute the solution using an XY linear equation if (!l_ComputeDFUVMatrixXY(ref Matrix, ref Params)) { return(false); } // Assign matrix to all points if successful Int32 u = 0, v = 0; for (int point = 0; point < faceVertsIn.Length; point++) { if (point > 2) { // Use generated matrix to calculate UV value from 2D point DF2DPoint pn; Vector3 PN = new Vector3(faceVertsIn[point].x, faceVertsIn[point].y, faceVertsIn[point].z); pn.x = (Int32)PN.DotProduct(V0); pn.y = (Int32)PN.DotProduct(V1); u = (Int32)((pn.x * Matrix.UA) + (pn.y * Matrix.UB) + Matrix.UD); v = (Int32)((pn.x * Matrix.VA) + (pn.y * Matrix.VB) + Matrix.VD); } else if (point == 0) { // UV[0] is absolute u = faceVertsIn[0].u; v = faceVertsIn[0].v; } else if (point == 1) { // UV[1] is a delta from UV[0] u = faceVertsIn[0].u + faceVertsIn[1].u; v = faceVertsIn[0].v + faceVertsIn[1].v; } else if (point == 2) { // UV[2] is a delta from UV[1] + UV[0] u = faceVertsIn[0].u + faceVertsIn[1].u + faceVertsIn[2].u; v = faceVertsIn[0].v + faceVertsIn[1].v + faceVertsIn[2].v; } // Write outgoing point faceVertsOut[point].x = faceVertsIn[point].x; faceVertsOut[point].y = faceVertsIn[point].y; faceVertsOut[point].z = faceVertsIn[point].z; faceVertsOut[point].nx = faceVertsIn[point].nx; faceVertsOut[point].ny = faceVertsIn[point].ny; faceVertsOut[point].nz = faceVertsIn[point].nz; faceVertsOut[point].u = u; faceVertsOut[point].v = v; } return(true); }
/// <summary> /// Calculates absolute UV values for all points of a face. /// </summary> /// <param name="faceVertsIn">Source array of native point values.</param> /// <param name="faceVertsOut">Destination array for calculated UV values.</param> /// <returns>True if successful, otherwise false.</returns> public bool ComputeFaceUVCoordinates(ref DFPurePoint[] faceVertsIn, ref DFPurePoint[] faceVertsOut) { // Get first three vertices of ngon (these three vertices are always non-collinear) Vector3 P0 = new Vector3(faceVertsIn[0].x, faceVertsIn[0].y, faceVertsIn[0].z); Vector3 P1 = new Vector3(faceVertsIn[1].x, faceVertsIn[1].y, faceVertsIn[1].z); Vector3 P2 = new Vector3(faceVertsIn[2].x, faceVertsIn[2].y, faceVertsIn[2].z); // Create coplanar vectors from p1->p0 and p2->p0 Vector3 V0 = P1 - P0; Vector3 V1 = P2 - P0; // Orthogonalize V1 V1 = V1 - (V0 * (V1.DotProduct(V0) / (V0.DotProduct(V0)))); // Normalize both vectors V0.Normalize(); V1.Normalize(); // Compute first three vertices in 2D space DF2DPoint p0, p1, p2; p0.x = (Int32)P0.DotProduct(V0); p0.y = (Int32)P0.DotProduct(V1); p1.x = (Int32)P1.DotProduct(V0); p1.y = (Int32)P1.DotProduct(V1); p2.x = (Int32)P2.DotProduct(V0); p2.y = (Int32)P2.DotProduct(V1); // Initialise the params struct df3duvparams_lt Params = new df3duvparams_lt(); Params.X = new float[4]; Params.Y = new float[4]; Params.Z = new float[4]; Params.U = new float[4]; Params.V = new float[4]; // Initialise the conversion matrix df3duvmatrix_t Matrix = new df3duvmatrix_t(); Matrix.UA = 1.0f; Matrix.UB = 0.0f; Matrix.UC = 0.0f; Matrix.UD = 0.0f; Matrix.VA = 0.0f; Matrix.VB = 1.0f; Matrix.VC = 0.0f; Matrix.UD = 0.0f; // Store the first 3 points of texture coordinates Params.U[0] = faceVertsIn[0].u; Params.U[1] = faceVertsIn[1].u + Params.U[0]; Params.U[2] = faceVertsIn[2].u + Params.U[1]; Params.V[0] = faceVertsIn[0].v; Params.V[1] = faceVertsIn[1].v + Params.V[0]; Params.V[2] = faceVertsIn[2].v + Params.V[1]; // Get and store the 1st point coordinates in face Params.X[0] = p0.x; Params.Y[0] = p0.y; Params.Z[0] = 0; // Get and store the 2nd point coordinates in face Params.X[1] = p1.x; Params.Y[1] = p1.y; Params.Z[1] = 0; // Get and store the 3rd point coordinates in face Params.X[2] = p2.x; Params.Y[2] = p2.y; Params.Z[2] = 0; // Compute the solution using an XY linear equation if (!l_ComputeDFUVMatrixXY(ref Matrix, ref Params)) return false; // Assign matrix to all points if successful Int32 u = 0, v = 0; for (int point = 0; point < faceVertsIn.Length; point++) { if (point > 2) { // Use generated matrix to calculate UV value from 2D point DF2DPoint pn; Vector3 PN = new Vector3(faceVertsIn[point].x, faceVertsIn[point].y, faceVertsIn[point].z); pn.x = (Int32)PN.DotProduct(V0); pn.y = (Int32)PN.DotProduct(V1); u = (Int32)((pn.x * Matrix.UA) + (pn.y * Matrix.UB) + Matrix.UD); v = (Int32)((pn.x * Matrix.VA) + (pn.y * Matrix.VB) + Matrix.VD); } else if (point == 0) { // UV[0] is absolute u = faceVertsIn[0].u; v = faceVertsIn[0].v; } else if (point == 1) { // UV[1] is a delta from UV[0] u = faceVertsIn[0].u + faceVertsIn[1].u; v = faceVertsIn[0].v + faceVertsIn[1].v; } else if (point == 2) { // UV[2] is a delta from UV[1] + UV[0] u = faceVertsIn[0].u + faceVertsIn[1].u + faceVertsIn[2].u; v = faceVertsIn[0].v + faceVertsIn[1].v + faceVertsIn[2].v; } // Write outgoing point faceVertsOut[point].x = faceVertsIn[point].x; faceVertsOut[point].y = faceVertsIn[point].y; faceVertsOut[point].z = faceVertsIn[point].z; faceVertsOut[point].nx = faceVertsIn[point].nx; faceVertsOut[point].ny = faceVertsIn[point].ny; faceVertsOut[point].nz = faceVertsIn[point].nz; faceVertsOut[point].u = u; faceVertsOut[point].v = v; } return true; }
/*=========================================================================== * * Local Function - boolean l_ComputeDFUVMatrixXY (Matrix, Params); * * Computes the UV conversion parameters from the given input based on * the formula: * U = AX + BY + D * * Returns FALSE on any error. For use on faces with 0 Z-coordinates. * *=========================================================================*/ private bool l_ComputeDFUVMatrixXY(ref df3duvmatrix_t matrix, ref df3duvparams_lt param) { float determinant; float[] Xi = new float[3]; float[] Yi = new float[3]; float[] Zi = new float[3]; /* Compute the determinant of the coefficient matrix */ determinant = param.X[0] * param.Y[1] + param.Y[0] * param.X[2] + param.X[1] * param.Y[2] - param.Y[1] * param.X[2] - param.Y[0] * param.X[1] - param.X[0] * param.Y[2]; /* Check for a singular matrix indicating no valid solution */ if (determinant == 0) { return false; } /* Compute parameters of the the inverted XYZ matrix */ Xi[0] = (param.Y[1] - param.Y[2]) / determinant; Xi[1] = (-param.X[1] + param.X[2]) / determinant; Xi[2] = (param.X[1] * param.Y[2] - param.X[2] * param.Y[1]) / determinant; Yi[0] = (-param.Y[0] + param.Y[2]) / determinant; Yi[1] = (param.X[0] - param.X[2]) / determinant; Yi[2] = (-param.X[0] * param.Y[2] + param.X[2] * param.Y[0]) / determinant; Zi[0] = (param.Y[0] - param.Y[1]) / determinant; Zi[1] = (-param.X[0] + param.X[1]) / determinant; Zi[2] = (param.X[0] * param.Y[1] - param.X[1] * param.Y[0]) / determinant; /* Compute the UV conversion parameters */ matrix.UA = (param.U[0] * Xi[0] + param.U[1] * Yi[0] + param.U[2] * Zi[0]); matrix.UB = (param.U[0] * Xi[1] + param.U[1] * Yi[1] + param.U[2] * Zi[1]); matrix.UC = (float)0.0; matrix.UD = (param.U[0] * Xi[2] + param.U[1] * Yi[2] + param.U[2] * Zi[2]); ; matrix.VA = (param.V[0] * Xi[0] + param.V[1] * Yi[0] + param.V[2] * Zi[0]); matrix.VB = (param.V[0] * Xi[1] + param.V[1] * Yi[1] + param.V[2] * Zi[1]); matrix.VC = (float)0.0; matrix.VD = (param.V[0] * Xi[2] + param.V[1] * Yi[2] + param.V[2] * Zi[2]); return true; }