コード例 #1
0
    private void PerformNode(BspNode inNode, CSGFace inFace, int nodeSide, OperationInfo info)
    {
        while (inNode != null)
        {
            CSGFace.EPlaneSide side = inFace.Side(inNode.plane);

            switch (side)
            {
            case CSGFace.EPlaneSide.Side_Front:

                //
                nodeSide = nodeSide | (inNode.IsCsg() ? 1 : 0);

                // leaf node
                if (inNode.front == null)
                {
                    // set operation infos
                    info.leafNode     = inNode;
                    info.leafLocation = BspNode.EBspLocation.BspLocation_Front;

                    // we are done, process face
                    ProcessFace(inFace, SIDE_Outside, info);
                }

                // get to next front node (if any)
                inNode = inNode.front;

                break;

            case CSGFace.EPlaneSide.Side_Back:

                int backSide = inNode.IsCsg() ? 0 : 1;
                //
                nodeSide = nodeSide & backSide;

                // leaf node
                if (inNode.back == null)
                {
                    // set leaf infos
                    info.leafNode     = inNode;
                    info.leafLocation = BspNode.EBspLocation.BspLocation_Back;

                    // we are done, process face
                    ProcessFace(inFace, SIDE_Inside, info);
                }

                // get to next front node (if any)
                inNode = inNode.back;
                break;

            case CSGFace.EPlaneSide.Side_Split:

                // split face and process front and back
                CSGFace frontFace, backFace;

                //
                inFace.Split(inNode.plane, out frontFace, out backFace);

                // TODO: set polygon cutted flags
                frontFace.flags |= CSGFace.FaceFlags_WasCutted;
                backFace.flags  |= CSGFace.FaceFlags_WasCutted;


                // front node is a leaf node
                if (inNode.front == null)
                {
                    //
                    info.leafNode     = inNode;
                    info.leafLocation = BspNode.EBspLocation.BspLocation_Front;


                    ProcessFace(frontFace, SIDE_Outside, info);
                }
                else
                {
                    PerformNode(inNode.front, frontFace, nodeSide, info);
                }

                // Prcess back node with back face
                if (inNode.back == null)
                {
                    //
                    info.leafNode     = inNode;
                    info.leafLocation = BspNode.EBspLocation.BspLocation_Back;


                    ProcessFace(backFace, SIDE_Inside, info);
                }
                else
                {
                    // process back node with new face
                    PerformNode(inNode.back, backFace, nodeSide, info);
                }

                // stop loop
                inNode = null;
                break;

            case CSGFace.EPlaneSide.Side_Planar:

                BspNode front, back;

                if (info.wasPlanar == true)
                {
                    Debug.Log("Reentering Planar Nodes!");
                }


                // set operation infos
                info.wasPlanar      = true;
                info.backNode       = null;
                info.processingBack = false;

                if (Vector3.Dot(inFace.GetPlane().normal, inNode.plane.normal) >= 0.0f)
                {
                    // same order as we face in the same order
                    front = inNode.front;
                    back  = inNode.back;

                    // we are for now outside (as we are looking outside)
                    info.planarSide = SIDE_Outside;
                }
                else
                {
                    // reverse order as we are facing in the opposite direction
                    front = inNode.back;
                    back  = inNode.front;

                    // we are now inside as we are looking to the inside
                    info.planarSide = SIDE_Inside;
                }

                // we are leaf node (coplanar face)
                if (front == null && back == null)
                {
                    // set leaf stuff
                    info.leafNode     = inNode;
                    info.leafLocation = BspNode.EBspLocation.BspLocation_Planar;

                    // process node
                    info.processingBack = true;

                    // process face
                    ProcessFace(inFace, InverseSide(info.planarSide), info);

                    // stop loop
                    inNode = null;
                }
                else if (front == null && back != null)
                {
                    // only back nodes
                    info.processingBack = true;

                    // process back
                    inNode = back;
                }
                else
                {
                    // tread like we were on front side (maybe we do have a back node)
                    info.processingBack = false;

                    // remember back node
                    info.backNode = back;

                    // process front
                    inNode = front;
                }

                break;
            }
        }
    }
