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