// PreCalcInfo takes the vertex values and computes information to // help with intersections with rays. void ViewableTriangle::PreCalcInfo() { VectorR3 EdgeAB = VertexB - VertexA; VectorR3 EdgeBC = VertexC - VertexB; VectorR3 EdgeCA = VertexA - VertexC; if ( (EdgeAB^EdgeBC) < (EdgeBC^EdgeCA) ) { Normal = EdgeAB*EdgeBC; } else { Normal = EdgeBC*EdgeCA; } double mag = Normal.Norm(); if ( mag>0.0 ) { Normal /= mag; // Unit vector to triangle's plane } PlaneCoef = (Normal^VertexA); // Same coef for all three vertices. double A = EdgeAB.NormSq(); double B = (EdgeAB^EdgeCA); double C = EdgeCA.NormSq(); double Dinv = 1.0/(A*C-B*B); A *= Dinv; B *= Dinv; C *= Dinv; Ubeta = EdgeAB; Ubeta *= C; Ubeta.AddScaled( EdgeCA, -B ); Ugamma = EdgeCA; Ugamma *= -A; Ugamma.AddScaled( EdgeAB, B ); }
RotationMapR3 VrRotateAlign( const VectorR3& fromVec, const VectorR3& toVec) { VectorR3 crossVec = fromVec; crossVec *= toVec; double sinetheta = crossVec.Norm(); // Not yet normalized! if ( sinetheta < 1.0e-40 ) { return ( RotationMapR3( 1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0) ); } crossVec /= sinetheta; // Normalize the vector double scale = 1.0/sqrt(fromVec.NormSq()*toVec.NormSq()); sinetheta *= scale; double cosinetheta = (fromVec^toVec)*scale; return ( VrRotate( cosinetheta, sinetheta, crossVec) ); }
bool ViewableSphere::CalcPartials( const VisiblePoint& visPoint, VectorR3& retPartialU, VectorR3& retPartialV ) const { retPartialV = visPoint.GetPosition(); retPartialV -= Center; retPartialU = retPartialV; retPartialU *= AxisC; // Magnitude = R sin(phi). retPartialU *= -PI2; // Adjust for [0,1] domain instead of [-pi,pi] retPartialV *= retPartialU; // Pointing in right direction, magnitude 2 pi R^2 sin(phi) // Sign and magnitude adjusted below. double badMagSq = retPartialV.NormSq(); double h; switch ( uvProjectionType ) { case 0: // Spherical projection h = sqrt(badMagSq); if ( h==0.0 ) { retPartialV = AxisB; return false; } retPartialV *= (PI*Radius/h); // Convert to domain [0,1] instead of [-pi/2,pi/2]. // Compensate for sign and R^2 magnitude. break; case 1: h = 2.0*(visPoint.GetV()-0.5); // In range [-1,1] h = sqrt(badMagSq*(1.0 - h*h)); // Derivative of arcsin(h) = 1/sqrt(1-h^2) if ( h==0 ) { retPartialV = AxisB; return false; } retPartialV *= PI*Radius/h; // Adjust sign and magnitude break; } return true; }