Пример #1
0
void COctree::CreateNewNode(CVector3 *pVertices, vector<bool> pList, int numberOfVerts,
                            CVector3 vCenter,	 float width,        int triangleCount, int nodeID)
{
    // This function helps us set up the new node that is being created.  We only
    // want to create a new node if it found triangles in it's area.  If there were
    // no triangle found in this node's cube, then we ignore it and don't create a node.

    // Check if the first node found some triangles in it
    if(triangleCount)
    {
        // Allocate memory for the triangles found in this node (tri's * 3 for vertices)
        CVector3 *pNodeVertices = new CVector3 [triangleCount * 3];

        // Create an counter to count the current index of the new node vertices
        int index = 0;

        // Go through all the vertices and assign the vertices to the node's list
        for(int i = 0; i < numberOfVerts; i++)
        {
            // If this current triangle is in the node, assign it's vertices to it
            if(pList[i / 3])
            {
                pNodeVertices[index] = pVertices[i];
                index++;
            }
        }

        // Now comes the initialization of the node.  First we allocate memory for
        // our node and then get it's center point.  Depending on the nodeID,
        // GetNewNodeCenter() knows which center point to pass back (TOP_LEFT_FRONT, etc..)

        // Allocate a new node for this octree
        m_pOctreeNodes[nodeID] = new COctree;

        // Get the new node's center point depending on the nodexIndex (which of the 8 subdivided cubes).
        CVector3 vNodeCenter = GetNewNodeCenter(vCenter, width, nodeID);

        // Below, before and after we recurse further down into the tree, we keep track
        // of the level of subdivision that we are in.  This way we can restrict it.

        // Increase the current level of subdivision
        g_CurrentSubdivision++;

        // Recurse through this node and subdivide it if necessary
        m_pOctreeNodes[nodeID]->CreateNode(pNodeVertices, triangleCount * 3, vNodeCenter, width / 2);

        // Decrease the current level of subdivision
        g_CurrentSubdivision--;

        // Free the allocated vertices for the triangles found in this node
        delete [] pNodeVertices;
    }
}
void COctree::CreateNewNode(t3DModel *pWorld, vector<tFaceList> pList, int triangleCount,
					  	    CVector3 vCenter, float width,			   int nodeID)
{
	// This function is used as our helper function to partition the world data
	// to pass into the subdivided nodes.  The same things go on as in the previous
	// tutorials, but it's dealing with more than just vertices.  We are given
	// the world data that needs to be partitioned, the list of faces that are in
	// the new node about to be created, the triangle count, the parent node's center
	// and width, along with the enum ID that tells us which new node is being created.
	//
	// The tFaceList structure stores a vector of booleans, which tell us if that face
	// index is in our end node (true) or not (false).  It also contains a integer
	// to tell us how many of those faces (triangles) are "true", or in other words, 
	// are in our node that is being created.  

	// Check if the first node found some triangles in it, if not we don't continue
	if(!triangleCount) return;
	
	// Here we create the temporary partitioned data model, which will contain
	// all the objects and triangles in this end node.
	t3DModel *pTempWorld = new t3DModel;

	// Intialize the temp model data and assign the object count to it
	memset(pTempWorld, 0, sizeof(t3DModel));
	pTempWorld->numOfObjects = pWorld->numOfObjects;
	
	// Go through all of the objects in the current partition passed in
	for(int i = 0; i < pWorld->numOfObjects; i++)
	{
		// Get a pointer to the current object to avoid ugly code
		t3DObject *pObject = &(pWorld->pObject[i]);

		// Create a new object, initialize it, then add it to our temp partition
		t3DObject newObject;
		memset(&newObject, 0, sizeof(t3DObject));
		pTempWorld->pObject.push_back(newObject);

		// Assign the new node's face count, material ID, texture boolean and 
		// vertices to the new object.  Notice that it's not that pObject's face
		// count, but the pList's.  Also, we are just assigning the pointer to the
		// vertices, not copying them.
		pTempWorld->pObject[i].numOfFaces  = pList[i].totalFaceCount;
		pTempWorld->pObject[i].materialID  = pObject->materialID;
		pTempWorld->pObject[i].bHasTexture = pObject->bHasTexture;
		pTempWorld->pObject[i].pVerts      = pObject->pVerts;

		// Allocate memory for the new face list
		pTempWorld->pObject[i].pFaces = new tFace [pTempWorld->pObject[i].numOfFaces];

		// Create a counter to count the current index of the new node vertices
		int index = 0;

		// Go through all of the current object's faces and only take the ones in this new node
		for(int j = 0; j < pObject->numOfFaces; j++)
		{
			// If this current triangle is in the node, assign it's index to our new face list
			if(pList[i].pFaceList[j])	
			{
				pTempWorld->pObject[i].pFaces[index] = pObject->pFaces[j];
				index++;
			}
		}
	}

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

	// Now comes the initialization of the node.  First we allocate memory for
	// our node and then get it's center point.  Depending on the nodeID, 
	// GetNewNodeCenter() knows which center point to pass back (TOP_LEFT_FRONT, etc..)

	// Allocate a new node for this octree
	m_pOctreeNodes[nodeID] = new COctree;

	// Get the new node's center point depending on the nodexIndex (which of the 8 subdivided cubes).
	CVector3 vNodeCenter = GetNewNodeCenter(vCenter, width, nodeID);
		
	// Below, before and after we recurse further down into the tree, we keep track
	// of the level of subdivision that we are in.  This way we can restrict it.

	// Increase the current level of subdivision
	g_CurrentSubdivision++;


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

	// This chance is just that we pass in the temp partitioned world for this node,
	// instead of passing in just straight vertices.

	// Recurse through this node and subdivide it if necessary
	m_pOctreeNodes[nodeID]->CreateNode(pTempWorld, triangleCount, vNodeCenter, width / 2);

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


	// Decrease the current level of subdivision
	g_CurrentSubdivision--;


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

	// To free the temporary partition, we just go through all of it's objects and
	// free the faces.  The rest of the dynamic data was just being pointed too and
	// does not to be deleted.  Finally, we delete the allocated pTempWorld.

	// Go through all of the objects in our temporary partition
	for(i = 0; i < pWorld->numOfObjects; i++)
	{
		// If there are faces allocated for this object, delete them
		if(pTempWorld->pObject[i].pFaces)
			delete [] pTempWorld->pObject[i].pFaces;
	}

	// Delete the allocated partition
	delete pTempWorld;

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

}