コード例 #2
0
ファイル: CsgOperation.cs プロジェクト: icegbq/csg-unity
	private void PerformNode( BspNode inNode, Face inFace, int nodeSide, OperationInfo info )
	{
		while( inNode != null )
		{
			Face.EPlaneSide side = inFace.Side( inNode.plane );			
			
			switch( side )
			{
			case Face.EPlaneSide.Side_Front:
				
				// 
				nodeSide = nodeSide | (inNode.IsCsg() ? 1 : 0);
				
				// leaf node
				if( inNode.front == null )
				{
					// set operation infos
					info.leafNode = inNode;
					info.leafLocation = BspNode.EBspLocation.BspLocation_Front;
					
					// we are done, process face
					ProcessFace( inFace, SIDE_Outside, info );
				}
				
				// get to next front node (if any)
				inNode = inNode.front;
				
				break;
			case Face.EPlaneSide.Side_Back:
				
				int backSide = inNode.IsCsg() ? 0 : 1;
				// 
				nodeSide = nodeSide & backSide;
				
				// leaf node
				if( inNode.back == null )
				{
					// set leaf infos
					info.leafNode = inNode;
					info.leafLocation = BspNode.EBspLocation.BspLocation_Back;
					
					// we are done, process face
					ProcessFace( inFace, SIDE_Inside, info );
				}
				
				// get to next front node (if any)
				inNode = inNode.back;
				break;
			case Face.EPlaneSide.Side_Split:
				
				// split face and process front and back
				Face frontFace, backFace;
				
				// 
				inFace.Split( inNode.plane, out frontFace, out backFace );
				
				// TODO: set polygon cutted flags
				frontFace.flags |= Face.FaceFlags_WasCutted;
				backFace.flags |= Face.FaceFlags_WasCutted;
				
				
				// front node is a leaf node
				if( inNode.front == null )
				{
					// 	
					info.leafNode = inNode;
					info.leafLocation = BspNode.EBspLocation.BspLocation_Front;
		
					
					ProcessFace( frontFace, SIDE_Outside, info );
				}
				else
				{
					PerformNode( inNode.front, frontFace, nodeSide, info );
				}
				
				// Prcess back node with back face
				if( inNode.back == null )
				{
					// 
					info.leafNode = inNode;
					info.leafLocation = BspNode.EBspLocation.BspLocation_Back;
		
					
					ProcessFace( backFace, SIDE_Inside, info );
				}
				else
				{
					// process back node with new face
					PerformNode( inNode.back, backFace, nodeSide, info );	
				}
				
				// stop loop
				inNode = null;
				break;
			case Face.EPlaneSide.Side_Planar:
				
				BspNode front, back;
				
				if( info.wasPlanar == true )
				{
					Debug.Log( "Reentering Planar Nodes!" );	
				}
				
				
				// set operation infos
				info.wasPlanar = true;
				info.backNode = null;
				info.processingBack = false;
				
				if( Vector3.Dot( inFace.GetPlane().normal, inNode.plane.normal ) >= 0.0f )
				{
					// same order as we face in the same order
					front = inNode.front;
					back = inNode.back;
					
					// we are for now outside (as we are looking outside)
					info.planarSide = SIDE_Outside;
				}
				else
				{
					// reverse order as we are facing in the opposite direction
					front = inNode.back;
					back = inNode.front;
					
					// we are now inside as we are looking to the inside
					info.planarSide = SIDE_Inside;
				}
				
				// we are leaf node (coplanar face)
				if( front == null && back == null )
				{
					// set leaf stuff
					info.leafNode = inNode;
					info.leafLocation = BspNode.EBspLocation.BspLocation_Planar;
									
					// process node
					info.processingBack = true;
					
					// process face
					ProcessFace( inFace, InverseSide(info.planarSide), info );
					
					// stop loop
					inNode = null;
				}
				else if( front == null && back != null )
				{
					// only back nodes
					info.processingBack = true;
					
					// process back
					inNode = back;
				}
				else
				{
					
					// tread like we were on front side (maybe we do have a back node)
					info.processingBack = false;
					
					// remember back node
					info.backNode = back;
					
					// process front
					inNode = front;
				}
				
				break;
			}
			
			
		}
	}