Mesh PrimitiveFactory::SubDivide(Mesh m, int count)
{
	if (count == 0) {
		return m;
	} else {
		return SubDivide(SubDivide(m), --count);
	}
}
Mesh PrimitiveFactory::InwardCubeSphere(int resolution)
{
	Mesh m(Spherize(SubDivide(SimpleInnerBox(), resolution)));
	m.ReverseNormals();

	return Mesh(m);
}
void DrawBall1()
{
    glScalef(10.0f,10.0f,10.0f);
    for(int i=0; i<20; i++)
    {
        SubDivide(&m_iconsahedronVertices[m_iconsahedronIndecies[i][0]][0],
                  &m_iconsahedronVertices[m_iconsahedronIndecies[i][1]][0],
                  &m_iconsahedronVertices[m_iconsahedronIndecies[i][2]][0],
                  5);
    }
}
void SubDivide(GLfloat* v1,GLfloat* v2,GLfloat* v3,int depth)
{
    GLfloat v12[3],v23[3],v31[3];
    if(depth == 0)
    {
        DrawTriangle(v1,v2,v3);
        return;
    }
    for(int i=0;i<3;i++)
    {
        v12[i] = (v1[i]+v2[i])/2.0;
        v23[i] = (v2[i]+v3[i])/2.0;
        v31[i] = (v3[i]+v1[i])/2.0;
    }
    UnitVector(v12);
    UnitVector(v23);
    UnitVector(v31);
    SubDivide(v1,v12,v31,depth-1);
    SubDivide(v2,v23,v12,depth-1);
    SubDivide(v3,v31,v23,depth-1);
    SubDivide(v12,v23,v31,depth-1);
}
示例#5
0
void CQuadTree::SubDivide( CQuadNode * pQNode, int iLevel )
{
	float		hw;

    assert(iLevel > 0);

	if( iLevel == 1 )	// lowest level of pQNodes, don't subdivide any further
		return;

	// Subdivide this Node into 4 and subdivide those even further if necessary
	hw = pQNode->m_fHalfWidth/2.0f;
    pQNode->m_pChildNode[SW] = new CQuadNode( Vector3f(pQNode->m_vOrigin.X() - hw, 0, pQNode->m_vOrigin.Z() - hw), hw );    
    pQNode->m_pChildNode[SE] = new CQuadNode( Vector3f(pQNode->m_vOrigin.X() + hw, 0, pQNode->m_vOrigin.Z() - hw), hw );
	pQNode->m_pChildNode[NW] = new CQuadNode( Vector3f(pQNode->m_vOrigin.X() - hw, 0, pQNode->m_vOrigin.Z() + hw), hw );
    pQNode->m_pChildNode[NE] = new CQuadNode( Vector3f(pQNode->m_vOrigin.X() + hw, 0, pQNode->m_vOrigin.Z() + hw), hw );

    // save these pointers for deletion later
    m_vpNodes.push_back(pQNode->m_pChildNode[SW]);
    m_vpNodes.push_back(pQNode->m_pChildNode[SE]);
    m_vpNodes.push_back(pQNode->m_pChildNode[NW]);
    m_vpNodes.push_back(pQNode->m_pChildNode[NE]);

    #ifdef _DEBUG
    CLog::GetLog().Write(LOG_MISC, "NE node origin: %f %f %f", pQNode->m_pChildNode[NE]->m_vOrigin.X(), pQNode->m_pChildNode[NE]->m_vOrigin.Y(), pQNode->m_pChildNode[NE]->m_vOrigin.Z());
    CLog::GetLog().Write(LOG_MISC, "NW node origin: %f %f %f", pQNode->m_pChildNode[NW]->m_vOrigin.X(), pQNode->m_pChildNode[NW]->m_vOrigin.Y(), pQNode->m_pChildNode[NW]->m_vOrigin.Z());
    CLog::GetLog().Write(LOG_MISC, "SE node origin: %f %f %f", pQNode->m_pChildNode[SE]->m_vOrigin.X(), pQNode->m_pChildNode[SE]->m_vOrigin.Y(), pQNode->m_pChildNode[SE]->m_vOrigin.Z());
    CLog::GetLog().Write(LOG_MISC, "SW node origin: %f %f %f", pQNode->m_pChildNode[SW]->m_vOrigin.X(), pQNode->m_pChildNode[SW]->m_vOrigin.Y(), pQNode->m_pChildNode[SW]->m_vOrigin.Z());
    #endif

    SubDivide(pQNode->m_pChildNode[NE], iLevel-1);
   	SubDivide(pQNode->m_pChildNode[NW], iLevel-1);
   	SubDivide(pQNode->m_pChildNode[SE], iLevel-1);
	SubDivide(pQNode->m_pChildNode[SW], iLevel-1);

	return;
}
示例#6
0
bool GQuadTree::BuildTree( GNode* pNode)
{
	// 분할 가능하냐
	if(SubDivide(pNode))
	{
		for( int iNode = 0; iNode < pNode->m_ChildList.size(); iNode++ )
		{	
			if (m_bUsedIndexList)
			{
				DWORD dwIndex = pNode->m_ChildList[iNode]->m_dwPositionIndex[1] * pow(2.0f, (float)pNode->m_ChildList[iNode]->m_iDepth) +
					pNode->m_ChildList[iNode]->m_dwPositionIndex[0];
				m_LevelList[pNode->m_ChildList[iNode]->m_iDepth][dwIndex] = pNode->m_ChildList[iNode];
			}
			BuildTree( pNode->m_ChildList[iNode]);
		}
	}
	return true;
}
示例#7
0
int MKS_RamdomFrac1(BITMAP *bmp, unsigned char adj, void (*CallBack)())
{
 int w,h;

 if (!is_linear_bitmap(bmp))
    return 1;
 clear(bmp);
 pl4Scr=bmp->line[0];
 w=bmp->w-1; h=bmp->h-1;
 recadj=adj;
 Bmp=bmp;
 CB=CallBack;
 cont=CB_CONT;

 // Initialize Random table
 MA2_InitRTable();
 if (w==Xopt-1)
   {
    // Set the first corners
    SetPixel(0,0,MA2_GetRand8());
    SetPixel(w,h,MA2_GetRand8());
    SetPixel(0,h,MA2_GetRand8());
    SetPixel(w,0,MA2_GetRand8());
    // Start the recursion
    SubDivide(0,0,w,h);
   }
 else
   {
    // Set the first corners
    SetPixelG(0,0,MA2_GetRand8());
    SetPixelG(w,h,MA2_GetRand8());
    SetPixelG(0,h,MA2_GetRand8());
    SetPixelG(w,0,MA2_GetRand8());
    // Start the recursion
    SubDivideG(0,0,w,h);
   }

 return 0;
}
Mesh PrimitiveFactory::CubeSphere(int resolution)
{
	Mesh m(SubDivide(UnitCube(), resolution));

	return Mesh(Spherize(m));
}
示例#9
0
void CQuadTree::Initialize( std::vector <CEntity *> * pvEntities )
{
    // use default values to create the quadtree centered at the origin
    if (!pvEntities)  {

        // Construct a quadtree of m_iLevels levels deep
	    m_pkQRoot = new CQuadNode( Vector3f(0, 0, 0), m_fNodeWidth );
    
        // save the root node for deletion later
        m_vpNodes.push_back(m_pkQRoot);

        // compute the initial sub levels of the tree
	    SubDivide(m_pkQRoot, m_iLevels);

        m_bIsInitialized = true;
        return;
    }

    // find min/max extents of the quadtree
    vector <CEntity *>::iterator it = pvEntities->begin();
    m_vfMaxExtent = m_vfMinExtent = *(*it)->GetTranslate();
    m_vfMapOrigin = Vector3f(0,0,0);

    for (it = pvEntities->begin(); it!=pvEntities->end(); it++)  {
        
        // look for max extent
        //if (*(*it)->GetTranslate() >= m_vfMaxExtent)
        if ((*it)->GetTranslate()->X() >= m_vfMaxExtent.X() &&
            (*it)->GetTranslate()->Z() >= m_vfMaxExtent.Z() )
            m_vfMaxExtent = *(*it)->GetTranslate();

        // look for min extent
        //if (*(*it)->GetTranslate() <= m_vfMinExtent)
        if ((*it)->GetTranslate()->X() <= m_vfMinExtent.X() &&
            (*it)->GetTranslate()->Z() <= m_vfMinExtent.Z() )        
            m_vfMinExtent = *(*it)->GetTranslate();

        m_vfMapOrigin += *(*it)->GetTranslate();
    }

    // compute the 'center' of the map
    m_vfMapOrigin.Y() = 0.0f;
    m_vfMapOrigin /= (float)pvEntities->size();

    #ifdef _DEBUG
    CLog::GetLog().Write(LOG_GAMECONSOLE, "Quadtree max extent: %f %f %f", m_vfMaxExtent.X(), m_vfMaxExtent.Y(), m_vfMaxExtent.Z() );
    CLog::GetLog().Write(LOG_GAMECONSOLE, "Quadtree min extent: %f %f %f", m_vfMinExtent.X(), m_vfMinExtent.Y(), m_vfMinExtent.Z() );
    CLog::GetLog().Write(LOG_GAMECONSOLE, "Quadtree Map Origint: %f %f %f", m_vfMapOrigin.X(), m_vfMapOrigin.Y(), m_vfMapOrigin.Z() );
    #endif

    // compute width of root node quadtree will cover
    m_vfMinExtent.Y() = m_vfMaxExtent.Y() = 0.0f;
    m_fNodeWidth = max( abs(m_vfMaxExtent.X()-m_vfMinExtent.X()), abs(m_vfMinExtent.X() - m_vfMaxExtent.X()));
    m_fNodeWidth = max( m_fNodeWidth, abs(m_vfMaxExtent.Z()-m_vfMinExtent.Z()));
    m_fNodeWidth = max( m_fNodeWidth, abs(m_vfMinExtent.Z()-m_vfMaxExtent.Z()));
    m_fNodeWidth *= 0.9f;//0.75f;//2.0f;   

    //$$$TEMP optimal for map_final only
    //m_fNodeWidth = 2200.0f;  

    #ifdef _DEBUG
    CLog::GetLog().Write(LOG_GAMECONSOLE, "Quadtree root node width: %f", m_fNodeWidth);
    #endif

    // create the quadtree based on these statistics
    m_pkQRoot = new CQuadNode( m_vfMapOrigin, m_fNodeWidth );
    
    // save the root node for deletion later
    m_vpNodes.push_back(m_pkQRoot);

    #ifdef _DEBUG
    CLog::GetLog().Write(LOG_ALL, "Root node origin: %f %f %f", m_pkQRoot->m_vOrigin.X(), m_pkQRoot->m_vOrigin.Y(), m_pkQRoot->m_vOrigin.Z());
    #endif

    // assuming a uniform distribution of entities, try to compute an optimal tree depth
    // want #levels = log(#entities)/log(#subdiv at each level=4)
    //m_iLevels = (int)Mathf::Ceil( (Mathf::Log((float)pvEntities->size())) / (Mathf::Log(4.0f)) );
    m_iLevels = 7;//m_iLevels = 7;/// optimal for map_final only!
    
    #ifdef _DEBUG
    CLog::GetLog().Write(LOG_GAMECONSOLE,"Quadtree depth %d", m_iLevels);
    #endif

    // compute the initial sub levels of the tree
	SubDivide(m_pkQRoot, m_iLevels);

    // quadtree is now initialized
    m_bIsInitialized = true;

    // add renderable game entities to the quadtree
    for (it = pvEntities->begin(); it!=pvEntities->end(); it++)  {
        
        // only add static and renderable entities
        if ((*it)->getIsStatic() && (*it)->getIsRenderable())
            Add(*it);
    }


    return;
}
示例#10
0
void CQuadTree::AddReference( Box3f box, CEntity * pEntity, CQuadNode * node )  {

    assert( m_iLevels > 1 ); 

    int iNumInside = 0;

    Box3f boxTemp =  box;
    Box3f boxEnt = *pEntity->GetBoundingBox();

    // move box to the entity's height
    boxTemp.Center().Y() = boxEnt.Center().Y();
    boxTemp.Extent(1) = 100.0f; //extend this box infinitely

    bool bEntInQuad = false;

    Vector3f vBoxVerts[8];
    bool abValid[8] = { 1,1,1,1,1,1,1,1 };//{ 0,0,0,0,0,0,0,0 };
    bool bEntBoxInNode = false;
    bool bNodeInEntBox = false;

    //switch(TestIntersection( boxTemp,  boxEnt ) ) 
    switch(TestIntersection( boxEnt, boxTemp ) ) 
    {
        case true:  // box intersects
            node->m_EntMap[pEntity->GetId()] = pEntity; 
            bEntInQuad = true;  // find if the children intersect too
            break;

        case false:  // ent box is INSIDE or OUTSIDE the node
            // get vertices for the bounding box                
            boxEnt.ComputeVertices(vBoxVerts);

            // if entities box is contained in node box
            for (int j=0; j<8; j++ ) {
                if (InBox( vBoxVerts[j], boxTemp))  {
                    bEntBoxInNode = true;
                }
            }

            if (bEntBoxInNode == true)  {
            //if (ContOrientedBox (8, vBoxVerts, abValid, node->m_BBox))  {
                node->m_EntMap[pEntity->GetId()] = pEntity; //entity is in this node
                bEntInQuad = true;  // find out what child quads also contain this
                iNumInside++;                
            }
            else { // OUTSIDE or entities box contains the bounding box!
                boxTemp.ComputeVertices(vBoxVerts);
                
                // if node box  is contained in entities box
                for (int j=0; j<8; j++ ) {
                    if (InBox( vBoxVerts[j], boxEnt))  {
                        bNodeInEntBox = true;
                    }
                }

                if (bNodeInEntBox == true)  {
                //if (ContOrientedBox (8, vBoxVerts, abValid, boxTemp))  {
                    node->m_EntMap[pEntity->GetId()] = pEntity; //entity is in this node
                    bEntInQuad = true;  // find out what child quads also contain this

                }
                else {
                    // entity is outside, so don't add
                    bEntInQuad = false;
                    return;
                }
            }
            break;
    }

    // now this box will also intersect/be contained in the children as well
    if (bEntInQuad == true )  {
        //check if we need to subdivide even further
        if (iNumInside >= MAX_ENTS_PER_NODE)  {
            m_iLevels++;  //increase the number of levels
            SubDivide(node, m_iLevels-1);
        }

        if (node->m_pChildNode[NE] != NULL)  {
            AddReference( node->m_pChildNode[NE]->m_BBox, pEntity, node->m_pChildNode[NE]);
            //node->m_pChildNode[NE]->m_EntMap[pEntity->GetId()] = pEntity;
        }
        if (node->m_pChildNode[NW] != NULL)  {
            AddReference( node->m_pChildNode[NW]->m_BBox, pEntity, node->m_pChildNode[NW]);
            //node->m_pChildNode[NW]->m_EntMap[pEntity->GetId()] = pEntity;
        }
        if (node->m_pChildNode[SE] != NULL)  {
            AddReference( node->m_pChildNode[SE]->m_BBox, pEntity, node->m_pChildNode[SE]);
            //node->m_pChildNode[SE]->m_EntMap[pEntity->GetId()] = pEntity;
        }
        if (node->m_pChildNode[SW] != NULL)  {
            AddReference( node->m_pChildNode[SW]->m_BBox, pEntity, node->m_pChildNode[SW]);
            //node->m_pChildNode[SW]->m_EntMap[pEntity->GetId()] = pEntity;
        }        
    }

    return;
}
示例#11
0
static void SubDivide(int x1,int y1,int x2,int y2)
{
 int x,y,val,acum;
 signed char oldrecadj;

 // First, check for recursion halts.
 x=(x1+x2)>>1; // X = X center
 y=(y1+y2)>>1; // Y = Y center
 if (x1==x && y1==y)  // That means we reached a central point
    return;

 //  Next, check each of the four sides for empty
 //  and call 'Adjust' if so.  Meanwhile, keep
 //  a running total of all the four sides so we
 //  can do a quick average of them in the next
 //  step.

 // TOP
 val=GetPixel(x,y1);
 if (val==0)
    val=Adjust(x1,y1,x2,y1,x,y1);
 acum=val;

 // RIGHT
 val=GetPixel(x2,y);
 if (val==0)
    val=Adjust(x2,y1,x2,y2,x2,y);
 acum+=val;

 // BOTTOM
 val=GetPixel(x,y2);
 if (val==0)
    val=Adjust(x1,y2,x2,y2,x,y2);
 acum+=val;

 // LEFT
 val=GetPixel(x1,y);
 if (val==0)
    val=Adjust(x1,y1,x1,y2,x1,y);
 acum+=val;

 //  Okay.  All four side pixels have been computed
 //  and plotted on the screen and in memory.  AX
 //  holds the sum of all four pixels.  Divide by four
 //  and set x,y to the resulting value.
 acum>>=2;
 SetPixel(x,y,acum);

 if (!--cont)
   {
    cont=CB_CONT;
    CB();
   }
 // Finally.  All the real work is done.  Now, decrease
 // the recurse-level adjustment and recurse down
 // to the next level for each of the four quads
 oldrecadj=recadj;
 recadj>>=1;
 SubDivide(x1,y1,x,y);
 SubDivide(x,y1,x2,y);
 SubDivide(x,y,x2,y2);
 SubDivide(x1,y,x,y2);
 recadj=oldrecadj;
}