void Frustum::Extract(const Matrix44f &view, const Projection &proj) { static const int LBN = kLBNCorner, LTN = kLTNCorner, LBF = kLBFCorner, LTF = kLTFCorner, RBN = kRBNCorner, RTN = kRTNCorner, RBF = kRBFCorner, RTF = kRTFCorner; const float lnear = -proj.get_near(); const float lfar = -proj.get_far(); const Vec3f nearNorm(0.0f, 0.0f, -1.0f); const Vec3f farNorm(0.0f, 0.0f, 1.0f); // kLeftPlane plane const Vec3f ltn(proj.get_left(), proj.get_top(), lnear), lbn(proj.get_left(), proj.get_bottom(), lnear), ltf(proj.get_far_left(), proj.get_far_top(), lfar), lbf(proj.get_far_left(), proj.get_far_bottom(), lfar); const Vec3f leftNorm = vecNormal( vecCross(lbn - ltn, ltf - ltn)); // kRightPlane plane const Vec3f rtn(proj.get_right(), proj.get_top(), lnear), // right top near rbn(proj.get_right(), proj.get_bottom(), lnear), // right bottom near rtf(proj.get_far_right(), proj.get_far_top(), lfar); // right top far const Vec3f rightNorm = vecNormal(vecCross(rtf - rtn, rbn - rtn)); // kTopPlane plane const Vec3f topNorm = vecNormal(vecCross(ltf - ltn, rtn - ltn)); // kBottomPlane plane lbn rbf const Vec3f rbf(proj.get_far_right(), proj.get_far_bottom(), lfar); const Vec3f botNorm = vecNormal(vecCross(rbf - rbn, lbn - rbn)); Matrix44f viewSpace, viewSpaceN; matrixInverse(view, &viewSpace); viewSpaceN = matrixTranspose(view); m_conners[LBN] = lbn * viewSpace; m_conners[LTN] = ltn * viewSpace; m_conners[LBF] = lbf * viewSpace; m_conners[LTF] = ltf * viewSpace; m_conners[RBN] = rbn * viewSpace; m_conners[RTN] = rtn * viewSpace; m_conners[RBF] = rbf * viewSpace; m_conners[RTF] = rtf * viewSpace; m_planes[kLeftPlane] = Planef(leftNorm * viewSpaceN, m_conners[LTN]); m_planes[kRightPlane] = Planef(rightNorm * viewSpaceN, m_conners[RTN]); m_planes[kTopPlane] = Planef(topNorm * viewSpaceN, m_conners[RTN]); m_planes[kBottomPlane] = Planef(botNorm * viewSpaceN, m_conners[LBN]); m_planes[kNearPlane] = Planef(nearNorm * viewSpaceN, m_conners[LBN]); m_planes[kFarPlane] = Planef(farNorm * viewSpaceN, m_conners[RTF]); }
float CProteinSurfaceBase::CalcAdjacentCurvature(int iVertex, float &sumCurvature, int depth, int depthLimit, CSTLLONGArray & arrayPoint ) { if ( m_ArrayArrayAdjacentVertex.size() == 0 ) CreateAdjacentVertex(); CSTLLONGArray & adjacentIndexArray = m_ArrayArrayAdjacentVertex[iVertex]; int lengthOfAdjacentIndexArrayLength = adjacentIndexArray.size(); CSTLLONGArray::iterator iterator; arrayPoint.push_back(iVertex); float dotProduct = 0.0; for ( iterator= adjacentIndexArray.begin( ); iterator != adjacentIndexArray.end( ); iterator++ ) { long iAdjacentVertex = (*iterator); D3DXVECTOR3 edgeVec( m_arrayVertex[iAdjacentVertex] - m_arrayVertex[iVertex] ); D3DXVec3Normalize( &edgeVec, &edgeVec ); D3DXVECTOR3 vecNormal(m_arrayNormal[iVertex] ); D3DXVec3Normalize( &vecNormal, &vecNormal ); dotProduct += D3DXVec3Dot(&edgeVec, &vecNormal); if ( depth < depthLimit ) { // 이미 계산했는지를 조사. BOOL bFind = FALSE; for ( int i = 0 ; i < arrayPoint.size() ; i++ ) { if ( arrayPoint[i] == iAdjacentVertex ) { bFind = TRUE; break; } } if ( bFind == FALSE ) CalcAdjacentCurvature ( iAdjacentVertex, sumCurvature, depth+1, depthLimit, arrayPoint ); } } sumCurvature += dotProduct; return sumCurvature; }
float sphereTriangleCollision( const BoundingSphere &sphere, const Vec3f &dir, const Vec3f &p0, const Vec3f &p1, const Vec3f &p2, Vec3f *contactPoint) { Planef trigPlane(p0, p1, p2); float d = vecDot(dir, trigPlane.normal); float minDist = NoIntersection; if ( vecDot(dir, trigPlane.normal) > 0.0 ) { return NoIntersection; } if ( d == 0.0f ) { if ( trigPlane.distance(sphere.center()) < sphere.radius() ) return NoIntersection; } else { const Vec3f orign = sphere.center() - sphere.radius()*vecNormal(trigPlane.normal); const float t = -(trigPlane.d + vecDot(orign, trigPlane.normal)) / d; if ( t >= 0.0f ) { const Vec3f planePoint = orign + dir * t; if ( pointInTriangle(planePoint, vecNormal(trigPlane.normal), p0, p1, p2) ) { *contactPoint = planePoint; return t; } } } float dist = spherePointDistance(sphere, dir, p0); if ( dist < minDist ) { minDist = dist; *contactPoint = p0; } dist = spherePointDistance(sphere, dir, p1); if ( dist < minDist ) { minDist = dist; *contactPoint = p1; } dist = spherePointDistance(sphere, dir, p2); if ( dist < minDist ) { minDist = dist; *contactPoint = p2; } Vec3f edgeContactPoint; dist = sphereEdgeDistance(sphere, dir, p1, p0, &edgeContactPoint); if ( dist < minDist ) { minDist = dist; *contactPoint = edgeContactPoint; } dist = sphereEdgeDistance(sphere, dir, p2, p1, &edgeContactPoint); if ( dist < minDist ) { minDist = dist; *contactPoint = edgeContactPoint; } dist = sphereEdgeDistance(sphere, dir, p0, p2, &edgeContactPoint); if ( dist < minDist ) { minDist = dist; *contactPoint = edgeContactPoint; } return minDist; }
void CNormalGenerator::NormalizeHeightValue(size_t x, size_t y) { if (!m_avecTextureTexels.size()) return; float flHiScale = ((m_iNormal2Width+m_iNormal2Height)/2.0f)/200.0f * m_flNormalTextureDepth; float flMidScale = ((m_iNormal2Width+m_iNormal2Height)/2.0f)/100.0f * m_flNormalTextureDepth; float flLowScale = ((m_iNormal2Width+m_iNormal2Height)/2.0f)/50.0f * m_flNormalTextureDepth; size_t iTexel; Texel(x, y, iTexel, m_iNormal2Width, m_iNormal2Height, false); tvector<Vector> avecHeights; float flHeight = m_avecTextureTexels[iTexel].Average() * flHiScale; float flMidPass = m_aflMidPassTexels[iTexel] * flMidScale; float flLowPass = m_aflLowPassTexels[iTexel] * flLowScale; Vector vecCenter((float)x, (float)y, flHeight*m_flNormalTextureHiDepth + flMidPass*m_flNormalTextureMidDepth + flLowPass*m_flNormalTextureLoDepth); Vector vecNormal(0,0,0); if (Texel(x+1, y, iTexel, m_iNormal2Width, m_iNormal2Height, false)) { flHeight = m_avecTextureTexels[iTexel].Average() * flHiScale; flMidPass = m_aflMidPassTexels[iTexel] * flMidScale; flLowPass = m_aflLowPassTexels[iTexel] * flLowScale; Vector vecNeighbor(x+1.0f, (float)y, flHeight*m_flNormalTextureHiDepth + flMidPass*m_flNormalTextureMidDepth + flLowPass*m_flNormalTextureLoDepth); vecNormal += (vecNeighbor-vecCenter).Normalized().Cross(Vector(0, 1, 0)); } if (Texel(x-1, y, iTexel, m_iNormal2Width, m_iNormal2Height, false)) { flHeight = m_avecTextureTexels[iTexel].Average() * flHiScale; flMidPass = m_aflMidPassTexels[iTexel] * flMidScale; flLowPass = m_aflLowPassTexels[iTexel] * flLowScale; Vector vecNeighbor(x-1.0f, (float)y, flHeight*m_flNormalTextureHiDepth + flMidPass*m_flNormalTextureMidDepth + flLowPass*m_flNormalTextureLoDepth); vecNormal += (vecNeighbor-vecCenter).Normalized().Cross(Vector(0, -1, 0)); } if (Texel(x, y+1, iTexel, m_iNormal2Width, m_iNormal2Height, false)) { flHeight = m_avecTextureTexels[iTexel].Average() * flHiScale; flMidPass = m_aflMidPassTexels[iTexel] * flMidScale; flLowPass = m_aflLowPassTexels[iTexel] * flLowScale; Vector vecNeighbor((float)x, y+1.0f, flHeight*m_flNormalTextureHiDepth + flMidPass*m_flNormalTextureMidDepth + flLowPass*m_flNormalTextureLoDepth); vecNormal += (vecNeighbor-vecCenter).Normalized().Cross(Vector(-1, 0, 0)); } if (Texel(x, y-1, iTexel, m_iNormal2Width, m_iNormal2Height, false)) { flHeight = m_avecTextureTexels[iTexel].Average() * flHiScale; flMidPass = m_aflMidPassTexels[iTexel] * flMidScale; flLowPass = m_aflLowPassTexels[iTexel] * flLowScale; Vector vecNeighbor((float)x, y-1.0f, flHeight*m_flNormalTextureHiDepth + flMidPass*m_flNormalTextureMidDepth + flLowPass*m_flNormalTextureLoDepth); vecNormal += (vecNeighbor-vecCenter).Normalized().Cross(Vector(1, 0, 0)); } vecNormal.Normalize(); for (size_t i = 0; i < 3; i++) vecNormal[i] = RemapVal(vecNormal[i], -1.0f, 1.0f, 0.0f, 0.99f); // Don't use 1.0 because of integer overflow. // Don't need to lock the data because we're guaranteed never to access the same texel twice due to the generation method. m_avecNormal2Texels[iTexel] = vecNormal; }