void sgHair_controlJoint::normalizeMatrix( MMatrix& mtx ) { MVector vAim( mtx(0,0), mtx(0,1), mtx(0,2) ); MVector vUp( mtx(1,0), mtx(1,1), mtx(1,2) ); MVector vCross( mtx(2,0), mtx(2,1), mtx(2,2) ); vAim.normalize(); vUp.normalize(); vCross.normalize(); mtx( 0, 0 ) = vAim.x; mtx( 0, 1 ) = vAim.y; mtx( 0, 2 ) = vAim.z; mtx( 1, 0 ) = vUp.x; mtx( 1, 1 ) = vUp.y; mtx( 1, 2 ) = vUp.z; mtx( 2, 0 ) = vCross.x; mtx( 2, 1 ) = vCross.y; mtx( 2, 2 ) = vCross.z; }
MMatrix sgHair_controlJoint::getAngleWeightedMatrix( const MMatrix& targetMtx, double weight ) { MMatrix mtx; if( m_bStaticRotation ) { mtx = MMatrix() * ( weight-1 ) + targetMtx * weight; cleanMatrix( mtx ); } else { MVector vUpDefault( 0, 1, 0 ); MVector vCrossDefault( 0,0,1 ); MVector vUpInput( targetMtx(1,0), targetMtx(1,1), targetMtx(1,2) ); double angleUp = vUpInput.angle( vUpDefault ) * weight; if( vUpInput.x == 0 && vUpInput.z == 0 ) vUpInput.x = 1; MVector direction( vUpInput.x, 0, vUpInput.z ); direction.normalize(); MVector vUp( sin( angleUp ) * direction.x, cos( angleUp ), sin( angleUp ) * direction.z ); double dot = vUp * MVector( 0.0, 0.0, 1.0 ); MVector vCross( 0.0, -dot, (dot+1) ); MVector vAim = vUp ^ vCross; vAim.normalize(); vUp.normalize(); vCross = vAim ^ vUp; mtx( 0, 0 ) = vAim.x; mtx( 0, 1 ) = vAim.y; mtx( 0, 2 ) = vAim.z; mtx( 1, 0 ) = vUp.x; mtx( 1, 1 ) = vUp.y; mtx( 1, 2 ) = vUp.z; mtx( 2, 0 ) = vCross.x; mtx( 2, 1 ) = vCross.y; mtx( 2, 2 ) = vCross.z; } return mtx; }
//=============================================== // Unit Tests //=============================================== int main() { // set for command line argument -t to run unit tests. bool test = true; if (test) { std::cout<<"\n=================\nBegin UNIT TESTS\n=================\n\n"; Light::Light n = *new Light::Light(0, 1, 1, 0, 0.5, 0.5, 0.5); n.print(); Intersect::Intersect i = *new Intersect::Intersect(); if(i.isHit()) { std::cout<<"INCORRECT! hit is true.\n\n"; } else { std::cout<<"CORRECT! hit is false.\n\n"; i.setHit(true); } if(i.isHit()) { std::cout<<"CORRECT! hit is true.\n\n"; } else { std::cout<<"INCORRECT! hit is false.\n\n"; } std::vector<float> ptest(3); ptest[0] = 0; ptest[1] = 1; ptest[2] = 2; i.setPoint(ptest); std::vector<float> p = i.getPoint(); std::cout<< "[" << p[0] << ", " << p[1] << ", " << p[2] << "]\n"; Vertex::Vertex a = *new Vertex::Vertex(0,0,0); Vertex::Vertex b = *new Vertex::Vertex(1,0,0); Vertex::Vertex c = *new Vertex::Vertex(0,1,0); a.print(); a = a.sub(b); a.print(); std::vector<float> d = c.toVec(); std::cout<<"vec ["<< d[0] << ", " << d[1] << ", " << d[2] << "]\n"; Vertex::Vertex e1 = *new Vertex::Vertex(d); e1.print(); Vertex a1 = *new Vertex::Vertex(0,1,0); Vertex b1 = *new Vertex::Vertex(1,-1,0); Vertex c1 = *new Vertex::Vertex(-1,-1,0); Triangle t = *new Triangle::Triangle(a1,b1,c1); p[0] = 0; p[1] = 0; p[2] = 0; std::vector<float> e(3); e[0] = 0; e[1] = 0; e[2] = 3; Ray::Ray r = *new Ray::Ray(e, p); i = t.intersect(r); if (i.isHit()) { std::cout<<"Triangle Intersected - OKAY\n"; } Sphere::Sphere s = *new Sphere::Sphere(1, p); if (s.intersect(r).isHit()) { std::cout<<"Sphere Intersected - OKAY\n"; } e[0] = 0; e[1] = -4; e[2] = -4; p[0] = 1; p[1] = 1; p[2] = -1; r.setEye(e); r.setPoint(p); std::cout<<"projected "; vPrint(r.project(1.5)); PPM* ppm = new PPM(640, 480, 255); int val; for (float h = 0; h<480; h++) { for (float w =0; w<640; w++) { val = h;//std::min(255, (int)((w/639)*255.0f)); ppm->addPixel(*(new Pixel::Pixel(val, val, val))); } } ppm->save("output"); /* for (float h = 0; h < 3; h++) { for (float w = 0; w< ppm->getW(); w++) { std::cout<<w<<" "; ppm->getPixel(w, h).print(); } } */ std::cout<<"End PPM tests\n"; Pixel::Pixel px = *new Pixel::Pixel(255, 255, 255); Pixel::Pixel black = *new Pixel::Pixel(0,0,0); Pixel::Pixel pfloat = *new Pixel::Pixel(1.0f, 0.9f, 0.05f); Pixel::Pixel pmax = *new Pixel::Pixel(2.0f, 1.0f, 0.5f); px.print(); black.print(); black.add(px); black.print(); pfloat.print(); pmax.print(); std::vector<float> test1(3); test1[0] = 1; test1[1] = 0; test1[2] = 0.5; std::vector<float> test2(3); test2[0] = 0; test2[1] = 1; test2[2] = 0.5; std::cout<<vDot(test1, test2)<<"\n"; vPrint(vSub(test1, test2)); vPrint(vAdd(test1, test2)); vPrint(vMult(test1, test2)); vPrint(normalize(test1)); vPrint(normalize(test2)); vPrint(vCross(test1, test2)); vPrint(vScale(-1, test1)); std::cout<<"\n=================\nEnd UNIT TESTS\n=================\n\n"; return 0; } else { return 0; } }
int KRLTrackCamera::GetCollisionPosition( const D3DXVECTOR3& crvCameraPos, const D3DXVECTOR3& crvTargetPos0, IKG3DCamera* p3DCamera, D3DXVECTOR3* pvCrossPos ) { HRESULT hRetCode = E_FAIL; int nRetCode = false; D3DXVECTOR3 vSrc[5]; D3DXVECTOR3 vDst[5]; D3DXVECTOR3 vCrossPos(0.0f, 0.0f, 0.0f); D3DXVECTOR3 vRightDirection(0.0f, 0.0f, 0.0f); // 当前的位置的右方向 D3DXVECTOR3 vUpDirection(0.0f, 0.0f, 0.0f); // 当前的位置的上方向 D3DXVECTOR3 vLimitY(0.0f, 0.0f, 0.0f); D3DXVECTOR3 vLimitX(0.0f, 0.0f, 0.0f); float fHalfHeight = 0.0f; float fHalfWidth = 0.0f; float fMinDistance = FLT_MAX; D3DXVECTOR3 crvTargetPos = crvTargetPos0 + D3DXVECTOR3(0.001F,0.001F,0.001f); int nHasCross = false; int i = 0; float fFovy = 0.0f; float fAspect = 0.0f; float fzNear = 0.0f; float fzFar = 0.0f; KGLOG_PROCESS_ERROR(p3DCamera); KGLOG_PROCESS_ERROR(pvCrossPos); hRetCode = p3DCamera->GetPerspective(&fFovy, &fAspect, &fzNear, &fzFar); KGLOG_COM_PROCESS_ERROR(hRetCode); fHalfHeight = tanf(fFovy * 0.5f) * fzNear; // half height of the near plan of view frustum fHalfWidth = fHalfHeight * fAspect; // half width of the near plan of view frustum hRetCode = p3DCamera->GetUpDirection(&vUpDirection); KGLOG_COM_PROCESS_ERROR(hRetCode); hRetCode = p3DCamera->GetRight(&vRightDirection); KGLOG_COM_PROCESS_ERROR(hRetCode); vLimitY = vUpDirection * fHalfHeight; vLimitX = vRightDirection * fHalfWidth; // 五射线检测 vSrc[0] = crvCameraPos; vSrc[1] = crvCameraPos + vLimitY - vLimitX; vSrc[2] = crvCameraPos + vLimitY + vLimitX; vSrc[3] = crvCameraPos - vLimitY - vLimitX; vSrc[4] = crvCameraPos - vLimitY + vLimitX; vDst[0] = crvTargetPos; vDst[1] = crvTargetPos + vLimitY - vLimitX; vDst[2] = crvTargetPos + vLimitY + vLimitX; vDst[3] = crvTargetPos - vLimitY - vLimitX; vDst[4] = crvTargetPos - vLimitY + vLimitX; fMinDistance = D3DXVec3Length(&(crvCameraPos - crvTargetPos)); ASSERT(fMinDistance > 0.9f); for (i = 0; i < 5; i++) { D3DXVECTOR3 vCross(0.0f, 0.0f, 0.0f); float fDistance = 0.0f; nRetCode = p3DCamera->GetCrossPosition(vDst[i], vSrc[i], &vCross); if (!nRetCode) continue; fDistance = D3DXVec3Length(&(vDst[i] - vCross)); if (fDistance < fMinDistance) { fMinDistance = fDistance; nHasCross = true; } } m_nCollisionFlag = false; if (nHasCross) { D3DXVECTOR3 vDirection = crvTargetPos - crvCameraPos; D3DXVec3Normalize(&vDirection, &vDirection); if (fMinDistance > 18.0f) fMinDistance -= 18.0f; vCrossPos = crvTargetPos - vDirection * fMinDistance; m_nCollisionFlag = true; } *pvCrossPos = vCrossPos; Exit0: return nHasCross; }