void computeBoundarySurface(const Vector4i *pTet, const int ntet, const int nvert, Vector3i *& pTri, int &nTri) { int i; CMemoryMgr* pm = new CMemoryMgr; //malloc the pointer buffer; CTriangleListItem** plist = new CTriangleListItem*[nvert]; assert(plist!=NULL); for (i=0; i<nvert; i++) plist[i]=NULL; //insert triangles into the buffer; for (i=0; i<ntet; i++){ Vector4i t = pTet[i]; const int v0=t.x; const int v1=t.y; const int v2=t.z; const int v3=t.w; Vector3i tri0(v0, v2, v1); Vector3i tri1(v0, v1, v3); Vector3i tri2(v1, v2, v3); Vector3i tri3(v0, v3, v2); _insertTriangle(tri0, plist, *pm); _insertTriangle(tri1, plist, *pm); _insertTriangle(tri2, plist, *pm); _insertTriangle(tri3, plist, *pm); } nTri = _countValidTriangle(plist, nvert); pTri = _collectBoundarySurface(plist, nvert, nTri); delete pm; delete [] plist; }
void D3D11RendererMesh::Pick(DirectX::SimpleMath::Ray ray) { m_bPick = false; mPickedTriangle = -1; XMFLOAT3 Center; // Center of the box. XMFLOAT3 Extents; // Distance from the center to each side. XMStoreFloat3(&Center, 0.5f*(vMin + vMax)); XMStoreFloat3(&Extents, 0.5f*(vMax - vMin)); float tmin = 0.0f; DirectX::BoundingBox box(Center,Extents); if (ray.Intersects(box, tmin)) { tmin = FLT_MAX; for (UINT i = 0; i < indices.size() / 3; ++i) { // Indices for this triangle. UINT i0 = indices[i * 3 + 0]; UINT i1 = indices[i * 3 + 1]; UINT i2 = indices[i * 3 + 2]; // Vertices for this triangle. XMVECTOR v0 = XMLoadFloat3(&vertices[i0].position); XMVECTOR v1 = XMLoadFloat3(&vertices[i1].position); XMVECTOR v2 = XMLoadFloat3(&vertices[i2].position); DirectX::SimpleMath::Vector3 tri0(v0); DirectX::SimpleMath::Vector3 tri1(v1); DirectX::SimpleMath::Vector3 tri2(v2); float t = 0.0f; if (ray.Intersects(tri0, tri1, tri2, t)) { if (t < tmin) { tmin = t; mPickedTriangle = i; m_bPick = true; } } } } }
void computeBoundarySurface(const Vector8i *pTet, const int ntet, const int nvert, Vector4i *& pTri, int &nTri) { int i; CMemoryMgr* pm = new CMemoryMgr; //malloc the pointer buffer; CQuadListItem** plist = new CQuadListItem*[nvert]; assert(plist!=NULL); for (i=0; i<nvert; i++) plist[i]=NULL; //insert triangles into the buffer; for (i=0; i<ntet; i++){ Vector8i t = pTet[i]; const int v0=t.x; const int v1=t.y; const int v2=t.z; const int v3=t.w; const int v4=t.x1; const int v5=t.y1; const int v6=t.z1; const int v7=t.w1; Vector4i tri0(v0, v3, v2, v1); Vector4i tri1(v4, v5, v6, v7); Vector4i tri2(v0, v4, v7, v3); Vector4i tri3(v1, v2, v6, v5); Vector4i tri4(v0, v1, v5, v4); Vector4i tri5(v2, v3, v7, v6); _insertQuad(tri0, plist, *pm); _insertQuad(tri1, plist, *pm); _insertQuad(tri2, plist, *pm); _insertQuad(tri3, plist, *pm); _insertQuad(tri4, plist, *pm); _insertQuad(tri5, plist, *pm); } nTri = _countValidQuad(plist, nvert); pTri = _collectBoundarySurface(plist, nvert, nTri); delete pm; delete [] plist; }
// 背面剔除,裁剪,透视除法 void Renderer::Clipping(const Vector3 &w_min, const Vector3 &w_max) { // assert((rend_primitive_.size % 3) == 0); // (rand_primitive_.size / 3) 向下截断 static const int TRIANGLE_SIZE = 3; for (int i = 0; i < rend_primitive_.size; i += 3) { int vertex_in_cvv = 0; bool vertex_in_ccodes[TRIANGLE_SIZE] = {true, true, true}; for (int j = 0; j < TRIANGLE_SIZE; ++j) { Vector4 &p0 = rend_primitive_.position[i + j]; if (p0.x < w_min.x || p0.x > w_max.x) vertex_in_ccodes[j] = false; if (p0.y < w_min.y || p0.y > w_max.y) vertex_in_ccodes[j] = false; if (p0.z < w_min.z || p0.z > w_max.z) vertex_in_ccodes[j] = false; if (vertex_in_ccodes[j]) { ++vertex_in_cvv; } } Vector4 *vtx = rend_primitive_.position + i; Vector4 *col = rend_primitive_.colors + i; Vector3 a = vtx[0].GetVector3(); Vector3 b = vtx[1].GetVector3(); Vector3 c = vtx[2].GetVector3(); Vector3 n = CrossProduct(b - a, c - b); // FIXME 背面剔除,需确定判断是否正确 if (backface_culling_ && n.z > 0) { continue; } int v0 = 0; int v1 = 1; int v2 = 2; if (vertex_in_cvv == 0) { continue; } else if (vertex_in_cvv == 1) { if (vertex_in_ccodes[0]) { } else if (vertex_in_ccodes[1]) { v0 = 1; v1 = 2; v2 = 0; } else if (vertex_in_ccodes[2]) { v0 = 2; v1 = 0; v2 = 1; } // make v0 is in. v1, v2 is out. // and keep the sequence of triangle. bool ret = false; ret = ClipLine3d(vtx[v0], vtx[v1], w_min, w_max, &vtx[v1]); assert(ret); ret = ClipLine3d(vtx[v0], vtx[v2], w_min, w_max, &vtx[v2]); assert(ret); Triangle tri(vtx[v0], col[v0], vtx[v1], col[v1], vtx[v2], col[v2]); triangles_.push_back(tri); } else if (vertex_in_cvv == 2) { if (!vertex_in_ccodes[0]) { // v0 = 0; v1 = 1; v2 = 2; } else if (!vertex_in_ccodes[1]) { v0 = 1; v1 = 2; v2 = 0; } else if (!vertex_in_ccodes[2]) { v0 = 2; v1 = 0; v2 = 1; } // make v0 is out. v1, v2 is in. // and keep the sequence of triangle. Vector4 m; Vector4 n; bool ret = false; ret = ClipLine3d(vtx[v0], vtx[v1], w_min, w_max, &m); assert(ret); ret = ClipLine3d(vtx[v0], vtx[v2], w_min, w_max, &n); assert(ret); Triangle tri0(m, col[v0], vtx[v1], col[v1], vtx[v2], Vector4(0, 0, 0, 0)); triangles_.push_back(tri0); Triangle tri1(n, col[v0], m, Vector4(0, 0, 0, 0), vtx[v2], col[v2]); triangles_.push_back(tri1); } else if (vertex_in_cvv == 3) { Triangle tri(vtx[v0], col[v0], vtx[v1], col[v1], vtx[v2], col[v2]); triangles_.push_back(tri); } else { assert(0); } } }
void IntrTriangle2Triangle2<Real>::GetIntersection ( const Configuration& cfg0, const Configuration& cfg1, int side, const Vector2<Real> V0[3], const Vector2<Real> V1[3], int& quantity, Vector2<Real> vertex[6]) { Vector2<Real> edge, diff; const Vector2<Real>* origin; Real invEdE, emin, emax; int i; if (side == 1) // V1-interval contacts V0-interval on right. { if (cfg0.Map == M21 || cfg0.Map == M11) { quantity = 1; vertex[0] = V0[cfg0.Index[2]]; } else if (cfg1.Map == M12 || cfg1.Map == M11) { quantity = 1; vertex[0] = V1[cfg1.Index[0]]; } else // cfg0.Map == M12 && cfg1.Map == M21 (edge overlap). { origin = &V0[cfg0.Index[1]]; edge = V0[cfg0.Index[2]] - *origin; invEdE = ((Real)1)/edge.Dot(edge); diff = V1[cfg1.Index[1]] - *origin; emin = edge.Dot(diff)*invEdE; diff = V1[cfg1.Index[0]] - *origin; emax = edge.Dot(diff)*invEdE; assertion(emin <= emax, "Unexpected condition\n"); Intersector1<Real> intr((Real)0, (Real)1, emin, emax); quantity = intr.GetNumIntersections(); assertion(quantity > 0, "Unexpected condition\n"); for (i = 0; i < quantity; ++i) { vertex[i] = *origin + intr.GetIntersection(i)*edge; } } } else if (side == -1) // V1-interval contacts V0-interval on left. { if (cfg1.Map == M21 || cfg1.Map == M11) { quantity = 1; vertex[0] = V1[cfg1.Index[2]]; } else if (cfg0.Map == M12 || cfg0.Map == M11) { quantity = 1; vertex[0] = V0[cfg0.Index[0]]; } else // cfg1.Map == M12 && cfg0.Map == M21 (edge overlap). { origin = &V1[cfg1.Index[1]]; edge = V1[cfg1.Index[2]] - *origin; invEdE = ((Real)1)/edge.Dot(edge); diff = V0[cfg0.Index[1]] - *origin; emin = edge.Dot(diff)*invEdE; diff = V0[cfg0.Index[0]] - *origin; emax = edge.Dot(diff)*invEdE; assertion(emin <= emax, "Unexpected condition\n"); Intersector1<Real> intr((Real)0, (Real)1, emin, emax); quantity = intr.GetNumIntersections(); assertion(quantity > 0, "Unexpected condition\n"); for (i = 0; i < quantity; ++i) { vertex[i] = *origin + intr.GetIntersection(i)*edge; } } } else // Triangles were initially intersecting. { Triangle2<Real> tri0(V0), tri1(V1); IntrTriangle2Triangle2 intr(tri0, tri1); intr.Find(); quantity = intr.GetQuantity(); for (i = 0; i < quantity; ++i) { vertex[i] = intr.GetPoint(i); } } }