Exemplo n.º 1
0
/**
* CABT::createTree
* @date Modified Apr 17, 2006
*/
void CABT::createTree(std::vector<CMesh::SVertex>& vVertex, std::vector<CMaterial*>& vMaterials)
{
	if(m_pRoot)
		destroyTree();

	m_pRoot = createSubtree(vVertex, vMaterials);
	m_pRenderQueue = new CRenderQueue(m_dwNumSolids, m_dwNumTrans);
}
Exemplo n.º 2
0
    Value find(const Key& k)
    {
#if 1
        auto subtree = this;
        while (subtree != nullptr) {
            if (k == subtree->key) return subtree->value;

            if (k < subtree->key) {
                if (!subtree->leftPendingValues.empty()) {
#if 1
                    Value pValue;
                    if (subtree->createSubtree(subtree->leftPendingValues,
                                               subtree->left,
                                               k,
                                               pValue)) {
                        return pValue;
                    }
#else
                    subtree->createSubtree(subtree->leftPendingValues, subtree->left);
#endif
                }

                subtree = subtree->left;
            }

            if (k > subtree->key) {
                if (!subtree->rightPendingValues.empty()) {
#if 1
                    Value pValue;
                    if (subtree->createSubtree(subtree->rightPendingValues,
                                               subtree->right,
                                               k,
                                               pValue)) {
                        return pValue;
                    }
#else
                    subtree->createSubtree(subtree->rightPendingValues, subtree->right);
#endif
                }

                subtree = subtree->right;
            }
        }
        throw;
#else
        if (k < key) {
            if (!leftPendingValues.empty()) {
                createSubtree(leftPendingValues, left);
            }
            
            if (left) {
                return left->find(k);
            }
        }
        
        if (k > key) {
            if (!rightPendingValues.empty()) {
                createSubtree(rightPendingValues, right);
            }
            
            if (right) {
                return right->find(k);
            }
        }

        if (key == k) {
            return value;
        }

        throw;
#endif
    }
