コード例 #1
0
// ******************************************************************
// Berechnung des Schattenvolumens
tbResult tbShadowVolume::ComputeVolume(const tbMatrix& mInvModelMatrix,
									   const D3DLIGHT9& Light,
									   const float fLength,		// = 1000.0f
									   const BOOL bNormalize)	// = FALSE
{
	tbVector3	vLight;
	tbVector3	vDir;
	tbEdge*		pEdge;
	tbVector3	vPointA;
	tbVector3	vPointB;
	tbVector3	vPointC;
	tbVector3	vPointD;


	if(Light.Type == D3DLIGHT_DIRECTIONAL)
	{
		// Ein Richtungslicht kann gesondert behandelt werden.
		// Erst transformieren wir die Richtung des Lichts mit der
		// inversen Transformationsmatrix des Modells.
		vDir = tbVector3TransformNormal(tbVector3NormalizeEx(Light.Direction), mInvModelMatrix);

		// Alle Dreiecke durchgehen und das Punktprodukt aus dem
		// Dreiecksnormalvektor und vDir berechnen. Nur wenn ein Wert größer
		// gleich null herauskommt, ist das Dreieck aus der Sicht des
		// Lichts sichtbar (Culling!).
		m_dwNumEdges = 0;
		for(DWORD t = 0; t < m_pModel->m_dwNumIndices / 3; t++)
		{
			// Punktprodukt berechnen und daraus die Sichtbarkeit bestimmen
			if(tbVector3Dot(m_pModel->m_pTrianglePlanes[t * 4].n, vDir) >= 0.0f)
			{
				// Die drei Seiten dieses Dreiecks hinzufügen
				AddEdge(m_pModel->m_pdwIndices[t * 3], m_pModel->m_pdwIndices[t * 3 + 1]);
				AddEdge(m_pModel->m_pdwIndices[t * 3 + 1], m_pModel->m_pdwIndices[t * 3 + 2]);
				AddEdge(m_pModel->m_pdwIndices[t * 3 + 2], m_pModel->m_pdwIndices[t * 3]);
			}
		}

		// Die verbliebenen Seiten durchgehen
		vDir *= fLength;
		m_dwNumVertices = 0;
		for(DWORD dwEdge = 0; dwEdge < m_dwNumEdges; dwEdge++)
		{
			pEdge = &m_pEdges[dwEdge];

			// Jetzt fügen wir 6 Vertizes zur Vertexliste hinzu,
			// um die Seite zu verlängern.
			vPointA = m_pModel->m_pvVectors[pEdge->dwPointA];
			vPointB = m_pModel->m_pvVectors[pEdge->dwPointB];
			vPointC = vPointB + vDir;
			vPointD = vPointA + vDir;
			m_pvVertices[m_dwNumVertices++] = vPointA;
			m_pvVertices[m_dwNumVertices++] = vPointD;
			m_pvVertices[m_dwNumVertices++] = vPointC;
			m_pvVertices[m_dwNumVertices++] = vPointA;
			m_pvVertices[m_dwNumVertices++] = vPointC;
			m_pvVertices[m_dwNumVertices++] = vPointB;
		}
	}
	else
	{
		// Bei den anderen Lichttypen hat das Licht eine Position.
		// Das heißt, dass der Richtungsvektor vom Licht zu den Dreiecken
		// bei jedem Dreieck unterschiedlich ist.

		// Die Lichtposition in das Modellkoordinatensystem umrechnen
		vLight = tbVector3TransformCoords(Light.Position, mInvModelMatrix);

		// Alle Dreiecke durchgehen. Wir verfahren fast wie oben, nur dass
		// vDir bei jedem Dreieck neu berechnet wird.
		m_dwNumEdges = 0;
		for(DWORD t = 0; t < m_pModel->m_dwNumIndices / 3; t++)
		{
			// Richtungsvektor vom Licht zum Mittelpunkt des Dreiecks berechnen
			vDir = tbVector3NormalizeEx(m_pvTriangleCenters[t] - vLight);

			// Punktprodukt berechnen und daraus die Sichtbarkeit bestimmen
			if(tbVector3Dot(m_pModel->m_pTrianglePlanes[t * 4].n, vDir) >= 0.0f)
			{
				// Die drei Seiten dieses Dreiecks hinzufügen
				AddEdge(m_pModel->m_pdwIndices[t * 3], m_pModel->m_pdwIndices[t * 3 + 1]);
				AddEdge(m_pModel->m_pdwIndices[t * 3 + 1], m_pModel->m_pdwIndices[t * 3 + 2]);
				AddEdge(m_pModel->m_pdwIndices[t * 3 + 2], m_pModel->m_pdwIndices[t * 3]);
			}
		}

		// Die verbliebenen Seiten durchgehen
		m_dwNumVertices = 0;
		if(bNormalize)
		{
			for(DWORD dwEdge = 0; dwEdge < m_dwNumEdges; dwEdge++)
			{
				pEdge = &m_pEdges[dwEdge];

				// Jetzt fügen wir 6 Vertizes zur Vertexliste hinzu,
				// um diese Seite zu verlängern.
				vPointA = m_pModel->m_pvVectors[pEdge->dwPointA];
				vPointB = m_pModel->m_pvVectors[pEdge->dwPointB];
				vPointC = vPointB + tbVector3NormalizeEx(vPointB - vLight) * fLength;
				vPointD = vPointA + tbVector3NormalizeEx(vPointA - vLight) * fLength;
				m_pvVertices[m_dwNumVertices++] = vPointA;
				m_pvVertices[m_dwNumVertices++] = vPointD;
				m_pvVertices[m_dwNumVertices++] = vPointC;
				m_pvVertices[m_dwNumVertices++] = vPointA;
				m_pvVertices[m_dwNumVertices++] = vPointC;
				m_pvVertices[m_dwNumVertices++] = vPointB;
			}
		}
		else
		{
			for(DWORD dwEdge = 0; dwEdge < m_dwNumEdges; dwEdge++)
			{
				pEdge = &m_pEdges[dwEdge];

				// Jetzt fügen wir 6 Vertizes zur Vertexliste hinzu,
				// um diese Seite zu verlängern.
				vPointA = m_pModel->m_pvVectors[pEdge->dwPointA];
				vPointB = m_pModel->m_pvVectors[pEdge->dwPointB];
				vPointC = vPointB + (vPointB - vLight) * fLength;
				vPointD = vPointA + (vPointA - vLight) * fLength;
				m_pvVertices[m_dwNumVertices++] = vPointA;
				m_pvVertices[m_dwNumVertices++] = vPointD;
				m_pvVertices[m_dwNumVertices++] = vPointC;
				m_pvVertices[m_dwNumVertices++] = vPointA;
				m_pvVertices[m_dwNumVertices++] = vPointC;
				m_pvVertices[m_dwNumVertices++] = vPointB;
			}
		}
	}

	return TB_OK;
}
コード例 #2
0
ファイル: Tracker.cpp プロジェクト: Interaptix/OvrvisionPro
//---------------------------------------------------------------
void Tracker::AddTrackerConeVerts(ovrSession Session, Model* m, bool isItEdges)
{
	//Get attributes of camera cone
	std::vector<ovrTrackerDesc>   TrackerDescArray;
	unsigned int trackerCount = std::max<unsigned int>(1, ovr_GetTrackerCount(Session)); // Make sure there's always at least one.
	for (unsigned int i = 0; i < trackerCount; ++i)
		TrackerDescArray.push_back(ovr_GetTrackerDesc(Session, i));
	                                                            // v4-------v5
	float hFOV = TrackerDescArray[0].FrustumHFovInRadians;      // | \     / |
	float vFOV  = TrackerDescArray[0].FrustumVFovInRadians;     // |  v0-v1  |
	float nearZ = TrackerDescArray[0].FrustumNearZInMeters;     // |  | C |  |
	float farZ  = TrackerDescArray[0].FrustumFarZInMeters;      // |  v2-v3  |
	                                                            // | /     \ |
	                                                            // v6-------v7
    // MA: Having the lines/pyramid start closer to camera looks better.
    nearZ = 0.08f;

	Vector3f baseVec3(tan(0.5f * hFOV), tan(0.5f * vFOV), 1.0f);
	v[0] = v[4] = Vector3f(baseVec3.x, -baseVec3.y, 1.0f);
	v[1] = v[5] = Vector3f(-baseVec3.x, -baseVec3.y, 1.0f);
	v[2] = v[6] = Vector3f(baseVec3.x, baseVec3.y, 1.0f);
	v[3] = v[7] = Vector3f(-baseVec3.x, baseVec3.y, 1.0f);
	v[8] = Vector3f(0, 0, 0.5f*lengthOfTrackerHead); //front of tracker location

	// Project to near and far planes
	for (int i = 0; i < 8; i++)
	{
		float depth = (i < 4 ? nearZ : farZ);
		v[i].x *= depth;
		v[i].y *= depth;
		v[i].z *= depth;
	}

	Color c = Color(255, 255, 255, 255);

	if (isItEdges) //Wire parts
	{
		#define AddEdge(i0,i1) m->AddQuad(    \
		Vertex(v[i0],c,0,0),Vertex(v[i1],c,0,0), \
		Vertex(v[i1], c, 0, 0), Vertex(v[i1], c, 0, 0));

        if (drawWalls)
        {   // Add wireframe fronty and back outlines if we have walls
            AddEdge(0, 1); AddEdge(1, 3); AddEdge(3, 2); AddEdge(2, 0);
            AddEdge(4, 5); AddEdge(5, 7); AddEdge(7, 6); AddEdge(6, 4);
        }
		AddEdge(4, 0); AddEdge(5, 1); AddEdge(7, 3); AddEdge(6, 2);
		if (extendLinesToTracker)
		{
			AddEdge(8, 0);	AddEdge(8, 1);	AddEdge(8, 2);	AddEdge(8, 3);
		}
	}
	else //Solid planes
	{
		float gridDensity = 6.0f;
		#define AddPlane(i0,i1,i2,i3,U,V,dense) m->AddQuad(    \
		Vertex(v[i0], c, dense*v[i0].U, dense*v[i0].V), \
		Vertex(v[i1], c, dense*v[i1].U, dense*v[i1].V), \
		Vertex(v[i2], c, dense*v[i2].U, dense*v[i2].V), \
		Vertex(v[i3], c, dense*v[i3].U, dense*v[i3].V))
		AddPlane(4, 0, 6, 2, z, y, gridDensity); // Left
		AddPlane(1, 5, 3, 7, z, y, gridDensity); // Right
		AddPlane(4, 5, 0, 1, x, z, gridDensity); // Top
		AddPlane(2, 3, 6, 7, x, z, gridDensity); // Bot
		AddPlane(5, 4, 7, 6, x, y, gridDensity); // Back
		if (frontOfGridAsWell) { AddPlane(0, 1, 2, 3, x, y, gridDensity); } // Front
	}
}
コード例 #3
0
ファイル: main.cpp プロジェクト: linmx0130/OJCode
	void AddEdge2(int a,int b)
	{
		AddEdge(a,b);
		AddEdge(b,a);
	}
