Not totally sure if this is of any help to you, but here's some fuctions from my own (not completely finished, but this works) lighting routines... You can't run this code (without the 57 other include files :) but the code in the LIGHT_GetLightAtPosition function might help you out or give you an idea?! It was originally written for vertex lighting (and is still used for it), but it basically calculates the amount of light a certain xyz point should receive - you can apply the resulting RGB value to a vertex or EntityColor as you wish...
Global LIGHT_VALUE[2] ; RGB storage container for Vertex Lighting routines
Const LIGHT_RET_BUSY = 0 ; lighting routine has NOT FINISHED lighting the entire entity YET.
Const LIGHT_RET_DONE = 1 ; lighting routine HAS FINISHED lighting the entity, and ready for the next one.
;Light shapes
Const LIGHT_SHAPE_DIRECTIONAL = 1
Const LIGHT_SHAPE_POINTLIGHT = 2
Const LIGHT_SHAPE_SPOTLIGHT = 3
Const LIGHT_SHAPE_LINEAR = 4 ; Note: VERTEX light only!
Const LIGHT_SHAPE_AREA = 5 ; Note: VERTEX light only!
Const LIGHT_SHAPE_ENTITY = 6 ; Note: VERTEX light only!
;Light types
Const LIGHT_TYPE_VERTEX = 0 ; pre-calculated vertex light
Const LIGHT_TYPE_DX7 = 1 ; live DirectX7 light (note: max 7 or 8!)
Type node_light
Field entity.node_entity ; handle back to entity (to quickly parse through lights!)
Field lightShape ; light type (0=ambient, 1=direction, 2=point, 3=spot)
Field lightType ; see LIGHT_TYPE_ consts
Field red, green, blue ; light color (seriously!)
Field intensity# ; value between typically between -1.0 and 1.0 (-1 = negative light)
Field doFallOff ; toggle
Field FallOffNear#,FallOffFar# ; intensity falloff (all light types)
Field innerAngle#, outerAngle# ; for spotlights
Field ShadowCaster ; true is this lamp casts shadows
Field shbrightness# ; shadow brightness (0=black, 1=full shadow color)
Field shRed, ShGreen, shBlue ; shadow color
Field prjMapFilename$ ;* ; RESERVED BUT NOT USED YET! - filename of projection map/texture
;live entity handles
Field prjMapHandle ; IMAGE handle to projection map
Field light ; blitz entity handle
End Type
Function LIGHT_RenderEntityColor( ent.node_entity )
;| Lights the entity by setting it's entity color to make it dark or full bright.
;|
;| Used on DYNAMIC entities.
;Set shading FX on entity (for Entity Coloring)
EntityFX ent\model\mesh, 1+ent\model\refModel\Fx
;prevent picking itself
ENT_setPickMode ent, 0, False
;calc light
LIGHT_GetLightAtPosition ent, EntityX#(ent\master,1), EntityY#(ent\master,1), EntityZ#(ent\master,1)
;set entity color
EntityColor ent\model\mesh, LIGHT_VALUE[0],LIGHT_VALUE[1],LIGHT_VALUE[2]
;restore pickmode
ENT_setPickMode ent, 2, True
Return LIGHT_RET_DONE
End Function
Function LIGHT_GetLightAtPosition( ent.node_entity, vx#,vy#,vz# )
;| NOTE: Assumes the entity has been tested to have a MODEL NODE!
;| NOTE: Uses the LIGHT_VALUE[3] global array for returning final RGB values for given coordinates
;reset vertex color
LIGHT_VALUE[0] = 0 ;Red channel
LIGHT_VALUE[1] = 0 ;Green channel
LIGHT_VALUE[2] = 0 ;Blue channel
;check if entity receives shadow
doShadow = ent\model\refmodel\ShadowReceive
;now parse EVERY LIGHT
For light.node_light = Each node_light
If (light\entity\enabled) And (light\lightType = LIGHT_TYPE_VERTEX) Then
;get light data
lx# = EntityX#(light\light,1)
ly# = EntityY#(light\light,1)
lz# = EntityZ#(light\light,1)
lR=0 : lG=0 : lB=0
;act pending shape of vertex light
Select light\lightShape
Case LIGHT_SHAPE_POINTLIGHT
DoFade = False ; fade between COLOR and SHADOW colors within Fallof range!
;get lamp-vertex vector
dx# = vx-lx
dy# = vy-ly
dz# = vz-lz
;check for FALLOFF
If light\doFallOff Then
;get distance
dist# = Sqr(dx*dx + dy*dy + dz*dz)
;check range
If dist# <= light\falloffNear# Then
mult# = 1.0
ElseIf dist# <= light\falloffFar#
;calc falloff
mult# = 1.0-(dist#-light\falloffNear#) / (light\fallofffar#-light\falloffNear#)
doFade = True
Else
;out of range
mult = 0
EndIf
Else
;no fallof, so always color shadow (if any detected next)
mult# = 1.0
EndIf
;check for shadowcasting
If doShadow Then
If (light\shadowCaster=True) And (mult > 0) Then
;ray
pickMesh = LinePick(lx#,ly#,lz#, dx#,dy#,dz#)
If pickMesh <> 0 Then
;RAY hit Something - get distance between vertex & picked point
pvx# = PickedX#()-vx#
pvy# = PickedY#()-vy#
pvz# = PickedZ#()-vz#
pdist# = Sqr( pvx*pvx + pvy*pvy + pvz*pvz )
;when ray stopped SHORT, it must be blocked: SHADOW
If pdist# > 0.01 Then
mult# = mult# * light\shBrightness#
doFade = True ; COLOR SHADOW!
EndIf
Else
;Ray Stopped short or overshot, but didn't hit anything!
;do nothing to keep current mult!
EndIf
EndIf
EndIf
If doFade Then
;Mix between light & shadow color
LR = Interpolate_Linear1D((light\red * light\intensity#), light\shRed , 1-mult#)
LG = Interpolate_Linear1D((light\green * light\intensity#), light\shGreen , 1-mult#)
LB = Interpolate_Linear1D((light\blue * light\intensity#), light\shBlue , 1-mult#)
Else
;Mix between light & shadow color
LR = Interpolate_Linear1D((light\red * light\intensity#), light\shRed * mult# , 1-mult#)
LG = Interpolate_Linear1D((light\green * light\intensity#), light\shGreen * mult#, 1-mult#)
LB = Interpolate_Linear1D((light\blue * light\intensity#), light\shBlue * mult# , 1-mult#)
EndIf
Default
;unsupported / unkown light shape
End Select
;ADD LIGHT result to VERTEX color
LIGHT_VALUE[0] = LIGHT_VALUE[0] + lR
LIGHT_VALUE[1] = LIGHT_VALUE[1] + lG
LIGHT_VALUE[2] = LIGHT_VALUE[2] + lB
EndIf
Next
;check the GLOBAL LIGHT_VALUE[RGB] for results!
; ------
End Function
Function Interpolate_Linear1D#( A#, B#, tween# )
Return ((1.0-tween#) * A#) + (tween# * B#)
End Function
Danny