Пример #1
0
void JObjectTree::OnMouse( JMouseEvent& e )
{
    JObject* pNode = PickNode( e.MouseX(), e.MouseY() );
    if (e.Action() == aKeyDown && e.MouseKey() == meLeft)
    {
        SelectObject( pNode );
    }

    if (pNode) e.Consume();
} // JObjectTree::OnMouse
Пример #2
0
void JObjectTree::OnDrag( JDragEvent& e )
{
    Vec2 mPos = e.GetCurPos();
    if (e.Key() == mkMiddle)
    {
        if (e.GetType() == deDragStart && IsDraggable())
        {
            if (PickNode( mPos.x, mPos.y ) != NULL)
            {
                e.SetDragObject( this );
                SetDragged();
            }
        }
        if (e.GetType() == deDrag && e.GetDragObject() == this)
        {
            m_RootPos += e.GetDelta();
        }
    }
    else if (e.Key() == mkRight)
    {
        if (e.GetType() == deDragStart)
        {
            Frame ext;
            JObject* pNode = PickNode( mPos.x, mPos.y, &ext );
            if (pNode)
            {
                e.SetSource( this );
                m_pDraggedNode = pNode;
                m_DragShift = Vec2( mPos.x - ext.x, mPos.y - ext.y );
                m_bClone = (GetKeyState( VK_CONTROL ) < 0);
            }
            e.Consume();
        }
        if (e.GetType() == deDrag && e.GetSource() == this)
        {
            //  check whether node can be dropped onto hovered one
            Frame ext;
            JObject* pNode = PickNode( e.GetCurPos().x, e.GetCurPos().y, &ext );
            bool bAsChild = (mPos.x > ext.center().x);
            m_bCanDrop = CanDropNode( m_pDraggedNode, pNode, bAsChild, m_bClone );
            if (m_bCanDrop)
            {
                if (bAsChild)
                {
                    ext.x += ext.w - 10;
                    ext.w = 10;
                    m_InsExt = ext;
                }
                else
                {
                    ext.y += ext.h;
                    ext.w -= 10;
                    ext.h = 4;
                    m_InsExt = ext;
                }
            }
            e.Consume();
        }
        if (e.GetType() == deDrop && e.GetSource() == this && m_pDraggedNode)
        {
            //  find node we are going to drop onto
            Frame ext;
            JObject* pNode = PickNode( e.GetCurPos().x, e.GetCurPos().y, &ext );
            bool bAsChild = (mPos.x > ext.center().x);
            if (CanDropNode( m_pDraggedNode, pNode, bAsChild, m_bClone ))
            {
                DropNode( m_pDraggedNode, pNode, bAsChild, m_bClone );
            }
            m_pDraggedNode = NULL;
            e.Consume();
        }
    }
} // JObjectTree::OnDrag
Пример #3
0
static inline void 
DivideSegs(struct Seg *ts, struct Seg **rs, struct Seg **ls, const bbox_t bbox)
{
	struct Seg *rights,*lefts;
	struct Seg *tmps,*best,*news,*prev;
	struct Seg *add_to_rs,*add_to_ls;
  	struct Seg *new_best=NULL,*new_rs,*new_ls;

	struct Seg *strights,*stlefts;
        int num_new=0;
	short int x,y,val;

	best = PickNode(ts,bbox);			/* Pick best node to use.*/

	if(best == NULL) ProgError("Couldn't pick nodeline!");

	node_x = vertices[best->start].x;
	node_y = vertices[best->start].y;
	node_dx = vertices[best->end].x-vertices[best->start].x;
	node_dy = vertices[best->end].y-vertices[best->start].y;

/* When we get to here, best is a pointer to the partition seg.
	Using this partition line, we must split any lines that are intersected
	into a left and right half, flagging them to be put their respective sides
	Ok, now we have the best line to use as a partitioning line, we must
   split all of the segs into two lists (rightside & leftside).				 */

	rights = NULL;									/* Start off with empty*/
	lefts = NULL;									/* lists.*/
	strights = NULL;								/* Start off with empty*/
	stlefts = NULL;								/* lists.*/

	psx = vertices[best->start].x;			/* Partition line coords*/
	psy = vertices[best->start].y;
	pex = vertices[best->end].x;
	pey = vertices[best->end].y;
	pdx = psx - pex;								/* Partition line DX,DY*/
	pdy = psy - pey;

	for(tmps=ts;tmps;tmps=tmps->next)
		{
		progress();									/* Something for the user to look at.*/
		add_to_rs = NULL;
		add_to_ls = NULL;
		if(tmps != best)
			{
			lsx = vertices[tmps->start].x;	/* Calculate this here, cos it doesn't*/
			lsy = vertices[tmps->start].y;	/* change for all the interations of*/
			lex = vertices[tmps->end].x;		/* the inner loop!*/
			ley = vertices[tmps->end].y;
			val = DoLinesIntersect();
			if((val&2 && val&64) || (val&4 && val&32))	/* If intersecting !!*/
				{
				ComputeIntersection(&x,&y);
/*				printf("Splitting Linedef %d at %d,%d\n",tmps->linedef,x,y);*/
 			        vertices = ResizeMemory(vertices, sizeof(struct Vertex) * (num_verts+1));
				vertices[num_verts].x = x;
				vertices[num_verts].y = y;

				news = GetMemory(sizeof( struct Seg));
				*news = *tmps;
				tmps->next = news;
				news->start = num_verts;
				tmps->end = num_verts;
				news->dist = SplitDist(news);
/*				printf("splitting dist = %d\n",news->dist);*/
/*				printf("splitting vertices = %d,%d,%d,%d\n",tmps->start,tmps->end,news->start,news->end);*/
				if(val&32) add_to_ls = tmps;
				if(val&64) add_to_rs = tmps;
				if(val&2) add_to_ls = news;
				if(val&4) add_to_rs = news;
				tmps = news;
				num_verts++;
				num_new++;
				}
			else
				{											/* Not split, which side ?*/
				if(val&34) add_to_ls = tmps;
				if(val&68) add_to_rs = tmps;
				if(val&1 && val&16)					/* On same line*/
					{
/* 06/01/97 Lee Killough: this fixes a bug ever since 1.2x,
   probably 1.0, of BSP: when partitioning a parallel seg,
   you must take its vertices' orientation into account, NOT the
   flip bits, to determine which side of the partitioning line a
   parallel seg should go on. If you simply flip the linedef in
   question, you will be flipping both its vertices and sidedefs,
   and the flip bits as well, even though the basic geometry has
   not changed. Thus you need to use the vertices' orientation
   (whether the seg is in the same direction or not, regardless
   of its original linedef's being flipped or not), into account.

   Originally, some segs were partitioned backwards, and if
   it happened that there were different sectors on either
   side of the seg being partitioned, it could leave holes
   in space, causing either invisible barriers or disappearing
   Things, because the ssector would be associated with the
   wrong sector.

   The old logic of tmps->flip != best->flip seems to rest on
   the assumption that if two segs are parallel, they came
   from the same linedef. This is clearly not always true.   */

              /*  if (tmps->flip != best->flip)   old logic -- wrong!!! */

              /* We know the segs are parallel or nearly so, so take their
                 dot product to determine their relative orientation. */

		if ( (lsx-lex)*pdx + (lsy-ley)*pdy < 0)
  	         add_to_ls = tmps;
	 	else
		 add_to_rs = tmps;
					}
				}
			}
		else add_to_rs = tmps;						/* This is the partition line*/

/*		printf("Val = %X\n",val);*/

		if(add_to_rs)							/* CHECK IF SHOULD ADD RIGHT ONE */
			{
			new_rs = GetMemory(sizeof(struct Seg));
			*new_rs = *add_to_rs;
			if(add_to_rs == best) new_best = new_rs;
			new_rs->next = NULL;
			if(!rights) strights = rights = new_rs;
			else
				{
				rights->next = new_rs;
				rights = new_rs;
				}
			}
				
		if(add_to_ls)							/* CHECK IF SHOULD ADD LEFT ONE */
			{
			new_ls = GetMemory(sizeof(struct Seg));
			*new_ls = *add_to_ls;
			if(add_to_ls == best) new_best = new_ls;
			new_ls->next = NULL;
			if(!lefts) stlefts = lefts = new_ls;
			else
				{
				lefts->next = new_ls;
				lefts = new_ls;
				}
			}
		}

	if(strights == NULL)
		{
/*		printf("No right side, moving partition into right side\n");*/
		strights = rights = new_best;
		prev = NULL;
		for(tmps=stlefts;tmps;tmps=tmps->next)
			{
			if(tmps == new_best)
				{
				if(prev != NULL) prev->next=tmps->next;
				else stlefts=tmps->next;
				}
			prev=tmps;
			}
		prev->next = NULL;
		}
	
	if(stlefts == NULL)
		{
/*		printf("No left side, moving partition into left side\n");*/
		stlefts = lefts = new_best;
		prev = NULL;
		for(tmps=strights;tmps;tmps=tmps->next)
			{
			if(tmps == new_best)
				{
				if(prev != NULL) prev->next=tmps->next;
				else strights=tmps->next;
				}
			prev=tmps;
			}
		stlefts->next = NULL;
		prev->next = NULL;								/* Make sure end of list = NULL*/
		}

	if(rights->next != NULL) rights->next = NULL;
	if(lefts->next != NULL) lefts->next = NULL;

	for(tmps=ts;tmps;tmps=best)
		{
		best=tmps->next;
		free(tmps);
		}

/*	printf("Made %d new Vertices and Segs\n",num_new);*/

	*rs = strights ; *ls = stlefts;
}