Ejemplo n.º 1
0
void CObjectNode::RenderPatch(int nSeedU, int nSeedV, CMultiTexData* pTexData, int nTexData)
{
    CObjectNode* pN1;
    CObjectNode* pN2;
    CObjectNode* pN3;
    CObjectNode* pN4;

    CNodeData aEdges[4][64];

    CNodeData aHLine1[64];
    CNodeData aHLine2[64];

    CNodeData* pHLine1 = aHLine1;
    CNodeData* pHLine2 = aHLine2;
    CNodeData* pTmp;

    float fU, fV;
    int nV, nU, nTex;

    CNodeData cE1, cE2, cE3, cE4, cE;

    /* calculate edge 1 */

    pN2 = pN1 = GetValidLeft();
    pN1 = pN1->GetValidUp();
    pN3 = pN2->GetValidDown();
    pN4 = pN3->GetValidDown();

    aEdges[0][0] = pN2->m_cNodeData;

    for (nV = 1; nV != nSeedV - 1; nV++) {
        fV = (float)nV / (float)(nSeedV - 1);
        SInterpolate(aEdges[0][nV], pN1, pN2, pN3, pN4, fV);
    }

    aEdges[0][nSeedV - 1] = pN3->m_cNodeData;

    /* calculate edge 2 */

    pN1 = GetValidUp();
    pN2 = this;
    pN3 = GetValidDown();
    pN4 = pN3->GetValidDown();

    aEdges[1][0] = pN2->m_cNodeData;

    for (nV = 1; nV != nSeedV - 1; nV++) {
        fV = (float)nV / (float)(nSeedV - 1);
        SInterpolate(aEdges[1][nV], pN1, pN2, pN3, pN4, fV);
    }

    aEdges[1][nSeedV - 1] = pN3->m_cNodeData;

    /* calculate edge 3 */

    pN2 = pN1 = GetValidRight();
    pN1 = pN1->GetValidUp();
    pN3 = pN2->GetValidDown();
    pN4 = pN3->GetValidDown();

    aEdges[2][0] = pN2->m_cNodeData;

    for (nV = 1; nV != nSeedV - 1; nV++) {
        fV = (float)nV / (float)(nSeedV - 1);
        SInterpolate(aEdges[2][nV], pN1, pN2, pN3, pN4, fV);
    }

    aEdges[2][nSeedV - 1] = pN3->m_cNodeData;

    /* calculate edge 4 */

    pN2 = pN2->GetValidRight();
    pN1 = pN2->GetValidUp();
    pN3 = pN2->GetValidDown();
    pN4 = pN3->GetValidDown();

    aEdges[3][0] = pN2->m_cNodeData;

    for (nV = 1; nV != nSeedV - 1; nV++) {
        fV = (float)nV / (float)(nSeedV - 1);
        SInterpolate(aEdges[3][nV], pN1, pN2, pN3, pN4, fV);
    }

    aEdges[3][nSeedV - 1] = pN3->m_cNodeData;

    /* make faces */

    int nWrap;

    if (m_nWarapUV) nWrap = 1;
    else
    if (GetValidLeft()->m_nWarapUV) nWrap = -1;
    else nWrap = 0;

    /*
    if (nWrap == 0) pHLine1[0] = aEdges[1][0];
    else if (nWrap > 0)  {
    pHLine1[0] = aEdges[1][0];
    pHLine1[0].m_cTexel.fU += 1.0f;
    }
    else {
    pHLine1[0] = aEdges[1][0];
    }
    */
    for (nU = 0; nU != nSeedU ; nU++) {
        fU = (float)nU/(float)(nSeedU - 1);
        SInterpolate(pHLine1[nU], aEdges[0][0], aEdges[1][0], aEdges[2][0], aEdges[3][0], fU, nWrap);
    }
    //pHLine1[nSeedU - 1] = aEdges[2][0];

    for (nV = 1; nV != nSeedV; nV++)
    {
        //pHLine2[0] = aEdges[1][nV];
        for (nU = 0; nU != nSeedU; nU++) {
            fU = (float)nU/(float)(nSeedU - 1);
            SInterpolate(pHLine2[nU], aEdges[0][nV], aEdges[1][nV], aEdges[2][nV], aEdges[3][nV], fU, nWrap);
        }
        //pHLine2[0] = aEdges[2][nV];

        /* oki.. we've got here a strip, so render it */

#ifdef GL_VERSION_ES_CM_1_1
        glClientActiveTexture(GL_TEXTURE0);

        glEnableClientState(GL_VERTEX_ARRAY);
        glEnableClientState(GL_COLOR_ARRAY);
        glEnableClientState(GL_TEXTURE_COORD_ARRAY);
#endif
        for (nTex = 0; nTex != nTexData; nTex++)
        {
            if (pTexData[nTex].m_nGLTexName)
            {
                glBindTexture(GL_TEXTURE_2D, *pTexData[nTex].m_nGLTexName);
#ifndef GL_VERSION_ES_CM_1_1
                glBegin(GL_TRIANGLES);
#endif

                if (pTexData[nTex].m_nMaterial & 1)
                {
                    for (nU = 0; nU != nSeedU - 1; nU++) {
                        glFace(pHLine1[nU], pHLine1[nU + 1], pHLine2[nU], pTexData[nTex].m_fAlpha, pTexData[nTex].m_fUShift, pTexData[nTex].m_fVShift);
                        glFace(pHLine1[nU + 1], pHLine2[nU + 1], pHLine2[nU], pTexData[nTex].m_fAlpha, pTexData[nTex].m_fUShift, pTexData[nTex].m_fVShift);
                    }
                } else
                if (pTexData[nTex].m_nMaterial & 2)
                {
                    for (nU = 0; nU != nSeedU - 1; nU++) {
                        glEnv(pHLine1[nU], pHLine1[nU + 1], pHLine2[nU], pTexData[nTex].m_fAlpha);
                        glEnv(pHLine1[nU + 1], pHLine2[nU + 1], pHLine2[nU], pTexData[nTex].m_fAlpha);
                    }
                }
#ifndef GL_VERSION_ES_CM_1_1
                glEnd();
#endif
            }
        }

#ifdef GL_VERSION_ES_CM_1_1
        glFaceFlush();
        glEnvFlush();

        glDisableClientState(GL_VERTEX_ARRAY);
        glDisableClientState(GL_COLOR_ARRAY);
        glDisableClientState(GL_TEXTURE_COORD_ARRAY);
#endif
        pTmp = pHLine1;
        pHLine1 = pHLine2;
        pHLine2 = pTmp;
    }
}
Ejemplo n.º 2
0
void CalculateBasisComponents(const MDoubleArray& weights, const BaryCoords& coords,
                              const MIntArray& triangleVertices, const MPointArray& points,
                              const MFloatVectorArray& normals, const MIntArray& sampleIds,
                              double* alignedStorage,
                              MPoint& origin, MVector& up, MVector& normal) {
  // Start with the recreated point and normal using the barycentric coordinates of the hit point.
  unsigned int hitIndex = weights.length()-1;
#ifdef __AVX__
  __m256d originV = Dot4<MPoint>(coords[0], coords[1], coords[2], 0.0,
                                points[triangleVertices[0]], points[triangleVertices[1]],
                                points[triangleVertices[2]], MPoint::origin);
  __m256d hitNormalV = Dot4<MVector>(coords[0], coords[1], coords[2], 0.0,
                                normals[triangleVertices[0]], normals[triangleVertices[1]],
                                normals[triangleVertices[2]], MVector::zero);
  __m256d hitWeightV = _mm256_set1_pd(weights[hitIndex]);
  // Create the barycentric point and normal.
  __m256d normalV = _mm256_mul_pd(hitNormalV, hitWeightV);
  // Then use the weighted adjacent data.
  for (unsigned int j = 0; j < hitIndex; j += 4) {
    __m256d tempNormal = Dot4<MVector>(weights[j], weights[j+1], weights[j+2], weights[j+3],
                                       normals[sampleIds[j]], normals[sampleIds[j+1]],
                                       normals[sampleIds[j+2]], normals[sampleIds[j+3]]);
    normalV = _mm256_add_pd(tempNormal, normalV);
  }

  _mm256_store_pd(alignedStorage, originV);
  origin.x = alignedStorage[0];
  origin.y = alignedStorage[1];
  origin.z = alignedStorage[2];
  _mm256_store_pd(alignedStorage, normalV);
  normal.x = alignedStorage[0];
  normal.y = alignedStorage[1];
  normal.z = alignedStorage[2];

  // Calculate the up vector
  const MPoint& pt1 = points[triangleVertices[0]];
  const MPoint& pt2 = points[triangleVertices[1]];
  __m256d p1 = _mm256_set_pd(pt1.w, pt1.z, pt1.y, pt1.x);
  __m256d p2 = _mm256_set_pd(pt2.w, pt2.z, pt2.y, pt2.x);
  p1 = _mm256_add_pd(p1, p2);
  __m256d half = _mm256_set_pd(0.5, 0.5, 0.5, 0.5);
  p1 = _mm256_mul_pd(p1, half);
  __m256d upV = _mm256_sub_pd(p1, originV);
  _mm256_store_pd(alignedStorage, upV);
  up.x = alignedStorage[0];
  up.y = alignedStorage[1];
  up.z = alignedStorage[2];
#else
  MVector hitNormal;
  // Create the barycentric point and normal.
  for (int i = 0; i < 3; ++i) {
    origin += points[triangleVertices[i]] * coords[i];
    hitNormal += MVector(normals[triangleVertices[i]]) * coords[i];
  }
  // Use crawl data to calculate normal
  normal = hitNormal * weights[hitIndex];
  for (unsigned int j = 0; j < hitIndex; j++) {
    normal += MVector(normals[sampleIds[j]]) * weights[j];
  }

  // Calculate the up vector
  // The triangle vertices are sorted by decreasing barycentric coordinates so the first two are
  // the two closest vertices in the triangle.
  up = ((points[triangleVertices[0]] + points[triangleVertices[1]]) * 0.5) - origin;
#endif
  normal.normalize();
  GetValidUp(weights, points, sampleIds, origin, normal, up);
}