void Frustum::MakeFOVPlane( const Ant::Matrix &kViewProj ) { int i; Ant::Matrix kMat(kViewProj.GetInverse()); // 투영행렬까지 거치면 모든 3차원 월드좌표의 점은 (-1,-1,0) ~ (1,1,1)사이의 값으로 바뀐다. // m_vtx에 이 동차공간의 경계값을 넣어둔다. m_vtx[0].x = -1.0f; m_vtx[0].y = -1.0f; m_vtx[0].z = 0.0f; m_vtx[1].x = 1.0f; m_vtx[1].y = -1.0f; m_vtx[1].z = 0.0f; m_vtx[2].x = 1.0f; m_vtx[2].y = -1.0f; m_vtx[2].z = 1.0f; m_vtx[3].x = -1.0f; m_vtx[3].y = -1.0f; m_vtx[3].z = 1.0f; m_vtx[4].x = -1.0f; m_vtx[4].y = 1.0f; m_vtx[4].z = 0.0f; m_vtx[5].x = 1.0f; m_vtx[5].y = 1.0f; m_vtx[5].z = 0.0f; m_vtx[6].x = 1.0f; m_vtx[6].y = 1.0f; m_vtx[6].z = 1.0f; m_vtx[7].x = -1.0f; m_vtx[7].y = 1.0f; m_vtx[7].z = 1.0f; for(i=0; i<8; ++i) { ::D3DXVec3TransformCoord((D3DXVECTOR3*)&m_vtx[i], (D3DXVECTOR3*)&m_vtx[i], (D3DXMATRIX*)&kMat); } m_kPos = (m_vtx[0] + m_vtx[5]) / 2.0f; D3DXPlaneFromPoints(&m_kPlane[0], (D3DXVECTOR3*)m_vtx+4, (D3DXVECTOR3*)m_vtx+7, (D3DXVECTOR3*)m_vtx+6); // 상 평면(top) D3DXPlaneFromPoints(&m_kPlane[1], (D3DXVECTOR3*)m_vtx , (D3DXVECTOR3*)m_vtx+1, (D3DXVECTOR3*)m_vtx+2); // 하 평면(bottom) // D3DXPlaneFromPoints(&m_plane[2], m_vtx , m_vtx+4, m_vtx+5); // 근 평면(near) D3DXPlaneFromPoints(&m_kPlane[3], (D3DXVECTOR3*)m_vtx+2, (D3DXVECTOR3*)m_vtx+6, (D3DXVECTOR3*)m_vtx+7); // 원 평면(far) D3DXPlaneFromPoints(&m_kPlane[4], (D3DXVECTOR3*)m_vtx , (D3DXVECTOR3*)m_vtx+3, (D3DXVECTOR3*)m_vtx+7); // 좌 평면(left) D3DXPlaneFromPoints(&m_kPlane[5], (D3DXVECTOR3*)m_vtx+1, (D3DXVECTOR3*)m_vtx+5, (D3DXVECTOR3*)m_vtx+6); // 우 평면(right) }
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); }
D3DXVECTOR3 TERRAIN::GetNormal(int x, int y) { //Neighboring map nodes (D, B, C, F, H, G) INTPOINT mp[] = {INTPOINT(x-1, y), INTPOINT(x, y-1), INTPOINT(x+1, y-1), INTPOINT(x+1, y), INTPOINT(x, y+1), INTPOINT(x-1, y+1)}; //if there's an invalid map node return (0, 1, 0) if(!Within(mp[0]) || !Within(mp[1]) || !Within(mp[2]) || !Within(mp[3]) || !Within(mp[4]) || !Within(mp[5])) return D3DXVECTOR3(0.0f, 1.0f, 0.0f); //Calculate the normals of the 6 neighboring planes D3DXVECTOR3 normal = D3DXVECTOR3(0.0f, 0.0f, 0.0f); for(int i=0;i<6;i++) { D3DXPLANE plane; D3DXPlaneFromPoints(&plane, &GetWorldPos(INTPOINT(x, y)), &GetWorldPos(mp[i]), &GetWorldPos(mp[(i + 1) % 6])); normal += D3DXVECTOR3(plane.a, plane.b, plane.c); } D3DXVec3Normalize(&normal, &normal); return normal; }
void ZBspTree::_MakeLeaf( ZBspNode* pLeaf ) { DWORD i; pLeaf->SetNodeType( ZBspNode::NODETYPE_LEAF ); D3DXPlaneFromPoints( pLeaf->GetPlane(), &(pLeaf->GetFaces()->GetVerts()+0)->p, &(pLeaf->GetFaces()->GetVerts()+1)->p, &(pLeaf->GetFaces()->GetVerts()+2)->p ); ZBspFace* faceRoot = pLeaf->GetFaces(); ZBspFace * tf; for ( tf = faceRoot; tf; tf = tf->GetNext() ) { for ( i = 0; i < tf->GetVertCount(); i++) { // max 확장. if ( (tf->GetVerts()+i)->p.x > (pLeaf->GetMax())->x ) (pLeaf->GetMax())->x = (tf->GetVerts()+i)->p.x; if ( (tf->GetVerts()+i)->p.y > (pLeaf->GetMax())->y ) (pLeaf->GetMax())->y = (tf->GetVerts()+i)->p.y; if ( (tf->GetVerts()+i)->p.z > (pLeaf->GetMax())->z ) (pLeaf->GetMax())->z = (tf->GetVerts()+i)->p.z; // min 확장 if ( (tf->GetVerts()+i)->p.x < (pLeaf->GetMin())->x ) (pLeaf->GetMin())->x = (tf->GetVerts()+i)->p.x; if ( (tf->GetVerts()+i)->p.y < (pLeaf->GetMin())->y ) (pLeaf->GetMin())->y = (tf->GetVerts()+i)->p.y; if ( (tf->GetVerts()+i)->p.z < (pLeaf->GetMin())->z ) (pLeaf->GetMin())->z = (tf->GetVerts()+i)->p.z; } } }
bool CEntity::ComputeNormalVector( LPD3DXMESH _pMesh, D3DXVECTOR3& _vNormal, D3DXVECTOR3& _vCol, CEntity* target) { BOOL isHit = false; DWORD dwFaceIndex = 0; float fDist = 0; LPD3DXBUFFER ppAllhit; DWORD pCountOfHits; D3DXVECTOR3 vPos = m_vPos - target->GetPos(); D3DXVECTOR3 vtar = (-vPos); D3DXVec3Normalize( &vtar, &vtar); D3DXIntersect( _pMesh, &vPos, &vtar, &isHit, &dwFaceIndex, NULL, NULL, &fDist, &ppAllhit, &pCountOfHits ); if ( !isHit || fDist > GetSize() ) return false;// Ãæµ¹ÀÌ ¾È‰ç°Å³ª °Å¸®°¡ ¸Ö´Ù¸é ¸®ÅÏ; LPDIRECT3DVERTEXBUFFER9 pVB; LPDIRECT3DINDEXBUFFER9 pIB; _pMesh->GetVertexBuffer(&pVB); _pMesh->GetIndexBuffer( &pIB ); WORD* pIndices; D3DVERTEX* pVertices; pIB->Lock( 0, 0, (void**)&pIndices, 0 ); pVB->Lock( 0, 0,(void**)&pVertices, 0); D3DXVECTOR3 v0 = pVertices[pIndices[3*dwFaceIndex+0]].vPos; D3DXVECTOR3 v1 = pVertices[pIndices[3*dwFaceIndex+1]].vPos; D3DXVECTOR3 v2 = pVertices[pIndices[3*dwFaceIndex+2]].vPos; D3DXPLANE plane; D3DXPlaneFromPoints( &plane, &v0, &v1, &v2); _vCol = (v0 + v1 + v2)/3.f; _vCol += target->GetPos(); _vNormal.x = plane.a; _vNormal.y = plane.b; _vNormal.z = plane.c; #ifdef _DEBUG //Ãæµ¹ÁöÁ¡ Ç¥½Ã _SINGLE(CDebug)->AddPosMark( _vCol, COLOR_BLACK); #endif pVB->Unlock(); pIB->Unlock(); Safe_Release(pVB); Safe_Release(pIB); return true; }
void TerrainBorderRenderable::MakeVertexBuffer(float left, float top, float right, float bottom) { auto device = Globals::GetDevice()->GetDeviceD3D9(); IDirect3DVertexBuffer9* pVb = 0; HRESULT res = device->CreateVertexBuffer(16 * sizeof(TerrainVertex), D3DUSAGE_WRITEONLY, 0, D3DPOOL_MANAGED, &pVb, 0); if (res != S_OK) ReportErr("SkyBox CreateVB Failed"); m_pVB.reset(pVb, [&](IDirect3DVertexBuffer9* p){p->Release(); }); TerrainVertex* v = 0; float scale = 500.0f; m_pVB->Lock(0, 0, (void**)&v, 0); float height = (top - bottom)*0.5f; float width = (right - left)*0.5f; // positive x v[0] = TerrainVertex(1.0f*right, -1.0f*height, 1.0f*width, 0.0f, 1.0f); v[1] = TerrainVertex(1.0f*right, 1.0f*height, 1.0f*width, 0.0f, 0.0f); v[2] = TerrainVertex(1.0f*right, 1.0f*height, -1.0f*width, 1.0f, 0.0f); v[3] = TerrainVertex(1.0f*right, -1.0f*height, -1.0f*width, 1.0f, 1.0f); D3DXPlaneFromPoints(&m_border_planes[POSITIVE_X], &v[0].m_pos, &v[1].m_pos, &v[2].m_pos); // negative x v[4] = TerrainVertex(1.0f*left, -1.0f*height, -1.0f*width, 0.0f, 1.0f); v[5] = TerrainVertex(1.0f*left, 1.0f*height, -1.0f*width, 0.0f, 0.0f); v[6] = TerrainVertex(1.0f*left, 1.0f*height, 1.0f*width, 1.0f, 0.0f); v[7] = TerrainVertex(1.0f*left, -1.0f*height, 1.0f*width, 1.0f, 1.0f); D3DXPlaneFromPoints(&m_border_planes[NEGATIVE_X], &v[4].m_pos, &v[5].m_pos, &v[6].m_pos); // positive z v[8] = TerrainVertex(-1.0f*width, -1.0f*height, 1.0f*top, 0.0f, 1.0f); v[9] = TerrainVertex(-1.0f*width, 1.0f*height, 1.0f*top, 0.0f, 0.0f); v[10] = TerrainVertex(1.0f*width, 1.0f*height, 1.0f*top, 1.0f, 0.0f); v[11] = TerrainVertex(1.0f*width, -1.0f*height, 1.0f*top, 1.0f, 1.0f); D3DXPlaneFromPoints(&m_border_planes[POSITIVE_Y], &v[8].m_pos, &v[9].m_pos, &v[10].m_pos); // negative z v[12] = TerrainVertex(1.0f*width, -1.0f*height, 1.0f*bottom, 0.0f, 1.0f); v[13] = TerrainVertex(1.0f*width, 1.0f*height, 1.0f*bottom, 0.0f, 0.0f); v[14] = TerrainVertex(-1.0f*width, 1.0f*height, 1.0f*bottom, 1.0f, 0.0f); v[15] = TerrainVertex(-1.0f*width, -1.0f*height, 1.0f*bottom, 1.0f, 1.0f); D3DXPlaneFromPoints(&m_border_planes[NEGATIVE_Y], &v[12].m_pos, &v[13].m_pos, &v[14].m_pos); m_pVB->Unlock(); }
HexahedronBisectionV::HexahedronBisectionV(Hexahedron a_Hexahedron, unsigned int a_iDepth) :AHexahedronBisection(a_Hexahedron, a_iDepth) { m_vSplitPoint0=(m_Hexahedron.v0+m_Hexahedron.v1)*.5; m_vSplitPoint1=(m_Hexahedron.v2+m_Hexahedron.v3)*.5; m_vSplitPoint2=(m_Hexahedron.v4+m_Hexahedron.v5)*.5; m_vSplitPoint3=(m_Hexahedron.v6+m_Hexahedron.v7)*.5; D3DXPlaneFromPoints(&m_SplitPlane, (D3DXVECTOR3*)&m_vSplitPoint0, (D3DXVECTOR3*)&m_vSplitPoint1, (D3DXVECTOR3*)&m_vSplitPoint2); }
// 输入摄像机(view)*投影矩阵(projection),得到6个平面. BOOL ZFrustum::Make( D3DXMATRIXA16* pmatViewProj ) { int i; D3DXMATRIXA16 matInv; // 如果经过投影矩阵,所有的三维世界坐标的点都变为 (-1,-1,0) ~ (1,1,1)之间的值. // 将同次空间的临界值填入m_vtx. m_vtx[0].x = -1.0f; m_vtx[0].y = -1.0f; m_vtx[0].z = 0.0f; m_vtx[1].x = 1.0f; m_vtx[1].y = -1.0f; m_vtx[1].z = 0.0f; m_vtx[2].x = 1.0f; m_vtx[2].y = -1.0f; m_vtx[2].z = 1.0f; m_vtx[3].x = -1.0f; m_vtx[3].y = -1.0f; m_vtx[3].z = 1.0f; m_vtx[4].x = -1.0f; m_vtx[4].y = 1.0f; m_vtx[4].z = 0.0f; m_vtx[5].x = 1.0f; m_vtx[5].y = 1.0f; m_vtx[5].z = 0.0f; m_vtx[6].x = 1.0f; m_vtx[6].y = 1.0f; m_vtx[6].z = 1.0f; m_vtx[7].x = -1.0f; m_vtx[7].y = 1.0f; m_vtx[7].z = 1.0f; // 求得view * proj的逆矩阵. D3DXMatrixInverse(&matInv, NULL, pmatViewProj ); // Vertex_最终 = Vertex_local * Matrix_world * Matrix_view * Matrix_Proj , // Vertex_world = Vertex_local * Matrix_world的缘由, // Vertex_最终 = Vertex_world * Matrix_view * Matrix_Proj . // Vertex_最终 = Vertex_world * ( Matrix_view * Matrix_Proj ) // 逆矩阵( Matrix_view * Matrix_Proj )^-1两边相乘 // Vertex_最终 * 逆矩阵( Matrix_view * Matrix_Proj )^-1 = Vertex_World . // 因此, m_vtx * matInv = Vertex_world, 可以得到世界坐标系的Frustum坐标. for( i = 0; i < 8; i++ ) D3DXVec3TransformCoord( &m_vtx[i], &m_vtx[i], &matInv ); // 0号和 5号为平截头体中近平面的左上方和右下方,将两个坐标相加再除2, // 可以得到摄像机的坐标.(不是完全一致.) m_vPos = ( m_vtx[0] + m_vtx[5] ) / 2.0f; // 通过得到的世界坐标制作平截头体平面. // 向量由平截头体内部指向外部的平面. // D3DXPlaneFromPoints(&m_plane[0], m_vtx+4, m_vtx+7, m_vtx+6); // 上平面(top) // D3DXPlaneFromPoints(&m_plane[1], m_vtx , m_vtx+1, m_vtx+2); // 下平面(bottom) // D3DXPlaneFromPoints(&m_plane[2], m_vtx , m_vtx+4, m_vtx+5); // 近平面(near) D3DXPlaneFromPoints(&m_plane[3], m_vtx+2, m_vtx+6, m_vtx+7); // 远平面(far) D3DXPlaneFromPoints(&m_plane[4], m_vtx , m_vtx+3, m_vtx+7); // 左平面(left) D3DXPlaneFromPoints(&m_plane[5], m_vtx+1, m_vtx+5, m_vtx+6); // 右平面(right) return TRUE; }
// 카메라(view) * 프로젝션(projection)행렬을 입력받아 6개의 평면을 만든다. BOOL ZFrustum::Make( D3DXMATRIXA16* pmatViewProj ) { int i; D3DXMATRIXA16 matInv; // 투영행렬까지 거치면 모든 3차원 월드좌표의 점은 (-1,-1,0) ~ (1,1,1)사이의 값으로 바뀐다. // m_vtx에 이 동차공간의 경계값을 넣어둔다. m_vtx[0].x = -1.0f; m_vtx[0].y = -1.0f; m_vtx[0].z = 0.0f; m_vtx[1].x = 1.0f; m_vtx[1].y = -1.0f; m_vtx[1].z = 0.0f; m_vtx[2].x = 1.0f; m_vtx[2].y = -1.0f; m_vtx[2].z = 1.0f; m_vtx[3].x = -1.0f; m_vtx[3].y = -1.0f; m_vtx[3].z = 1.0f; m_vtx[4].x = -1.0f; m_vtx[4].y = 1.0f; m_vtx[4].z = 0.0f; m_vtx[5].x = 1.0f; m_vtx[5].y = 1.0f; m_vtx[5].z = 0.0f; m_vtx[6].x = 1.0f; m_vtx[6].y = 1.0f; m_vtx[6].z = 1.0f; m_vtx[7].x = -1.0f; m_vtx[7].y = 1.0f; m_vtx[7].z = 1.0f; // view * proj의 역행렬을 구한다. D3DXMatrixInverse(&matInv, NULL, pmatViewProj ); // Vertex_최종 = Vertex_local * Matrix_world * Matrix_view * Matrix_Proj 인데, // Vertex_world = Vertex_local * Matrix_world이므로, // Vertex_최종 = Vertex_world * Matrix_view * Matrix_Proj 이다. // Vertex_최종 = Vertex_world * ( Matrix_view * Matrix_Proj ) 에서 // 역행렬( Matrix_view * Matrix_Proj )^-1를 양변에 곱하면 // Vertex_최종 * 역행렬( Matrix_view * Matrix_Proj )^-1 = Vertex_World 가 된다. // 그러므로, m_vtx * matInv = Vertex_world가 되어, 월드좌표계의 프러스텀 좌표를 얻을 수 있다. for( i = 0; i < 8; i++ ) D3DXVec3TransformCoord( &m_vtx[i], &m_vtx[i], &matInv ); // 0번과 5번은 프러스텀중 near평면의 좌측상단과 우측하단이므로, 둘의 좌표를 더해서 2로 나누면 // 카메라의 좌표를 얻을 수 있다.(정확히 일치하는 것은 아니다.) m_vPos = ( m_vtx[0] + m_vtx[5] ) / 2.0f; // 얻어진 월드좌표로 프러스텀 평면을 만든다 // 벡터가 프러스텀 안쪽에서 바깥쪽으로 나가는 평면들이다. // D3DXPlaneFromPoints(&m_plane[0], m_vtx+4, m_vtx+7, m_vtx+6); // 상 평면(top) // D3DXPlaneFromPoints(&m_plane[1], m_vtx , m_vtx+1, m_vtx+2); // 하 평면(bottom) // D3DXPlaneFromPoints(&m_plane[2], m_vtx , m_vtx+4, m_vtx+5); // 근 평면(near) // D3DXPlaneFromPoints(&m_plane[3], m_vtx+2, m_vtx+6, m_vtx+7); // 원 평면(far) D3DXPlaneFromPoints(&m_plane[4], m_vtx , m_vtx+3, m_vtx+7); // 좌 평면(left) D3DXPlaneFromPoints(&m_plane[5], m_vtx+1, m_vtx+5, m_vtx+6); // 우 평면(right) return TRUE; }
//----------------------------------------------------------------------------// void Direct3D10RenderTarget::unprojectPoint(const GeometryBuffer& buff, const Vector2& p_in, Vector2& p_out) const { if (!d_matrixValid) updateMatrix(); const Direct3D10GeometryBuffer& gb = static_cast<const Direct3D10GeometryBuffer&>(buff); D3D10_VIEWPORT vp; setupViewport(vp); D3DXVECTOR3 in_vec; in_vec.z = 0.0f; // project points to create a plane orientated with GeometryBuffer's data D3DXVECTOR3 p1; D3DXVECTOR3 p2; D3DXVECTOR3 p3; in_vec.x = 0; in_vec.y = 0; D3DXVec3Project(&p1, &in_vec, &vp, &d_matrix, 0, gb.getMatrix()); in_vec.x = 1; in_vec.y = 0; D3DXVec3Project(&p2, &in_vec, &vp, &d_matrix, 0, gb.getMatrix()); in_vec.x = 0; in_vec.y = 1; D3DXVec3Project(&p3, &in_vec, &vp, &d_matrix, 0, gb.getMatrix()); // create plane from projected points D3DXPLANE surface_plane; D3DXPlaneFromPoints(&surface_plane, &p1, &p2, &p3); // unproject ends of ray in_vec.x = vp.Width * 0.5f; in_vec.y = vp.Height * 0.5f; in_vec.z = -d_viewDistance; D3DXVECTOR3 t1; D3DXVec3Unproject(&t1, &in_vec, &vp, &d_matrix, 0, gb.getMatrix()); in_vec.x = p_in.d_x; in_vec.y = p_in.d_y; in_vec.z = 0.0f; D3DXVECTOR3 t2; D3DXVec3Unproject(&t2, &in_vec, &vp, &d_matrix, 0, gb.getMatrix()); // get intersection of ray and plane D3DXVECTOR3 intersect; D3DXPlaneIntersectLine(&intersect, &surface_plane, &t1, &t2); p_out.d_x = intersect.x; p_out.d_y = intersect.y; }
PRIVATE void _ModelComputeNormPlane(D3DXPLANE *plane, gfxVtx *vtx1, gfxVtx *vtx2, gfxVtx *vtx3) { //create a plane and store it to first index to plane buffer D3DXVECTOR3 v1(vtx1->x,vtx1->y,vtx1->z); D3DXVECTOR3 v2(vtx2->x,vtx2->y,vtx2->z); D3DXVECTOR3 v3(vtx3->x,vtx3->y,vtx3->z); D3DXPlaneFromPoints(plane, &v1, &v2, &v3); D3DXPlaneNormalize(plane, plane); }
PRIVATE RETCODE _MapSetCel(gfxCel *cel, const gfxVtx *theVtx) { cel->numVtx = NUMPTQUAD; if(_GFXCheckError(g_p3DDevice->CreateVertexBuffer(sizeof(gfxVtx)*cel->numVtx, D3DUSAGE_DYNAMIC, GFXVERTEXFLAG, D3DPOOL_DEFAULT, &cel->vtx, 0), true, "Error in _MapSetCel")) return RETCODE_FAILURE; //fill 'er up gfxVtx *pVtx; D3DXPLANE planeOne, planeTwo; if(SUCCEEDED(cel->vtx->Lock(0,0, (void**)&pVtx, D3DLOCK_DISCARD))) { memcpy(pVtx, theVtx, sizeof(gfxVtx)*cel->numVtx); D3DXPlaneFromPoints(&planeOne, &D3DXVECTOR3(pVtx[0].x,pVtx[0].y,pVtx[0].z), &D3DXVECTOR3(pVtx[1].x,pVtx[1].y,pVtx[1].z), &D3DXVECTOR3(pVtx[2].x,pVtx[2].y,pVtx[2].z)); D3DXPlaneFromPoints(&planeTwo, &D3DXVECTOR3(pVtx[2].x,pVtx[2].y,pVtx[2].z), &D3DXVECTOR3(pVtx[3].x,pVtx[3].y,pVtx[3].z), &D3DXVECTOR3(pVtx[0].x,pVtx[0].y,pVtx[0].z)); cel->plane[0][ePA] = planeOne.a; cel->plane[1][ePA] = planeTwo.a; cel->plane[0][ePB] = planeOne.b; cel->plane[1][ePB] = planeTwo.b; cel->plane[0][ePC] = planeOne.c; cel->plane[1][ePC] = planeTwo.c; cel->plane[0][ePD] = planeOne.d; cel->plane[1][ePD] = planeTwo.d; pVtx[2].nX = pVtx[0].nX = (planeOne.a + planeTwo.a)/2; pVtx[1].nX = planeOne.a; pVtx[3].nX = planeTwo.a; pVtx[2].nY = pVtx[0].nY = (planeOne.b + planeTwo.b)/2; pVtx[1].nY = planeOne.b; pVtx[3].nY = planeTwo.b; pVtx[2].nZ = pVtx[0].nZ = (planeOne.c + planeTwo.c)/2; pVtx[1].nZ = planeOne.c; pVtx[3].nZ = planeTwo.c; cel->vtx->Unlock(); } return RETCODE_SUCCESS; }
BOOL ZBspFace::MakePlane( BSPVERTEX* pV, int n ) { if( n < 3 ) return FALSE; D3DXPlaneFromPoints( &m_plane, (D3DXVECTOR3*)pV, (D3DXVECTOR3*)(pV+1), (D3DXVECTOR3*)(pV+2) ); m_pVerts = pV; m_nVertCount = n; return TRUE; }
void FieldSector::generateHeights() { if(m_heights) return; m_heights = new D3DXFLOAT16[g_grassSectorSize * g_grassSectorSize]; TerrainVertex *terrainVertices = core.game->getWorld()->getTerrainManager()->m_vertices; int terrainWidth = core.game->getWorld()->getTerrainManager()->m_size; float coordinatesModifier = g_grassTileSize / core.game->getWorld()->getTerrainManager()->m_hmGeoStep; for(int y = 0; y < g_grassSectorSize; y++) { for(int x = 0; x < g_grassSectorSize; x++) { float terrainGrassProportion = g_grassTileSize / core.game->getWorld()->getTerrainManager()->m_hmGeoStep; //terrainGrassProportion = 0.5f; /// filling heightmap with data up D3DXPLANE plane; int X = x + m_posX; int Y = y + m_posY; Vec3 p1 = terrainVertices[(int)(Y*terrainGrassProportion)*terrainWidth+(int)(X*terrainGrassProportion)].pos; Vec3 p2 = terrainVertices[(int)((Y*terrainGrassProportion)+1)*terrainWidth+(int)(X*terrainGrassProportion)].pos; Vec3 p3 = terrainVertices[(int)(Y*terrainGrassProportion)*terrainWidth+(int)(X*terrainGrassProportion)+1].pos; Vec3 p4 = terrainVertices[(int)(Y*terrainGrassProportion+1)*terrainWidth+(int)(X*terrainGrassProportion)+1].pos; Vec3 resultPos; Vec3 upPoint = Vec3((X)*g_grassTileSize, 2000, (Y)*g_grassTileSize); Vec3 downPoint = Vec3((X)*g_grassTileSize, -2000, (Y)*g_grassTileSize); f32 pU, pV, pDist; if(D3DXIntersectTri(&p1, &p2, &p3, &upPoint, &Vec3(0,-1,0), &pU, &pV, &pDist)) D3DXPlaneFromPoints(&plane, &p1, &p2, &p3); else if(D3DXIntersectTri(&p2, &p3, &p4, &upPoint, &Vec3(0,-1,0), &pU, &pV, &pDist)) D3DXPlaneFromPoints(&plane, &p2, &p3, &p4); D3DXPlaneIntersectLine(&resultPos, &plane, &upPoint, &downPoint); D3DXFloat32To16Array(&m_heights[y * g_grassSectorSize + x], &resultPos.y, 1); } } }
// 카메라에 따라 occlusion의 평면을 갱신한다. void ROcclusionList::UpdateCamera(rmatrix &matWorld,rvector &cameraPos) { // TODO : matWorld 가 identity 가 아닌경우 검증이 안되어있음 float fDet; rmatrix invWorld; D3DXMatrixInverse(&invWorld,&fDet,&matWorld); // camera 의 좌표를 local로 가져온다 rvector localCameraPos; D3DXVec3TransformCoord(&localCameraPos,&cameraPos,&invWorld); rmatrix trInvMat; D3DXMatrixTranspose(&trInvMat, &invWorld); for(ROcclusionList::iterator i=begin();i!=end();i++) { ROcclusion *poc=*i; bool bm_pPositive=D3DXPlaneDotCoord(&poc->plane,&localCameraPos)>0; // 로컬의 평면의 방정식을 월드로 가져가고 싶다. matWorld 로 변환하면되는데, // D3DXPlaneTransform 의 사용법이 변환행렬의 inverse transpose 매트릭스를 넘겨줘야하므로 // tr(inv(matWorld)) 가 되므로 결국 tr(mat) 가 된다 D3DXPlaneTransform(poc->pPlanes,poc->pPlanes,&trInvMat); poc->pPlanes[0] = bm_pPositive ? poc->plane : -poc->plane; for(int j=0;j<poc->nCount;j++) { if(bm_pPositive) D3DXPlaneFromPoints(poc->pPlanes+j+1,&poc->pVertices[j],&poc->pVertices[(j+1)%poc->nCount],&localCameraPos); else D3DXPlaneFromPoints(poc->pPlanes+j+1,&poc->pVertices[(j+1)%poc->nCount],&poc->pVertices[j],&localCameraPos); // 로컬의 평면의 방정식을 월드로 가져가고 싶다. 위와 같다 D3DXPlaneTransform(poc->pPlanes+j+1,poc->pPlanes+j+1,&trInvMat); } } }
void ZMakePlane( D3DXPLANE* pPlane, D3DXVECTOR3* pv0, D3DXVECTOR3* pv1, D3DXVECTOR3* pv2 ) { D3DXPlaneFromPoints( pPlane, pv0, pv1, pv2 ); // 直接求取平面方程式的源代码 // for OpenGL // D3DXVECTOR3 v0, v1, v2; // v1 = *pv1 - *pv0; // v2 = *pv2 - *pv0; // D3DXVec3Cross( &v0, &v1, &v2 ); // D3DXVec3Normalize( &v0, &v0 ); // pPlane->a = v0.x; // pPlane->b = v0.y; // pPlane->c = v0.z; // pPlane->d = -( v0.x * pv0->x + v0.y * pv0->y + v0.z * pv0->z ); }
/*------------------------------------------------------------------------------* | <<< メッシュが視錐台の中にあるかチェック >>> | 入力 pHit = メッシュのヒットワーク | mWorld = メッシュのワールド座標 | 戻り値 0 : 視錐台の中 | 1 : 一部分が切れている | 2 : 視錐台の外 *------------------------------------------------------------------------------*/ int d3_frustum_hit_check(D3_HIT *pHit, MTX *mWorld) { for(int i = 0; i < 8; i++) D3DXVec3TransformCoord(&pHit->vecWorld[i], &pHit->vecLocal[i], mWorld); pHit->vecWorld[8].x = mWorld->_41; // バウンディングボックスの中心点 pHit->vecWorld[8].y = mWorld->_42; pHit->vecWorld[8].z = mWorld->_43; //--- 面の作成 -------------------------------------------------- D3DXPlaneFromPoints(&pHit->planeWorld[0], &pHit->vecWorld[0], &pHit->vecWorld[1], &pHit->vecWorld[2]); // Near D3DXPlaneFromPoints(&pHit->planeWorld[1], &pHit->vecWorld[6], &pHit->vecWorld[7], &pHit->vecWorld[5]); // Far D3DXPlaneFromPoints(&pHit->planeWorld[2], &pHit->vecWorld[2], &pHit->vecWorld[6], &pHit->vecWorld[4]); // Left D3DXPlaneFromPoints(&pHit->planeWorld[3], &pHit->vecWorld[7], &pHit->vecWorld[3], &pHit->vecWorld[5]); // Right D3DXPlaneFromPoints(&pHit->planeWorld[4], &pHit->vecWorld[2], &pHit->vecWorld[3], &pHit->vecWorld[6]); // Top D3DXPlaneFromPoints(&pHit->planeWorld[5], &pHit->vecWorld[1], &pHit->vecWorld[0], &pHit->vecWorld[4]); // Bottom //--------------------------------------------------------------- WORD bOutside[8]; int out = 0; ZeroMemory(&bOutside, sizeof(bOutside)); // bitfieldの中の6つの円錐台平面、および結果(1の場合、外部) // すべてに対するチェック境界頂点 float aa[8]; for(int iPoint = 0; iPoint < 8; iPoint++) { for(int iPlane = 0; iPlane < 6; iPlane++) { aa[iPoint] = d3.planeFrustum[iPlane].a * pHit->vecWorld[iPoint].x + d3.planeFrustum[iPlane].b * pHit->vecWorld[iPoint].y + d3.planeFrustum[iPlane].c * pHit->vecWorld[iPoint].z + d3.planeFrustum[iPlane].d; if(d3.planeFrustum[iPlane].a * pHit->vecWorld[iPoint].x + d3.planeFrustum[iPlane].b * pHit->vecWorld[iPoint].y + d3.planeFrustum[iPlane].c * pHit->vecWorld[iPoint].z + d3.planeFrustum[iPlane].d < 0) { bOutside[iPoint] |= (1 << iPlane); out++; } } } if(out == 0){ return 0;} if((bOutside[0] & bOutside[1] & bOutside[2] & bOutside[3] & bOutside[4] & bOutside[5] & bOutside[6] & bOutside[7]) != 0) { return 2; } return 1; }
/*------------------------------------------------------------------------------* | <<< 立方体の八頂点が視錐台の中にあるかチェック >>> | 入力 apvecPos = 立方体の八頂点 | mtxWorld = メッシュのワールド座標 | 戻り値 0 : 視錐台の中 | 1 : 一部分が切れている | 2 : 視錐台の外 *------------------------------------------------------------------------------*/ int d3_frustum_hit_check(VEC3 *apvecPos, MTX *mtxWorld) { //--- 立方体の八頂点をトランスフォーム -------------------------- VEC3 avecP[8]; for(int i = 0; i < 8; i++) D3DXVec3TransformCoord(&avecP[i], &apvecPos[i], mtxWorld); //--- 箱の定義 -------------------------------------------------- D3DXPLANE planeWorld[6]; D3DXPlaneFromPoints(&planeWorld[0], &avecP[0], &avecP[1], &avecP[2]); // Near D3DXPlaneFromPoints(&planeWorld[1], &avecP[6], &avecP[7], &avecP[5]); // Far D3DXPlaneFromPoints(&planeWorld[2], &avecP[2], &avecP[6], &avecP[4]); // Left D3DXPlaneFromPoints(&planeWorld[3], &avecP[7], &avecP[3], &avecP[5]); // Right D3DXPlaneFromPoints(&planeWorld[4], &avecP[2], &avecP[3], &avecP[6]); // Top D3DXPlaneFromPoints(&planeWorld[5], &avecP[1], &avecP[0], &avecP[4]); // Bottom //--- 判定 ------------------------------------------------------ WORD adwOut[8]; int iOut = 0; ZeroMemory(&adwOut, sizeof(adwOut)); // bitfieldの中の6つの円錐台平面、および結果(1の場合、外部) // すべてに対するチェック境界頂点 //float aa[8]; for(int iPoint = 0; iPoint < 8; iPoint++) { for(int iPlane = 0; iPlane < 6; iPlane++) { /* aa[iPoint] = d3.planeFrustum[iPlane].a * avecP[iPoint].x + d3.planeFrustum[iPlane].b * avecP[iPoint].y + d3.planeFrustum[iPlane].c * avecP[iPoint].z + d3.planeFrustum[iPlane].d; */ if(d3.planeFrustum[iPlane].a * avecP[iPoint].x + d3.planeFrustum[iPlane].b * avecP[iPoint].y + d3.planeFrustum[iPlane].c * avecP[iPoint].z + d3.planeFrustum[iPlane].d < 0) { adwOut[iPoint] |= (1 << iPlane); iOut++; } } } if(iOut == 0){ return 0;} if((adwOut[0] & adwOut[1] & adwOut[2] & adwOut[3] & adwOut[4] & adwOut[5] & adwOut[6] & adwOut[7]) != 0) { return 2;} return 1; }
bool AVFrustum::Make( D3DXMATRIXA16 *viewProjection ) { int i; D3DXMATRIXA16 matInv; m_planeVertex[0].x = -1.0f; m_planeVertex[0].y = -1.0f; m_planeVertex[0].z = 0.0f; m_planeVertex[1].x = 1.0f; m_planeVertex[1].y = -1.0f; m_planeVertex[1].z = 0.0f; m_planeVertex[2].x = 1.0f; m_planeVertex[2].y = -1.0f; m_planeVertex[2].z = 1.0f; m_planeVertex[3].x = -1.0f; m_planeVertex[3].y = -1.0f; m_planeVertex[3].z = 1.0f; m_planeVertex[4].x = -1.0f; m_planeVertex[4].y = 1.0f; m_planeVertex[4].z = 0.0f; m_planeVertex[5].x = 1.0f; m_planeVertex[5].y = 1.0f; m_planeVertex[5].z = 0.0f; m_planeVertex[6].x = 1.0f; m_planeVertex[6].y = 1.0f; m_planeVertex[6].z = 1.0f; m_planeVertex[7].x = -1.0f; m_planeVertex[7].y = 1.0f; m_planeVertex[7].z = 1.0f; D3DXMatrixInverse(&matInv, NULL, viewProjection ); for( i = 0; i < 8; i++ ) D3DXVec3TransformCoord( &m_planeVertex[i], &m_planeVertex[i], &matInv ); m_vPosition = ( m_planeVertex[0] + m_planeVertex[5] ) / 2.0f; // 얻어진 월드좌표로 프러스텀 평면을 만든다 // 벡터가 프러스텀 안쪽에서 바깥쪽으로 나가는 평면들이다. D3DXPlaneFromPoints(&m_plane[0], m_planeVertex+4, m_planeVertex+7, m_planeVertex+6); // 상 평면(top) D3DXPlaneFromPoints(&m_plane[1], m_planeVertex , m_planeVertex+1, m_planeVertex+2); // 하 평면(bottom) D3DXPlaneFromPoints(&m_plane[2], m_planeVertex , m_planeVertex+4, m_planeVertex+5); // 근 평면(near) D3DXPlaneFromPoints(&m_plane[3], m_planeVertex+2, m_planeVertex+6, m_planeVertex+7); // 원 평면(far) D3DXPlaneFromPoints(&m_plane[4], m_planeVertex , m_planeVertex+3, m_planeVertex+7); // 좌 평면(left) D3DXPlaneFromPoints(&m_plane[5], m_planeVertex+1, m_planeVertex+5, m_planeVertex+6); // 우 평면(right) return TRUE; }
TEST( Plane, setFromPoints ) { Plane tamyPlane; D3DXPLANE dxPlane; Vector ptA, ptB, ptC; ptA.set( 0, 0, 0 ); ptB.set( 10, 0, 0 ); ptC.set( 0, 10, 0 ); D3DXPlaneFromPoints( &dxPlane, ( const D3DXVECTOR3* )&ptA, ( const D3DXVECTOR3* )&ptB, ( const D3DXVECTOR3* )&ptC ); tamyPlane.setFromPoints( ptA, ptB, ptC ); COMPARE_PLANE( dxPlane, tamyPlane ); ptA.set( 0, 0, 0 ); ptB.set( 10, 0, 0 ); ptC.set( 0, 0, 10 ); D3DXPlaneFromPoints( &dxPlane, ( const D3DXVECTOR3* )&ptA, ( const D3DXVECTOR3* )&ptB, ( const D3DXVECTOR3* )&ptC ); tamyPlane.setFromPoints( ptA, ptB, ptC ); COMPARE_PLANE( dxPlane, tamyPlane ); ptA.set( 0, 0, 0 ); ptB.set( 0, 10, 0 ); ptC.set( 0, 0, 10 ); D3DXPlaneFromPoints( &dxPlane, ( const D3DXVECTOR3* )&ptA, ( const D3DXVECTOR3* )&ptB, ( const D3DXVECTOR3* )&ptC ); tamyPlane.setFromPoints( ptA, ptB, ptC ); COMPARE_PLANE( dxPlane, tamyPlane ); ptA.set( 0, 0, 0 ); ptB.set( 3, 0, 0 ); ptC.set( 0, -4, 0 ); D3DXPlaneFromPoints( &dxPlane, ( const D3DXVECTOR3* )&ptA, ( const D3DXVECTOR3* )&ptB, ( const D3DXVECTOR3* )&ptC ); tamyPlane.setFromPoints( ptA, ptB, ptC ); COMPARE_PLANE( dxPlane, tamyPlane ); ptA.set( 0, 0, 0 ); ptB.set( -10, 0, 0 ); ptC.set( 0, 0, -5 ); D3DXPlaneFromPoints( &dxPlane, ( const D3DXVECTOR3* )&ptA, ( const D3DXVECTOR3* )&ptB, ( const D3DXVECTOR3* )&ptC ); tamyPlane.setFromPoints( ptA, ptB, ptC ); COMPARE_PLANE( dxPlane, tamyPlane ); ptA.set( 0, 0, 0 ); ptB.set( 0, -10, 0 ); ptC.set( 0, 0, -10 ); D3DXPlaneFromPoints( &dxPlane, ( const D3DXVECTOR3* )&ptA, ( const D3DXVECTOR3* )&ptB, ( const D3DXVECTOR3* )&ptC ); tamyPlane.setFromPoints( ptA, ptB, ptC ); COMPARE_PLANE( dxPlane, tamyPlane ); ptA.set( 20, 3, -4 ); ptB.set( 5, -10, 1 ); ptC.set( 2, -1, -10 ); D3DXPlaneFromPoints( &dxPlane, ( const D3DXVECTOR3* )&ptA, ( const D3DXVECTOR3* )&ptB, ( const D3DXVECTOR3* )&ptC ); tamyPlane.setFromPoints( ptA, ptB, ptC ); COMPARE_PLANE( dxPlane, tamyPlane ); }
// 输入摄像机投影矩阵,得到6个平面 bool ZFrustum::Make(D3DXMATRIX* pmatViewProj,float fEpsilon) { m_fEpsilon = fEpsilon; int i; D3DXMATRIX matInv; m_vtx[0].x = -1.0f; m_vtx[0].y = -1.0f; m_vtx[0].z = 0.0f; m_vtx[1].x = 1.0f; m_vtx[1].y = -1.0f; m_vtx[1].z = 0.0f; m_vtx[2].x = 1.0f; m_vtx[2].y = -1.0f; m_vtx[2].z = 1.0f; m_vtx[3].x = -1.0f; m_vtx[3].y = -1.0f; m_vtx[3].z = 1.0f; m_vtx[4].x = -1.0f; m_vtx[4].y = 1.0f; m_vtx[4].z = 0.0f; m_vtx[5].x = 1.0f; m_vtx[5].y = 1.0f; m_vtx[5].z = 0.0f; m_vtx[6].x = 1.0f; m_vtx[6].y = 1.0f; m_vtx[6].z = 1.0f; m_vtx[7].x = -1.0f; m_vtx[7].y = 1.0f; m_vtx[7].z = 1.0f; // 求得view*proj的逆矩阵 D3DXMatrixInverse(&matInv,NULL,pmatViewProj); // 将8个顶点转换到世界空间 for (i = 0;i < 8;i++) { D3DXVec3TransformCoord(&m_vtx[i],&m_vtx[i],&matInv); D3DXVECTOR3 v = m_vtx[i]; } // 求出摄像机的大致坐标(近裁截面中心,非准确摄像机位置) m_vPos = (m_vtx[0] + m_vtx[5]) / 2.0f; // 通过8个顶点的世界坐标,制作平截台体平面,法线方向向外 // top D3DXPlaneFromPoints(&m_plane[0],m_vtx + 4,m_vtx + 7,m_vtx + 6); // bottom D3DXPlaneFromPoints(&m_plane[1],m_vtx,m_vtx + 1,m_vtx + 2); // near D3DXPlaneFromPoints(&m_plane[2],m_vtx,m_vtx + 4,m_vtx + 5); // far D3DXPlaneFromPoints(&m_plane[3],m_vtx + 2,m_vtx + 6,m_vtx + 7); // left D3DXPlaneFromPoints(&m_plane[4],m_vtx,m_vtx + 3,m_vtx + 7); // right D3DXPlaneFromPoints(&m_plane[5],m_vtx + 1,m_vtx + 5,m_vtx + 6); return true; }
void CBoundBox::CalculatePlanes() { D3DXPlaneFromPoints( m_pPlaneTop, &m_vertices[4], &m_vertices[5], &m_vertices[6] ); D3DXPlaneFromPoints( m_pPlaneBottom, &m_vertices[12], &m_vertices[13], &m_vertices[14] ); D3DXPlaneFromPoints( m_pPlaneSides[0],&m_vertices[0], &m_vertices[1], &m_vertices[2] ); // 后面 D3DXPlaneFromPoints( m_pPlaneSides[1],&m_vertices[8], &m_vertices[9], &m_vertices[10] );// 前面 D3DXPlaneFromPoints( m_pPlaneSides[2],&m_vertices[16], &m_vertices[17], &m_vertices[18] );// 角色左面 D3DXPlaneFromPoints( m_pPlaneSides[3],&m_vertices[20], &m_vertices[21], &m_vertices[22] );// 角色右面 // 更新真实顶点 memcpy( m_pTrueVertices[0], m_vertices[4], sizeof(D3DXVECTOR3) ); memcpy( m_pTrueVertices[1], m_vertices[5], sizeof(D3DXVECTOR3) ); memcpy( m_pTrueVertices[2], m_vertices[6], sizeof(D3DXVECTOR3) ); memcpy( m_pTrueVertices[3], m_vertices[8], sizeof(D3DXVECTOR3) ); memcpy( m_pTrueVertices[4], m_vertices[12], sizeof(D3DXVECTOR3) ); memcpy( m_pTrueVertices[5], m_vertices[13], sizeof(D3DXVECTOR3) ); memcpy( m_pTrueVertices[6], m_vertices[14], sizeof(D3DXVECTOR3) ); memcpy( m_pTrueVertices[7], m_vertices[10], sizeof(D3DXVECTOR3) ); }
/*----------------------------------------------------------------------* | <<< 視錘台の初期化 >>> | ※カメラが動くならば、毎周期実行のこと *----------------------------------------------------------------------*/ void d3_frustum_init(void) { MTX mat; D3DXMatrixInverse(&mat, NULL, &d3.mtxViewProjection); d3.vecFrustum[0] = VEC3(-1.0f, -1.0f, 0.0f); // xyz d3.vecFrustum[1] = VEC3( 1.0f, -1.0f, 0.0f); // Xyz d3.vecFrustum[2] = VEC3(-1.0f, 1.0f, 0.0f); // xYz d3.vecFrustum[3] = VEC3( 1.0f, 1.0f, 0.0f); // XYz d3.vecFrustum[4] = VEC3(-1.0f, -1.0f, 1.0f); // xyZ d3.vecFrustum[5] = VEC3( 1.0f, -1.0f, 1.0f); // XyZ d3.vecFrustum[6] = VEC3(-1.0f, 1.0f, 1.0f); // xYZ d3.vecFrustum[7] = VEC3( 1.0f, 1.0f, 1.0f); // XYZ for(int i = 0; i < 8; i++){ D3DXVec3TransformCoord(&d3.vecFrustum[i], &d3.vecFrustum[i], &mat);} // 視錘台用の平面式を作る D3DXPlaneFromPoints(&d3.planeFrustum[0], &d3.vecFrustum[0], &d3.vecFrustum[1], &d3.vecFrustum[2]); // Near D3DXPlaneFromPoints(&d3.planeFrustum[1], &d3.vecFrustum[6], &d3.vecFrustum[7], &d3.vecFrustum[5]); // Far D3DXPlaneFromPoints(&d3.planeFrustum[2], &d3.vecFrustum[2], &d3.vecFrustum[6], &d3.vecFrustum[4]); // Left D3DXPlaneFromPoints(&d3.planeFrustum[3], &d3.vecFrustum[7], &d3.vecFrustum[3], &d3.vecFrustum[5]); // Right D3DXPlaneFromPoints(&d3.planeFrustum[4], &d3.vecFrustum[2], &d3.vecFrustum[3], &d3.vecFrustum[6]); // Top D3DXPlaneFromPoints(&d3.planeFrustum[5], &d3.vecFrustum[1], &d3.vecFrustum[0], &d3.vecFrustum[4]); // Bottom }
//HRESULT KModelBelt::UpdateAtRest(SRCLINE Line) HRESULT KModelBelt::AddLine(SRCLINE Line) { // SRCLINE LineA = Line; // SRCLINE LineB = m_SrcLineList.front(); // D3DXVECTOR3 Dist = D3DXVECTOR3(0,9.8f,0); // D3DXVECTOR3 Dist = D3DXVECTOR3(5.0f,9.8f,5.0f); D3DXVECTOR3 Dist = D3DXVECTOR3(0,0,0); if(m_bShowWind) { Dist = m_Gravity + m_WindForce; } else { Dist = m_Gravity; } // Dist = D3DXVECTOR3(0,0,0); //D3DXVec3Length(&Dist) 值不能为0 if( D3DXVec3Length(&Dist) > 1.0f ) { list<SRCLINE>::iterator i = m_SrcLineList.begin(); //本代码段用于生成正弦波 if(( i != m_SrcLineList.end() )&&(m_bShowSin)) { SRCLINE LineA = *i; D3DXVECTOR3 Dist1 = Dist + LineA.A; D3DXPLANE plane1; D3DXPlaneFromPoints(&plane1, &LineA.A, &LineA.B, &Dist1 ); D3DXVECTOR3 N; N.x = plane1.a; N.y = plane1.b; N.z = plane1.c; D3DXVec3Normalize(&N,&N); float fSwing = 3.0f; float fCyc = m_fCyc * 0.0001f; fSwing = m_fSwing * 0.1f; (*i).A += fSwing*sinf(timeGetTime() * fCyc) * N; (*i).B += fSwing*sinf(timeGetTime() * fCyc) * N; } while ( i != m_SrcLineList.end() ) { // SRCLINE LineX = *i; (*i).A -= Dist; (*i).B -= Dist; i++; } } else return E_FAIL; m_SrcLineList.push_front(Line); if( (int)m_SrcLineList.size() > m_nListMaxSize ) { m_SrcLineList.pop_back(); } return S_OK; }
void cMainGame::Render(){ D3DXMATRIXA16 matRot, matWorld; g_pD3DDevice->Clear( NULL, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, //D3DCOLOR_XRGB(47, 121, 112), D3DCOLOR_XRGB(0, 0, 0), 1.0f, 0); g_pD3DDevice->BeginScene(); g_pD3DDevice->SetRenderState(D3DRS_LIGHTING, false); m_pPyramid->render(); m_cAxis->render(); m_cGrid->render(); D3DXMATRIXA16 mat; D3DXMatrixIdentity(&mat); g_pD3DDevice->SetTransform(D3DTS_WORLD, &mat); g_pD3DDevice->SetRenderState(D3DRS_LIGHTING, true); //typedef struct _D3DVIEWPORT9 { // DWORD X; // DWORD Y; /* Viewport Top left */ // DWORD Width; // DWORD Height; /* Viewport Dimensions */ // float MinZ; /* Min/max of clip Volume */ // float MaxZ; //} D3DVIEWPORT9; D3DVIEWPORT9 vp; g_pD3DDevice->GetViewport(&vp); std::vector<D3DXVECTOR3> vecfrusmtom(8); vecfrusmtom[0] = D3DXVECTOR3(-1.0f, -1.0f, 0.0f); vecfrusmtom[1] = D3DXVECTOR3(1.0f, -1.0f, 0.0f); vecfrusmtom[2] = D3DXVECTOR3(-1.0f, 1.0f, 0.0f); vecfrusmtom[3] = D3DXVECTOR3(1.0f, 1.0f, 0.0f); vecfrusmtom[4] = D3DXVECTOR3(-1.0f, -1.0f, 1.0f); vecfrusmtom[5] = D3DXVECTOR3(1.0f, -1.0f, 1.0f); vecfrusmtom[6] = D3DXVECTOR3(-1.0f, 1.0f, 1.0f); vecfrusmtom[7] = D3DXVECTOR3(1.0f, 1.0f, 1.0f); // //std::vector<D3DXVECTOR3> vecWorldVertex(8); //for (size_t i = 0; i < 8; ++i){ // D3DXVec3Unproject( // &vecWorldVertex[i], // &m_vecProjVertex[i], // NULL, // &matProj, // &matWorld) //} //std::vector<D3DXVECTOR3> frustom; // //frustom.push_back(); //frustom.push_back(); //frustom.push_back(); //frustom.push_back(); //frustom.push_back(); //frustom.push_back(); // /// if (GetAsyncKeyState(VK_SPACE)){ D3DXMATRIXA16 invProj; g_pD3DDevice->GetTransform(D3DTS_PROJECTION, &invProj); D3DXMatrixInverse(&invProj, NULL, &invProj); D3DXMATRIXA16 invView; g_pD3DDevice->GetTransform(D3DTS_VIEW, &invView); D3DXMatrixInverse(&invView, NULL, &invView); D3DXMATRIXA16 world; world = invProj * invView; for (size_t i = 0; i < vecfrusmtom.size(); i++){ D3DXVec3TransformCoord(&vecfrusmtom[i], &vecfrusmtom[i], &world); } std::vector<D3DXPLANE> vecPlanes(6); D3DXPlaneFromPoints(&vecPlanes[0], &vecfrusmtom[0], &vecfrusmtom[1], &vecfrusmtom[2]); // near D3DXPlaneFromPoints(&vecPlanes[1], &vecfrusmtom[6], &vecfrusmtom[7], &vecfrusmtom[5]); // far D3DXPlaneFromPoints(&vecPlanes[2], &vecfrusmtom[2], &vecfrusmtom[6], &vecfrusmtom[4]); // left D3DXPlaneFromPoints(&vecPlanes[3], &vecfrusmtom[7], &vecfrusmtom[3], &vecfrusmtom[5]); // right D3DXPlaneFromPoints(&vecPlanes[4], &vecfrusmtom[2], &vecfrusmtom[3], &vecfrusmtom[6]); // top D3DXPlaneFromPoints(&vecPlanes[5], &vecfrusmtom[1], &vecfrusmtom[0], &vecfrusmtom[4]); // bottom for (auto p : m_vecSpheres){ D3DXVECTOR3 pos = p->GetTransform()->GetPosition(); float a = p->GetRadius(); if (D3DXPlaneDotCoord(&vecPlanes[0], &pos) + a > 0 && D3DXPlaneDotCoord(&vecPlanes[1], &pos) + a > 0 && D3DXPlaneDotCoord(&vecPlanes[2], &pos) + a > 0 && D3DXPlaneDotCoord(&vecPlanes[3], &pos) + a > 0 && D3DXPlaneDotCoord(&vecPlanes[4], &pos) + a > 0 && D3DXPlaneDotCoord(&vecPlanes[5], &pos) + a > 0){ SAFE_RENDER(p); } } } else { for (auto p : m_vecSpheres){ SAFE_RENDER(p); } } g_pD3DDevice->EndScene(); g_pD3DDevice->Present(NULL, NULL, NULL, NULL); }
//----------------------------------------------------------------------------- // 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 ); }
/** * @brief 放大飘带末端的运动 */ HRESULT KModelBelt::UpdateExtend(void) { if( m_SrcLineList.empty() ) return E_FAIL; SRCLINE LineA =m_SrcLineList.front(); D3DXVECTOR3 Dist = D3DXVECTOR3(0,0,0); if(m_bShowWind) { Dist = m_Gravity + m_WindForce; } else { Dist = m_Gravity; } //D3DXVec3Length(&Dist)值不能为0 if( D3DXVec3Length(&Dist) > 1.0f ) { Dist += LineA.A; D3DXPLANE plane1; D3DXPlaneFromPoints(&plane1, &LineA.A, &LineA.B, &Dist ); D3DXVECTOR3 N; N.x = plane1.a; N.y = plane1.b; N.z = plane1.c; D3DXVec3Normalize(&N,&N); list<SRCLINE>::iterator i = m_SrcLineList.begin(); i++; SRCLINE* LineX; D3DXVECTOR3 offset; float kk = 0.001f; kk = m_fExtendNum / 10000.0f; int nStep = 0; while ( i != m_SrcLineList.end() ) { LineX = &(*i); // float jj = nStep*kk; offset = N * D3DXPlaneDotCoord( &plane1, &LineX->A) * kk * (float)nStep; LineX->A += offset; offset = N*D3DXPlaneDotCoord( &plane1, &LineX->B)*kk*(float)nStep; LineX->B +=offset; i++; nStep++; } LineX = NULL; } else return E_FAIL; return S_OK; }
/*------------------------------------------------------------------------------* | <<< 線と直方体の交差判定 >>> | 入力 pStart - pEnd = 線分 | pV0, pV1, pV2 = 三角形それぞれの頂点 | 出力 pOut = 交点出力用 (NULLなら出力しない) | 戻り値 TRUE : 交差した | FALSE : 交差していない *------------------------------------------------------------------------------*/ BOOL d3_collision_line_plane(VEC3 *pOut, VEC3 *pStart, VEC3 *pEnd, VEC3 *pV0, VEC3 *pV1, VEC3 *pV2) { //D3_3DTRI_FILL(pP0, pP1, pP2, D3_COL(255, 255, 0, 255)); VEC3 vecP; VEC3 vecQ; VEC3 vecT; float fDet; float fInvDet; float fT, fU, fV; // 面の作成 D3DXPLANE plane; D3DXPlaneFromPoints(&plane, pV0, pV1, pV2); // 線分の両端がが平面をまたいで存在しているかをチェック float fDist0 = (plane.a * pStart->x) + (plane.b * pStart->y) + (plane.c * pStart->z) + plane.d; float fDist1 = (plane.a * pEnd->x ) + (plane.b * pEnd->y ) + (plane.c * pEnd->z ) + plane.d; if((fDist0 * fDist1) >= 0.0f) return FALSE; //VEC3 Start = VEC3(pStart->x, pStart->y, pStart->z); //VEC3 Dir = VEC3(pEnd->x, pEnd->y, pEnd->z ) - Start; VEC3 vecDir = *pEnd - *pStart; //VEC3 Vx[3]; //Vx[0] = *pP0; //Vx[1] = *pP1; //Vx[2] = *pP2; // Vx[0]を共有する2ベクトルを算出 //VEC3 Edge1 = Vx[1] - Vx[0]; //VEC3 Edge2 = Vx[2] - Vx[0]; VEC3 vecEdge0 = *pV1 - *pV0; VEC3 vecEdge1 = *pV2 - *pV0; // Uパラメーターを計算 D3DXVec3Cross(&vecP, &vecDir, &vecEdge1); // 内積が0に近い場合は三角形の平面にある fDet = D3DXVec3Dot(&vecEdge0, &vecP); //if(fDet > 0) vecT = Start - Vx[0]; if(fDet > 0) vecT = *pStart - *pV0; //else vecT = Vx[0] - Start, fDet = -fDet; else vecT = *pV0 - *pStart, fDet = -fDet; if(fDet < 0.0001f) return FALSE; // Uパラメーターおよびテスト境界を計算 fU = D3DXVec3Dot(&vecT, &vecP); if((fU < 0.0f) || (fU > fDet)) return FALSE; // Vパラメーターをテストする準備をします D3DXVec3Cross(&vecQ, &vecT, &vecEdge0); // Vパラメーターおよびテスト境界を計算 fV = D3DXVec3Dot(&vecDir, &vecQ); if((fV < 0.0f) || ((fU + fV) > fDet)) return FALSE; // 位置情報を保存 if(pOut != NULL) { // Tを計算し、スケーリング fT = D3DXVec3Dot(&vecEdge1, &vecQ); fInvDet = 1.0f / fDet; fT *= fInvDet; fU *= fInvDet; fV *= fInvDet; //pOut->x = Vx[0].x + (fU * (Vx[1].x - Vx[0].x)) + (fV * (Vx[2].x - Vx[0].x)); //pOut->y = Vx[0].y + (fU * (Vx[1].y - Vx[0].y)) + (fV * (Vx[2].y - Vx[0].y)); //pOut->z = Vx[0].z + (fU * (Vx[1].z - Vx[0].z)) + (fV * (Vx[2].z - Vx[0].z)); pOut->x = pV0->x + (fU * (pV1->x - pV0->x)) + (fV * (pV2->x - pV0->x)); pOut->y = pV0->y + (fU * (pV1->y - pV0->y)) + (fV * (pV2->y - pV0->y)); pOut->z = pV0->z + (fU * (pV1->z - pV0->z)) + (fV * (pV2->z - pV0->z)); } return TRUE; }