/*! * SamplePlanarTriangle(real xi_1, real xi_2) * { * Compute the warping function (xi_1, xi_2) -> (s, t). * s <- sqrt(xi_1); * t <- xi_2 ; * Plug the warped coords into the original parametrization. * P <- (1-s)*A + s*(1-t)*B + s*t*C; * return P; * } */ void Triangle::Sample( __in xyz::float_t const &fXi1, ///< [in] __in xyz::float_t const &fXi2, ///< [in] __out xyz::float3_t *const pvPosition, ///< [out] 三角形上のサンプル位置 __out xyz::float3_t *const pvShadingNormal, ///< [out] シェーディング法線 __out xyz::float3_t *const pvGeometricNormal, ///< [out] 幾何学的法線 __out xyz::float3_t *const pvTangentVector, ///< [out] 接線ベクトル __out xyz::float3_t *const pvBinormalVector ///< [out] 従法線ベクトル ) const { float_t const s = std::sqrt(fXi1); float_t const t = (fXi2); float_t const u = s * (1 - t); float_t const v = s * (t); *pvPosition = Barycenter(v0_, e1_, e2_, u, v); *pvShadingNormal = hi::normalize(Barycenter(n0_, s1_, s2_, u, v)); *pvGeometricNormal = ng_; // 球面座標系をベースに基底を求める *pvTangentVector = float3_t(-(*pvGeometricNormal)[2], 0, (*pvGeometricNormal)[0]); value_type const fLengthSquared = hi::length_squared(*pvTangentVector); if (fLengthSquared > 0) { // 接ベクトルから求める *pvTangentVector *= hi::rsqrt(fLengthSquared); *pvBinormalVector = BinormalVector(*pvTangentVector, *pvGeometricNormal); } else { // 従接ベクトルから求める *pvBinormalVector = float3_t(0, 0, ((*pvGeometricNormal)[1] > 0) ? 1 : -1); *pvTangentVector = TangentVector(*pvGeometricNormal, *pvBinormalVector); } }
void Triangle::ShadingBasis(__in Intersection const ¶m, __out xyz::float3_t *const pvShadingNormal, __out xyz::float3_t *const pvGeometricNormal, __out xyz::float3_t *const pvTangent, __out xyz::float3_t *const pvBinormal) const { *pvShadingNormal = hi::normalize(Barycenter(n0_, s1_, s2_, param.f(), param.g())); *pvGeometricNormal = ng_; if (param.is_back_side()) { *pvGeometricNormal = -*pvGeometricNormal; *pvShadingNormal = -*pvShadingNormal; } *pvTangent = float3_t(-(*pvShadingNormal)[2], 0, (*pvShadingNormal)[0]); value_type const fLengthSquared = hi::length_squared(*pvTangent); if (fLengthSquared > 0) { // 接ベクトルから求める *pvTangent *= hi::rsqrt(fLengthSquared); *pvBinormal = BinormalVector(*pvTangent, *pvShadingNormal); } else { // 従接ベクトルから求める *pvBinormal = float3_t(0, 0, ((*pvShadingNormal)[1] > 0) ? 1 : -1); *pvTangent = TangentVector(*pvShadingNormal, *pvBinormal); } }
void VertexArray::add(double *x, double *y, double *z, SVector3 *n, unsigned char *r, unsigned char *g, unsigned char *b, unsigned char *a, MElement *ele, bool unique, bool boundary) { int npe = getNumVerticesPerElement(); if(boundary && npe == 3){ ElementData<3> e(x, y, z, n, r, g, b, a, ele); ElementDataLessThan<3>::tolerance = (float)(CTX::instance()->lc * 1.e-12); std::set<ElementData<3>, ElementDataLessThan<3> >::iterator it = _data3.find(e); if(it == _data3.end()) _data3.insert(e); else _data3.erase(it); return; } // enabling this will reduce memory and rendering time; but will increase the // time it takes to create the vertex array #if 0 if(unique){ Barycenter pc(0.0F, 0.0F, 0.0F); for(int i = 0; i < npe; i++) pc += Barycenter(x[i], y[i], z[i]); BarycenterLessThan::tolerance = (float)(CTX::instance()->lc * 1.e-12); if(_barycenters.find(pc) != _barycenters.end()) return; _barycenters.insert(pc); } #endif for(int i = 0; i < npe; i++){ _addVertex((float)x[i], (float)y[i], (float)z[i]); if(n) _addNormal((float)n[i].x(), (float)n[i].y(), (float)n[i].z()); if(r && g && b && a) _addColor(r[i], g[i], b[i], a[i]); _addElement(ele); } }