I think what you're saying is there is no way of doing this with the pure 2D side of 3D.
Just in case, this is the 'hack' I have so far.
<some of the code has been taken from examples on bb and bc so thanks and apologies for no credits).
It's, basically, a shadow caster with a lot of stuff hard-coded at the moment.
Lines are traces from the centre of the light (black oval in big white oval) to each predetermined edge of the rectangle. The lines are then checked to cast a shadow by taking the points of the furthest intersections and using floodfill to make the resulting 'shape' black.
There's quite a few bugs (such as the flip at 180 degress) which can be worked out later.
What I really want to do is fill that shadow shape as quickly as possible.
Just in case, this is the 'hack' I have so far.
Graphics 640,480 SetBuffer BackBuffer() Global msx#,msy#,point1,point2,hi_angle#=-1000,lo_angle#=1000,hi_circ_x#,hi_circ_y#,lo_circ_x#,lo_circ_y# Global hi_pty#,hi_ptx#,lo_pty#,lo_ptx#, msxhi#, msxlo#, hi_msx#, hi_msy#, lo_msy# , lo_msx# Global Intersection_X# ; Values returned by the Lines_Intersect() function. Global Intersection_Y# Global Intersection_AB# Global Intersection_CD# rgb = getrgb(40,40,40) ;[needed for flood fill] Dim map(GraphicsWidth(),GraphicsHeight()) Dim stackx(GraphicsWidth()*GraphicsHeight()) Dim stacky(GraphicsWidth()*GraphicsHeight()) Dim xmove(4),ymove(4) xmove(1)=+1 xmove(3)=-1 ymove(2)=+1 ymove(4)=-1 ;[/needed] While Not KeyHit(1) ClsColor 60,255,60 Cls msx# = MouseX() msy# = MouseY() Color 255,255,255 Oval msx-100,msy-100,200,200,1 Color 0,0,0 Oval msx-4,msy-4,8,8 pt1x = 360 : pt1y = 280 : pt2x = 380 : pt2y = 320 Color 40,40,40 line_extend(pt1x,pt1y,msx,msy) line_extend(pt2x,pt2y,msx,msy) line_extend(pt1x,pt2y,msx,msy) line_extend(pt2x,pt1y,msx,msy) Line hi_ptx,hi_pty,hi_msx+hi_circ_x,hi_msy+hi_circ_y Line lo_ptx,lo_pty,lo_msx+lo_circ_x,lo_msy+lo_circ_y Line hi_ptx,hi_pty,lo_ptx,lo_pty lines_intersect(hi_ptx,hi_pty,lo_msx+lo_circ_x,lo_msy+lo_circ_y,lo_ptx,lo_pty,hi_msx+hi_circ_x,hi_msy+hi_circ_y) If ((msx-intersection_x)*(msx-intersection_x))+((msy-intersection_y)*(msy-intersection_y)) <= 10000 fillfast(Intersection_X#,Intersection_y#,rgb,BackBuffer()) EndIf Color 0,0,255 Rect pt1x,pt1y,pt2x-pt1x,pt2y-pt1y Text 100,0,"low angle = " + lo_angle Text 100,10,"High angle = " + hi_angle curTime = MilliSecs() If curTime > checkTime Then checkTime = curTime + 1000 curFPS = fpscounter fpscounter = 0 Else fpscounter = fpscounter + 1 End If Text 100,20,"FPS : " + curFPS Flip hi_angle = -1000 lo_angle = 1000 Wend Function line_extend(point1,point2,msx1,msy1) If ((msx1-point1)*(msx1-point1))+((msy1-point2)*(msy1-point2)) <= 10000 angle = ATan2(msx1-point1,msy1-point2) If angle > hi_angle hi_angle = angle hi_circ_x# = -Sin(hi_angle)*100 hi_circ_y# = -Cos(hi_angle)*100 hi_msx = msx1 hi_msy = msy1 hi_ptx = point1 hi_pty = point2 EndIf If angle < lo_angle lo_angle = angle lo_circ_x# = -Sin(lo_angle)*100 lo_circ_y# = -Cos(lo_angle)*100 lo_msx = msx1 lo_msy = msy1 lo_ptx = point1 lo_pty = point2 EndIf EndIf End Function Function GetRGB% ( Red% , Green% , Blue% ) ; Combines Red, Green and Blue values into one RGB value Return Red Shl 16 + Green Shl 8 + Blue End Function Function fillfast(startx,starty,fillc,buffer) scx=GraphicsWidth() scy=GraphicsHeight() If startx<0 Or starty<0 Or startx>=scx Or starty>=scy Then RuntimeError "fill starting point out of bounds" fillover=ReadPixelFast(startx,starty) If fillover=fillc Then Return LockBuffer buffer Dim map(scx,scy) WritePixelFast startx,starty,fillc map(startx,starty)=-1 stackx(1)=startx stacky(1)=starty i2=1 Repeat i=i+1 If i>i2 Then Exit For dir=1 To 4 If map(stackx(i),stacky(i))<>dir Then x=stackx(i)+xmove(dir) y=stacky(i)+ymove(dir) If x>=0 And y>=0 And x<scx And y<scy Then If map(x,y)=0 Then If ReadPixelFast(x,y)=fillover Then map(x,y)=dir+2-(dir+2>4) Shl 2 i2=i2+1 stackx(i2)=x stacky(i2)=y WritePixelFast x,y,fillc EndIf EndIf EndIf EndIf Next Forever UnlockBuffer buffer End Function Function Lines_Intersect(Ax#, Ay#, Bx#, By#, Cx#, Cy#, Dx#, Dy#) Rn# = (Ay#-Cy#)*(Dx#-Cx#) - (Ax#-Cx#)*(Dy#-Cy#) Rd# = (Bx#-Ax#)*(Dy#-Cy#) - (By#-Ay#)*(Dx#-Cx#) If Rd# = 0 ; Lines are parralel. ; If Rn# is also 0 then lines are coincident. All points intersect. ; Otherwise, there is no intersection point. Return False Else ; The lines intersect at some point. Calculate the intersection point. Sn# = (Ay#-Cy#)*(Bx#-Ax#) - (Ax#-Cx#)*(By#-Ay#) Intersection_AB# = Rn# / Rd# Intersection_CD# = Sn# / Rd# Intersection_X# = Ax# + Intersection_AB#*(Bx#-Ax#) Intersection_Y# = Ay# + Intersection_AB#*(By#-Ay#) Return True EndIf End Function
<some of the code has been taken from examples on bb and bc so thanks and apologies for no credits).
It's, basically, a shadow caster with a lot of stuff hard-coded at the moment.
Lines are traces from the centre of the light (black oval in big white oval) to each predetermined edge of the rectangle. The lines are then checked to cast a shadow by taking the points of the furthest intersections and using floodfill to make the resulting 'shape' black.
There's quite a few bugs (such as the flip at 180 degress) which can be worked out later.
What I really want to do is fill that shadow shape as quickly as possible.