'Special thx to Devils Child (http://www.devil-engines.net/)

Type TShadowMain
	Field ShadowMesh:TMesh
	Field ShadowSurface:TSurface
	Field VolumeCap:TMesh
	Field VolumeCapSurf:TSurface
	Field VolumeLenght:Int = 500

	
	Field Entity_List:TList = New TList
	Field AnimEntity_List:TList = New TList
	Field AnimVolume:TList = New TList 
	
	Function init:TShadowMain()
		Local SM:TShadowMain = New TShadowMain
		SM.ShadowMesh = CreateMesh()
		SM.ShadowSurface = CreateSurface(SM.ShadowMesh)
		SM.VolumeCap = CreateMesh()
		SM.VolumeCapSurf = CreateSurface(SM.VolumeCap)
		
		SM.ShadowMesh.Name = "Shadow"
		EntityAlpha SM.ShadowMesh, 0.5
		EntityColor SM.ShadowMesh, 0, 0, 0
		EntityFX SM.ShadowMesh , 17
		
		SM.VolumeCap .Name = "Shadow"
		EntityAlpha SM.VolumeCap , 0.5
		EntityColor SM.VolumeCap , 0, 0, 0
		EntityFX SM.VolumeCap , 17


		Return SM
	End Function
	
	Method Clear()
		ShadowSurface.ClearSurface()
		VolumeCapSurf.ClearSurface()
	End Method
	
	Method InitCaster(M:TMesh)
		'If m.anim = True
		'	AnimEntity_List.Addlast(M)
		'	Return
		'Else
			Entity_List.Addlast(M)
		'EndIf
		Local cnt:Int = -1
		m.cnt_tris = - 1
		
	Local cnt_surf:Int = CountSurfaces(M)
	For Local s:Int = 1 To cnt_surf
		Local surf:TSurface = GetSurface(m , s)
		
		Local cnt_tris:Int = CountTriangles(surf) - 1
		m.cnt_tris:+cnt_tris + 1
		For Local v:Int = 0 To cnt_tris
			cnt = cnt + 1
			m.tri[cnt] = New TShadowTriangle
			Local etet:TShadowTriangle = m.tri[cnt]
			Local vert0:Int = TriangleVertex(surf, v, 0)
			Local vert1:Int = TriangleVertex(surf, v, 1)
			Local vert2:Int = TriangleVertex(surf , v , 2)
				etet.v1x# = VertexX(surf, vert0)
				etet.v1y# = VertexY(surf, vert0)
				etet.v1z# = VertexZ(surf, vert0)
				etet.v2x# = VertexX(surf, vert1)
				etet.v2y# = VertexY(surf, vert1)
				etet.v2z# = VertexZ(surf, vert1)
				etet.v3x# = VertexX(surf, vert2)
				etet.v3y# = VertexY(surf, vert2)
				etet.v3z# = VertexZ(surf , vert2)
			etet.ta = -1
			etet.tb = -1
			etet.tc = -1
		Next
	Next
	Local cnt_tris:Int = m.cnt_tris
	Local v1a_x# 
	Local v1a_y#
	Local v1a_z# 
	Local v1b_x# 
	Local v1b_y#
	Local v1b_z# 
	Local v1c_x# 
	Local v1c_y#
	Local v1c_z# 
	
	Local v1a_v2a# 
	Local v1a_v2b#
	Local v1a_v2c#
	Local v1b_v2a# 
	Local v1b_v2b#
	Local v1b_v2c# 
	Local v1c_v2a# 
	Local v1c_v2b#
	Local v1c_v2c# 
 
	
	
	For Local a:Int = 0 To cnt_tris
		Local at:TShadowTriangle = m.tri[a]
		v1a_x# = at.v1x#
		v1a_y# = at.v1y#
		v1a_z# = at.v1z#
		v1b_x# = at.v2x#
		v1b_y# = at.v2y#
		v1b_z# = at.v2z#
		v1c_x# = at.v3x#
		v1c_y# = at.v3y#
		v1c_z# = at.v3z#
		For Local b:Int = a + 1 To cnt_tris
			Local bt:TShadowTriangle = m.tri[b]
			v1a_v2a = (v1a_x# = bt.v1x# And v1a_y# = bt.v1y# And v1a_z# = bt.v1z#)
			v1a_v2b = (v1a_x# = bt.v2x# And v1a_y# = bt.v2y# And v1a_z# = bt.v2z#)
			v1a_v2c = (v1a_x# = bt.v3x# And v1a_y# = bt.v3y# And v1a_z# = bt.v3z#)
			v1b_v2a = (v1b_x# = bt.v1x# And v1b_y# = bt.v1y# And v1b_z# = bt.v1z#)
			v1b_v2b = (v1b_x# = bt.v2x# And v1b_y# = bt.v2y# And v1b_z# = bt.v2z#)
			v1b_v2c = (v1b_x# = bt.v3x# And v1b_y# = bt.v3y# And v1b_z# = bt.v3z#)
			v1c_v2a = (v1c_x# = bt.v1x# And v1c_y# = bt.v1y# And v1c_z# = bt.v1z#)
			v1c_v2b = (v1c_x# = bt.v2x# And v1c_y# = bt.v2y# And v1c_z# = bt.v2z#)
			v1c_v2c = (v1c_x# = bt.v3x# And v1c_y# = bt.v3y# And v1c_z# = bt.v3z#)
			If v1a_v2b And v1b_v2a Then
				at.ta = b
				bt.ta = a
			ElseIf v1b_v2b And v1c_v2a Then
				at.tb = b
				bt.ta = a
			ElseIf v1c_v2b And v1a_v2a Then
				at.tc = b
				bt.ta = a
			ElseIf v1a_v2c And v1b_v2b Then
				at.ta = b
				bt.tb = a
			ElseIf v1b_v2c And v1c_v2b Then
				at.tb = b
				bt.tb = a
			ElseIf v1c_v2c And v1a_v2b Then
				at.tc = b
				bt.tb = a
			ElseIf v1a_v2a And v1b_v2c Then
				at.ta = b
				bt.tc = a
			ElseIf v1b_v2a And v1c_v2c Then
				at.tb = b
				bt.tc = a
			ElseIf v1c_v2a And v1a_v2c Then
				at.tc = b
				bt.tc = a
			EndIf
		Next

	Next
	InitShadow(m)
	'Return m
	End Method
	
	
	Method UpdateAnim(m:TMesh)
		Local cnt:Int = -1
		m.cnt_tris = - 1
		
	Local cnt_surf:Int = CountSurfaces(M)
	For Local s:Int = 1 To cnt_surf
		Local surf:TSurface = GetSurface(m , s)
		
		Local anim_surf:TSurface = TSurface(TMesh(m).anim_surf_list.First())
		If m.ismd2 = True Then
			anim_surf = surf
		EndIf
		Local cnt_tris:Int = CountTriangles(surf) - 1
		m.cnt_tris:+cnt_tris + 1
		For Local v:Int = 0 To cnt_tris
			cnt = cnt + 1
			m.tri[cnt] = New TShadowTriangle
			Local etet:TShadowTriangle = m.tri[cnt]
			Local vert0:Int = TriangleVertex(surf, v, 0)
			Local vert1:Int = TriangleVertex(surf, v, 1)
			Local vert2:Int = TriangleVertex(surf , v , 2)
				etet.v1x# = VertexX(anim_surf, vert0)
				etet.v1y# = VertexY(anim_surf, vert0)
				etet.v1z# = VertexZ(anim_surf, vert0)
				etet.v2x# = VertexX(anim_surf, vert1)
				etet.v2y# = VertexY(anim_surf, vert1)
				etet.v2z# = VertexZ(anim_surf, vert1)
				etet.v3x# = VertexX(anim_surf, vert2)
				etet.v3y# = VertexY(anim_surf, vert2)
				etet.v3z# = VertexZ(anim_surf, vert2)
			etet.ta = -1
			etet.tb = -1
			etet.tc = -1
		Next
	Next
	Local cnt_tris:Int = m.cnt_tris
	Local v1a_x# 
	Local v1a_y#
	Local v1a_z# 
	Local v1b_x# 
	Local v1b_y#
	Local v1b_z# 
	Local v1c_x# 
	Local v1c_y#
	Local v1c_z# 
	
	Local v1a_v2a# 
	Local v1a_v2b#
	Local v1a_v2c#
	Local v1b_v2a# 
	Local v1b_v2b#
	Local v1b_v2c# 
	Local v1c_v2a# 
	Local v1c_v2b#
	Local v1c_v2c# 
 
	
	
	For Local a:Int = 0 To cnt_tris
		Local at:TShadowTriangle = m.tri[a]
		v1a_x# = at.v1x#
		v1a_y# = at.v1y#
		v1a_z# = at.v1z#
		v1b_x# = at.v2x#
		v1b_y# = at.v2y#
		v1b_z# = at.v2z#
		v1c_x# = at.v3x#
		v1c_y# = at.v3y#
		v1c_z# = at.v3z#
		For Local b:Int = a + 1 To cnt_tris
			Local bt:TShadowTriangle = m.tri[b]
			v1a_v2a = (v1a_x# = bt.v1x# And v1a_y# = bt.v1y# And v1a_z# = bt.v1z#)
			v1a_v2b = (v1a_x# = bt.v2x# And v1a_y# = bt.v2y# And v1a_z# = bt.v2z#)
			v1a_v2c = (v1a_x# = bt.v3x# And v1a_y# = bt.v3y# And v1a_z# = bt.v3z#)
			v1b_v2a = (v1b_x# = bt.v1x# And v1b_y# = bt.v1y# And v1b_z# = bt.v1z#)
			v1b_v2b = (v1b_x# = bt.v2x# And v1b_y# = bt.v2y# And v1b_z# = bt.v2z#)
			v1b_v2c = (v1b_x# = bt.v3x# And v1b_y# = bt.v3y# And v1b_z# = bt.v3z#)
			v1c_v2a = (v1c_x# = bt.v1x# And v1c_y# = bt.v1y# And v1c_z# = bt.v1z#)
			v1c_v2b = (v1c_x# = bt.v2x# And v1c_y# = bt.v2y# And v1c_z# = bt.v2z#)
			v1c_v2c = (v1c_x# = bt.v3x# And v1c_y# = bt.v3y# And v1c_z# = bt.v3z#)
			If v1a_v2b And v1b_v2a Then
				at.ta = b
				bt.ta = a
			ElseIf v1b_v2b And v1c_v2a Then
				at.tb = b
				bt.ta = a
			ElseIf v1c_v2b And v1a_v2a Then
				at.tc = b
				bt.ta = a
			ElseIf v1a_v2c And v1b_v2b Then
				at.ta = b
				bt.tb = a
			ElseIf v1b_v2c And v1c_v2b Then
				at.tb = b
				bt.tb = a
			ElseIf v1c_v2c And v1a_v2b Then
				at.tc = b
				bt.tb = a
			ElseIf v1a_v2a And v1b_v2c Then
				at.ta = b
				bt.tc = a
			ElseIf v1b_v2a And v1c_v2c Then
				at.tb = b
				bt.tc = a
			ElseIf v1c_v2a And v1a_v2c Then
				at.tc = b
				bt.tc = a
			EndIf
		Next

	Next
	InitShadow(m)
	'Return m
	End Method



	
	Method InitShadow(m:TMesh)
	Local cnt_tris:Int = m.cnt_tris
	'Print "Init_Shadow: " + cnt_Tris
	For Local v:Int = 0 To cnt_tris
		Local etet:TShadowTriangle = m.tri[v]
		If etet.ta > -1 Then etet.id_ta = m.tri[etet.ta]
		If etet.tb > -1 Then etet.id_tb = m.tri[etet.tb]
		If etet.tc > -1 Then etet.id_tc = m.tri[etet.tc]
	Next
	End Method
	
	Method UpdateCaster(Light:TLight) 
		Local top_caps:Byte 
		If TGLobal.ShadowRender = 0 Then
			top_caps = False
		Else
			top_caps = True
		EndIf
		Local Parallel:Byte
		If Light.Light_type = 0 Then 
			Parallel = True
		Else
			Parallel = False
		EndIf
		

		
		Local e0x#
		Local e0y#
		Local e0z#
		
		Local e1x#
		Local e1y#
		Local e1z#
		
		Local normlight_x#
		Local normlight_y#
		Local normlight_z#
		
		Local r1x#
		Local r1y#
		Local r1z#
		
		Local r2x#
		Local r2y#
		Local r2z#

		Local r3x#
		Local r3y#
		Local r3z#
		
		Local rr1x#
		Local rr1y#
		Local rr1z#
		
		Local rr2x#
		Local rr2y#
		Local rr2z#

		Local rr3x#
		Local rr3y#
		Local rr3z#


		Local vert1:Int
		Local vert2:Int
		Local vert3:Int
		Local vert4:Int
		
		Local check1:Byte = False
		Local check2:Byte = False
		Local check3:Byte = False

		
		Local light_x# = EntityX(Light, True) * (1 + parallel * 1000000)
		Local light_y# = EntityY(Light, True) * (1 + parallel * 1000000)
		Local light_z# = EntityZ(Light, True) * (1 + parallel * 1000000)
		For Local etem:TMesh = EachIn Entity_List
			If etem.anim = True Or etem.ismd2 = True Then
				UpdateAnim(etem)
			EndIf
			
			
				'Print "Update name : " + etem.name
				'Print "Light Entity Distance: "  + EntityDistance(light, etem) + " --> "  +Light.Range#*1000.0
			If Int(light.range#*1000.0) = 1 Or EntityDistance(light, etem) < Light.Range#*1000.0 Then
				Local cnt_tris:Int = etem.cnt_tris
				'Print "ShadowUpdate : " + cnt_tris
				For Local v:Int = 0 To cnt_tris
					'Print v
					Local etet:TShadowTriangle = etem.tri[v]
					TFormPoint etet.v1x#, etet.v1y#, etet.v1z#, etem, Null
					etet.tf_v1x# = TFormedX()
					etet.tf_v1y# = TFormedY()
					etet.tf_v1z# = TFormedZ()
					TFormPoint etet.v2x#, etet.v2y#, etet.v2z#, etem, Null
					etet.tf_v2x# = TFormedX()
					etet.tf_v2y# = TFormedY()
					etet.tf_v2z# = TFormedZ()
					TFormPoint etet.v3x#, etet.v3y#, etet.v3z#, etem, Null
					etet.tf_v3x# = TFormedX()
					etet.tf_v3y# = TFormedY()
					etet.tf_v3z# = TFormedZ()
					e0x# = etet.tf_v3x# - etet.tf_v2x#
					e0y# = etet.tf_v3y# - etet.tf_v2y#
					e0z# = etet.tf_v3z# - etet.tf_v2z#
					e1x# = etet.tf_v2x# - etet.tf_v1x#
					e1y# = etet.tf_v2y# - etet.tf_v1y#
					e1z# = etet.tf_v2z# - etet.tf_v1z#
					normlight_x# = (etet.tf_v1x# - light_x#) * (e0y# * e1z# - e0z# * e1y#)
					normlight_y# = (etet.tf_v1y# - light_y#) * (e0z# * e1x# - e0x# * e1z#)
					normlight_z# = (etet.tf_v1z# - light_z#) * (e0x# * e1y# - e0y# * e1x#)
					etet.cull = (normlight_x# + normlight_y# + normlight_z# > 0)
				Next
				For Local v:Int = 0 To cnt_tris
					'Print v
					Local etet:TShadowTriangle = etem.tri[v]
					r1x# = etet.tf_v1x# + (etet.tf_v1x# - light_x#) * VolumeLenght
					r1y# = etet.tf_v1y# + (etet.tf_v1y# - light_y#) * VolumeLenght
					r1z# = etet.tf_v1z# + (etet.tf_v1z# - light_z#) * VolumeLenght
					r2x# = etet.tf_v2x# + (etet.tf_v2x# - light_x#) * VolumeLenght
					r2y# = etet.tf_v2y# + (etet.tf_v2y# - light_y#) * VolumeLenght
					r2z# = etet.tf_v2z# + (etet.tf_v2z# - light_z#) * VolumeLenght
					r3x# = etet.tf_v3x# + (etet.tf_v3x# - light_x#) * VolumeLenght
					r3y# = etet.tf_v3y# + (etet.tf_v3y# - light_y#) * VolumeLenght
					r3z# = etet.tf_v3z# + (etet.tf_v3z# - light_z#) * VolumeLenght
									
					
					
					If etet.cull = False Then
						If etet.ta > -1 Then check1 = etet.id_ta.cull Else check1 = True
						If etet.tb > -1 Then check2 = etet.id_tb.cull Else check2 = True
						If etet.tc > -1 Then check3 = etet.id_tc.cull Else check3 = True
						If check1 Then
							vert1 = AddVertex(ShadowSurface , etet.tf_v1x#, etet.tf_v1y#, etet.tf_v1z#)
							vert2 = AddVertex(ShadowSurface , etet.tf_v2x#, etet.tf_v2y#, etet.tf_v2z#)
							vert3 = AddVertex(ShadowSurface , r1x#, r1y#, r1z#)
							vert4 = AddVertex(ShadowSurface , r2x#, r2y#, r2z#)
							AddTriangle ShadowSurface , vert1, vert3, vert4
							AddTriangle ShadowSurface , vert1 , vert4 , vert2
							'Print "Check 1 :  Triangle added"
						EndIf
						If check2 Then
							vert1 = AddVertex(ShadowSurface , etet.tf_v2x#, etet.tf_v2y#, etet.tf_v2z#)
							vert2 = AddVertex(ShadowSurface , etet.tf_v3x#, etet.tf_v3y#, etet.tf_v3z#)
							vert3 = AddVertex(ShadowSurface , r2x#, r2y#, r2z#)
							vert4 = AddVertex(ShadowSurface , r3x#, r3y#, r3z#)
							AddTriangle ShadowSurface , vert1, vert3, vert4
							AddTriangle ShadowSurface , vert1 , vert4 , vert2
							'Print "Check 2 :  Triangle added"
						EndIf
						If check3 Then
							vert1 = AddVertex(ShadowSurface , etet.tf_v1x#, etet.tf_v1y#, etet.tf_v1z#)
							vert2 = AddVertex(ShadowSurface , etet.tf_v3x#, etet.tf_v3y#, etet.tf_v3z#)
							vert3 = AddVertex(ShadowSurface , r1x#, r1y#, r1z#)
							vert4 = AddVertex(ShadowSurface , r3x#, r3y#, r3z#)
							AddTriangle ShadowSurface , vert1, vert4, vert3
							AddTriangle ShadowSurface , vert1 , vert2 , vert4
							'Print "Check 3 :  Triangle added"
						EndIf
						If top_caps Then
							vert1 = AddVertex(ShadowSurface , etet.tf_v1x#, etet.tf_v1y#, etet.tf_v1z#)
							vert2 = AddVertex(ShadowSurface , etet.tf_v2x#, etet.tf_v2y#, etet.tf_v2z#)
							vert3 = AddVertex(ShadowSurface , etet.tf_v3x#, etet.tf_v3y#, etet.tf_v3z#)
							
							'vert1 = AddVertex(VolumeCapSurf, rr1x#,rr1y,rr1z)
						'	vert2 = AddVertex(VolumeCapSurf, rr2x#,rr2y,rr2z)
						'	vert3 = AddVertex(VolumeCapSurf, rr3x#,rr3y,rr3z)

							AddTriangle ShadowSurface , vert1, vert2, vert3
						EndIf
					ElseIf parallel = False Then
						vert1 = AddVertex(ShadowSurface , r1x#, r1y#, r1z#)
						vert2 = AddVertex(ShadowSurface , r2x#, r2y#, r2z#)
						vert3 = AddVertex(ShadowSurface , r3x#, r3y#, r3z#)
						AddTriangle ShadowSurface , vert1, vert2, vert3
					EndIf
				Next
			EndIf
		Next
		
		'DebugLog(ShadowMesh.name + " updated")
		'DebugLog("Tris : " + ShadowMesh.CountTriangles())
		
		ShadowMesh.UpdateBuffer()
		VolumeCap.UpdateBuffer()
		
		
	End Method
	
	Method UpdateAnimShadow(light:TLight) 
	For Local MV:TMesh = EachIn AnimVolume
		FreeEntity(MV)
	Next
	ClearList(AnimVolume)
		
	For Local M:TMesh = EachIn AnimEntity_List
		Local surf:TSurface 
		Local VolumeMesh:TMesh = TMesh.CreateMesh()
		VolumeMesh.Name = "Shadow"
		Local VolumeSurface:TSurface = .CreateSurface(VolumeMesh)
		.EntityAlpha VolumeMesh, .3
		.EntityColor VolumeMesh, 255, 0, 255
		.EntityFX VolumeMesh, 1
		Local light_x# = .EntityX(light)
		Local light_y# = .EntityY(light)
		Local light_z# = .EntityZ(light)
		Local Surfcount:Int = 0
		Local alink:TLink = M.anim_surf_list.FirstLink()
		Local anim_surf:TSurface
		Local edge:Tedge[] = New TEdge[65000]
		Local CNTFront:Int = 0
			
		For Local n:Int = 1 To CountSurfaces(M)
			surf = GetSurface(M,n)
			If m.anim Then
				anim_surf=TSurface(alink.Value:Object())
			EndIf
		
			Local dwNumFaces = surf.CountTriangles() - 1
			For Local v = 0 To dwNumFaces
				Local vert0 = TriangleVertex(surf, v, 0)
				Local vert1 = TriangleVertex(surf, v, 1)
				Local vert2 = TriangleVertex(surf , v , 2)
				If m.anim Then
				TFormPoint VertexX(anim_surf , vert0) , VertexY(anim_surf , vert0) , VertexZ(anim_surf , vert0) , M , Null
				Else
				TFormPoint VertexX(surf , vert0) , VertexY(surf , vert0) , VertexZ(surf , vert0) , M , Null
				EndIf
				Local v1_x# = TFormedX()
				Local v1_y# = TFormedY()
				Local v1_z# = TFormedZ()
				If m.anim Then
				TFormPoint VertexX(anim_surf , vert1) , VertexY(anim_surf , vert1) , VertexZ(anim_surf , vert1) , M , Null
				Else
				TFormPoint VertexX(surf , vert1) , VertexY(surf , vert1) , VertexZ(surf , vert1) , M , Null
				EndIf
				Local v2_x# = TFormedX()
				Local v2_y# = TFormedY()
				Local v2_z# = TFormedZ()
				If m.anim Then
				TFormPoint VertexX(anim_surf , vert2) , VertexY(anim_surf , vert2) , VertexZ(anim_surf , vert2) , M , Null
				Else
				TFormPoint VertexX(surf , vert2) , VertexY(surf , vert2) , VertexZ(surf , vert2) , M , Null
				EndIf
				Local v3_x# = TFormedX()
				Local v3_y# = TFormedY()
				Local v3_z# = TFormedZ()
				Local aa_x# = v3_x# - v2_x#
				Local aa_y# = v3_y# - v2_y#
				Local aa_z# = v3_z# - v2_z#
				Local bb_x# = v2_x# - v1_x#
				Local bb_y# = v2_y# - v1_y#
				Local bb_z# = v2_z# - v1_z#
				Local norm_x# = aa_y# * bb_z# - aa_z# * bb_y#
				Local norm_y# = aa_z# * bb_x# - aa_x# * bb_z#
				Local norm_z# = aa_x# * bb_y# - aa_y# * bb_x#
				Local normlight_x# = (v1_x# + v2_x# + v3_x#) / 3 - light_x#
				Local normlight_y# = (v1_y# + v2_y# + v3_y#) / 3 - light_y#
				Local normlight_z# = (v1_z# + v2_z# + v3_z#) / 3 - light_z#
				If (norm_x# * normlight_x# + norm_y# * normlight_y# + norm_z# * normlight_z#) * (1.0 / Float(Sqr(norm_x# * norm_x# + norm_y# * norm_y# + norm_z# * norm_z#))) * (1.0 / Float(Sqr(normlight_x# * normlight_x# + normlight_y# * normlight_y# + normlight_z# * normlight_z#))) => 0 Then
					Edge[CNTFront] = New TEdge
					Edge[CNTFront].surf = surf
					Edge[CNTFront].data[0] = 0
					Edge[CNTFront].data[1] = v1_x#
					Edge[CNTFront].data[2] = v1_y#
					Edge[CNTFront].data[3] = v1_z#
					Edge[CNTFront].data[4] = v2_x#
					Edge[CNTFront].data[5] = v2_y#
					Edge[CNTFront].data[6] = v2_z#
					CNTFront = CNTFront + 1
					Edge[CNTFront] = New TEdge
					Edge[CNTFront].surf = surf
					Edge[CNTFront].data[0] = 0
					Edge[CNTFront].data[1] = v2_x#
					Edge[CNTFront].data[2] = v2_y#
					Edge[CNTFront].data[3] = v2_z#
					Edge[CNTFront].data[4] = v3_x#
					Edge[CNTFront].data[5] = v3_y#
					Edge[CNTFront].data[6] = v3_z#
					CNTFront = CNTFront + 1
					Edge[CNTFront] = New TEdge
					Edge[CNTFront].surf = surf
					Edge[CNTFront].data[0] = 0
					Edge[CNTFront].data[1] = v3_x#
					Edge[CNTFront].data[2] = v3_y#
					Edge[CNTFront].data[3] = v3_z#
					Edge[CNTFront].data[4] = v1_x#
					Edge[CNTFront].data[5] = v1_y#
					Edge[CNTFront].data[6] = v1_z#
					CNTFront = CNTFront + 1
				EndIf
			Next
		Next
		
		
		'Print "Using Edge: " + edge.length + " Front : " + CNTFront
		'DebugStop 	
		Local p0_x#,p0_y#,p0_z#,p1_x#,p1_y#,p1_z#,p0_2_x#,p0_2_y#,p0_2_z#,p1_2_x#,p1_2_y#,p1_2_z#
		Local Diverso:Byte
		Local pe0_x#,pe0_y#,pe0_z#
		Local pe1_x# , pe1_y# , pe1_z#
		
	
		For Local a = 0 To CNTFront-1
			If edge[a].surf <> Null Then
				Diverso = True
				p0_x# = edge[a].data[1]
				p0_y# = edge[a].data[2]
				p0_z# = edge[a].data[3]
				p1_x# = edge[a].data[4]
				p1_y# = edge[a].data[5]
				p1_z# = edge[a].data[6]
				
				'Local vaf = AddVertex(VolumeSurface, p0_x#, p0_y#, p0_z#)
				'Local vbf = AddVertex(VolumeSurface, p1_x#, p1_y#, p1_z#)
				'AddTriangle(VolumeSurface, vaf, AddVertex(VolumeSurface, p0_x#, p0_y#, p0_z#), vbf)
				'AddTriangle(VolumeSurface, vaf, vbf, AddVertex(VolumeSurface, p1_x#, p1_y#, p1_z#))

				For Local b = a + 1 To CNTFront-1
					p0_2_x# = edge[b].data[1]
					p0_2_y# = edge[b].data[2]
					p0_2_z# = edge[b].data[3]
					p1_2_x# = edge[b].data[4]
					p1_2_y# = edge[b].data[5]
					p1_2_z# = edge[b].data[6]
					If edge[b].surf <> Null Then
						If (p0_x# = p0_2_x# And p0_y# = p0_2_y# And p0_z# = p0_2_z# And p1_x# = p1_2_x# And p1_y# = p1_2_y# And p1_z# = p1_2_z#) = False Then
							If p0_x# = p1_2_x# And p0_y# = p1_2_y# And p0_z# = p1_2_z# And p1_x# = p0_2_x# And p1_y# = p0_2_y# And p1_z# = p0_2_z# Then
								edge[a].surf = Null
								edge[b].surf = Null
								surf = Null
								Diverso = False
								Exit
							EndIf
						EndIf
					EndIf
				Next
				If Diverso Then
					pe0_x# = p0_x# - light_x#
					pe0_y# = p0_y# - light_y#
					pe0_z# = p0_z# - light_z#
					
					
					Local do# = 1.0 / Float(Sqr(pe0_x# * pe0_x# + pe0_y# * pe0_y# + pe0_z# * pe0_z#))
					pe0_x# = pe0_x# * do# * VolumeLenght+ p0_x#
					pe0_y# = pe0_y# * do# * VolumeLenght+ p0_y#
					pe0_z# = pe0_z# * do# * VolumeLenght+ p0_z#
					pe1_x# = (p1_x# - light_x#) * VolumeLenght+ p1_x#
					pe1_y# = (p1_y# - light_y#) * VolumeLenght+ p1_y#
					pe1_z# = (p1_z# - light_z#) * VolumeLenght+ p1_z#
					Local va = AddVertex(VolumeSurface, p0_x#, p0_y#, p0_z#)
					Local vb = AddVertex(VolumeSurface, pe1_x#, pe1_y#, pe1_z#)
					AddTriangle(VolumeSurface, va, AddVertex(VolumeSurface, pe0_x#, pe0_y#, pe0_z#), vb)
					AddTriangle(VolumeSurface, va, vb, AddVertex(VolumeSurface, p1_x#, p1_y#, p1_z#))
					edge[a].surf = Null
				EndIf
			EndIf
			
			If M.anim
				If alink <> Null Then alink=alink.NextLink() ' iterate thought anim_surf_list in sync with surf_list
			EndIf
		Next
		
		VolumeMesh.UpdateBuffer()
		AnimVolume.Addlast(VolumeMesh)
		Next
	End Method
	
End Type

Type TShadowTriangle
	Field v1x#, v1y#, v1z#
	Field v2x#, v2y#, v2z#
	Field v3x#, v3y#, v3z#
	Field tf_v1x#, tf_v1y#, tf_v1z#
	Field tf_v2x#, tf_v2y#, tf_v2z#
	Field tf_v3x#, tf_v3y#, tf_v3z#
	Field nx#, ny#, nz#, cull
	Field ta, tb, tc, id_ta:TShadowTriangle, id_tb:TShadowTriangle, id_tc:TShadowTriangle
End Type

Type Tedge
	Field surf:TSurface
	Field data:Float[7]
	
	Method Copy:TEdge()
		Local C:TEdge = New TEdge
		C.Surf = surf
		For Local I:Int = 0 To 6
			C.Data = data
		Next
		Return C
	End Method
End Type


		