コード例 #4
0
ファイル: WEdge.cpp プロジェクト: DrangPo/blender
WShape::WShape(WShape& iBrother)
{
	_Id = iBrother.GetId();
	_Name = iBrother._Name;
	_FrsMaterials = iBrother._FrsMaterials;
#if 0
	_meanEdgeSize = iBrother._meanEdgeSize;
	iBrother.bbox(_min, _max);
#endif
	vector<WVertex *>& vertexList = iBrother.getVertexList();
	vector<WVertex *>::iterator v = vertexList.begin(), vend = vertexList.end();
	for (; v != vend; ++v) {
		//WVertex *newVertex = new WVertex(*(*v));
		WVertex *newVertex = (*v)->duplicate();

		newVertex->setShape(this);
		AddVertex(newVertex);
	}

	vector<WEdge *>& edgeList = iBrother.getEdgeList();
	vector<WEdge *>::iterator e = edgeList.begin(), eend = edgeList.end();
	for (; e != eend; ++e) {
		//WEdge *newEdge = new WEdge(*(*e));
		WEdge *newEdge = (*e)->duplicate();
		AddEdge(newEdge);
	}

	vector<WFace *>& faceList = iBrother.GetFaceList();
	vector<WFace *>::iterator f = faceList.begin(), fend = faceList.end();
	for (; f != fend; ++f) {
		//WFace *newFace = new WFace(*(*f));
		WFace *newFace = (*f)->duplicate();
		AddFace(newFace);
	}

	// update all pointed addresses thanks to the newly created objects:
	vend = _VertexList.end();
	for (v = _VertexList.begin(); v != vend; ++v) {
		const vector<WEdge *>& vedgeList = (*v)->GetEdges();
		vector<WEdge *> newvedgelist;
		unsigned int i;
		for (i = 0; i < vedgeList.size(); i++) {
			WEdge *current = vedgeList[i];
			edgedata *currentvedata = (edgedata *)current->userdata;
			newvedgelist.push_back(currentvedata->_copy);
		}
		(*v)->setEdges(newvedgelist);
	}

	eend = _EdgeList.end();
	for (e = _EdgeList.begin(); e != eend; ++e) {
		// update aOedge:
		WOEdge *aoEdge = (*e)->GetaOEdge();
		aoEdge->setaVertex(((vertexdata *)(aoEdge->GetaVertex()->userdata))->_copy);
		aoEdge->setbVertex(((vertexdata *)(aoEdge->GetbVertex()->userdata))->_copy);
		if (aoEdge->GetaFace())
			aoEdge->setaFace(((facedata *)(aoEdge->GetaFace()->userdata))->_copy);
		aoEdge->setbFace(((facedata *)(aoEdge->GetbFace()->userdata))->_copy);
		aoEdge->setOwner(((edgedata *)(aoEdge->GetOwner()->userdata))->_copy);

		// update bOedge:
		WOEdge *boEdge = (*e)->GetbOEdge();
		if (boEdge) {
			boEdge->setaVertex(((vertexdata *)(boEdge->GetaVertex()->userdata))->_copy);
			boEdge->setbVertex(((vertexdata *)(boEdge->GetbVertex()->userdata))->_copy);
			if (boEdge->GetaFace())
				boEdge->setaFace(((facedata *)(boEdge->GetaFace()->userdata))->_copy);
			boEdge->setbFace(((facedata *)(boEdge->GetbFace()->userdata))->_copy);
			boEdge->setOwner(((edgedata *)(boEdge->GetOwner()->userdata))->_copy);
		}
	}

	fend = _FaceList.end();
	for (f = _FaceList.begin(); f != fend; ++f) {
		unsigned int i;
		const vector<WOEdge *>& oedgeList = (*f)->getEdgeList();
		vector<WOEdge *> newoedgelist;

		unsigned int n = oedgeList.size();
		for (i = 0; i < n; i++) {
			WOEdge *current = oedgeList[i];
			oedgedata *currentoedata = (oedgedata *)current->userdata;
			newoedgelist.push_back(currentoedata->_copy);
			//oedgeList[i] = currentoedata->_copy;
			//oedgeList[i] = ((oedgedata *)(oedgeList[i]->userdata))->_copy;
		}
		(*f)->setEdgeList(newoedgelist);
	}

	// Free all memory (arghh!)
	// Vertex
	vend = iBrother.getVertexList().end();
	for (v = iBrother.getVertexList().begin(); v != vend; ++v) {
		delete (vertexdata *)((*v)->userdata);
		(*v)->userdata = NULL;
	}

	// Edges and OEdges:
	eend = iBrother.getEdgeList().end();
	for (e = iBrother.getEdgeList().begin(); e != eend; ++e) {
		delete (edgedata *)((*e)->userdata);
		(*e)->userdata = NULL;
		// OEdge a:
		delete (oedgedata *)((*e)->GetaOEdge()->userdata);
		(*e)->GetaOEdge()->userdata = NULL;
		// OEdge b:
		WOEdge *oedgeb = (*e)->GetbOEdge();
		if (oedgeb) {
			delete (oedgedata *)(oedgeb->userdata);
			oedgeb->userdata = NULL;
		}
	}

	// Faces
	fend = iBrother.GetFaceList().end();
	for (f = iBrother.GetFaceList().begin(); f != fend; ++f) {
		delete (facedata *)((*f)->userdata);
		(*f)->userdata = NULL;
	}
}
コード例 #5
0
ファイル: WEdge.cpp プロジェクト: DrangPo/blender
WFace *WShape::MakeFace(vector<WVertex *>& iVertexList, vector<bool>& iFaceEdgeMarksList, unsigned iMaterial,
                        WFace *face)
{
	int id = _FaceList.size();

	face->setFrsMaterialIndex(iMaterial);

	// Check whether we have a degenerated face:

	// LET'S HACK IT FOR THE TRIANGLE CASE:

	if (3 == iVertexList.size()) {
		if ((iVertexList[0] == iVertexList[1]) ||
		    (iVertexList[0] == iVertexList[2]) ||
		    (iVertexList[2] == iVertexList[1]))
		{
			cerr << "Warning: degenerated triangle detected, correcting" << endl;
			return NULL;
		}
	}

	vector<WVertex *>::iterator it;

	// compute the face normal (v1v2 ^ v1v3)
	WVertex *v1, *v2, *v3;
	it = iVertexList.begin();
	v1 = *it;
	it++;
	v2 = *it;
	it++;
	v3 = *it;

	Vec3f vector1(v2->GetVertex() - v1->GetVertex());
	Vec3f vector2(v3->GetVertex() - v1->GetVertex());

	Vec3f normal(vector1 ^ vector2);
	normal.normalize();
	face->setNormal(normal);

	vector<bool>::iterator mit = iFaceEdgeMarksList.begin();
	face->setMark(*mit);
	mit++;

	// vertex pointers used to build each edge
	vector<WVertex *>::iterator va, vb;

	va = iVertexList.begin();
	vb = va;
	for (; va != iVertexList.end(); va = vb) {
		++vb;
		// Adds va to the vertex list:
		//face->AddVertex(*va);

		WOEdge *oedge;
		if (*va == iVertexList.back())
			oedge = face->MakeEdge(*va, iVertexList.front()); //for the last (closing) edge
		else
			oedge = face->MakeEdge(*va, *vb);

		if (!oedge)
			return NULL;

		WEdge *edge = oedge->GetOwner();
		if (1 == edge->GetNumberOfOEdges()) {
			// means that we just created a new edge and that we must add it to the shape's edges list
			edge->setId(_EdgeList.size());
			AddEdge(edge);
#if 0
			// compute the mean edge value:
			_meanEdgeSize += edge->GetaOEdge()->GetVec().norm();
#endif
		}

		edge->setMark(*mit);
		++mit;
	}

	// Add the face to the shape's faces list:
	face->setId(id);
	AddFace(face);

	return face;
}
コード例 #6
0
ファイル: main.c プロジェクト: shawnelee88/dsacc
int main()
{
	ptrGraph G;
	Indegree inDegree[MAXVEX];
	int tmp;

	G = InitializeGraph(7);
	AddVertex(1, 0, G);
	AddVertex(2, 1, G);
	AddVertex(3, 2, G);
	AddVertex(4, 3, G);
	AddVertex(5, 4, G);
	AddVertex(6, 5, G);
	AddVertex(7, 6, G);
	
	AddEdge(1, 2, G);
	AddEdge(1, 3, G);
	AddEdge(1, 4, G);

	AddEdge(2, 4, G);
	AddEdge(2, 5, G);
	AddEdge(3, 6, G);

	AddEdge(4, 7, G);
	AddEdge(4, 3, G);
	AddEdge(4, 6, G);

	AddEdge(5, 4, G);
	AddEdge(5, 7, G);
	AddEdge(7, 6, G);

	GetIndegree(inDegree, G->numVertexes, G);
	//tmp = FindNewVertexOfIndegreeZero(inDegree, G->numVertexes);
	TopSort(inDegree, G->numVertexes, G);
}
コード例 #7
0
ファイル: WEdge.cpp プロジェクト: DrangPo/blender
WOEdge *WFace::MakeEdge(WVertex *v1, WVertex *v2)
{
	// First check whether the same oriented edge already exists or not:
	vector<WEdge *>& v1Edges = v1->GetEdges();
	for (vector<WEdge*>::iterator it1 = v1Edges.begin(), end = v1Edges.end(); it1 != end; it1++) {
		WEdge *we = (*it1);
		WOEdge *woea = we->GetaOEdge();

		if ((woea->GetaVertex() == v1) && (woea->GetbVertex() == v2)) {
			// The oriented edge already exists
			cerr << "Warning: edge " << v1->GetId() << " - " << v2->GetId() << " appears twice, correcting" << endl;
			// Adds the edge to the face
			AddEdge(woea);
			(*it1)->setNumberOfOEdges((*it1)->GetNumberOfOEdges() + 1);
			//sets these vertices as border:
			v1->setBorder(true);
			v2->setBorder(true);
			return woea;
		}

		WOEdge *woeb = we->GetbOEdge();
		if (woeb && (woeb->GetaVertex() == v1) && (woeb->GetbVertex() == v2)) {
			// The oriented edge already exists
			cerr << "Warning: edge " << v1->GetId() << " - " << v2->GetId() << " appears twice, correcting" << endl;
			// Adds the edge to the face
			AddEdge(woeb);
			(*it1)->setNumberOfOEdges((*it1)->GetNumberOfOEdges() + 1);
			//sets these vertices as border:
			v1->setBorder(true);
			v2->setBorder(true);
			return woeb;
		}
	}

	// the oriented edge we're about to build
	WOEdge *pOEdge = new WOEdge;
	// The edge containing the oriented edge.
	WEdge *edge;

	// checks whether this edge already exists or not
	// If it exists, it points outward v2
	bool exist = false;
	WOEdge *pInvertEdge = NULL; // The inverted edge if it exists
	vector<WEdge *>& v2Edges = v2->GetEdges();
	vector<WEdge *>::iterator it;
	for (it = v2Edges.begin(); it != v2Edges.end(); it++) {
		if ((*it)->GetbVertex() == v1) {
			// The invert edge already exists
			exist = true;
			pInvertEdge = (*it)->GetaOEdge();
			break;
		}
	}

	//DEBUG:
	if (true == exist) { // The invert edge already exists
		// Retrieves the corresponding edge
		edge = pInvertEdge->GetOwner();

		// Sets the a Face (retrieved from pInvertEdge
		pOEdge->setaFace(pInvertEdge->GetbFace());

		// Updates the invert edge:
		pInvertEdge->setaFace(this);
	}
	else { // The invert edge does not exist yet
		// we must create a new edge
		//edge = new WEdge;
		edge = instanciateEdge();

		// updates the a,b vertex edges list:
		v1->AddEdge(edge);
		v2->AddEdge(edge);
	}

	pOEdge->setOwner(edge);
	// Add the vertices:
	pOEdge->setaVertex(v1);
	pOEdge->setbVertex(v2);

	// Debug:
	if (v1->GetId() == v2->GetId())
		cerr << "Warning: edge " << this << " null with vertex " << v1->GetId() << endl;

	edge->AddOEdge(pOEdge);
	//edge->setNumberOfOEdges(edge->GetNumberOfOEdges() + 1);

	// Add this face (the b face)
	pOEdge->setbFace(this);

	// Adds the edge to the face
	AddEdge(pOEdge);

	return pOEdge;
}
コード例 #8
0
ファイル: P1860.cpp プロジェクト: yuchenguangfd/Arena
 void AddEdge(int u, int v, T weight) { AddEdge(WeightedEdge<T>(u, v, weight)); }
