Hey all. I'm working on a concept that uses 2d spotlights shining on 3d objects creating shadows. hard to explain, but if you run my code you'll see what i mean.
Unfortunately, I'm having problems getting the "shadowing" to work right. I'm basically using linepicks from the source of the light to test if there is something blocking the light. I then use this to create the mesh that makes up the light on the fly.
Everything seems to work splendidly when the light is facing some directions, but doesn't work at all when you spin the light around. Can anyone help me figure out what I'm doing wrong?
In this code, click and drag on the cube "light" to move it, right-click and drag up and down on it to spin it. If you force the red "light" to go over the green spheres, they should stop the light where it hits them.
I'd be happy to hear other approaches to this too!
thanks,
roland
Unfortunately, I'm having problems getting the "shadowing" to work right. I'm basically using linepicks from the source of the light to test if there is something blocking the light. I then use this to create the mesh that makes up the light on the fly.
Everything seems to work splendidly when the light is facing some directions, but doesn't work at all when you spin the light around. Can anyone help me figure out what I'm doing wrong?
In this code, click and drag on the cube "light" to move it, right-click and drag up and down on it to spin it. If you force the red "light" to go over the green spheres, they should stop the light where it hits them.
I'd be happy to hear other approaches to this too!
thanks,
roland
Graphics3D 800,600,32,2 SeedRnd MilliSecs() Type light Field entity Field red Field green Field blue Field cone Field conesurf Field l Field angle# Field picker Field picked Field xspeed# Field yspeed# Field xtarget# Field ytarget# Field pickcyl Field length# Field width# End Type Type block Field entity Field picked End Type Type beacon Field entity Field red Field green Field blue Field activated End Type Global pivot = CreatePivot() Global mainlight = CreateLight(1) RotateEntity mainlight,30,120,0 PositionEntity mainlight,5,20,20 Global cam = CreateCamera() PositionEntity cam,0,-5,30 PointEntity cam,pivot Global ground = CreateCube() ScaleEntity ground,22,15,1 EntityColor ground,200,200,200 PositionEntity ground,-3,0,0 EntityPickMode ground,2 Global pickedlight = 0 Global resetpicks = 1 Global startmousex Global startmousey makelight(0,0,2,255,0,0,45) makebeacon(5,5,2,0,255,0) makebeacon(12,5,2,0,255,0) ;WireFrame True While Not KeyHit(1) If MouseHit(1) Or MouseHit(2) startmousex = MouseX() startmousey = MouseY() chooselight() EndIf If MouseDown(1) movelight() Else If resetpicks = 0 For l.light= Each light EntityPickMode l\entity,2 resetpicks = 1 Next EndIf EndIf If MouseDown(2) rotatelight() EndIf updatelights() If KeyHit(57) wf = 1-wf WireFrame wf EndIf UpdateWorld() RenderWorld() Text 0,0,pickedlight l.light = First light Text 0,20,EntityRoll(l\entity) ;ex# = EntityX#(l\entity) ;ey# = EntityY#(l\entity) ;ez# = EntityZ#(l\entity) ;CameraProject cam,ex,ey,ez ;startx = ProjectedX() ;starty = ProjectedY() ;For a=-l\width To l\width ; dx# = Sin(l\angle+a)*l\length ; dy# = -Cos(l\angle+a)*l\length ; CameraProject cam,dx+ex,dy+ey,z ; endx = ProjectedX() ; endy = ProjectedY() ;Line startx,starty,endx,endy ;Next Flip Wend Function makelight(x#,y#,z#,r,g,b,angle#) l.light = New light l\red = r l\green = g l\blue = b l\angle = angle l\width = 15 l\length = 20 l\entity = CreateCube() EntityColor l\entity,200,100,100 PositionEntity l\entity,x,y,z l\xtarget = x l\ytarget= y EntityPickMode l\entity,2 l\cone = CreateMesh() l\conesurf = CreateSurface(l\cone) EntityColor l\cone,255,0,0 EntityFX l\cone,2+32 ; l\cone = CreateCone(16) ; PositionEntity l\cone,x,y-5,z ; ScaleEntity l\cone,3,5,3 ; EntityColor l\cone,l\red,l\green,l\blue ; EntityParent l\cone,l\entity ; EntityBlend l\cone,3 ; l\pickcyl = CreateCylinder(3) ; ScaleEntity l\pickcyl,.1,5,.1 ; EntityFX l\pickcyl,1 ; EntityColor l\pickcyl,0,0,0 ; PositionEntity l\pickcyl,x,y-5,z ; EntityParent l\pickcyl,l\entity RotateEntity l\entity,0,0,l\angle End Function Function makebeacon(x#,y#,z#,r,g,bl) b.beacon = New beacon b\red = r b\green = g b\blue= bl b\entity = CreateSphere(8) PositionEntity b\entity,x,y,z EntityColor b\entity,b\red,b\green,b\blue b\activated = 0 EntityPickMode b\entity,1 EntityRadius b\entity,1.25 End Function Function chooselight() CameraPick cam,MouseX(),MouseY() If PickedEntity() <> 0 And PickedEntity() <> ground For l.light = Each light If PickedEntity() = l\entity l\picked = 1 pickedlight = Handle(l) EndIf Next Else pickedlight = 0 EndIf End Function Function updatelights() For l.light = Each light l\xspeed = (l\xtarget-EntityX(l\entity))/5 l\yspeed = (l\ytarget-EntityY(l\entity))/5 PositionEntity l\entity,EntityX(l\entity)+l\xspeed,EntityY(l\entity)+l\yspeed,EntityZ(l\entity) x# = EntityX#(l\entity) y# = EntityY#(l\entity) z# = EntityZ#(l\entity) d1x# = Sin(l\angle-l\width)*l\length d1y# = -Cos(l\angle-l\width)*l\length d2x# = Sin(l\angle+l\width)*l\length d2y# = -Cos(l\angle+l\width)*l\length ClearSurface l\conesurf startvert = AddVertex(l\conesurf,x,y,z) leftvert = AddVertex(l\conesurf,x+d1x,y+d1y,z) rightvert = AddVertex(l\conesurf,x+d2x,y+d2y,z) VertexColor l\conesurf,startvert,255,0,0,255 VertexColor l\conesurf,leftvert,255,0,0,0 VertexColor l\conesurf,rightvert,255,0,0,0 ;AddTriangle(l\conesurf,v1,v2,v3) ;UpdateNormals l\cone prevvert = leftvert For a=-l\width To l\width For b.beacon = Each beacon dx# = Sin(l\angle+a)*l\length dy# = -Cos(l\angle+a)*l\length LinePick(x,y,z,x+dx,y+dy,z) If PickedEntity() <> 0 newvert = AddVertex(l\conesurf,PickedX#(),PickedY#(),z) AddTriangle(l\conesurf,prevvert,newvert,startvert) prevvert = newvert VertexColor l\conesurf,newvert,255,0,0,0 Else newvert = AddVertex(l\conesurf,x+dx,y+dy,z) AddTriangle(l\conesurf,prevvert,newvert,startvert) prevvert = newvert VertexColor l\conesurf,newvert,255,0,0,0 EndIf Next Next AddTriangle(l\conesurf,prevvert,rightvert,startvert) UpdateNormals l\cone Next End Function Function movelight() If pickedlight <> 0 l.light = Object.light(pickedlight) EntityPickMode l\entity,0 resetpicks = 0 CameraPick cam,MouseX(),MouseY() If PickedEntity() = ground l\xtarget = PickedX() l\ytarget = PickedY() EndIf EndIf End Function Function rotatelight() If pickedlight <> 0 l.light = Object.light(pickedlight) dy# = MouseY()-startmousey l\angle = EntityRoll(l\entity)-(dy/20) RotateEntity l\entity,0,0,l\angle EndIf End Function