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
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
|