コード例 #9
0
ファイル: graph.hpp プロジェクト: SnoozeTime/c--training
 /*
     Add edges with the same value
     bool if inserting one edge failed (if already exists)
 */
 bool AddEdges(int vertex_1, int vertex_2, EV value)
 {
     return AddEdge(vertex_1, vertex_2, value) && AddEdge(vertex_2, vertex_1, value);
 }
コード例 #10
0
ファイル: writebsp.cpp プロジェクト: Baer42/source-sdk-2013
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
int CreateOrigFace( face_t *f )
{
    int         i, j;
    dface_t     *of;
    side_t      *side;
    int         vIndices[128];
    int         eIndex[2];
    winding_t   *pWinding;

    // not a real face!
    if( !f->w )
        return -1;

    // get the original face -- the "side"
    side = f->originalface;

    // get the original face winding
	if( !side->winding )
	{
		return -1;
	}

    //
    // get the next original face
    //
    if( numorigfaces >= MAX_MAP_FACES )
		Error( "Too many faces in map, max = %d", MAX_MAP_FACES );
	of = &dorigfaces[numorigfaces];
    numorigfaces++;

    // set original face to -1 -- it is an origianl face!
    of->origFace = -1;

    //
    // add side to plane list
    //
    side->next = pOrigFaceSideList[f->planenum];
    pOrigFaceSideList[f->planenum] = side;
    side->origIndex = numorigfaces - 1;

    pWinding = CopyWinding( side->winding );

    //
    // plane info
    //
    of->planenum = side->planenum;
	if ( side->contents & CONTENTS_DETAIL )
		of->onNode = 0;
	else
		of->onNode = 1;
	of->side = side->planenum & 1;

    //
    // edge info
    //
    of->firstedge = numsurfedges;
    of->numedges = side->winding->numpoints;

    //
    // material info
    //
    of->texinfo = side->texinfo;
	of->dispinfo = f->dispinfo;

    //
    // save the vertices
    //
    for( i = 0; i < pWinding->numpoints; i++ )
    {
        //
        // compare vertices
        //
		vIndices[i] = GetVertexnum( pWinding->p[i] );
    }

    //
    // save off points -- as edges
    //
    for( i = 0; i < pWinding->numpoints; i++ )
	{
        //
        // look for matching edges first
        //
        eIndex[0] = vIndices[i];
        eIndex[1] = vIndices[(i+1)%pWinding->numpoints];

        for( j = firstmodeledge; j < numedges; j++ )
        {
            if( ( eIndex[0] == dedges[j].v[1] ) &&
                ( eIndex[1] == dedges[j].v[0] ) &&
         	    ( edgefaces[j][0]->contents == f->contents ) )
            {
                // check for multiple backward edges!! -- shouldn't have
				if( edgefaces[j][1] )
					continue;

                // set back edge
				edgefaces[j][1] = f;

                //
                // get next surface edge
                //
                if( numsurfedges >= MAX_MAP_SURFEDGES )
                    Error( "Too much brush geometry in bsp, numsurfedges == MAX_MAP_SURFEDGES" );                
                dsurfedges[numsurfedges] = -j;
                numsurfedges++;
                break;
            }
        }
        
        if( j == numedges )
        {
            //
            // get next edge
            //
			AddEdge( eIndex[0], eIndex[1], f );
        
            //
            // get next surface edge
            //
            if( numsurfedges >= MAX_MAP_SURFEDGES )
				Error( "Too much brush geometry in bsp, numsurfedges == MAX_MAP_SURFEDGES" );                
            dsurfedges[numsurfedges] = ( numedges - 1 );
            numsurfedges++;
        }
	}

    // return the index
    return ( numorigfaces - 1 );
}
コード例 #11
0
ファイル: Silhouette.cpp プロジェクト: benardp/contours
  /* splits an edge into 2 edges. The new vertex and edge are added
   *  to the sshape list of vertices and edges
   *  a new chain is also created.
   *  returns the new edge.
   *    ioEdge
   *      The edge that gets splitted
   *    newpoint
   *      x,y,z coordinates of the new point.
   */
