예제 #1
0
파일: triangle.cpp 프로젝트: goofoo/xyz
/*!
 * 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);
  }
}
예제 #2
0
파일: triangle.cpp 프로젝트: goofoo/xyz
void Triangle::ShadingBasis(__in Intersection const &param,
                            __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);
  }
}
예제 #3
0
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);
  }
}