TerrainRenderablePlane::TerrainRenderablePlane(GameEntity* parent): TerrainRenderable(parent) { D3DXVECTOR3 org000(0,0,0); D3DXVECTOR3 nrm(0,1,0); D3DXPlaneFromPointNormal(&m_phy_shape,&org000,&nrm); }
bool CD3DWater::Create(float iSizeX, float iSizeY, float iPosX , // 横坐标 float iPosY , // 纵坐标 float iHeight ) { if (!LoadContent()) return false; FetchSurfaces();//获得折射反射渲染表面 if (FAILED(m_pDevice->CreateVertexBuffer(6 * sizeof(VertexPositionTex), D3DUSAGE_WRITEONLY, VertexPositionTex::FVF, D3DPOOL_DEFAULT, &m_pVB, 0))) return false; VertexPositionTex* pVertices; m_pVB->Lock(0, 0, (void**)&pVertices, 0); pVertices[0] = VertexPositionTex{ iPosX, iHeight, iPosY + iSizeY, 0, 0 }; pVertices[1] = VertexPositionTex{ iPosX + iSizeX, iHeight, iPosY + iSizeY, 1, 0 }; pVertices[2] = VertexPositionTex{ iPosX, iHeight, iPosY, 0, 1 }; pVertices[3] = VertexPositionTex{ iPosX + iSizeX, iHeight, iPosY + iSizeY, 1, 0 }; pVertices[4] = VertexPositionTex{ iPosX + iSizeX, iHeight, iPosY, 1, 1 }; pVertices[5] = VertexPositionTex{ iPosX, iHeight, iPosY, 0, 1 }; m_pVB->Unlock(); //设置摄像机反射面 //创建折射 反射横切面 D3DXPlaneFromPointNormal(&m_waterPlane, &D3DXVECTOR3(iPosX, iHeight, iPosY), &D3DXVECTOR3(0,1,0)); D3DXPlaneNormalize(&m_waterPlane, &m_waterPlane); return true; }
void MSPlane::RenderStencil( float dTime, D3DXVECTOR3 pos ) { // 평면 생성 D3DXPLANE plane; D3DXPlaneFromPointNormal(&plane, &pos, &D3DXVECTOR3(0, 1, 0)); // 반사 행렬 생성 D3DXMATRIX mReflect; D3DXMatrixReflect(&mReflect, &plane); // 최종 행렬 D3DXMATRIX mTMReflect; D3DXMatrixMultiply(&mTMReflect, &m_mTM, &mReflect); // 그리기모드 설정 g_pDevice->SetRenderState(D3DRS_CULLMODE, D3DCULL_CW); // 최종 월드 행렬 설정 g_pDevice->SetTransform(D3DTS_WORLD, &mTMReflect); RenderPlaneMesh(dTime, mTMReflect, true); //옵션 복구. g_pDevice->SetRenderState(D3DRS_CULLMODE, D3DCULL_CCW); }
PlaneIntergrationMaker() { D3DXVECTOR3 vNormal(1,1,1); D3DXVec3Normalize(&vNormal, &vNormal); FLOAT fNear = (FLOAT)em_mesh_range / 4; D3DXPlaneFromPointNormal(&plane, &D3DXVECTOR3(fNear, 0,0), &vNormal); }
BOOL KG3DBaseCoordImp::IntersectPlaneAndFindPoint( KG3DCOORD WhichCoord , const D3DXVECTOR3& Center , const D3DXVECTOR3& vSrc , const D3DXVECTOR3& vDir , D3DXVECTOR3& vInter ) { _ASSERTE(WhichCoord >= KG3DCOORD_FIRST_AXIS && WhichCoord <= KG3DCOORD_INTEGRATION); D3DXPLANE planeUse; if(WhichCoord >= KG3DCOORD_FIRST_AXIS && WhichCoord < KG3DCOORD_FIRST_AXIS + KG3DCOORD_AXIS_COUNT) { //如果选中的是线,那么找过这条线和发射线垂直的面,然后求交点 const D3DXVECTOR3& vAxis = D3DXVec3GetNormalOfPlane(WhichCoord - KG3DCOORD_FIRST_AXIS); D3DXVECTOR3 vUp; D3DXVec3Cross(&vUp, &vAxis, &vDir); D3DXVECTOR3 vNormalOfBestPlane; D3DXVec3Cross(&vNormalOfBestPlane, &vUp, &vAxis); D3DXVec3Normalize(&vNormalOfBestPlane, &vNormalOfBestPlane); D3DXPlaneFromPointNormal(&planeUse, &Center, &vNormalOfBestPlane); } else if(WhichCoord >= KG3DCOORD_FIRST_PLANE && WhichCoord < KG3DCOORD_FIRST_PLANE + KG3DCOORD_PLANE_COUNT) { const D3DXVECTOR3& NormalUse = D3DXVec3GetNormalOfPlane(WhichCoord - KG3DCOORD_FIRST_PLANE); D3DXPlaneFromPointNormal(&planeUse, &Center, &NormalUse); } else if (WhichCoord == KG3DCOORD_INTEGRATION) { const D3DXPLANE planeIntergration = GetPlaneIntergration(); const D3DXVECTOR3& NormalUse = (const D3DXVECTOR3&)planeIntergration; D3DXPlaneFromPointNormal(&planeUse, &Center, &NormalUse); } else { return FALSE; } const FLOAT someLargeLength = 100000.f; return NULL != D3DXPlaneIntersectLine(&vInter, &planeUse, &vSrc, &(vSrc + vDir * someLargeLength)); }
void Storm3D_SpotlightShared::setClipPlanes(const float *cameraView) { D3DXMATRIX m(cameraView); float determinant = D3DXMatrixDeterminant(&m); D3DXMatrixInverse(&m, &determinant, &m); D3DXMatrixTranspose(&m, &m); D3DXVECTOR3 d(direction.x, direction.y, direction.z); VC2 bd(d.x, d.z); bd.Normalize(); D3DXVECTOR3 p1(position.x - 8*bd.x, position.y, position.z - 8*bd.y); //D3DXVECTOR3 p1(position.x - 1*bd.x, position.y, position.z - 1*bd.y); D3DXVECTOR3 p2(p1.x, p1.y + 5.f, p1.z); float angle = D3DXToRadian(fov) * .55f; D3DXPLANE leftPlane; D3DXMATRIX leftTransform; D3DXMatrixRotationY(&leftTransform, -angle); D3DXVECTOR3 leftPoint(direction.x, 0, direction.z); D3DXVECTOR4 leftPoint2; D3DXVec3Transform(&leftPoint2, &leftPoint, &leftTransform); leftPoint = p1; leftPoint.x += leftPoint2.x; leftPoint.z += leftPoint2.z; D3DXPlaneFromPoints(&leftPlane, &p1, &p2, &leftPoint); D3DXPlaneNormalize(&leftPlane, &leftPlane); D3DXPlaneTransform(&leftPlane, &leftPlane, &m); D3DXPLANE rightPlane; D3DXMATRIX rightTransform; D3DXMatrixRotationY(&rightTransform, angle); D3DXVECTOR3 rightPoint(direction.x, 0, direction.z); D3DXVECTOR4 rightPoint2; D3DXVec3Transform(&rightPoint2, &rightPoint, &rightTransform); rightPoint = p1; rightPoint.x += rightPoint2.x; rightPoint.z += rightPoint2.z; D3DXPlaneFromPoints(&rightPlane, &rightPoint, &p2, &p1); D3DXPlaneNormalize(&rightPlane, &rightPlane); D3DXPlaneTransform(&rightPlane, &rightPlane, &m); D3DXPLANE backPlane; D3DXVECTOR3 pb(p1.x, p1.y, p1.z); D3DXPlaneFromPointNormal(&backPlane, &pb, &d); D3DXPlaneNormalize(&backPlane, &backPlane); D3DXPlaneTransform(&backPlane, &backPlane, &m); device.SetClipPlane(0, leftPlane); device.SetClipPlane(1, rightPlane); device.SetClipPlane(2, backPlane); device.SetRenderState(D3DRS_CLIPPLANEENABLE, D3DCLIPPLANE0 | D3DCLIPPLANE1 | D3DCLIPPLANE2); }
bool CWall3D::intersectRay( const SLine3& ray, float& t ) const { SPlane plane; D3DXPlaneFromPointNormal( &plane, &mMatrix.getOrigin(), &mMatrix.getAxisZ() ); SVector3 pt; if( !plane.intersect( ray, pt ) ) { return false; } t = ray.project( pt ); if( t < 0 ) return false; return true; }
CBoxObject::CBoxObject() { D3DXVECTOR3 Normal[6]{ D3DXVECTOR3(0, 0, -1), D3DXVECTOR3(0, 0, 1), D3DXVECTOR3(0, -1, 0), D3DXVECTOR3(0, 1, 0), D3DXVECTOR3(-1, 0, 0), D3DXVECTOR3(1, 0, 0) }; D3DXVECTOR3 point[6]{ D3DXVECTOR3(0, 0, PLANE_WIDTH / 2), D3DXVECTOR3(0, 0, -PLANE_WIDTH / 2), D3DXVECTOR3(0, PLANE_WIDTH/2, 0), D3DXVECTOR3(0, -PLANE_WIDTH / 2, 0), D3DXVECTOR3(PLANE_WIDTH / 2, 0, 0), D3DXVECTOR3(-PLANE_WIDTH / 2, 0, 0) }; for (int i = 0; i < 6; ++i) { m_point[i] = point[i]; m_Normal[i] = Normal[i]; D3DXPlaneFromPointNormal(&m_Plane[i], &m_point[i], &m_Normal[i]); } }
// Project the mouse cursor from screen space to object space void EditExt::ProjectScreenToWorld(D3DXVECTOR3* pOut, float screenX, float screenY, float worldZ) { D3DXVECTOR3 lineBegin, lineEnd; // Unproject the near and far points given by the screen X,Y coords D3DXVECTOR3 screenSpace(screenX, screenY, 0.0f); D3DXVec3Unproject(&lineBegin, &screenSpace, &viewport, &projection_matrix, &view_matrix, &worldMatrix); screenSpace.z = 1.0f; D3DXVec3Unproject(&lineEnd, &screenSpace, &viewport, &projection_matrix, &view_matrix, &worldMatrix); // Using a plane intersection, we can determine the object space coordinates of the screen space coords // at a certain Z depth, intersecting the line given above. orig.z = worldZ; D3DXPlaneFromPointNormal(&plane, &orig, &normal); D3DXPlaneIntersectLine(pOut, &plane, &lineBegin, &lineEnd); }
TEST( Plane, setFromPointNormal ) { Plane tamyPlane; D3DXPLANE dxPlane; Vector point, normal; point.set( 10, 20, 30 ); normal.set( Quad_1000 ); D3DXPlaneFromPointNormal( &dxPlane, ( const D3DXVECTOR3* )&point, ( const D3DXVECTOR3* )&normal ); tamyPlane.setFromPointNormal( point, normal ); COMPARE_PLANE( dxPlane, tamyPlane ); point.set( -4, 0, 5.5f ); normal.set( Quad_0100 ); D3DXPlaneFromPointNormal( &dxPlane, ( const D3DXVECTOR3* )&point, ( const D3DXVECTOR3* )&normal ); tamyPlane.setFromPointNormal( point, normal ); COMPARE_PLANE( dxPlane, tamyPlane ); point.set( 0, 0, -20.0f ); normal.set( Quad_0010 ); D3DXPlaneFromPointNormal( &dxPlane, ( const D3DXVECTOR3* )&point, ( const D3DXVECTOR3* )&normal ); tamyPlane.setFromPointNormal( point, normal ); COMPARE_PLANE( dxPlane, tamyPlane ); point.set( 10, 20, 30 ); normal.set( Quad_Neg_1000 ); D3DXPlaneFromPointNormal( &dxPlane, ( const D3DXVECTOR3* )&point, ( const D3DXVECTOR3* )&normal ); tamyPlane.setFromPointNormal( point, normal ); COMPARE_PLANE( dxPlane, tamyPlane ); point.set( -4, 0, 5.5f ); normal.set( Quad_Neg_0100 ); D3DXPlaneFromPointNormal( &dxPlane, ( const D3DXVECTOR3* )&point, ( const D3DXVECTOR3* )&normal ); tamyPlane.setFromPointNormal( point, normal ); COMPARE_PLANE( dxPlane, tamyPlane ); point.set( 0, 0, -20.0f ); normal.set( Quad_Neg_0010 ); D3DXPlaneFromPointNormal( &dxPlane, ( const D3DXVECTOR3* )&point, ( const D3DXVECTOR3* )&normal ); tamyPlane.setFromPointNormal( point, normal ); COMPARE_PLANE( dxPlane, tamyPlane ); }
HRESULT KG3DRotationCoordinateOld::RotateBegin() { //m_matEntityWorld = m_EntityList.GetWorldMatrix(); { D3DXVECTOR3 vCenter(0,0,0); KSF::GetSelectionCenter(m_pAttachScene->GetSelectionTool(), vCenter); D3DXMatrixTranslation(&m_matEntityWorld, vCenter.x, vCenter.y, vCenter.z); } m_vBeginCross.x = m_matEntityWorld._41; m_vBeginCross.y = m_matEntityWorld._42; m_vBeginCross.z = m_matEntityWorld._43; m_vPrevCross = m_vBeginCross; HRESULT hResult = E_FAIL; HRESULT hRetCode = E_FAIL; D3DXVECTOR3 vOrg; D3DXVECTOR3 vDir; D3DXMATRIX matWorldInv; D3DXVECTOR3 vCrossXZ; D3DXVECTOR3 vCrossYZ; D3DXVECTOR3 vCrossXY; D3DXPLANE planeXZ; D3DXPLANE planeXY; D3DXPLANE planeYZ; D3DXVECTOR3 vPoint = D3DXVECTOR3(m_matCoord._41, m_matCoord._42, m_matCoord._43); D3DXVECTOR3 vNorXZ = D3DXVECTOR3(m_matCoord._21, m_matCoord._22, m_matCoord._23); D3DXVECTOR3 vNorXY = D3DXVECTOR3(m_matCoord._31, m_matCoord._32, m_matCoord._33); D3DXVECTOR3 vNorYZ = D3DXVECTOR3(m_matCoord._11, m_matCoord._12, m_matCoord._13); D3DXVECTOR3 vCross; IEKG3DSceneOutputWnd *piCurOutputWnd = NULL; KG_PROCESS_ERROR(m_dwCurrSelCoord != 0xFFFFFFFF); //KG_PROCESS_ERROR(m_pAttachScene); //KG_PROCESS_ERROR(m_EntityList.GetSize()); _ASSERTE(NULL != m_pAttachScene); KG_PROCESS_ERROR(0 != m_pAttachScene->GetSelectionTool().GetSelectionCount()); hRetCode = m_pAttachScene->GetCurOutputWnd(&piCurOutputWnd); KGLOG_COM_PROCESS_ERROR(hRetCode); piCurOutputWnd->GetPickRay(&vOrg, &vDir, NULL); D3DXPlaneFromPointNormal( &planeXZ, &vPoint, &vNorXZ ); D3DXPlaneFromPointNormal( &planeXY, &vPoint, &vNorXY ); D3DXPlaneFromPointNormal( &planeYZ, &vPoint, &vNorYZ ); D3DXPlaneNormalize(&planeYZ, &planeYZ); D3DXPlaneNormalize(&planeXZ, &planeXZ); D3DXPlaneNormalize(&planeXY, &planeXY); switch (m_dwCurrSelCoord) { case 0 : // y KG_PROCESS_ERROR( D3DXPlaneIntersectLine( &vCross, &planeXZ, &vOrg, &(vOrg + vDir * 10000000.0f) ) ); m_vPrevCross = vCross; m_currSelPane = planeXZ; m_currSelNormal = vNorXZ; break; case 1 : // x KG_PROCESS_ERROR( D3DXPlaneIntersectLine( &vCross, &planeYZ, &vOrg, &(vOrg + vDir * 10000000.0f) ) ); m_vPrevCross = vCross; m_currSelPane = planeYZ; m_currSelNormal = vNorYZ; break; case 2 : // z KG_PROCESS_ERROR( D3DXPlaneIntersectLine( &vCross, &planeXY, &vOrg, &(vOrg + vDir * 10000000.0f) ) ); m_vPrevCross = vCross; m_currSelPane = planeXY; m_currSelNormal = vNorXY; break; default : ASSERT(FALSE); break; } m_vBeginCross = m_vPrevCross; m_fAngelX = 0.0f; m_fAngelY = 0.0f; m_fAngelZ = 0.0f; m_nMoveFlag = TRUE; hResult = S_OK; Exit0: return hResult; }
HRESULT KSceneSwordTest::InitPhysicsTest(int choice) { Physics::LPRIGIDBODY pRigid = NULL; Physics::LPRIGIDBODY pRigid0 = NULL; D3DXPLANE plane; /////////////////////////////////////////////////////////////////////////////////////////////////// //说明 //1. 刚体初始化的问题,一定要先调用SetSP函数,后调用Initialise函数 // pRigid->SetSP() (用于确定刚体的几何属性) // pRigid->Initialise() (用于确定刚体的物理属性) // //2.刚体进行初始化操作后可以设置的属性 // SetMass(float mass); 设置质量 // SetInertia(float inertia); 设置转动惯量,目前转动惯量以一个浮点数来表示,可以考虑使用一个矩阵来存储多维转动惯量信息 // m_LineVel; 线速度 // m_AngVel; 角速度 // m_Force; 合力 //注意事项,在物理环境中尽量不要直接设置合力或合力矩,可以去设置线速度或角速度 // m_Torque; 合力矩 // m_matOrient; 刚体局部坐标系, 对应于质心 //注意,同样尽量不要尝试直接设置这个矩阵 // m_fStaticFriction; 静摩擦系数 // m_fDynamicFriction; 动摩擦系数 // // 本来可以提供多一些参数设置,如 // m_bImmovable; 不可移动物体标记 //但需要对KPhysicsSimulator类稍做修改,并不困难,但来不及修改并测试,所以注释掉了 // //增加这一属性的思路是,如果两个物体都是不可移动物体,则不做碰撞检测 // //如果其中之一是不可移动物体,则做碰撞检测,在碰撞处理时,利用类似刚体撞平面的代码部分来完成冲量的计算 // // m_bNonePenetration //这个变量的设置是为了阻止刚体之间互相嵌入现象的,可参考KPhysicsSimulator类中的这部分代码(已注释掉) // //因为效果不好,所以也注释掉了,原理是根据刚体碰撞检测所得的嵌入深度,修正刚体预期的速度 ////////////////////////////////////////////////////////////////////////////////////////////////////// //3.物理环境设置的参数 // m_bAddingGravity; //是否考虑重力场作用 // m_bUsingFriction; //是否考虑摩擦力作用(目前只考虑了刚体中的摩擦系数,事实上可以考虑为平面类添加相应的摩擦系数,再在KPhysicsSimulator类中稍做修改即可) // m_fEpsilon; //碰撞恢复系数,0~1之间,1为完全弹性碰撞,0为完全非弹性碰撞 // // DisableCollision() //本函数可以屏蔽两刚体之间的碰撞 /////////////////////////////////////////////////////////////////////////////////////////////////// switch(choice) { case 1: //单个物体自由落体碰撞地面的效果,启用重力,摩擦力,碰撞恢复系数0.65f m_Sim.m_bAddingGravity = TRUE; m_Sim.m_bUsingFriction = TRUE; m_Sim.m_fEpsilon = 0.65f; m_RigidTable.Get1NewRigidBody(&pRigid); pRigid->SetSP( D3DXVECTOR3(0,300,0), D3DXVECTOR3(0,0.7f,0.7f), 70.0f, 30.0f ); pRigid->Initialise( D3DXVECTOR3(0,300,0), 1.0f, 833.3f ); m_Sim.AddRigidBody(pRigid); D3DXPlaneFromPointNormal( &plane, &D3DXVECTOR3(0,0,0), &D3DXVECTOR3(0,1,0) ); m_Sim.listPlane.push_back( plane ); break; case 2: //两刚体轴平行,无重力,无摩擦力,正碰,完全弹性碰撞 m_Sim.m_bAddingGravity = FALSE; m_Sim.m_bUsingFriction = FALSE; m_Sim.m_fEpsilon = 1.0f; m_RigidTable.Get1NewRigidBody(&pRigid); pRigid->SetSP( D3DXVECTOR3(1,100,0), D3DXVECTOR3(0,1,0), 70.0f, 30.0f ); pRigid->Initialise( D3DXVECTOR3(1,100,0), 1.0f, 833.3f ); m_Sim.AddRigidBody(pRigid); m_RigidTable.Get1NewRigidBody(&pRigid); pRigid->SetSP( D3DXVECTOR3(1000,100,0), D3DXVECTOR3(0,1,0), 70.0f, 30.0f ); pRigid->Initialise( D3DXVECTOR3(1000,100,0), 1.0f, 833.3f ); pRigid->m_LineVel = D3DXVECTOR3(-100,0,0); m_Sim.AddRigidBody(pRigid); break; case 3: //两轴异面垂直,无重力,无摩擦力,完全弹性碰撞 m_Sim.m_bAddingGravity = FALSE; m_Sim.m_bUsingFriction = FALSE; m_Sim.m_fEpsilon = 1.0f; m_RigidTable.Get1NewRigidBody(&pRigid); pRigid->SetSP( D3DXVECTOR3(1,100,0), D3DXVECTOR3(0,1,0), 70.0f, 30.0f ); pRigid->Initialise( D3DXVECTOR3(1,100,0), 1.0f, 833.3f ); m_Sim.AddRigidBody(pRigid); m_RigidTable.Get1NewRigidBody(&pRigid); pRigid->SetSP( D3DXVECTOR3(100,100,0), D3DXVECTOR3(0,0,1), 70.0f, 30.0f ); pRigid->Initialise( D3DXVECTOR3(100,100,0), 1.0f, 833.3f ); pRigid->m_LineVel = D3DXVECTOR3( -10, 0, 0 ); m_Sim.AddRigidBody(pRigid); break; case 4: //两轴平行,中心不等高,无重力,无摩擦力,完全弹性碰撞 m_Sim.m_bAddingGravity = FALSE; m_Sim.m_bUsingFriction = FALSE; m_Sim.m_fEpsilon = 1.0f; m_RigidTable.Get1NewRigidBody(&pRigid); pRigid->SetSP( D3DXVECTOR3(1,100,0), D3DXVECTOR3(0,1,0), 70.0f, 30.0f ); pRigid->Initialise( D3DXVECTOR3(1,100,0), 1.0f, 833.3f ); m_Sim.AddRigidBody(pRigid); m_RigidTable.Get1NewRigidBody(&pRigid); pRigid->SetSP( D3DXVECTOR3(100,180,0), D3DXVECTOR3(0,1,0), 70.0f, 30.0f ); pRigid->Initialise( D3DXVECTOR3(100,180,0), 1.0f, 833.3f ); pRigid->m_LineVel = D3DXVECTOR3( -10, 0, 0 ); m_Sim.AddRigidBody(pRigid); break; case 5: //两轴异面不垂直,无重力,无摩擦力,完全弹性碰撞 m_Sim.m_bAddingGravity = FALSE; m_Sim.m_bUsingFriction = FALSE; m_Sim.m_fEpsilon = 1.0f; m_RigidTable.Get1NewRigidBody(&pRigid); pRigid->SetSP( D3DXVECTOR3(1,100,0), D3DXVECTOR3(0,1,0), 70.0f, 30.0f ); pRigid->Initialise( D3DXVECTOR3(1,100,0), 1.0f, 833.3f ); m_Sim.AddRigidBody(pRigid); m_RigidTable.Get1NewRigidBody(&pRigid); pRigid->SetSP( D3DXVECTOR3(150,110,0), D3DXVECTOR3(0,0.7f,0.7f), 70.0f, 30.0f ); pRigid->Initialise( D3DXVECTOR3(150,110,0), 1.0f, 833.3f ); pRigid->m_LineVel = D3DXVECTOR3( -10, 0, 0 ); m_Sim.AddRigidBody(pRigid); break; case 6: //两轴异面, 刚体球体部分碰刚体柱体部分,无重力,无摩擦力,完全弹性碰撞 m_Sim.m_bAddingGravity = FALSE; m_Sim.m_bUsingFriction = FALSE; m_Sim.m_fEpsilon = 1.0f; m_RigidTable.Get1NewRigidBody(&pRigid); pRigid->SetSP( D3DXVECTOR3(1,100,0), D3DXVECTOR3(0,1,0), 70.0f, 30.0f ); pRigid->Initialise( D3DXVECTOR3(1,100,0), 1.0f, 833.3f ); m_Sim.AddRigidBody(pRigid); m_RigidTable.Get1NewRigidBody(&pRigid); pRigid->SetSP( D3DXVECTOR3(100,100,50), D3DXVECTOR3(0,0.7f,0.7f), 70.0f, 30.0f ); pRigid->Initialise( D3DXVECTOR3(100,100,50), 1.0f, 833.3f ); pRigid->m_LineVel = D3DXVECTOR3( -10, 0, 0 ); m_Sim.AddRigidBody(pRigid); break; case 7: //从本例可看出,刚体可能会出现互相嵌入的现象,这需要修正 m_Sim.m_bAddingGravity = TRUE; m_Sim.m_bUsingFriction = TRUE; m_Sim.m_fEpsilon = 0.65f; m_RigidTable.Get1NewRigidBody(&pRigid); pRigid->SetSP( D3DXVECTOR3(0,100,0), D3DXVECTOR3(0,1,0), 70.0f, 30.0f ); pRigid->Initialise( D3DXVECTOR3(0,100,0), 100.0f, 83333.3f ); m_Sim.AddRigidBody(pRigid); m_RigidTable.Get1NewRigidBody(&pRigid); pRigid->SetSP( D3DXVECTOR3(0,230,0), D3DXVECTOR3(0,1,0), 0, 30.0f ); pRigid->Initialise( D3DXVECTOR3(0,230,0), 20.0f, 7200 ); m_Sim.AddRigidBody(pRigid); m_RigidTable.Get1NewRigidBody(&pRigid); pRigid->SetSP( D3DXVECTOR3(300,210,0), D3DXVECTOR3(0,1,0), 0.0f, 30.0f ); pRigid->Initialise( D3DXVECTOR3(300,210,0), 10.0f, 10*360 ); pRigid->m_LineVel = D3DXVECTOR3(-200,0,0); m_Sim.AddRigidBody(pRigid); D3DXPlaneFromPointNormal( &plane, &D3DXVECTOR3(0,0,0), &D3DXVECTOR3(0,1,0) ); m_Sim.listPlane.push_back( plane ); break; case 8: //刚体与平面碰撞的效果,有重力,摩擦力,碰撞系数0.65f m_Sim.m_bAddingGravity = TRUE; m_Sim.m_bUsingFriction = TRUE; m_Sim.m_fEpsilon = 0.65f; m_RigidTable.Get1NewRigidBody(&pRigid); pRigid->SetSP( D3DXVECTOR3(110,300,-110), D3DXVECTOR3(0,0.7f,0.7f), 70.0f, 30.0f ); pRigid->Initialise( D3DXVECTOR3(110,300,-110), 1.0f, 833.3f ); m_Sim.AddRigidBody(pRigid); D3DXPlaneFromPointNormal( &plane, &D3DXVECTOR3(0,0,0), &D3DXVECTOR3(0,1,0) ); m_Sim.listPlane.push_back( plane ); D3DXPlaneFromPointNormal( &plane, &D3DXVECTOR3(0,0,0), &D3DXVECTOR3(0,0.7f,0.7f) ); m_Sim.listPlane.push_back( plane ); break; } return S_OK; }
//----------------------------------------------------------------------------- // Builds an occlusion volume for the given occluder. //----------------------------------------------------------------------------- void SceneManager::BuildOcclusionVolume( SceneOccluder *occluder, D3DXVECTOR3 viewer ) { // Create a list of edges for the occluder's silhouette. LinkedList< Edge > *edges = new LinkedList< Edge >; // Go through all the faces in the occluder's mesh. for( unsigned long f = 0; f < occluder->totalFaces; f++ ) { // Get the indices of this face. unsigned short index0 = occluder->indices[3 * f + 0]; unsigned short index1 = occluder->indices[3 * f + 1]; unsigned short index2 = occluder->indices[3 * f + 2]; // Find the angle between the face's normal and the vector point from // viewer's position to the face's position. If the angle is less than // 0, then the face is visible to the viewer. if( D3DXVec3Dot( &occluder->vertices[index0].normal, &( occluder->vertices[index0].translation - viewer ) ) < 0.0f ) { // Check if the list of edges is empty. if( edges->GetTotalElements() == 0 ) { // Add all the edges for this face. edges->Add( new Edge( &occluder->vertices[index0], &occluder->vertices[index1] ) ); edges->Add( new Edge( &occluder->vertices[index1], &occluder->vertices[index2] ) ); edges->Add( new Edge( &occluder->vertices[index2], &occluder->vertices[index0] ) ); } else { Edge *found0 = NULL; Edge *found1 = NULL; Edge *found2 = NULL; // Iterate through the list of edges. edges->Iterate( true ); while( edges->Iterate() != NULL ) { // Check if the first edge of this face already exists. if( ( edges->GetCurrent()->vertex0->translation == occluder->vertices[index0].translation && edges->GetCurrent()->vertex1->translation == occluder->vertices[index1].translation ) || ( edges->GetCurrent()->vertex0->translation == occluder->vertices[index1].translation && edges->GetCurrent()->vertex1->translation == occluder->vertices[index0].translation ) ) found0 = edges->GetCurrent(); // Check if the second edge of this face already exists. if( ( edges->GetCurrent()->vertex0->translation == occluder->vertices[index1].translation && edges->GetCurrent()->vertex1->translation == occluder->vertices[index2].translation ) || ( edges->GetCurrent()->vertex0->translation == occluder->vertices[index2].translation && edges->GetCurrent()->vertex1->translation == occluder->vertices[index1].translation ) ) found1 = edges->GetCurrent(); // Check if the third edge of this face already exists. if( ( edges->GetCurrent()->vertex0->translation == occluder->vertices[index2].translation && edges->GetCurrent()->vertex1->translation == occluder->vertices[index0].translation ) || ( edges->GetCurrent()->vertex0->translation == occluder->vertices[index0].translation && edges->GetCurrent()->vertex1->translation == occluder->vertices[index2].translation ) ) found2 = edges->GetCurrent(); } // If the first edge was found, remove it. Otherwise add it. if( found0 != NULL ) edges->Remove( &found0 ); else edges->Add( new Edge( &occluder->vertices[index0], &occluder->vertices[index1] ) ); // If the second edge was found, remove it. Otherwise add it. if( found1 != NULL ) edges->Remove( &found1 ); else edges->Add( new Edge( &occluder->vertices[index1], &occluder->vertices[index2] ) ); // If the thrid edge was found, remove it. Otherwise add it. if( found2 != NULL ) edges->Remove( &found2 ); else edges->Add( new Edge( &occluder->vertices[index2], &occluder->vertices[index0] ) ); } } } // Empty the occluder's list of planes. occluder->planes->Empty(); // Create the front cap plane. D3DXPLANE *plane = new D3DXPLANE; D3DXPlaneFromPointNormal( plane, &occluder->translation, &( occluder->translation - viewer ) ); occluder->planes->Add( plane ); // Iterate through the list of edges. edges->Iterate( true ); while( edges->Iterate() != NULL ) { // Get the position of the vertices in the edge. D3DXVECTOR3 vertex1 = edges->GetCurrent()->vertex0->translation; D3DXVECTOR3 vertex2 = edges->GetCurrent()->vertex1->translation; // Calculate the position of the thrid vertex for creating the plane. D3DXVECTOR3 dir = vertex1 - viewer; D3DXVec3Normalize( &dir, &dir ); D3DXVECTOR3 vertex3 = vertex1 + dir; // Create a plane from this edge. plane = new D3DXPLANE; D3DXPlaneFromPoints( plane, &vertex1, &vertex2, &vertex3 ); occluder->planes->Add( plane ); } // Destroy the list of edges. SAFE_DELETE( edges ); }
/** * CABT::splitTriangle * @date Modified Apr 18, 2006 */ void CABT::splitTriangle(CMesh::SVertex* pVertex, SPlane& oPlane, std::vector<CMesh::SVertex>& vFront, std::vector<CMesh::SVertex>& vBack) { unsigned int nResA, nResB; CMesh::SVertex vA, vB; vA = pVertex[2]; nResA = getPointClassification(vA.vPosition, oPlane); std::vector<CMesh::SVertex> vFrontFaces, vBackFaces; // Check triangle edges for(unsigned int i = 0; i < 3; ++i) { // Get the next triangle point vB = pVertex[i]; nResB = getPointClassification(vB.vPosition, oPlane); if(nResB == PT_FRONT) { if(nResA == PT_BACK) { // Find intersection D3DXVECTOR3 vIntersect; D3DXPLANE oDXPlane; D3DXPlaneIntersectLine(&vIntersect, D3DXPlaneFromPointNormal(&oDXPlane, &oPlane.point, &oPlane.normal), &vA.vPosition, &vB.vPosition); // Calculate interpolation factor D3DXVECTOR3 vNew, vWhole; D3DXVec3Subtract(&vNew, &vA.vPosition, &vIntersect); D3DXVec3Subtract(&vWhole, &vA.vPosition, &vB.vPosition); float fFactor = D3DXVec3Length(&vNew) / D3DXVec3Length(&vWhole); // Interpolate vertex data. CMesh::SVertex vNewVertex; D3DXCOLOR oColor; vNewVertex.vPosition = vIntersect; D3DXVec3Lerp(&vNewVertex.vNormal, &vA.vNormal, &vB.vNormal, fFactor); D3DXVec2Lerp(&vNewVertex.vTexCoord0, &vA.vTexCoord0, &vB.vTexCoord0, fFactor); D3DXColorLerp(&oColor, &D3DXCOLOR(vA.Color), &D3DXCOLOR(vB.Color), fFactor); vNewVertex.Color = oColor; vFrontFaces.push_back(vNewVertex); vBackFaces.push_back(vNewVertex); } vFrontFaces.push_back(vB); } else if(nResB == PT_BACK) { if(nResA == PT_FRONT) { // Find intersection D3DXVECTOR3 vIntersect; D3DXPLANE oDXPlane; D3DXPlaneIntersectLine(&vIntersect, D3DXPlaneFromPointNormal(&oDXPlane, &oPlane.point, &oPlane.normal), &vA.vPosition, &vB.vPosition); // Calculate interpolation factor D3DXVECTOR3 vNew, vWhole; D3DXVec3Subtract(&vNew, &vA.vPosition, &vIntersect); D3DXVec3Subtract(&vWhole, &vA.vPosition, &vB.vPosition); float fFactor = D3DXVec3Length(&vNew) / D3DXVec3Length(&vWhole); // Interpolate vertex data. CMesh::SVertex vNewVertex; D3DXCOLOR oColor; vNewVertex.vPosition = vIntersect; D3DXVec3Lerp(&vNewVertex.vNormal, &vA.vNormal, &vB.vNormal, fFactor); D3DXVec2Lerp(&vNewVertex.vTexCoord0, &vA.vTexCoord0, &vB.vTexCoord0, fFactor); D3DXColorLerp(&oColor, &D3DXCOLOR(vA.Color), &D3DXCOLOR(vB.Color), fFactor); vNewVertex.Color = oColor; vFrontFaces.push_back(vNewVertex); vBackFaces.push_back(vNewVertex); } vBackFaces.push_back(vB); } else { vFrontFaces.push_back(vB); vBackFaces.push_back(vB); } // Next Edge vA = vB; nResA = nResB; } // Make a triangle list out of the the vertices created. for(unsigned int i = 1; i < vFrontFaces.size() - 1; ++i) { vFront.push_back(vFrontFaces[0]); vFront.push_back(vFrontFaces[i]); vFront.push_back(vFrontFaces[i+1]); } for(unsigned int i = 1; i < vBackFaces.size() - 1; ++i) { vBack.push_back(vBackFaces[0]); vBack.push_back(vBackFaces[i]); vBack.push_back(vBackFaces[i+1]); } }