FEdge* SShape::SplitEdgeIn2(FEdge* ioEdge, SVertex * ioNewVertex)
    {
      SVertex *A = ioEdge->vertexA();
      SVertex *B = ioEdge->vertexB();

      
      // We split edge AB into AA' and A'B. A' and A'B are created.
      // AB becomes (address speaking) AA'. B is updated.
      //--------------------------------------------------
      
      // a new edge, A'B is created.
      FEdge *newEdge;
      if (ioEdge->getNature() & Nature::ALL_INTERSECTION)
	{
	  newEdge = new FEdgeIntersection(ioNewVertex, B);
	  FEdgeIntersection * se = dynamic_cast<FEdgeIntersection*>(newEdge);
	  FEdgeIntersection * fes = dynamic_cast<FEdgeIntersection*>(ioEdge);
	  se->SetMaterialIndex(fes->materialIndex());
	  se->SetFaces(fes->getFace1(), fes->getFace2());

#ifdef DEBUG_INTERSECTION
	  void debugFES(FEdgeIntersection * newEdge);
	  
	  debugFES(se);
	  debugFES(fes);
#endif

	}else
      if(ioEdge->isSmooth()){
        newEdge = new FEdgeSmooth(ioNewVertex, B);
        FEdgeSmooth * se = dynamic_cast<FEdgeSmooth*>(newEdge);
        FEdgeSmooth * fes = dynamic_cast<FEdgeSmooth*>(ioEdge);
        se->SetMaterialIndex(fes->materialIndex());
	se->SetFace(fes->face());
      }else{
        newEdge = new FEdgeSharp(ioNewVertex, B);
        FEdgeSharp * se = dynamic_cast<FEdgeSharp*>(newEdge);
        FEdgeSharp * fes = dynamic_cast<FEdgeSharp*>(ioEdge);
        se->SetaMaterialIndex(fes->aMaterialIndex());
        se->SetbMaterialIndex(fes->bMaterialIndex());
	se->SetEdge(fes->edge());
      }
      newEdge->SetNature(ioEdge->getNature());
      
      
      if(ioEdge->nextEdge() != 0)
        ioEdge->nextEdge()->SetPreviousEdge(newEdge);

      // update edge A'B for the next pointing edge
      newEdge->SetNextEdge(ioEdge->nextEdge());
      // update edge A'B for the previous pointing edge
      newEdge->SetPreviousEdge(0); // because it is now a ViewVertex
      Id id(ioEdge->getId().getFirst(), ioEdge->getId().getSecond()+1);
      newEdge->SetId(ioEdge->getId());
      ioEdge->SetId(id);
   
      // update edge AA' for the next pointing edge
      ioEdge->SetNextEdge(0); // because it is now a TVertex

      // update vertex pointing edges list:
      // -- vertex B --
      B->Replace(ioEdge, newEdge);
      // -- vertex A' --
      ioNewVertex->AddFEdge(ioEdge);
      ioNewVertex->AddFEdge(newEdge);

      // to build a new chain:
      AddChain(newEdge);
      AddEdge(newEdge); // FIXME ??
      
      // The edge AB becomes edge AA'.
      ioEdge->SetVertexB(ioNewVertex);

      // added by Aaron (looks redundant now, can probably be deleted)
      newEdge->SetVertexA(ioNewVertex);
      newEdge->SetVertexB(B);
      
      //      if(ioEdge->isSmooth()){
      //  ((FEdgeSmooth*)newEdge)->SetFace(((FEdgeSmooth*)ioEdge)->face());
      //}
      

      return newEdge;
    }
