UnderwareDESIGN

PlayBASIC => Resources => Source Codes => Topic started by: kevin on March 02, 2014, 08:07:38 AM

Title: Polygon Track Editor
Post by: kevin on March 02, 2014, 08:07:38 AM
  Polygon Track Editor

    This is a bare bones race track creation tool from line segments.  The tool lets the user position and append new segments to an existing chain.  This chain is drawn as a set of quad polygons to make the track.

 
  Controls:

   * Mouse Position Segment
   * Mouse Wheel Rotate/Turn segment
   * A= Add current segment to the end of the existing list
   * D= delete (mouse has to be over center point of segment in track)
   * I = insert behind the current highlighted point


[pbcode]

   MakeBitmapFont 1,-1,8

   Type tPolyLine
         x1#,y1#      ; left edge of track
         x2#,y2#      ; right edge of trac
   EndTYpe

   Dim TRack(0) as tPolyLine

   radius=60
   angle#=0

   ; --------------------------------------------------------------------------
   Do   ;--------------------------->> Main Loop <<-----------------------------
   ; --------------------------------------------------------------------------

         cls    
   

         CurrentTime=Timer()
         Mx            =MouseX()
         My            =MouseY()
         Mz            =Mousemovez()

         if Mz<>0
               angle#=wrapangle(angle#+(mz*5))
         endif
         
         DrawTrack(mx,my)
         
         
         Show_Cursor(mx,my,angle#,radius)
         
         ThisKey$   =INkey$()
         
         if Keystate(211) then ThisKey$="d"
         
            ; -----------------------------------------------------------
            Select lower$(ThisKey$)
            
                  ; -----------------------------------------------------------
                  case "a"   ;  ADD point end track         
                  ; -----------------------------------------------------------
                     AddPointToTrack(mx,my,angle#,Radius)
                     flushkeys      
         
                  ; -----------------------------------------------------------
                  case  "i"   ; insert point
                  ; -----------------------------------------------------------

                     InsertPointIntoTrack(mx,my,angle#,Radius)
                     flushkeys      
         
                  ; -----------------------------------------------------------
                  case  "d"   ; delete the segment the mouse is over
                  ; -----------------------------------------------------------

                     DeletePointFromTrack(mx,my)
                     flushkeys      

            EndSelect

         Info_Blurb(10,10)
         
         Sync   
   loop esckey()=true



   ; --------------------------------------------------------------------------
   ; --------------------------------------------------------------------------
   ; --------------------------------------------------------------------------
   ;   ------------------------->> FUnctions <<-----------------------------
   ; --------------------------------------------------------------------------
   ; --------------------------------------------------------------------------
   ; --------------------------------------------------------------------------

Psub Show_Cursor(mx,my,angle#,radius)

      x1#,y1#,x2#,y2#=Compute_track_edges(mx,my,angle#,Radius)

      linec x1#,y1#,x2#,y2#,$ff0000   
      circlec x1#,y1#,5,true,$0000ff
      circlec mx,my,5,true,$0000ff

EndPsub


Psub Compute_track_edges(x,y,angle#,Radius)

      angle2#=wrapangle(angle#-180)

      x1#=x+cos(angle2#)*RAdius
      y1#=y+sin(angle2#)*RAdius
      x2#=x+cos(angle#)*RAdius
      y2#=y+sin(angle#)*RAdius
      
EndPsub x1#,y1#,x2#,y2#


Psub Info_Blurb(xpos,ypos)
      Th=GetTextHeight("|")
      text xpos,ypos,"Track Size:"+Str$(GetTRackSize()): ypos+=Th
      text xpos,ypos,"Fps:"+Str$(fps()): ypos+=Th
EndPsub


Psub GetTRackSize()
      size=GetArrayElements(Track())
EndPsub Size




Function DrawTrack(Mx,My)

      size =GetTRackSize()

      if Size>0
         TrackColour = $30ff40

         Xpos=GetSCreenWidth()-100      

         lockbuffer
            for lp =1 to Size-1

               Index=lp
               NextIndex=LP+1
               if NextIndex>Size then NextIndex=1
         
               if Index <> NextINdex

                  text Xpos,lp*20, str$(Index) + " to " +Str$(NextIndex)

                  ; current point
                  x1=TRack(Index).x1
                  y1=TRack(Index).y1

                  ; next point
                  x2=TRack(nextIndex).x1
                  y2=TRack(nextIndex).y1

                  x3=TRack(nextIndex).x2
                  y3=TRack(nextIndex).y2

                  x4=TRack(Index).x2
                  y4=TRack(Index).y2

                  quadc x1,y1,x2,y2,x3,y3,x4,y4,TrackColour
               endif

            next


         // ------------------------------------------------------------------
         // draw dots to show center points of each track fragment
         // ------------------------------------------------------------------

            for lp =1 to Size
   
               Index=lp

               ; current point
               x1=TRack(Index).x1
               y1=TRack(Index).y1

               x4=TRack(Index).x2
               y4=TRack(Index).y2

               linec x1,y1,x4,y4,$ff00ff

               circlec x1,y1,5,true,$0000ff         ; left edge
               circlec ((x1+x4)/2),((y1+y4)/2),5,true,$ff00ff
            next
         unlockbuffer



         // ------------------------------------------------------------------
         // High light the closest point in the track to the mouse pointer
         // ------------------------------------------------------------------
         Index=FindNearestPointOnTRack(Mx,My)
         if Index

            ; current point
            x1=TRack(Index).x1
            y1=TRack(Index).y1

            x4=TRack(Index).x2
            y4=TRack(Index).y2

            circlec ((x1+x4)/2),((y1+y4)/2),10,false,$ffff00
         
         endif

      endif
EndFunction




Function DeletePointFromTRack(x,y)

      size =GetTRackSize()
      if Size >0


            // Find the point the mouse is current over

            print "DELETE ME"
      
   
            DeleteThisIndex=0
   
            for lp =1 to Size
      
                  x1#=TRack(lp).x1
                  y1#=TRack(lp).y1
                  x2#=TRack(lp).x2
                  y2#=TRack(lp).y2
   
                  cx=(x1#+x2#)/2.0
                  cy=(y1#+y2#)/2.0
            
                  Dist#=GEtDistance2d(x,y,cx,cy)
                     
                  if dist#<=8
                     DeleteThisIndex=lp
                     exitfor
                  endif
            next


            if DeleteThisIndex
      
               Track(DeleteThisIndex) = NUll
               
               SrcPtr=GetArrayPtr(track(),true)+4
               DestPtr=SrcPtr
               for lp=1 to size
                  TypeBank=PeekInt(SrcPtr)   
                  if TypeBank               
                        PokeInt DestPtr,TypeBank
                        DestPtr+=4
                  endif
                  SrcPtr+=4
               next

               ; clear this last cell
               PokeInt SrcPtr-4,0

               redim Track(Size-1) as tPolyLine

               #print "deleted point #"+str$(DeleteThisIndex)
         
               
            endif
      
      endif   
      
EndFunction



Function FindNearestPointOnTRack(x,y)
      index=0
      
      ClosestPoint= 100000
      size =GetTRackSize()
      if Size>1
      
         For lp=1 to Size
         
            x1#=TRack(lp).x1
            y1#=TRack(lp).y1
            x2#=TRack(lp).x2
            y2#=TRack(lp).y2

            cx=(x1#+x2#)/2.0
            cy=(y1#+y2#)/2.0
            
            angletomouse#=getangle2d(cx,cy,x,y)
            
            SegAngle#   =GetAngle2d(x2#,y2#,x1#,y1#)
            SegAngle#   =wrapangle(segAngle#+90)

            Difference#=AngleDifference(SegAngle#,AngleToMouse#)

            if Difference#<90
                  Dist#=GEtDistance2d(x,y,cx,cy)
                  if Dist#<closestPoint
                     ClosestPoint=Dist#
                     Index=lp   
                  endif
            endif                        
         next
      
      endif

EndFUnction Index




Function InsertPointIntoTRack(x,y,angle#,Radius)

      size =GetTRackSize()
      if Size >2
      
            NearestIndex=FindNearestPointOnTRack(x,y)
            If   NearestIndex
               Size++            

               redim TRack(Size) as tPolyLine
         
               Ptr=GetArrayPtr(track(),true)
               for lp=size-1 to NearestIndex step -1
                  SrcPtr=Ptr+(lp*4)
                  TypeBank=PeekInt(SrcPtr)   
                  PokeInt SrcPtr+4,TypeBank
               next
               PokeInt SrcPtr,0
               
               InitPointOnTrack(NearestIndex, x,y,angle#,Radius)

               #print "inserting new point into track @"+str$(NearestIndex)   

            endif
      
      endif   
      
EndFunction


Function AddPointToTrack(x,y,angle#,Radius)
         index      =GetFreecell(Track())
         InitPointOnTrack(index, x,y,angle#,Radius)
         #print "Added new point into track @"+str$(Index)   
EndFunction


Function InitPointOnTrack(index, x,y,angle#,Radius)
         x1#,y1#,x2#,y2#=Compute_track_edges(x,y,angle#,Radius)
         Track(index)= new tPolyline
         TRack(Index).x1=x1#
         TRack(Index).y1=y1#
         TRack(Index).x2=x2#
         TRack(Index).y2=y2#
EndFunction

[/pbcode]
Title: Re: Polygon Track Editor
Post by: monkeybot on March 02, 2014, 11:43:42 AM
hmm that's nice.it would make it much easier to implement computer racers than the method i am using.