Exemplo n.º 3
0
/**
* CABT::createSubtree
* @date Modified Apr 17, 2006
*/
CABT::SABTNode* CABT::createSubtree(std::vector<CMesh::SVertex>& vVertex, std::vector<CMaterial*>& vMaterials)
{
	if(vVertex.empty())
		return NULL;

	// Generate AABB for the geometry set.
	SABTNode* pNode = new SABTNode;
	pNode->dwColor = D3DCOLOR_XRGB(rand()%255, rand()%255, rand()%255);
	generateAABB(vVertex, pNode->m_oAABB);

	// Check against triangle limits
	if(vVertex.size() > ABT_MAX_NODETRIANGLES * 3)
	{
		// Not a leaf. Break down the vertices.
		pNode->m_bIsLeaf = false;
		pNode->m_pVB = NULL;
		pNode->m_nVertCount = 0;

		SPlane oSplitPlane, oSplitGrow1, oSplitGrow2;
		unsigned int unAxis = getSplittingPlane(vVertex, pNode->m_oAABB, oSplitPlane);

		oSplitGrow1 = oSplitPlane;
		oSplitGrow2 = oSplitPlane;

		// Calculate growth planes
		float fChildAABBLen = (getSplitPercent(oSplitGrow1, pNode->m_oAABB) * AABB_LEN(pNode->m_oAABB, unAxis));
		VEC_ARRAY(oSplitGrow1.point, unAxis) += fChildAABBLen * ABT_GROWTH_FACTOR;
		VEC_ARRAY(oSplitGrow2.point, unAxis) -= (AABB_LEN(pNode->m_oAABB, unAxis) - fChildAABBLen) * ABT_GROWTH_FACTOR;

		// Split geometry
		std::vector<CMesh::SVertex> vVertexLeft, vVertexRight;
		std::vector<CMaterial*> vMaterialLeft, vMaterialRight;
		vVertexLeft.reserve(vVertex.size() * 3 / 4);
		vVertexRight.reserve(vVertex.size() * 3 / 4);
		vMaterialLeft.reserve(vMaterials.size() * 3 / 4);
		vMaterialRight.reserve(vMaterials.size() * 3 / 4);

		unsigned int nSplits = 0;
		CMesh::SVertex vTriangle[3];
		unsigned int unTriangle;
		for(unsigned int i = 0; i < vVertex.size(); i += 3)
		{
			ETriClass eClass = getTriangleClassification(&(vVertex[i]), oSplitPlane);
			unTriangle = i / 3;

			// Split required
			if(eClass == TRI_SPLIT)
			{
				// Check against grown plane
				eClass = getTriangleClassification(&(vVertex[i]), oSplitGrow1);
				if(eClass == TRI_SPLIT)
				{
					eClass = getTriangleClassification(&(vVertex[i]), oSplitGrow2);
					if(eClass == TRI_SPLIT)
					{
						// Split the triangle
						std::vector<CMesh::SVertex> vFront, vBack;
						splitTriangle(&(vVertex[i]), oSplitPlane, vFront, vBack);

						ACEASSERT((vFront.size() % 3) == 0 && (vBack.size() % 3) == 0);

						// Add triangles to global list
						for(unsigned int j = 0; j < vFront.size(); ++j)
							vVertexLeft.push_back(vFront[j]);
						for(unsigned int j = 0; j < vBack.size(); ++j)
							vVertexRight.push_back(vBack[j]);

						// Triangle split; Duplicate material reference
						for(unsigned int j = 0; j < vFront.size() / 3; ++j)
							vMaterialLeft.push_back(vMaterials[unTriangle]);
						for(unsigned int j = 0; j < vBack.size() / 3; ++j)
							vMaterialRight.push_back(vMaterials[unTriangle]);

						++nSplits;
						continue;
					}
				}
			}

			if(eClass == PT_FRONT)
			{
				vVertexLeft.push_back(vVertex[i]);
				vVertexLeft.push_back(vVertex[i+1]);
				vVertexLeft.push_back(vVertex[i+2]);
				vMaterialLeft.push_back(vMaterials[unTriangle]);
			}
			else if(eClass == PT_BACK)
			{
				vVertexRight.push_back(vVertex[i]);
				vVertexRight.push_back(vVertex[i+1]);
				vVertexRight.push_back(vVertex[i+2]);
				vMaterialRight.push_back(vMaterials[unTriangle]);
			}
			else
			{
				// Coplanar. Keep tree balanced.
				if(vVertexLeft.size() < vVertexRight.size())
				{
					vVertexLeft.push_back(vVertex[i]);
					vVertexLeft.push_back(vVertex[i+1]);
					vVertexLeft.push_back(vVertex[i+2]);
					vMaterialLeft.push_back(vMaterials[unTriangle]);
				}
				else
				{
					vVertexRight.push_back(vVertex[i]);
					vVertexRight.push_back(vVertex[i+1]);
					vVertexRight.push_back(vVertex[i+2]);
					vMaterialRight.push_back(vMaterials[unTriangle]);
				}
			}
		}

		// Clear memory allocated to our vertex vector.
		// Hack courtesy of http://www.gotw.ca/gotw/054.htm
		std::vector<CMesh::SVertex>().swap(vVertex);

		if(vVertexLeft.empty() || vVertexRight.empty())
		{
			Debug << "Invalid Split with panel {n: (" << oSplitPlane.normal.x << ", " << oSplitPlane.normal.y << ", " << oSplitPlane.normal.z << ") p: ("
				  << oSplitPlane.point.x << ", " << oSplitPlane.point.y << ", " << oSplitPlane.point.z << ")}" << endl;
		}

		if((vMaterialLeft.size() + vMaterialRight.size()) != ((vVertexLeft.size() + vVertexRight.size()) / 3))
		{
			bool _ = true;
		}

		// Continue
		pNode->m_pLeft = createSubtree(vVertexLeft, vMaterialLeft);
		pNode->m_pRight = createSubtree(vVertexRight, vMaterialRight);
	}
	else
	{
		// Found a leaf node. Store it up.
		pNode->m_bIsLeaf = true;
		pNode->m_pLeft = pNode->m_pRight = NULL;

		// Create and load vertex buffer.
		//CMesh::SVertex* pVert = 0;
		//LPDIRECT3DDEVICE9 pDev = CRenderSystem::getInstance().getRenderDevice().getD3DDevice();
		//HRESULT hr = pDev->CreateVertexBuffer(sizeof(CMesh::SVertex) * vVertex.size(), D3DUSAGE_WRITEONLY, CMesh::FVF, D3DPOOL_MANAGED, &pNode->m_pVB, NULL);
		//hr = pNode->m_pVB->Lock(0, 0, (LPVOID*)&pVert, 0);
		//memcpy(pVert, &(vVertex[0]), sizeof(CMesh::SVertex) * vVertex.size());
		//pNode->m_pVB->Unlock();

		// Save vertex list
		pNode->m_pTris = new SRenderTriangle[vVertex.size() / 3];
		size_t nCurrentTri;
		for(size_t i = 0; i < vVertex.size(); i+=3)
		{
			nCurrentTri = i / 3;
			pNode->m_pTris[nCurrentTri].m_oVerts[0] = vVertex[i];
			pNode->m_pTris[nCurrentTri].m_oVerts[1] = vVertex[i+1];
			pNode->m_pTris[nCurrentTri].m_oVerts[2] = vVertex[i+2];

			// Save material, and update material count.
			pNode->m_pTris[nCurrentTri].m_pMaterial = vMaterials[nCurrentTri];
			if(pNode->m_pTris[nCurrentTri].m_pMaterial->isTransparent())
				++m_dwNumTrans;
			else
				++m_dwNumSolids;
		}

		pNode->m_nVertCount = vVertex.size();
		m_nNumTrianglesTotal += vVertex.size() / 3;

		// Clear old vector.
		std::vector<CMesh::SVertex>().swap(vVertex);
		std::vector<CMaterial*>().swap(vMaterials);
	}
	return pNode;
}