コード例 #12
0
ファイル: Silhouette.cpp プロジェクト: benardp/contours
  /* splits an edge into several edges. 
   *  The edge's vertices are passed rather than 
   *  the edge itself. This way, all feature edges (SILHOUETTE,
   *  CREASE, BORDER) are splitted in the same time.
   *  The processed edges are flagged as done (using the userdata
   *  flag).One single new vertex is created whereas 
   *  several splitted edges might created for the different 
   *  kinds of edges. These new elements are added to the lists
   *  maintained by the shape.
   *  new chains are also created.
   *    ioA
   *      The first vertex for the edge that gets splitted
   *    ioB
   *      The second vertex for the edge that gets splitted
   *    iParameters
   *      A vector containing 2D real vectors indicating the parameters
   *      giving the intersections coordinates in 3D and in 2D.
   *      These intersections points must be sorted from B to A.
   *      Each parameter defines the intersection point I as I=A+T*AB.
   *      T<0 and T>1 are then incorrect insofar as they give intersections
   *      points that lie outside the segment.
   *    ioNewEdges
   *      The edges that are newly created (the initial edges are not 
   *      included) are added to this list.
   */
void SShape::SplitEdge(FEdge *fe, const vector<Vec2r>& iParameters, vector<FEdge*>& ioNewEdges)
    {
    
    SVertex *ioA = fe->vertexA();
    SVertex *ioB = fe->vertexB();
    Vec3r A = ioA->point3D();
    Vec3r B = ioB->point3D();
    Vec3r a = ioA->point2D();
    Vec3r b = ioB->point2D();
    SVertex *svA, *svB;

    Vec3r newpoint3d,newpoint2d;
    vector<SVertex*> intersections;
    real t,T;
    for(vector<Vec2r>::const_iterator p=iParameters.begin(),pend=iParameters.end();
    p!=pend;
    p++)
    {
      T=(*p)[0];
      t=(*p)[1];

      if((t < 0) || (t > 1))
        cerr << "Warning: Intersection out of range for edge " << ioA->getId() << " - " << ioB->getId() << endl;
    
      // compute the 3D and 2D coordinates for the intersections points:
      newpoint3d = Vec3r(A + T*(B-A));
      newpoint2d = Vec3r(a + t*(b-a));

      // create new SVertex:
      // (we keep B's id)
      SVertex* newVertex = new SVertex(newpoint3d, ioB->getId());
      newVertex->SetPoint2D(newpoint2d);
      
      // Add this vertex to the intersections list:
      intersections.push_back(newVertex);

      // Add this vertex to this sshape:
      AddNewVertex(newVertex);
    }
    
    for(vector<SVertex*>::iterator sv=intersections.begin(),svend=intersections.end();
    sv!=svend;
    sv++)
    {
      svA = fe->vertexA();
      svB = fe->vertexB();
        
      // We split edge AB into AA' and A'B. A' and A'B are created.
      // AB becomes (address speaking) AA'. B is updated.
      //--------------------------------------------------
      // The edge AB becomes edge AA'.
      (fe)->SetVertexB((*sv));
      // a new edge, A'B is created.
      FEdge *newEdge;
      if (fe->getNature() & Nature::ALL_INTERSECTION)
	{
	  newEdge = new FEdgeIntersection((*sv), svB);
	  FEdgeIntersection * se = dynamic_cast<FEdgeIntersection*>(newEdge);
	  FEdgeIntersection * fes = dynamic_cast<FEdgeIntersection*>(fe);
	  se->SetMaterialIndex(fes->materialIndex());
	  se->SetFaces(fes->getFace1(), fes->getFace2());


#ifdef DEBUG_INTERSECTION
	  void debugFES(FEdgeIntersection * newEdge);
	  
	  debugFES(se);
	  debugFES(fes);
#endif



	}
      else
      if(fe->isSmooth()){
        newEdge = new FEdgeSmooth((*sv), svB);
        FEdgeSmooth * se = dynamic_cast<FEdgeSmooth*>(newEdge);
        FEdgeSmooth * fes = dynamic_cast<FEdgeSmooth*>(fe);
        se->SetMaterialIndex(fes->materialIndex());
      }else{
        newEdge = new FEdgeSharp((*sv), svB);
        FEdgeSharp * se = dynamic_cast<FEdgeSharp*>(newEdge);
        FEdgeSharp * fes = dynamic_cast<FEdgeSharp*>(fe);
        se->SetaMaterialIndex(fes->aMaterialIndex());
        se->SetbMaterialIndex(fes->bMaterialIndex());
	se->SetEdge(fes->edge());
      }
        
      newEdge->SetNature((fe)->getNature());
      

      // to build a new chain:
      AddChain(newEdge);
      // add the new edge to the sshape edges list.
      AddEdge(newEdge);
      // add new edge to the list of new edges passed as argument:
      ioNewEdges.push_back(newEdge);

      // update edge A'B for the next pointing edge
      newEdge->SetNextEdge((fe)->nextEdge());
      fe->nextEdge()->SetPreviousEdge(newEdge);
      Id id(fe->getId().getFirst(), fe->getId().getSecond()+1);
      newEdge->SetId(fe->getId());
      fe->SetId(id);

      // update edge AA' for the next pointing edge
      //ioEdge->SetNextEdge(newEdge);
      (fe)->SetNextEdge(NULL);

      // update vertex pointing edges list:
      // -- vertex B --
      svB->Replace((fe), newEdge);
      // -- vertex A' --
      (*sv)->AddFEdge((fe));
      (*sv)->AddFEdge(newEdge);
    }
          
    }