Triangle::Triangle(std::size_t const mat, float3_t const &vp0, float3_t const &vp1, float3_t const &vp2, float3_t const &ns0, float3_t const &ns1, float3_t const &ns2, value_type const s0, value_type const t0, value_type const s1, value_type const t1, value_type const s2, value_type const t2) : bsdf_(mat), isDoubleFace_(true), v0_(vp0), e1_(vp1 - vp0), e2_(vp2 - vp0), ng_(hi::normalize(NormalVector(e1_, e2_))), n0_(ns0), s1_(ns1 - ns0), s2_(ns2 - ns0), uv0_(s0, t0), uv1_(s1, t1), uv2_(s2, t2) #ifdef HI_TRIANGLE_HAS_MINMAX , min_(hi::min(hi::min(vp0, vp1), vp2)), max_(hi::max(hi::max(vp0, vp1), vp2)) #endif HI_TRIANGLE_HAS_MINMAX { }
NormalVector ShapeTroughCHC::GetNormal (double u ,double v) const { Vector3D dpdu = GetDPDU( u, v ); Vector3D dpdv = GetDPDV( u, v ); return Normalize( NormalVector( CrossProduct( dpdu, dpdv ) ) ); }
Triangle::Triangle(Vertices v0, Vertices v1, Vertices v2) { tVertices[0] = v0; tVertices[1] = v1; tVertices[2] = v2; CrossProduct(v0, v1); NormalVector(); }
double cOrbit::PhaseAngle(cOrbit &orbit, double t, bool &status) const { Vector3d n = NormalVector(); Vector3d p1 = PositionAtTrueAnomaly(TrueAnomalyAt(t, status)); Vector3d p2 = orbit.PositionAtTrueAnomaly(orbit.TrueAnomalyAt(t, status)); p2 = p2 - (n * p2.dot(n)); // Project p2 onto our orbital plane double r1 = p1.norm(); double r2 = p2.norm(); double phaseAngle = std::acos(p1.dot(p2) / (r1 * r2)); if(p1.cross(p2).dot(n) < 0.0) { phaseAngle = TWO_PI - phaseAngle; } if (orbit.SemiMajorAxis() < SemiMajorAxis()) { phaseAngle = phaseAngle - TWO_PI; } return phaseAngle; }
/*! * Triangle intersection */ bool Triangle::Intersect( const Ray& objectRay, double* tHit, DifferentialGeometry* dg ) const { //e1 = B - A //e2 = C - A Vector3D pVector = CrossProduct( objectRay.direction(), m_vE2 ); double det = DotProduct( m_vE1, pVector ); double inv_det = 1/det; //std::cout<<"det: "<<det<<std::endl; //Vector3D tVector = Vector3D( objectRay.origin ) – Vector3D(m_v1) ; Vector3D tVector = Vector3D( objectRay.origin - m_v1 ); Vector3D qVec = CrossProduct( tVector , m_vE1 ); double thit; double tol = 0.000001; if (det > tol) { double u = DotProduct( tVector,pVector ); if (u < 0 || u > det ) return ( false ); double v = DotProduct( objectRay.direction(), qVec ); if (v < 0 || ( v + u ) > det) return ( false ); double t = DotProduct( m_vE2, qVec ); thit = t * inv_det; u *= inv_det; v *= inv_det; } else if (det < - tol) { double u = DotProduct( tVector, pVector ) * inv_det; if (u < 0.0 || u > 1.0) return ( false ); double v = DotProduct( objectRay.direction(), qVec ) * inv_det; if (v < 0.0 || ( ( v+u ) > 1.0 ) ) return ( false ); double t = DotProduct( m_vE2, qVec ) * inv_det; thit = t; } else return ( false ); //return intersection == true , t, P /*//Jimenez algorithm double t0; double t1; if( !m_bbox.IntersectP(objectRay, &t0, &t1 ) ) return ( false ); //Evaluate Tolerance t0 -= 0.1; t1 += 0.1; Point3D Q1 = objectRay( t0 ); Point3D Q2 = objectRay( t1 ); Vector3D vA = Vector3D( Q1 - m_v3 ); double w = DotProduct( vA, m_vW1 ); Vector3D vD = Vector3D( Q2 - m_v3 ); double s = DotProduct( vD, m_vW1 ); double tol = 0.000001; if( w > tol ) { if( s > tol ) return ( false ); Vector3D vW2 = CrossProduct( vA, vD ); double t = DotProduct( vW2, m_vC ); if( t < -tol ) return ( false ); double u = DotProduct( - vW2, m_vB ); if( u < -tol ) return ( false ); if( w < ( s + t + u ) ) return ( false ); } else if ( w < -tol ) { if( s < -tol ) return ( false ); Vector3D vW2 = CrossProduct( vA, vD ); double t = DotProduct( vW2, m_vC ); if( t > tol ) return ( false ); double u = DotProduct( - vW2, m_vB ); if( u > tol ) return ( false ); if( w > ( s + t + u ) ) return ( false ); } else // w == 0, swap( Q1, Q2 ) { Vector3D vW2 = CrossProduct( vD, vA ); double t = DotProduct( vW2, m_vC ); if( s > tol ) { if( t < -tol ) return ( false ); double u = DotProduct( - vW2, m_vB); if( u < -tol ) return ( false ); if( -s < ( t + u ) ) return ( false ); } else if( s < - tol ) { if( t > tol ) return ( false ); double u = DotProduct( - vW2, m_vB ); if( u > tol ) return ( false ); if( -s > ( t + u ) ) return ( false ); } else return ( false ); } double t_param = ( DotProduct( Normalize( m_vW1 ), vA ) / DotProduct( Normalize( m_vW1 ), Vector3D( Q1 - Q2 ) ) ); double thit = t0 + t_param * Distance( Q1, Q2 ); */ if( thit > *tHit ) return false; if( (thit - objectRay.mint) < tol ) return false; Point3D hitPoint = objectRay( thit ); Vector3D dpdu = Normalize( m_vE1 ); Vector3D dpdv = Normalize( m_vE2 ); // Compute ShapeCone \dndu and \dndv Vector3D d2Pduu( 0.0, 0.0, 0.0 ); Vector3D d2Pduv( 0.0, 0.0, 0.0 ); Vector3D d2Pdvv( 0.0, 0.0, 0.0 ); // Compute coefficients for fundamental forms double E = DotProduct( dpdu, dpdu ); double F = DotProduct( dpdu, dpdv ); double G = DotProduct( dpdv, dpdv ); Vector3D N = Normalize( NormalVector( CrossProduct( dpdu, dpdv ) ) ); double e = DotProduct( N, d2Pduu ); double f = DotProduct( N, d2Pduv ); double g = DotProduct( N, d2Pdvv ); // Compute \dndu and \dndv from fundamental form coefficients double invEGF2 = 1.0 / (E*G - F*F); Vector3D dndu = (f*F - e*G) * invEGF2 * dpdu + (e*F - f*E) * invEGF2 * dpdv; Vector3D dndv = (g*F - f*G) * invEGF2 * dpdu + (f*F - g*E) * invEGF2 * dpdv; // Initialize _DifferentialGeometry_ from parametric information *dg = DifferentialGeometry( hitPoint , dpdu, dpdv, dndu, dndv, -1, -1, 0 ); dg->shapeFrontSide = ( DotProduct( N, objectRay.direction() ) > 0 ) ? false : true; // Update _tHit_ for quadric intersection *tHit = thit; return true; }
NormalVector NormalVector::operator/( double scalar ) const { double inv = 1.0/scalar; return NormalVector( x * inv, y * inv, z * inv ); }
NormalVector NormalVector::operator*( double scalar ) const { return NormalVector( x * scalar, y * scalar, z * scalar ); }
NormalVector operator*( double scalar, const NormalVector& nV ) { return NormalVector( scalar * nV.x, scalar * nV.y, scalar * nV.z ); }
NormalVector NormalVector::operator-() const { return NormalVector( -x, -y, -z ); }
NormalVector ShapeParabolicRectangle::GetNormal( double u, double v ) const { Vector3D dpdu( widthX.getValue(), ( (-0.5 + u) * widthX.getValue() * widthX.getValue() )/(2 * focusLength.getValue()), 0 ); Vector3D dpdv( 0.0, (( -0.5 + v) * widthZ.getValue() * widthZ.getValue() ) /( 2 * focusLength.getValue() ), widthZ.getValue() ); return Normalize( NormalVector( CrossProduct( dpdu, dpdv ) ) ); }
bool ShapeParabolicRectangle::Intersect(const Ray& objectRay, double *tHit, DifferentialGeometry *dg) const { double focus = focusLength.getValue(); double wX = widthX.getValue(); double wZ = widthZ.getValue(); // Compute quadratic coefficients double A = objectRay.direction().x * objectRay.direction().x + objectRay.direction().z * objectRay.direction().z; double B = 2.0 * ( objectRay.direction().x * objectRay.origin.x + objectRay.direction().z * objectRay.origin.z - 2 * focus * objectRay.direction().y ); double C = objectRay.origin.x * objectRay.origin.x + objectRay.origin.z * objectRay.origin.z - 4 * focus * objectRay.origin.y; // Solve quadratic equation for _t_ values double t0, t1; if( !gf::Quadratic( A, B, C, &t0, &t1 ) ) return false; // Compute intersection distance along ray if( t0 > objectRay.maxt || t1 < objectRay.mint ) return false; double thit = ( t0 > objectRay.mint )? t0 : t1 ; if( thit > objectRay.maxt ) return false; //Evaluate Tolerance double tol = 0.00001; //Compute possible hit position Point3D hitPoint = objectRay( thit ); // Test intersection against clipping parameters if( (thit - objectRay.mint) < tol || hitPoint.x < ( - wX / 2 ) || hitPoint.x > ( wX / 2 ) || hitPoint.z < ( - wZ / 2 ) || hitPoint.z > ( wZ / 2 ) ) { if ( thit == t1 ) return false; if ( t1 > objectRay.maxt ) return false; thit = t1; hitPoint = objectRay( thit ); if( (thit - objectRay.mint) < tol || hitPoint.x < ( - wX / 2 ) || hitPoint.x > ( wX / 2 ) || hitPoint.z < ( - wZ / 2 ) || hitPoint.z > ( wZ / 2 ) ) return false; } // Now check if the function is being called from IntersectP, // in which case the pointers tHit and dg are 0 if( ( tHit == 0 ) && ( dg == 0 ) ) return true; else if( ( tHit == 0 ) || ( dg == 0 ) ) gf::SevereError( "Function ParabolicCyl::Intersect(...) called with null pointers" ); /////////////////////////////////////////////////////////////////////////////////////// // Compute possible parabola hit position // Find parametric representation of paraboloid hit double u = ( hitPoint.x / wX ) + 0.5; double v = ( hitPoint.z / wZ ) + 0.5; Vector3D dpdu( wX, ( (-0.5 + u) * wX * wX ) / ( 2 * focus ), 0 ); Vector3D dpdv( 0.0, (( -0.5 + v) * wZ * wZ ) /( 2 * focus ), wZ ); // Compute parabaloid \dndu and \dndv Vector3D d2Pduu( 0.0, (wX * wX ) /( 2 * focus ), 0.0 ); Vector3D d2Pduv( 0.0, 0.0, 0.0 ); Vector3D d2Pdvv( 0.0, (wZ * wZ ) /( 2 * focus ), 0.0 ); // Compute coefficients for fundamental forms double E = DotProduct(dpdu, dpdu); double F = DotProduct(dpdu, dpdv); double G = DotProduct(dpdv, dpdv); NormalVector N = Normalize( NormalVector( CrossProduct( dpdu, dpdv ) ) ); double e = DotProduct(N, d2Pduu); double f = DotProduct(N, d2Pduv); double g = DotProduct(N, d2Pdvv); // Compute \dndu and \dndv from fundamental form coefficients double invEGF2 = 1.0 / (E*G - F*F); Vector3D dndu = (f*F - e*G) * invEGF2 * dpdu + (e*F - f*E) * invEGF2 * dpdv; Vector3D dndv = (g*F - f*G) * invEGF2 * dpdu + (f*F - g*E) * invEGF2 * dpdv; // Initialize _DifferentialGeometry_ from parametric information *dg = DifferentialGeometry(hitPoint, dpdu, dpdv, dndu, dndv, u, v, this); dg->shapeFrontSide = ( DotProduct( N, objectRay.direction() ) > 0 ) ? false : true; /////////////////////////////////////////////////////////////////////////////////////// // Update _tHit_ for quadric intersection *tHit = thit; return true; }
void TriangleMesh::AppendAllIntersections( const Vector& vantage, const Vector& direction, IntersectionList& intersectionList) const { // Iterate through all the triangles in this solid object, // looking for every intersection. TriangleList::const_iterator iter = triangleList.begin(); TriangleList::const_iterator end = triangleList.end(); for (; iter != end; ++iter) { const Triangle& tri = *iter; const Vector& aPoint = pointList[tri.a]; const Vector& bPoint = pointList[tri.b]; const Vector& cPoint = pointList[tri.c]; // The variables u, v, w are deliberately left // uninitialized for efficiency; they are only // assigned values if we find an intersection. double u, v, w; // Sometimes we have to try more than one ordering of the points (A,B,C) // in order to get a valid solution to the intersection equations. // Take advantage of C++ short-circuit boolean or "||" operator: // as soon as one of the function calls returns true, we don't call any more. if (AttemptPlaneIntersection(vantage, direction, aPoint, bPoint, cPoint, u, v, w) || AttemptPlaneIntersection(vantage, direction, bPoint, cPoint, aPoint, u, v, w) || AttemptPlaneIntersection(vantage, direction, cPoint, aPoint, bPoint, u, v, w)) { // We found an intersection of the direction with the plane that passes through the points (A,B,C). // Figure out whether the intersection point is inside the triangle (A,B,C) or outside it. // We are interested only in intersections that are inside the triangle. // The trick here is that the values v,w are fractions that will be 0..1 along the // line segments AB and BC (or whichever ordered triple of points we found the solution for). // If we just checked that both v and w are in the range 0..1, we would be finding // intersections with a parallelogram ABCD, where D is the fourth point that completes the // parallelogram whose other vertices are ABC. // But checking instead that v + w <= 1.0 constrains the set of points // to the interior or border of the triangle ABC. if ((v >= 0.0) && (w >= 0.0) && (v + w <= 1.0) && (u >= EPSILON)) { // We have found an intersection with one of the triangular facets! // Also determine whether the intersection point is in "front" of the vantage (positively along the direction) // by checking for (u >= EPSILON). Note that we allow for a little roundoff error by checking // against EPSILON instead of 0.0, because this method is called using vantage = a point on this surface, // in order to calculate surface lighting, and we don't want to act like the surface is shading itself! if (u >= EPSILON) { // We have found a new intersection to be added to the list. const Vector displacement = u * direction; Intersection intersection; intersection.distanceSquared = displacement.MagnitudeSquared(); intersection.point = vantage + displacement; intersection.surfaceNormal = NormalVector(tri); intersection.solid = this; intersection.context = &tri; // remember which triangle we hit, for SurfaceOptics(). intersectionList.push_back(intersection); } } } } }
/** Creates a list for a sphere with unit radius */ void ThreeDWidget::GLCreateUnitSphere() { double start_lat, start_lon,lat_incr, lon_incr, R; double phi1, phi2, theta1, theta2; GLdouble u[3], v[3], w[3], n[3]; int row, col; int NumLongitudes, NumLatitudes; NumLongitudes = NumLatitudes = 19; glNewList(GLLISTSPHERE, GL_COMPILE); { glDisable(GL_TEXTURE_2D); glEnable(GL_DEPTH_TEST); glEnable(GL_POLYGON_OFFSET_FILL); glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); glBegin(GL_TRIANGLES); // glColor3d(cr.redF(),cr.greenF(),cr.blueF()); start_lat = -90; start_lon = 0.0; R = 1.0; lat_incr = 180.0 / NumLatitudes; lon_incr = 360.0 / NumLongitudes; for (col = 0; col < NumLongitudes; col++) { phi1 = (start_lon + col * lon_incr) * PI/180.0; phi2 = (start_lon + (col + 1) * lon_incr) * PI/180.0; for (row = 0; row < NumLatitudes; row++) { theta1 = (start_lat + row * lat_incr) * PI/180.0; theta2 = (start_lat + (row + 1) * lat_incr) * PI/180.0; u[0] = R * cos(phi1) * cos(theta1);//x u[1] = R * sin(theta1);//y u[2] = R * sin(phi1) * cos(theta1);//z v[0] = R * cos(phi1) * cos(theta2);//x v[1] = R * sin(theta2);//y v[2] = R * sin(phi1) * cos(theta2);//z w[0] = R * cos(phi2) * cos(theta2);//x w[1] = R * sin(theta2);//y w[2] = R * sin(phi2) * cos(theta2);//z NormalVector(u,v,w,n); glNormal3dv(n); glVertex3dv(u); glVertex3dv(v); glVertex3dv(w); v[0] = R * cos(phi2) * cos(theta1);//x v[1] = R * sin(theta1);//y v[2] = R * sin(phi2) * cos(theta1);//z NormalVector(u,w,v,n); glNormal3dv(n); glVertex3dv(u); glVertex3dv(w); glVertex3dv(v); } } glEnd(); glDisable(GL_DEPTH_TEST); } glEndList(); }