Beispiel #1
0
void Quake3BSP_GL::RenderLevel(unsigned int bufferID)
{
	// Get the number of faces in our level
	int i = m_numOfLeafs;
	int leafIndex;

	if(!Camera::GetInstance().getVisibilityState()){
		// Finding the leaf the camera is in
		m_cameraPos = Camera::GetInstance().GetCamEye();
		leafIndex = FindLeaf(0,m_cameraPos);
		// Once the leaf is found, reset the bools for leaf searching
		m_foundLeaf=false;
		m_foundIndex=0;
	} else {
		// We are in a frozen state for visibility, so use the last stored camera position,
		// don't get the updated one.
		leafIndex = FindLeaf(0,m_cameraPos);
		// Once the leaf is found, reset the bools for leaf searching
		m_foundLeaf=false;
		m_foundIndex=0;
	}

	// Getting the cluster that leaf is assigned to
	int cluster = m_pLeafs[leafIndex].cluster;

	// Go through the BSP tree checking to draw only what is visible from our
	// current cluster and what is visible within the frustum
	while(i--)
	{
		// Getting the current leaf to check with our camera's leaf
		BSPLeaf *pLeaf = &(m_pLeafs[i]);

		// Cluster Visiblity check
		if(!IsClusterValid(cluster, pLeaf->cluster)) 
			continue;

		// Frustum visibility check
		if(!ViewFrustum::GetInstance().RectangleIntersect((float)pLeaf->min.x, (float)pLeaf->min.y, (float)pLeaf->min.z,
														  (float)pLeaf->max.x, (float)pLeaf->max.y, (float)pLeaf->max.z)){
			continue;
		}
		
		// The leaf must be valid to draw, set the counter for his number
		// of faces, then call RenderFaces to draw them all.
		int faceTotal = pLeaf->numOfLeafFaces;

		// Loop through and render all of the faces in this leaf
		while(faceTotal--)
		{
			int faceIndex = m_pLeafFaces[pLeaf->leafface + faceTotal];

			// Check if this is a valid face to draw
			if(m_pFaces[faceIndex].type != FACE_POLYGON)
				continue;

			RenderFace(bufferID, faceIndex);
		}
	}
}
status_t SNode::RenameEntry(const SString& name, const SString& rename) const
{
	if (name.FindFirst(*name.PathDelimiter()) < 0) {
		if (m_catalog != NULL) return m_catalog->RenameEntry(name, rename);
		get_catalog();
		return (m_catalog != NULL) ? m_catalog->RenameEntry(name, rename) : B_UNSUPPORTED;
	}
 
	SString parentName,parentRename;
	name.PathGetParent(&parentName);
	rename.PathGetParent(&parentRename);
	if (parentName != parentRename) {
		/*	We don't "yet" support renaming (really moving) entries
			across different nodes. */
		return B_UNSUPPORTED;		
	}

	sptr<INode> node = m_node;
	SString path(name);

	if (node != NULL) {
		status_t err = FindLeaf(&node,&path);
		if (err != B_OK) return err;

		sptr<ICatalog> catalog = ICatalog::AsInterface(m_node->AsBinder());
		return (catalog != NULL) ? catalog->RenameEntry(path, SString(rename.PathLeaf())) : B_UNSUPPORTED;
	}
	
	return B_UNSUPPORTED; // We don't yet support renaming values in an SValue...
}
Beispiel #3
0
//=====================================================================================
//	PlaceEntities
//=====================================================================================
geBoolean PlaceEntities(GBSP_Node *RootNode)
{				
	int32		i;
	GBSP_Node	*Node;
	geBoolean	Empty;

	Empty = GE_FALSE;

	for (i=1; i< NumEntities; i++)
	{
		if (!(Entities[i].Flags & ENTITY_HAS_ORIGIN))		// No "Origin" in entity
			continue;

		Node = FindLeaf(RootNode, &Entities[i].Origin);
		if (!Node)
			return GE_FALSE;

		if (!(Node->Contents & BSP_CONTENTS_SOLID2))
		{
			Node->Entity = i;
			Empty = GE_TRUE;
		}
	}
	
	if (!Empty)
	{
		GHook.Error("PlaceEntities:  No valid entities for operation %i.\n", NumEntities);
		return GE_FALSE;
	}
	
	return GE_TRUE;
}
Beispiel #4
0
//=====================================================================================
//	FillFromEntities
//=====================================================================================
geBoolean FillFromEntities(GBSP_Node *RootNode)
{
	int32		i;
	GBSP_Node	*Node;
	geBoolean	Empty;

	Empty = GE_FALSE;
	
	for (i=1; i< NumEntities; i++)	// Don't use the world as an entity (skip 0)!!
	{
		if (!(Entities[i].Flags & ENTITY_HAS_ORIGIN))		// No "Origin" in entity
			continue;

		Node = FindLeaf(RootNode, &Entities[i].Origin);

		if (Node->Contents & BSP_CONTENTS_SOLID2)
			continue;
		
		// There is at least one entity in empty space...
		Empty = GE_TRUE;

		if (!FillLeafs2_r(Node))
			return GE_FALSE;
	}

	if (!Empty)
	{
		GHook.Error("FillFromEntities:  No valid entities for operation.\n");
		return GE_FALSE;
	}

	return GE_TRUE;
}
t_rc INXM_IndexHandle::InsertEntry(void *pData, const REM_RecordID &rid) {
	t_rc rc;
		
	/* Tree does not exist yet.
	 * Start a new tree.
	 */	
	if (this->inxmFileHeader.treeRoot == 0) {
		return StartNewTree(pData, rid);
	}
	
	/* If tree already exists. */
	
	/* If key exists, append. */
	rc = FindAndAppend(this->inxmFileHeader.treeRoot, pData, rid);
	if (rc == OK) { return rc; }

	/* Else add new node and data to b+ tree. */
	STORM_PageHandle leafPageHandle;
	rc = FindLeaf(this->inxmFileHeader.treeRoot, pData, leafPageHandle);
	if (rc != OK) { return rc; }
	
	/* Case: leaf has room for key and pointer.
	 */
	
	if (LeafHasRoom(leafPageHandle)) {
		return InsertIntoLeaf(leafPageHandle, pData, rid);
	}
	
	/* Case: leaf must be split.
	 */
	
	return InsertIntoLeafAfterSplitting(this->inxmFileHeader.treeRoot, leafPageHandle, pData, rid);
	
	return(OK);
}
Beispiel #6
0
void CQuake3BSP::RenderLevel(const CVector3 &vPos)
{
    // Reset our bitset so all the slots are zero.
    m_FacesDrawn.ClearAll();

    // Grab the leaf index that our camera is in
    int leafIndex = FindLeaf(vPos);

    // Grab the cluster that is assigned to the leaf
    int cluster = m_pLeafs[leafIndex].cluster;

    // Initialize our counter variables (start at the last leaf and work down)
    int i = m_numOfLeafs;
    g_VisibleFaces = 0;

    // Go through all the leafs and check their visibility
    while(i--)
    {
        // Get the current leaf that is to be tested for visibility from our camera's leaf
        tBSPLeaf *pLeaf = &(m_pLeafs[i]);

        // If the current leaf can't be seen from our cluster, go to the next leaf
        if(!IsClusterVisible(cluster, pLeaf->cluster))
            continue;

        // If the current leaf is not in the camera's frustum, go to the next leaf
        if(!g_Frustum.BoxInFrustum((float)pLeaf->min.x, (float)pLeaf->min.y, (float)pLeaf->min.z,
                                   (float)pLeaf->max.x, (float)pLeaf->max.y, (float)pLeaf->max.z))
            continue;

        // If we get here, the leaf we are testing must be visible in our camera's view.
        // Get the number of faces that this leaf is in charge of.
        int faceCount = pLeaf->numOfLeafFaces;

        // Loop through and render all of the faces in this leaf
        while(faceCount--)
        {
            // Grab the current face index from our leaf faces array
            int faceIndex = m_pLeafFaces[pLeaf->leafface + faceCount];

            // Before drawing this face, make sure it's a normal polygon
            if(m_pFaces[faceIndex].type != FACE_POLYGON) continue;

            // Since many faces are duplicated in other leafs, we need to
            // make sure this face already hasn't been drawn.
            if(!m_FacesDrawn.On(faceIndex))
            {
                // Increase the rendered face count to display for fun
                g_VisibleFaces++;

                // Set this face as drawn and render it
                m_FacesDrawn.Set(faceIndex);
                RenderFace(faceIndex);
            }
        }
    }
}
Beispiel #7
0
void FindLeaf(std::ostream& output, Tree& node, Graph& g)
{
	if((node.m_son == NULL) || (node.m_weight == -1))
		output << "  {\"leaf\":" << g.m_switch[node.m_id] << "},\n";
	Tree* son = node.m_son;
	while(son != NULL)
	{
		FindLeaf(output, *son, g);
		son = son->m_brother;
	}
}
Beispiel #8
0
void showLeaf(BinTree bt)
{
	int i,j;
	BinTree p[16];
	FindLeaf(bt,p);
	for(i=0;p[i];i++)
	{	
		j=0;
		while(p[i]!=BTXY[j].bt&&j<31)j++;
		SignFilledCircle(BTXY[j].x,BTXY[j].y,BTXY[j].bt->data);
		delay(200);
	}
	
}
Beispiel #9
0
static u_long *
FindCounter(
    struct dyn_counter **ppdc,
    u_long ix,
    int fcreate)
{
    struct dyn_counter *pdc;
    struct node *pnode;
    u_long *pcounter;

    if (ldebug)
	fprintf(stderr,"FindCounter(p, %lu) called\n", ix);

    /* if the counter tree doesn't exist yet, create it */
    if (*ppdc == NULL) {
	*ppdc = MakeCounterStruct();
    }
    pdc = *ppdc;

    /* track MAX and MIN */
    if (ix > pdc->maxix)
	pdc->maxix = ix;
    if (ix < pdc->minix)
	pdc->minix = ix;

    if (ldebug>1)
	PrintTree(pdc->tree);

    /* scale (TRUNCATE) the index by the granularity */
    ix /= (*ppdc)->gran;

    /* find the leaf node */
    pnode = FindLeaf(pdc, &pdc->tree,
		     pdc->tree?pdc->tree->depth:1,
		     ix, fcreate);
    if (pnode == NULL)
	return(NULL);

    /* find the right counter */
    pcounter = FindTwig(pnode, ix);

    return(pcounter);
}
status_t SNode::RemoveEntry(const SString& name) const
{
	if (name.FindFirst(*name.PathDelimiter()) < 0) {
		if (m_catalog != NULL) return m_catalog->RemoveEntry(name);
		get_catalog();
		return (m_catalog != NULL) ? m_catalog->RemoveEntry(name) : B_UNSUPPORTED;
	}

	sptr<INode> node = m_node;
	SString path(name);

	if (node != NULL) {
		status_t err = FindLeaf(&node,&path);
		if (err != B_OK) return err;

		sptr<ICatalog> catalog = ICatalog::AsInterface(m_node->AsBinder());
		return (catalog != NULL) ? catalog->RemoveEntry(path) : B_UNSUPPORTED;
	}
	
	return B_UNSUPPORTED; // We don't yet support removing values in an SValue...
}
Beispiel #11
0
/* the heart of the routines, a 10-ary recursize search */
static struct node *
FindLeaf(
    struct dyn_counter *pdc,
    struct node **ptree,
    u_long depth,
    u_long value,
    int fcreate)
{
    u_long hidigit;
    u_long lowdigits;
    u_long valdepth;
    u_long valunits;
    u_long temp_value;

    if (ldebug)
	fprintf(stderr,"FindLeaf(%p(depth %lu), %lu, %s) called\n",
		*ptree,
		*ptree?((*ptree)->depth):0,
		value,
		fcreate?"CREATE":"NOCREATE");


    /* if the tree is empty and we haven't asked to "create", then not found */
    if ((*ptree == NULL) && (!fcreate))
	return(NULL);

    /* determine the units of the MSDigit (the depth) */
    valdepth = 1;
    valunits = 1;
    temp_value = value;
    while (temp_value >= CARDINALITY) {
	temp_value /= CARDINALITY;
	++valdepth;
	valunits *= CARDINALITY;
    }

    if (ldebug)
	fprintf(stderr,"FindLeaf: value:%lu  depth:%lu  units:%lu\n",
		value, valdepth, valunits);


    /* is the tree deep enough? */
    if ((*ptree == NULL) || (valdepth > (*ptree)->depth)) {
	u_long correct_depth;

	/* the correct depth is the MAX of: */
	/* - the depth of the number we're looking for */
	/* - the value of "depth" passed down */
	correct_depth = depth;
	if (valdepth > correct_depth)
	    correct_depth = valdepth;

	/* if the tree isn't that deep and we haven't asked to create, then not found */
	if (!fcreate)
	    return(NULL);

	/* increase the depth of this branch */
	*ptree = MakeDepth((*ptree), correct_depth);

	/* linked list of leaves no longer valid! */
	pdc->firstleaf = NULL;

	/* adjust */
	depth = correct_depth;
    }

    /* if we're at the leaf depth, then we're done */
    if ((*ptree)->depth == 1)
	return(*ptree);

    /* if the "depth" of val is less than the depth of this node,
       recurse down the "0" branch without changing the number */
    if (valdepth < (*ptree)->depth) {
	return(FindLeaf(pdc,
			&(*ptree)->un.down[0],
			depth-1,
			value,
			fcreate));
    }

    /* (else), already the correct level */

    /* break the number into the MSDigit and LSDigits */
    hidigit = value / valunits;
    lowdigits = value % valunits;

    if (ldebug)
	fprintf(stderr,"for value %lu,  depth:%lu  units:%lu  hidigit:%lu  lowdigits:%lu\n",
		value, valdepth, valunits, hidigit, lowdigits);

    /* recurse */
    return(FindLeaf(pdc,
		    &(*ptree)->un.down[hidigit],
		    depth-1,
		    lowdigits,
		    fcreate));
}
Beispiel #12
0
int Quake3BSP_GL::FindLeaf(int nodeIndex, const Vector &vPos)
{
	float distance = 0.0f;
	int currentIndex = 0;

	// This is the recursive function to sort through our BSP tree and find which leaf 
	// the camera is residing in.  Ideally, we would want to optimize our search by
	// checking the camera direction with the plane normal, thus reducing more checks
	// but for the moment, we'll just check the position with the splitting planes
	// to decide which side of the node we are on till we reach the leaf.  Node side indexes
	// are always positive, but for a leaf, it's negative, which is our indicator we are at a 
	// leaf, not another node, so we'll check that first, which would end the recursion.
	
	if(nodeIndex < 0 ){
		return nodeIndex;
	} else {
		// Still have not found the leaf, keep looking.  First we get the node, and it's splitter plane.
		// From there, we check the distance from the camera position to the splitter plane.  So,
		// if it is positive, we are on the front of the plane, negative, back of the plane.
		
		const BSPNode&  node = m_pNodes[nodeIndex];
		const BSPPlane& plane = m_pPlanes[node.plane];

		// Plane equation to check distance.
		distance =	plane.vNormal.x * vPos.x + 
					plane.vNormal.y * vPos.y + 
					plane.vNormal.z * vPos.z - plane.d;

		// Camera in front of the plane
        if(distance >= 0){
			// We treat sitting on the plane as being in front.
			currentIndex = FindLeaf(node.front, vPos);
			if(currentIndex < 0){
				m_foundLeaf = true;
				m_foundIndex = ~currentIndex;
			}
			if(!m_foundLeaf){
				currentIndex = FindLeaf(node.back, vPos);
				if(currentIndex < 0){
					m_foundLeaf = true;
					m_foundIndex = ~currentIndex;
				}
			}
        } else {
			// Behind the plane
			if(!m_foundLeaf){
        		currentIndex = FindLeaf(node.back, vPos);
				if(currentIndex < 0){
					m_foundLeaf = true;
					m_foundIndex = ~currentIndex;
				}
			}
			if(!m_foundLeaf){
				currentIndex = FindLeaf(node.front, vPos);
				if(currentIndex < 0){
					m_foundLeaf = true;
					m_foundIndex = ~currentIndex;
				}
			}
        }
		
		// Either a leaf was found or not, we are just exiting out of our recursion passing back the index.
		return m_foundIndex;
    }
}
t_rc INXM_IndexHandle::FindAndAppend(int rootPageID, void *key, const REM_RecordID &rid) {
	t_rc rc;
	
	STORM_PageHandle leafPageHandle;
	rc = FindLeaf(rootPageID, key, leafPageHandle);
	if (rc != OK) { return rc; }
	
	INXM_InitPageHeader initPageHeader;
	rc = LoadInitHeaders(leafPageHandle, initPageHeader);
	if (rc != OK) { return rc; }
	
	INXM_Node node;
	int i;
	for (i=0; i < initPageHeader.nItems; i++) {
		rc = ReadNode(leafPageHandle, i, node);
		if (rc != OK) { return rc; }
		
		if (KeyCmp(key, node.key) == 0) {
			break;
		}
	}
	
	if (i == initPageHeader.nItems) {		
		return(INXM_KEY_NOT_FOUND);
	} else {
		
		int slotOfNewData;
		STORM_PageHandle lastDataPageHandle;
		
		rc = this->sfh.GetPage(this->inxmFileHeader.lastDataPage, lastDataPageHandle);
		if (rc != OK) { return rc; }
		
		/* Check if last data page has room. */
		
		INXM_InitPageHeader initPageHeader;
		
		rc = LoadInitHeaders(lastDataPageHandle, initPageHeader);
		if (rc != OK) { return rc; }
		
		int room = PAGE_DATA_SIZE-(INXM_INITPAGEHEADER_SIZE+(initPageHeader.nItems+1)*INXM_DATA_SIZE);
		
		/* If no room. Reserve new last data page. */
		if (room < 0 ) {
			CreateLastDataPage(lastDataPageHandle);
			
			/* Write last data. */
			WriteData(lastDataPageHandle, rid, slotOfNewData);
		} else if (room == 0) {
			/* Write last data. */
			WriteData(lastDataPageHandle, rid, slotOfNewData);
			
			CreateLastDataPage(lastDataPageHandle);
		} else {
			/* Write last data. */
			WriteData(lastDataPageHandle, rid, slotOfNewData);
		}

		
		/* Update last-1 link data. */
		STORM_PageHandle listDataPageHandle;
		this->sfh.GetPage(node.left, listDataPageHandle);
		
		INXM_Data data;
		ReadData(listDataPageHandle, node.slot, data);
		
		int fromWhere = node.slot;
		
		while (data.nextPageID != 0) {
			this->sfh.GetPage(data.nextPageID, listDataPageHandle);
			fromWhere = data.nextSlot;
			ReadData(listDataPageHandle, data.nextSlot, data);
		}
		
		data.nextPageID=this->inxmFileHeader.lastDataPage;
		data.nextSlot=slotOfNewData;
		
		/* Write updated last-1 data of list. */
		
		EditData(listDataPageHandle, fromWhere, data);
		
		return(OK);
	}
	
}
Beispiel #14
0
void Output_Data(Graph& g)
{
	srand((unsigned)time(NULL));
	ofstream output("MusicDoubanGraph.js");
	output << "var graph = {\n"
		" \"nodes\":[\n";
	int temp = 0;
	for(int i = 0;i < g.m_v;i++)
		if(g.m_hash[i])
	{
		temp = rand() % 19 + 1;
		output << "  {\"name\":\"" << g.m_name[i] 
		<< "\",\"group\":" << temp << "},\n";
	}
	output << "],\n\"links\":[\n";

	int num = 0;
	int* switch_ = new int[g.m_e];
	for(int i = 0;i < g.m_v;i++)
		if(g.m_hash[i])
		for(int j = g.m_p[i];j < g.m_p[i+1];j++)
			if(g.m_hash[g.m_q[j]])
			{
				switch_[j] = num;
				num++;
			output << "  {\"source\":" << g.m_switch[i] <<
			",\"target\":" << g.m_switch[g.m_q[j]] << 
			",\"value\":" << (int)(g.m_r[j] / (double)30)+2 << "},\n";
			}
	//output << "],\n\"minpath\":[\n";
	//for(int i = 0;i < g.m_v;i++)
	//	if(g.m_hash[i])
	//	{
	//		vector<vector<int>> path;
	//		vector<vector<int>> epath;
	//		for(int j = 0;j < g.m_v;j++)
	//			if((i != j) && (g.m_hash[j]))
	//			{
	//				Path p;
	//				Enquire_MinPath(i, j, g, p);
	//				Add(path, epath, p);
	//			}

	//		int n = path.size();
	//		char s[500];
	//		IntToStr(g.m_switch[i], s);
	//		char* ss = s;
	//		while(*ss != 0)ss++;
	//		*ss = ' ';
	//		ss++;
	//		*ss = 0;
	//		for(int j = 0;j < n;j++)
	//		{
	//			PathToStr(g, epath[j], switch_,  ss);
	//			output << "  {\"epath\":\"" << s << "\",\"path\":\"";
	//			*s = 0;
	//			PathToStr(g, path[j], s);
	//			output << s << "\"},\n";
	//		}
	//	}
	output << "],\n\"mst_edge\":[\n";
	Tree tree;
	Enquire_MST(g, tree);
	TreeShow(output, tree, switch_);
	output << "],\n\"mst_leaf\":[\n";
	FindLeaf(output, tree, g);
	output << " ]\n}";
}
Beispiel #15
0
void CBspMapMeshProvider::GetMeshes(Palleon::MeshArray& meshes, const Palleon::CCamera* camera)
{
	const Bsp::LeafArray& leaves(m_bspFile->GetLeaves());
	const Bsp::LeafFaceArray& leafFaces(m_bspFile->GetLeafFaces());
	const Bsp::FaceArray& faces(m_bspFile->GetFaces());
	const Bsp::VISDATA& visData(m_bspFile->GetVisData());

	CMatrix4 invViewMatrix = camera->GetViewMatrix().Inverse();
	CVector3 cameraPosition = CVector3(invViewMatrix(3, 0), invViewMatrix(3, 1), invViewMatrix(3, 2));

	int32 leafIndex = FindLeaf(cameraPosition);
	const Bsp::LEAF& leaf(leaves[leafIndex]);

	CFrustum cameraFrustum = camera->GetFrustum();

	memset(m_faceVisibleSet, 0, m_faceVisibleSetSize);

	if(leaf.cluster != -1)
	{
		const uint8* visVector = &visData.vectors[leaf.cluster * visData.vectorSize];
		for(uint32 i = 0; i < leaves.size(); i++)
		{
			const Bsp::LEAF& testLeaf = leaves[i];
			uint32 testCluster = testLeaf.cluster;
			if(static_cast<int32>(testCluster) < 0) continue;
			uint8 visByte = visVector[testCluster / 8];
			bool visible = (visByte & (1 << (testCluster & 7))) != 0;
			if(visible)
			{
				CVector3 leafBoxMin = Bsp::ConvertToAthenaCoord(static_cast<float>(testLeaf.mins[0]), static_cast<float>(testLeaf.mins[1]), static_cast<float>(testLeaf.mins[2]));
				CVector3 leafBoxMax = Bsp::ConvertToAthenaCoord(static_cast<float>(testLeaf.maxs[0]), static_cast<float>(testLeaf.maxs[1]), static_cast<float>(testLeaf.maxs[2]));

				if(cameraFrustum.Intersects(leafBoxMin, leafBoxMax))
				{
					for(unsigned int i = 0; i < testLeaf.leafFaceCount; i++)
					{
						unsigned int faceIndex = leafFaces[i + testLeaf.leafFaceIndex];
						unsigned int faceByte = faceIndex / 8;
						assert(faceByte < m_faceVisibleSetSize);
						m_faceVisibleSet[faceByte] |= (1 << (faceIndex & 7));
					}
				}
			}
		}
	}

	m_visibleFaceIndices.clear();

	for(unsigned int i = 0; i < faces.size(); i++)
	{
		const Bsp::FACE& currentFace = faces[i];
		if(currentFace.textureIndex != -1)
		{
			BspMapMaterialPtr faceMaterial = m_bspMapResourceProvider->GetMaterial(currentFace.textureIndex);
			if(faceMaterial->GetIsSky()) continue;
		}

		unsigned int faceByte = i / 8;
		if(m_faceVisibleSet[faceByte] & (1 << (i & 7)))
		{
			m_visibleFaceIndices.push_back(i);
		}
	}

	if(m_visibleFaceIndices.size() == 0) return;

	std::sort(m_visibleFaceIndices.begin(), m_visibleFaceIndices.end(), FaceSorter(faces));

	uint32 currentTextureIdx = -2;
	uint32 currentLightMapIdx = -2;
	BatchMeshPtr currentBatch;
	unsigned int currentBatchIndex = 0;
	for(unsigned int i = 0; i < m_visibleFaceIndices.size(); i++)
	{
		uint32 faceIndex = m_visibleFaceIndices[i];
		const Bsp::FACE& currentFace = faces[faceIndex];
		BspFaceMeshPtr faceMesh = m_faceMeshes[faceIndex];
		if(!faceMesh) continue;
		bool needNewBatch = false;
		needNewBatch |= (currentFace.textureIndex != currentTextureIdx);
		needNewBatch |= (currentFace.lightMapIndex != currentLightMapIdx);
		needNewBatch |= (currentBatch && !currentBatch->CanWriteMesh(faceMesh->GetVertexCount(), faceMesh->GetIndexCount()));
		if(needNewBatch)
		{
			//Switch to new batch
			if(currentBatch)
			{
				currentBatch->EndBatch();
			}
			currentBatch = m_batches[currentBatchIndex++];
			meshes.push_back(currentBatch.get());
			currentBatch->BeginBatch();
			currentTextureIdx = currentFace.textureIndex;
			currentLightMapIdx = currentFace.lightMapIndex;

			//Prepare material
			Palleon::MaterialPtr batchMaterial = currentBatch->GetMaterial();
			BspMapMaterialPtr faceMaterial = m_bspMapResourceProvider->GetMaterial(currentTextureIdx);
			
			for(unsigned int i = 0; i < Palleon::CMaterial::MAX_TEXTURE_SLOTS; i++)
			{
				batchMaterial->SetTexture(i, Palleon::TexturePtr());
			}

			for(unsigned int i = 0; i < faceMaterial->GetPassCount(); i++)
			{
				const BspMapPassPtr& pass(faceMaterial->GetPass(i));
				Palleon::TEXTURE_COMBINE_MODE combineMode = pass->GetBlendingFunction();
				if(pass->GetTextureSource() == CBspMapPass::TEXTURE_SOURCE_DIFFUSE)
				{
					batchMaterial->SetTexture(i, pass->GetTexture());
					batchMaterial->SetTextureMatrix(i, pass->GetUvMatrix());
					batchMaterial->SetTextureCoordSource(i, Palleon::TEXTURE_COORD_UV0);
					batchMaterial->SetTextureCombineMode(i, combineMode);
				}
				else
				{
					batchMaterial->SetTexture(i, m_bspMapResourceProvider->GetLightMap(currentLightMapIdx));
					batchMaterial->SetTextureMatrix(i, CMatrix4::MakeIdentity());
					batchMaterial->SetTextureCoordSource(i, Palleon::TEXTURE_COORD_UV1);
					batchMaterial->SetTextureCombineMode(i, combineMode);
				}
				batchMaterial->SetTextureAddressModeU(i, Palleon::TEXTURE_ADDRESS_REPEAT);
				batchMaterial->SetTextureAddressModeV(i, Palleon::TEXTURE_ADDRESS_REPEAT);
			}
		}

		assert(currentBatch->CanWriteMesh(faceMesh->GetVertexCount(), faceMesh->GetIndexCount()));
		currentBatch->WriteMesh(faceMesh->GetVertices(), faceMesh->GetVertexCount(), faceMesh->GetIndices(), faceMesh->GetIndexCount());
	}

	if(currentBatch)
	{
		currentBatch->EndBatch();
	}
}
Beispiel #16
0
//	this will filter all the faces that should be drawn
void TSRBSPTree::FilterFaces( TSRCamera* _pCamera, TSRBSPFace** m_ppFaces, vector< TSRBSPDoor* >&	AllDoors )
{
    // Reset our bit set so all the slots are Zero.
    m_FacesDrawn.ClearAll();

    // Grab the leaf index that our camera is in
    int leafIndex = FindLeaf( _pCamera->m_Loc );

    // Grab the cluster that is Assigned to the leaf
    int cluster = Leafs[ leafIndex ].cluster;

    //	clear everything to be refilled again
    m_apDoors.clear();
    m_apTransparentFaces.clear();
    m_apPunchThroughFaces.clear();
    m_apOpaqueFaces.clear();

    TSRFrustum frustum;

    frustum.Update( _pCamera->GetProjectionMatrix().d, _pCamera->GetViewMatrix().d );

    for ( unsigned int j = 0; j < AllDoors.size(); j++ )
    {
        if ( !frustum.CanViewBox( AllDoors[ j ]->m_Box.m_vMin.x, AllDoors[ j ]->m_Box.m_vMin.y, AllDoors[ j ]->m_Box.m_vMin.z, AllDoors[ j ]->m_Box.m_vMax.x, AllDoors[ j ]->m_Box.m_vMax.y, AllDoors[ j ]->m_Box.m_vMax.z ) )
        {
            continue;
        }
        m_apDoors.push_back( AllDoors[ j ] );
    }
    int i = NumLeafs;
    // Go through all the leafs and check their visibility
    while ( i-- )
    {
        // Get the current leaf that is to be tested for visibility from our camera's leaf
        tBSPLeaf *pLeaf = &( Leafs[ i ] );


        // If the current leaf can't be seen from our cluster, go to the next leaf
        if ( !IsVisible( cluster, pLeaf->cluster ) )
        {
            continue;
        }

        // If the current leaf is not in the camera's frustum, go to the next leaf
        if ( !frustum.CanViewBox( ( float ) pLeaf->min.x, ( float ) pLeaf->min.y, ( float ) pLeaf->min.z, ( float ) pLeaf->max.x, ( float ) pLeaf->max.y, ( float )pLeaf->max.z ) )
        {
            continue;
        }

        // If we get here, the leaf we are testing must be visible in our camera's view.
        // Get the number of faces that this leaf is in charge of.
        int faceCount = pLeaf->numOfLeafFaces;

        // Loop through and Render all of the faces in this leaf
        while ( faceCount-- )
        {
            // Grab the current face index from our leaf faces array
            int faceIndex = LeafFaces[ pLeaf->leafface + faceCount ];

            // Since many faces are duplicated in other leafs, we need to
            // make sure this face already hasn't been drawn.
            if ( !m_FacesDrawn.On( faceIndex ) ) 
            {
                // Set this face as drawn and Render it
                m_FacesDrawn.Set( faceIndex );

                //	only static faces are Added
                if ( m_ppFaces[ faceIndex ]->m_Owner == FACE_STATIC )
                {
                    switch(m_ppFaces[faceIndex]->m_RenderMode)
                    {
                        case FACE_NONE:
                            break;
                        case FACE_NORMAL:
                            m_apOpaqueFaces.push_back(m_ppFaces[faceIndex]);
                            break;
                        case FACE_BLENDED:
                            m_apTransparentFaces.push_back(m_ppFaces[faceIndex]);
                            break;
                        case FACE_ALPHA:
                            m_apPunchThroughFaces.push_back(m_ppFaces[faceIndex]);
                            break;
                    }
                }
            }
        }
    }
}
Beispiel #17
0
void CQuake3BSP::RenderLevel(const CVector3 &vPos)
{
	// Reset our bitset so all the slots are zero.
	m_FacesDrawn.ClearAll();


/////// * /////////// * /////////// * NEW * /////// * /////////// * /////////// *

	// In this new revision of RenderLevel(), we do things a bit differently.
	// Instead of looping through all the faces, we now want to loop through
	// all of the leafs.  Each leaf stores a list of faces assign to it.
	// We call FindLeaf() to find the current leaf index that our camera is
	// in.  This leaf will then give us the cluster that the camera is in.  The
	// cluster is then used to test visibility between our current cluster
	// and other leaf clusters.  If another leaf's cluster is visible from our 
	// current cluster, the leaf's bounding box is checked against our frustum.  
	// Assuming the bounding box is inside of our frustum, we draw all the faces
	// stored in that leaf.  

	// Grab the leaf index that our camera is in
	int leafIndex = FindLeaf(vPos);

	// Grab the cluster that is assigned to the leaf
	int cluster = m_pLeafs[leafIndex].cluster;

	// Initialize our counter variables (start at the last leaf and work down)
	int i = m_numOfLeafs;
	g_VisibleFaces = 0;

	// Go through all the leafs and check their visibility
	while(i--)
	{
		// Get the current leaf that is to be tested for visibility from our camera's leaf
		tBSPLeaf *pLeaf = &(m_pLeafs[i]);

		// If the current leaf can't be seen from our cluster, go to the next leaf
		if(!IsClusterVisible(cluster, pLeaf->cluster)) 
			continue;

		// If the current leaf is not in the camera's frustum, go to the next leaf
		if(!g_Frustum.BoxInFrustum((float)pLeaf->min.x, (float)pLeaf->min.y, (float)pLeaf->min.z,
		  	 				       (float)pLeaf->max.x, (float)pLeaf->max.y, (float)pLeaf->max.z))
			continue;
		
		// If we get here, the leaf we are testing must be visible in our camera's view.
		// Get the number of faces that this leaf is in charge of.
		int faceCount = pLeaf->numOfLeafFaces;

		// Loop through and render all of the faces in this leaf
		while(faceCount--)
		{
			// Grab the current face index from our leaf faces array
			int faceIndex = m_pLeafFaces[pLeaf->leafface + faceCount];

			// Before drawing this face, make sure it's a normal polygon
			if(m_pFaces[faceIndex].type != FACE_POLYGON) continue;

			// Since many faces are duplicated in other leafs, we need to
			// make sure this face already hasn't been drawn.
			if(!m_FacesDrawn.On(faceIndex)) 
			{
				// Increase the rendered face count to display for fun
				g_VisibleFaces++;

				// Set this face as drawn and render it
				m_FacesDrawn.Set(faceIndex);
				RenderFace(faceIndex);
			}
		}			
	}

/////// * /////////// * /////////// * NEW * /////// * /////////// * /////////// *

}