示例#1
0
文件: Roads.cpp 项目: kamalsirsa/vtp
//
// Given a node and a link, return the two points that the link
// will need in order to hook up with the node.
//
void NodeGeom::FindVerticesForLink(TLink *pL, bool bStart, FPoint3 &p0, FPoint3 &p1)
{
	if (NumLinks() == 1)
	{
		p0 = m_v[0];
		p1 = m_v[1];
	}
	else if (NumLinks() == 2)
	{
		if (pL == m_connect[0])
		{
			p0 = m_v[1];
			p1 = m_v[0];
		}
		else
		{
			p0 = m_v[0];
			p1 = m_v[1];
		}
	}
	else
	{
		for (int i = 0; i < NumLinks(); i++)
		{
			if (m_connect[i] == pL)
			{
				p0 = m_v[i*2];
				p1 = m_v[i*2+1];
				return;
			}
		}
		// Should not get here!  This node does not reference the link passed
		; // (put a breakpoint here)
	}
}
示例#2
0
//------------------------------------------------------------------------------
// Purpose : Used to get links in different order each time.  
//			 Call ShuffleLinks() first
// Input   :
// Output  :
//------------------------------------------------------------------------------
CAI_Link* CAI_Node::GetShuffeledLink(int nNum)
{
	int nLinkID = m_iFirstShuffledLink + nNum;
	if (nLinkID >= NumLinks())
	{
		nLinkID -= NumLinks();
	}
	return m_Links[nLinkID];
}
示例#3
0
//------------------------------------------------------------------------------
// Purpose : Called before GetShuffeledLinks to change the order in which
//			 links are returned 
// Input   :
// Output  :
//------------------------------------------------------------------------------
void CAI_Node::ShuffleLinks(void)
{
	m_iFirstShuffledLink++;
	if (m_iFirstShuffledLink >= NumLinks())
	{
		m_iFirstShuffledLink = 0;
	}
}
示例#4
0
文件: Roads.cpp 项目: kamalsirsa/vtp
vtMesh *NodeGeom::GenerateGeometry(const VirtualTexture &vt)
{
	if (NumLinks() < 3)
		return NULL;

	FPoint2 uv;

	const FPoint3 upvector(0.0f, 1.0f, 0.0f);

	vtMesh *pMesh = new vtMesh(osg::PrimitiveSet::TRIANGLE_FAN, VT_TexCoords | VT_Normals, NumLinks()*2 + 1);
	int verts = 0;

	vt.Adapt(FPoint2(0.5f, 0.5f), uv);

	pMesh->SetVtxPUV(verts, m_p3, uv.x, uv.y);
	pMesh->SetVtxNormal(verts, upvector);
	verts++;

	for (int j = 0; j < NumLinks(); j++)
	{
		vt.Adapt(FPoint2(0.0f, 1.0f), uv);
		pMesh->SetVtxPUV(verts, m_v[j*2+1], uv.x, uv.y);

		vt.Adapt(FPoint2(1.0f, 1.0f), uv);
		pMesh->SetVtxPUV(verts+1, m_v[j*2], uv.x, uv.y);

		pMesh->SetVtxNormal(verts, upvector);
		pMesh->SetVtxNormal(verts+1, upvector);
		verts += 2;
	}

	// create triangles
	verts = 0;
	int idx[100];
	idx[verts++] = 0;
	for (int j = 0; j < NumLinks(); j++)
	{
		idx[verts++] = (j*2+1);
		idx[verts++] = (j*2+2);
	}
	idx[verts++] = 1;	// close it
	pMesh->AddFan(idx, verts);
	return pMesh;
}
示例#5
0
//-----------------------------------------------------------------------------
// Purpose: Returns link if node has a link to node of the given nNodeID.
//			Otherwise returns NULL
// Input  :
// Output :
//-----------------------------------------------------------------------------
CAI_Link* CAI_Node::HasLink(int nNodeID)
{
	for (int link=0;link<NumLinks();link++)
	{
		// If node has link to myself, than add link to my list of links
		if (m_Links[link]->DestNodeID(m_iID) == nNodeID)
		{
			return m_Links[link];
		}
	}
	return NULL;
}
示例#6
0
//-----------------------------------------------------------------------------
// Purpose: Add a link to this node
// Input  :
// Output :
//-----------------------------------------------------------------------------
void CAI_Node::AddLink(CAI_Link *newLink)
{
	if ( NumLinks() == AI_MAX_NODE_LINKS )
	{
		DevMsg( "Node %d has too many links\n", m_iID );
		return;
	}

#ifdef _DEBUG
	for (int link=0;link<NumLinks();link++)
	{
		if (m_Links[link] == newLink)
		{
			AssertMsgOnce( 0, "Link added to node multiple times!" );
			return;
		}
	}

	AssertMsg( newLink->m_iDestID == m_iID || newLink->m_iSrcID == m_iID, "Added link to node that doesn't reference the node" );
#endif

	m_Links.AddToTail( newLink );
}
示例#7
0
CAI_Link *CAI_Node::GetLink( int destNodeId )
{
	// Now make sure this node still has a link to the destID
	for ( int link = 0; link < NumLinks(); link++ )
	{
		// If we find the link the dynamic link is valid
		if ( m_Links[link]->DestNodeID(m_iID) == destNodeId )
		{
			return m_Links[link];
		}
	}

	return NULL;
}
示例#8
0
文件: Roads.cpp 项目: kamalsirsa/vtp
void NodeGeom::ComputeIntersectionVertices()
{
	FPoint3 v, v_next, v_prev;
	FPoint3 pn0, pn1;
	float w;			// link width

	SortLinksByAngle();

	// how many links meet here?
	if (NumLinks() == 0)
	{
		; // bogus case (put a breakpoint here)
	}
	else if (NumLinks() == 1)
	{
		// dead end: only need 2 vertices for this node
		m_iVerts = 2;
		m_v.SetSize(2);

		// get info about the link
		LinkGeom *r = GetLink(0);
		w = (r->m_fLeftWidth + r->m_fRightWidth) / 2;

		pn1 = GetAdjacentRoadpoint(0);
		v = CreateRoadVector(m_p3, pn1, w);

		m_v[0].Set(m_p3.x + v.z, m_p3.y, m_p3.z - v.x);
		m_v[1].Set(m_p3.x - v.z, m_p3.y, m_p3.z + v.x);

		one++;
	}
	else if (NumLinks() == 2)
	{
		// only need 2 vertices for this node; no intersection
		m_iVerts = 2;
		m_v.SetSize(2);

		// get info about the links
		w = (GetLink(0)->m_fLeftWidth + GetLink(1)->m_fRightWidth) / 2.0f;

		pn0 = GetAdjacentRoadpoint(0);
		pn1 = GetAdjacentRoadpoint(1);

		v = CreateRoadVector(pn0, pn1, w);

		m_v[0].Set(m_p3.x + v.z, m_p3.y, m_p3.z - v.x);
		m_v[1].Set(m_p3.x - v.z, m_p3.y, m_p3.z + v.x);

		two++;
	}
	else
	{
		// intersection: need 2 vertices for each link meeting here
		m_iVerts = 2 * NumLinks();
		m_v.SetSize(m_iVerts);

		// For each pairs of links, find the places where the link edges
		//  intersect as they approach this node.

		// The following is an array of float triples, used as follows:
		//  x = minimum distance which avoids intersection with next link
		//  y = minimum distance which avoids intersection with previous link
		//  z = greater of x or y.
		FLine3 distance_to_intersection(NumLinks());

		// Go through the links once, collecting the minimum distances
		for (int i = 0; i < NumLinks(); i++)
		{
			// indices of the next and previous links
			const int i_next = (i == NumLinks()-1) ? 0 : i+1;

			const TLink *pL = GetLink(i);
			const TLink *pL_next = GetLink(i_next);

			const float width1 = pL->m_fLeftWidth;
			const float width2 = pL_next->m_fRightWidth;

			const FPoint3 linkv1 = GetUnitLinkVector(i);
			const FPoint3 linkv2 = GetUnitLinkVector(i_next);

			// Use 2D vectors for the following math
			// Compute two vectors: left road edge of this link, right road
			//  edge of the following link, compute where they intersect, in
			//  terms of the ua and ub factors, which are the distance along
			//  each input vector to the intersection point.
			const FPoint2 v1(linkv1.x, linkv1.z);
			const FPoint2 v2(linkv2.x, linkv2.z);

			const float denom = v2.y*v1.x - v2.x*v1.y;
			if (fabs(denom) < 0.01)
			{
				// too parallel, pick a safety value
				distance_to_intersection[i].x = 1.0f;
				distance_to_intersection[i_next].y = 1.0f;
			}
			else
			{
				FPoint2 norm1(linkv1.z, -linkv1.x);
				FPoint2 norm2(linkv2.z, -linkv2.x);
				norm1.Normalize();
				norm2.Normalize();

				const FPoint2 center(m_p3.x, m_p3.z);
				const FPoint2 p1 = center + norm1 * width1;
				const FPoint2 p2 = center - norm2 * width2;

				const float ua = (v2.x*(p1.y - p2.y) - v2.y*(p1.x - p2.x)) / denom;
				const float ub = (v1.x*(p1.y - p2.y) - v1.y*(p1.x - p2.x)) / denom;

				distance_to_intersection[i].x = ua;
				distance_to_intersection[i_next].y = ub;
			}
		}
		// Go through the links again, picking the largest minimum
		for (int i = 0; i < NumLinks(); i++)
		{
			distance_to_intersection[i].z = std::max(distance_to_intersection[i].x,
				distance_to_intersection[i].y);
		}
		// Now we can finally set the two points where this link meets the
		//  intersection without overlapping with the other links
		for (int i = 0; i < NumLinks(); i++)
		{
			const TLink *pL = GetLink(i);
			v = GetUnitLinkVector(i);

			FPoint3 norm(v.z, 0, -v.x);
			norm.Normalize();
			norm *= pL->m_fLeftWidth;

			const float dist = distance_to_intersection[i].z;
			m_v[i * 2 + 0] = m_p3 + norm + (v * dist);
			m_v[i * 2 + 1] = m_p3 - norm + (v * dist);
		}
		many++;
	}
}
示例#9
0
文件: Roads.cpp 项目: kamalsirsa/vtp
vtTransform *vtRoadMap3d::GenerateGeometry(bool do_texture,
	bool bHwy, bool bPaved, bool bDirt, bool progress_callback(int))
{
	VTLOG("   vtRoadMap3d::GenerateGeometry\n");
	VTLOG("   Nodes %d, Links %d\n", NumNodes(), NumLinks());

	_CreateMaterials(do_texture);

	m_pGroup = new vtGroup;
	m_pGroup->setName("Roads");

	m_pTransform = new vtTransform;
	m_pTransform->addChild(m_pGroup);
	m_pTransform->SetTrans(FPoint3(0, m_fGroundOffset, 0));

	// We wrap the roads' geometry with an array of simple LOD nodes
	int a, b;
	for (a = 0; a < ROAD_CLUSTER; a++)
		for (b = 0; b < ROAD_CLUSTER; b++)
		{
			m_pRoads[a][b] = NULL;
		}

	_GatherExtents();

#if 0
	vtGeode *pGeode = CreateLineGridGeom(m_pMats, 0,
						   m_extents.min, m_extents.max, ROAD_CLUSTER);
	m_pGroup->addChild(pGeode);
#endif

	vtMesh *pMesh;
	int count = 0, total = NumLinks() + NumNodes();
	for (LinkGeom *pL = GetFirstLink(); pL; pL = pL->GetNext())
	{
		// Decide whether to construct this link
		bool include = false;
		if (bHwy && bPaved && bDirt)
			include = true;
		else
		{
			bool bIsDirt = (pL->m_Surface == SURFT_2TRACK || pL->m_Surface == SURFT_DIRT);
			if (bHwy && pL->m_iHwy != -1)
				include = true;
			if (bPaved && !bIsDirt)
				include = true;
			if (bDirt && bIsDirt)
				include = true;
		}
		if (include)
			pL->GenerateGeometry(this);
		count++;
		if (progress_callback != NULL)
			progress_callback(count * 100 / total);
	}
	count = 0;
	for (NodeGeom *pN = GetFirstNode(); pN; pN = pN->GetNext())
	{
		// What material to use?  We used to simply use "pavement", but that is
		// bad when they are e.g. trail or stone.  Now, we will try to guess
		// what to use by looking at the links here.
		int node_vti = VTI_PAVEMENT;
		for (int i = 0; i < pN->NumLinks(); i++)
		{
			LinkGeom *pL = pN->GetLink(i);
			switch (pL->m_vti)
			{
			case VTI_RAIL:
			case VTI_4WD:
			case VTI_TRAIL:
			case VTI_GRAVEL:
			case VTI_STONE:
				node_vti = pL->m_vti;
			}
		}
		VirtualTexture &vt = m_vt[node_vti];

		pMesh = pN->GenerateGeometry(vt);
		if (pMesh)
			AddMeshToGrid(pMesh, vt.m_idx);
		count++;
		if (progress_callback != NULL)
			progress_callback(count * 100 / total);
	}

	// return the top group, ready to be added to scene graph
	return m_pTransform;
}