/// <summary> /// 计算t后差值的Transform /// </summary> /// <param name="time"></param> /// <param name="t"></param> public void Interpolate(float time, out Transform t) { // Handle boundary conditions for matrix interpolation if (!actuallyAnimated || time <= startTime) { t = startTransform; return; } if (time >= endTime) { t = endTransform; return; } float dt = (time - startTime) / (endTime - startTime); // Interpolate translation at _dt_ Vector trans = (1.0f - dt) * T[0] + dt * T[1]; // Interpolate rotation at _dt_ Quaternion rotate = LR.Slerp(dt, R[0], R[1]); // Interpolate scale at _dt_ Matrix4x4 scale = new Matrix4x4(); for (int i = 0; i < 3; ++i) { for (int j = 0; j < 3; ++j) { scale.m[i, j] = LR.Lerp(dt, S[0].m[i, j], S[1].m[i, j]); } } // Compute interpolated matrix as product of interpolated components t = LR.Multiply(LR.Translate(trans), rotate.ToTransform(), new Transform(scale)); }
public float Evaluate(float cosi) { cosi = LR.Clamp(cosi, -1.0f, 1.0f); // Compute indices of refraction for dielectric bool entering = cosi > 0.0;//>0 入射 float ei = eta_i, et = eta_t; if (!entering) { LR.Swap(ei, et); } // Compute _sint_ using Snell's law float sint = ei / et * (float)Math.Sqrt(Math.Max(0.0f, 1.0f - cosi * cosi));//处理溢出? if (sint >= 1.0) { // Handle total internal reflection return(1.0f); } else { float cost = (float)Math.Sqrt(Math.Max(0.0f, 1.0f - sint * sint)); return(BSDFFunction.FrDiel(Math.Abs(cosi), cost, ei, et)); } }
public static float SinPhi(Vector w) { float sintheta = SinTheta(w); if (sintheta == 0.0f) { return(0.0f); } return(LR.Clamp(w.y / sintheta, -1.0f, 1.0f)); }
public static float CosPhi(Vector w) { float sintheta = SinTheta(w); if (sintheta == 0.0f) { return(1.0f); //垂直 } return(LR.Clamp(w.x / sintheta, -1.0f, 1.0f)); }
/// <summary> /// M = TRS ,get TRS /// </summary> /// <param name="m"></param> /// <param name="T"></param> /// <param name="Rquat"></param> /// <param name="S"></param> public void Decompose(Matrix4x4 m, out Vector T, out Quaternion Rquat, out Matrix4x4 S) { T = new Vector(); // Rquat = new Quaternion(); //S = new Matrix4x4(); T.x = m.m[0, 3]; T.y = m.m[1, 3]; T.z = m.m[2, 3]; // Compute new transformation matrix _M_ without translation Matrix4x4 M = new Matrix4x4(m); for (int i = 0; i < 3; ++i) { M.m[i, 3] = M.m[3, i] = 0.0f; } M.m[3, 3] = 1.0f; // Extract rotation _R_ from transformation matrix float norm; int count = 0; Matrix4x4 R = new Matrix4x4(M); do { // Compute next matrix _Rnext_ in series Matrix4x4 Rnext = new Matrix4x4(); Matrix4x4 Rit = LR.Inverse(LR.Transpose(R)); for (int i = 0; i < 4; ++i) { for (int j = 0; j < 4; ++j) { Rnext.m[i, j] = 0.5f * (R.m[i, j] + Rit.m[i, j]); } } // Compute norm of difference between _R_ and _Rnext_ norm = 0.0f; for (int i = 0; i < 3; ++i) { float n = (float)Math.Abs(R.m[i, 0] - Rnext.m[i, 0]) + (float)Math.Abs(R.m[i, 1] - Rnext.m[i, 1]) + (float)Math.Abs(R.m[i, 2] - Rnext.m[i, 2]); norm = (float)Math.Max(norm, n); } R = Rnext; } while (++count < 100 && norm > .0001f); // XXX TODO FIXME deal with flip... Rquat = new Quaternion(new Transform(R)); // Compute scale _S_ using rotation and original matrix S = LR.Multiply(LR.Inverse(R), M); }
/// <summary> /// v' = q*v*q-1 /// v' = M*v /// </summary> /// <returns></returns> public Transform ToTransform() { float xx = v.x * v.x, yy = v.y * v.y, zz = v.z * v.z; float xy = v.x * v.y, xz = v.x * v.z, yz = v.y * v.z; float wx = v.x * w, wy = v.y * w, wz = v.z * w; Matrix4x4 m = new Matrix4x4(); m.m[0, 0] = 1.0f - 2.0f * (yy + zz); m.m[0, 1] = 2.0f * (xy + wz); m.m[0, 2] = 2.0f * (xz - wy); m.m[1, 0] = 2.0f * (xy - wz); m.m[1, 1] = 1.0f - 2.0f * (xx + zz); m.m[1, 2] = 2.0f * (yz + wx); m.m[2, 0] = 2.0f * (xz + wy); m.m[2, 1] = 2.0f * (yz - wx); m.m[2, 2] = 1.0f - 2.0f * (xx + yy); // Transpose since we are left-handed. Ugh. return(new Transform(LR.Transpose(m), m)); }
public Transform(Matrix4x4 M) { m = M; mInv = LR.Inverse(M); }