Shadow volume

Blitz3D Forums/Blitz3D Programming/Shadow volume

This demo is created for simulate the volume shadow

shipment the code in order to test it and hoping that you can help me to improve it
hello

excuse for the my english

http://digilander.libero.it/enzo_light/shw.zip



Where to start....

1. You're referencing several include files which the rest of us don't have. [edit] I found one of them hidden in the above 'mess'. See point 3 below.

2. You're loading models and textures that the rest of us don't have.

3. Your code is not indented and is nigh on impossible to read. At LEAST put it in code tags.

People simply cannot be bothered messing about getting your code to run. Post a downloadable demo with EXE/ZIP file, and possibly a screenshot as well, and you might get people interested.

or better still codebox tags.

Vincenzo,

Use "[code] ...your code goes here... [\code]" to show your code - Oh but ignore the " ".

IPete2.

or codebox, it's much better for lots of long code.

Ok!!!

Bye

Ran the EXE - Memory Access Violation.

Your code gives the same error at "WritePixelFast X,Y,0", in Function ShadowVolumeCreateImage()

?

you have got the same problem as i have...did u read my thread about stencil shadow volumes?
if not, this would be helpful at all :)

i ha a simulate stencil buffer :D
this is a very slow speed :(
help me for speed up

bye

yes, i will check the code out when i come back from my holiday trip in a few days...

i have changed the code function ShadowVolumeCreate3$ for speed up, imcrements 16 milliseconds

bye

post a new code

;=======================
; Creazione volume
; forse si può fare ancora qualcosina!!
Function ShadowVolumeCreate3$( model, Normalize)
	;===> 
	Local Result$=""
	Local Norm.Point3D=New Point3D 
	Local MidPoint.Point3D=New Point3D 
	Local NormLight.Point3D=New Point3D
	Local CNTFront=0
	Local CNTBack=0
	Local surf=0
	Local check1 = False
	Local check2 = False
	;===> 
	; Cerchiamoci i vertici faccia vista verso la luce
	For n=1 To CountSurfaces(model) 
		;DebugLog "Testing surface "+n 
		surf = GetSurface(model,n) 
		dwNumFaces = CountTriangles(surf)-1 
		;dwNumVertex = CountVertices(surf)-1 
		;DebugLog "Limb "+EntityName(model)+", surface "+n+" contains "+dwNumVertex+" vertices." 
		For v=0 To dwNumFaces
			;Stop
			;===> 
			vert0 = TriangleVertex(surf,v,0) : vert1 = TriangleVertex(surf,v,1) : vert2 = TriangleVertex(surf,v,2)
			;===>
			;associamo le trasformazioni ai vertici
			TFormPoint VertexX( surf, vert0), VertexY( surf, vert0) , VertexZ( surf, vert0 ), model, 0
			sh_v1\x = TFormedX() : sh_v1\y = TFormedY() : sh_v1\z = TFormedZ()
			;===> 
			;associamo le trasformazioni ai vertici
			TFormPoint VertexX( surf, vert1), VertexY( surf, vert1) , VertexZ( surf, vert1 ), model, 0
			sh_v2\x = TFormedX() : sh_v2\y = TFormedY() : sh_v2\z = TFormedZ() 
			;===> 
			;associamo le trasformazioni ai vertici
			TFormPoint VertexX( surf, vert2), VertexY( surf, vert2) , VertexZ( surf, vert2 ), model, 0
			sh_v3\x = TFormedX() : sh_v3\y = TFormedY() : sh_v3\z = TFormedZ() 
			;===> 
			Norm= CalcNormal(sh_v1,sh_v2,sh_v3)
			MidPoint=V_3Mid(sh_v1,sh_v2,sh_v3) 
			NormLight= V_3Dec(MidPoint,sh_light) 
			V_3Normalize(Norm) 
			V_3Normalize(NormLight) 
			Dot#=V_3Dot(Norm,NormLight) 
			;===>
			; Ricerchiamo i vertici rivolti verso la luce e non e li memoriziamo
			If Dot#=>0.1 And Dot#<=1 Then
				;Stop
				;VertexColor surf,vert0,255,0,0
				;VertexColor surf,vert1,255,0,0
				;VertexColor surf,vert2,255,0,0
				;===>
				; Edge 1
				;===>
				ID_EdgeF.EdgeF = edgeFront(CNTFront)
				ID_EdgeF\Surf = surf
				ID_EdgeF\Triangle = v
				V_3Copy(ID_EdgeF\Point0,sh_v1)
				V_3Copy(ID_EdgeF\Point1,sh_v2)
				CNTFront=CNTFront+1
				;===>
				; Edge 2
				;===>
				ID_EdgeF.EdgeF = edgeFront(CNTFront)
				ID_EdgeF\Surf = surf
				ID_EdgeF\Triangle = v
				V_3Copy(ID_EdgeF\Point0,sh_v2)
				V_3Copy(ID_EdgeF\Point1,sh_v3)
				CNTFront=CNTFront+1
				;===>
				; Edge 3Result$
				;===>
				ID_EdgeF.EdgeF = edgeFront(CNTFront)
				ID_EdgeF\Surf = surf
				ID_EdgeF\Triangle = v
				V_3Copy(ID_EdgeF\Point0,sh_v3)
				V_3Copy(ID_EdgeF\Point1,sh_v1)
				CNTFront=CNTFront+1
				;===> 
			EndIf
			;===> 
		Next 
	Next
	Result$=Result$+" ==> Facce Front : "+CNTFront+"  Facce Back : "+CNTBack
	;===> 
	cntUguali=0
	cntDiverse=0

	;CNTFront=CNTFront-1 ;serve solo per eliminare x sottrazioni nel ciclo Più interno
	For a=0 To CNTFront
		;===> 
		If (EdgeFront(a)\surf>0) Then
			;===>
			Diverso=True
			MemB=0
			;===>
			; Inizializziamo i puntatori
			ID_EdgeFA.EdgeF = edgeFront(a) ; funziona come i puntatori del c++
			ID_P0.Point3d = ID_EdgeFA\Point0
			ID_P1.Point3d = ID_EdgeFA\Point1	; Puntiamo a Point - funziona come i puntatori del c++
			;===>
			For b=a+1 To CNTFront	; Ottimizzazione 2°
				;===>
				ID_EdgeFB.EdgeF = edgeFront(b)
				;===>
				If (EdgeFront(b)\surf>0) Then
					;non conviene quì fare il puntatore perche il tempo di acquisizione del puntatore.
					;ID_PB0.Point3d = ID_EdgeFB\Point0
					;ID_PB1.Point3d = ID_EdgeFB\Point1	; Puntiamo a Point - funziona come i puntatori del c++
					;===>
					; verifichiamo che i vertici che stiamo visionando non appartengano allo stesso triangolo
					;===>
					;Ulteriore verifica di diversità
					check1 = CheckVertex( ID_P0, ID_EdgeFB\Point0 )
					check2 = CheckVertex( ID_P1, ID_EdgeFB\Point1 )
						;===>
					If  (check1 And check2)  Then
						;===>
						MemB=b
						;===>
						cntUguali = cntUguali + 1
						ID_EdgeFA\surf = 0
						ID_EdgeFB\surf = 0
						Diverso = False
						Exit
						;===>
					Else
						;===>
						check1 = CheckVertex(ID_P0,ID_EdgeFB\Point1)
						check2 = CheckVertex(ID_P1,ID_EdgeFB\Point0)
						;===>
						If (check1 And check2) Then
							;===>
							MemB=b
							;===>
							cntUguali=cntUguali+1
							ID_EdgeFA\surf=0
							ID_EdgeFB\surf=0
							Diverso=False
							Exit
							;===>
						EndIf
						;===>
					EndIf
					;===>
				EndIf
				;===> 
			Next
			;===>
			If  (Diverso=True) Then
				cntDiverse=cntDiverse+1
				;===>
				; per debug
				;VertexColor EdgeFront(a)\surf,EdgeFront(a)\Vert0,255,0,255
				;VertexColor EdgeFront(a)\surf,EdgeFront(a)\Vert1,255,0,255
				;===>
				ID_EdgeFA\Ray0 = V_3Dec( ID_P0, sh_light ) 
				V_3Normalize(ID_EdgeFA\Ray0 ) 
				ID_EdgeFA\Ray0 = V_3Inc( V_3Mul(ID_EdgeFA\Ray0, sh_lenght ), ID_P0 )
				;===>
				ID_EdgeFA\Ray1 = V_3Dec( ID_P1,sh_light ) 
				V_3Normalize( ID_EdgeFA\Ray1 ) 
				ID_EdgeFA\Ray1 = V_3Inc( V_3Mul( ID_EdgeFA\Ray1, sh_lenght ), ID_P1 ) 
				;===>
				va = AddVertex(SurfaceFront,  ID_P0\x, ID_P0\y, ID_P0\z ); 
				vb = AddVertex(SurfaceFront,  ID_EdgeFA\Ray0\x,   ID_EdgeFA\Ray0\y,   ID_EdgeFA\Ray0\z ); 
				vc = AddVertex(SurfaceFront,  ID_EdgeFA\Ray1\x,   ID_EdgeFA\Ray1\y,   ID_EdgeFA\Ray1\z); 
				vd = AddVertex(SurfaceFront,  ID_P1\x, ID_P1\y, ID_P1\z ); 
				;===>
				AddTriangle(SurfaceFront, va, vb, vc); faccia 1/3 a 
				AddTriangle(SurfaceFront, va, vc, vd); faccia 1/3 b
				ID_EdgeFA\surf=0
				EdgeFront(MemB)\surf=0
				;===>
			EndIf
		;===>
		EndIf
		;===>
	Next
	Result$=Result$+" Edges : "+cntDiverse
	;===>
	.jump
	;UpdateNormals model
	For e=1 To CountChildren(Model) 
		limb = GetChild(model,e) 
		ShadowVolumeCreate3(limb, Normalize) 
	Next 
;	;===>
	;Stop
	Return Result$
End Function 



ok, i can help you(i have got the same problem as you!)

if you help me to find the function in that code which creates the volume and isolate it, i can help you to create a good stencil shadow system!

so where is the function which creates the volume?

edit: i found some things about the volume, but it is to slow for a real shadow system, and i can't really isolate the function from the rest(from the rubbish)

the function for create volume is the last function posted ShadowVolumeCreate3$(...)

this function is composed the 2 section

1° section:

acquire vertex transformed, selected vertex front side light, and defined edge triangle


2° section:

discard edge equal and create volume object other adge

the funtion is indipendent to the system

i have a idea.... InitShadow this function acquire vertex object first and precessed vertex(in the memory) post for volume, this system increment speed 2 - 10%

the very problem is generate ShadowVolumeCreateImage this funcion create slow speed for 2 read pixel(back and front face object volume) and 1 write pixel, this function simulate stencil

congratulation!! the your system render is very good speed

excuse for the my english

Thank's for all bye

but why is this thingy so slowly?
i think it is thew volume create function which is so slowly... so i cannot use it for my system sry :(

?

test the your system disabled the creation volume or system simulate stencil

ok, i found the function which lames all down, now i'm making a system out of this... if it works(IF IT WORKS) i will send it to u :)

edit: your source is 1200 lines large. i'm modifying it, and now it's only 250 lines long, how could this be?? - half of ypur code is rubish!

i send a link new version simplex

;)

i have divide common and shadow

digilander.libero.it/enzo_light/shw01.zip

there is nothing changed, but i'll try to make the best of both :)

i search the new alghoritm for generate silhouette bye

i have modifyed you one up to this:

Graphics3D 1024, 768, 32, 2
SetBuffer BackBuffer()

;Globs
Global sh_v1.Point3D, sh_v2.Point3D, sh_v3.Point3D, sh_nv1.Point3D, sh_nv2.Point3D, sh_nv3.Point3D, sh_vect1.Point3D, sh_vect2.Point3D, sh_vect3.Point3D, sh_light.Point3D, sh_lenght.Point3D, sh_normal.Point3D, sh_NCamera.Point3D
Global VolumeMesh, VolumeSurface
Dim Edge.Edge(65000)

;Camera
Cam = CreateCamera()

;Shadows
InitShadows()

;Floor
c = CreateCube()
ScaleEntity c, 10, 1, 10
PositionEntity c, 0, -5, 10
EntityColor c, 0, 255, 0

;Caster
Cube = CreateSphere()
PositionEntity Cube, -1.5, 0, 10
Cube2 = CreateCube()
PositionEntity Cube2, 1.5, 0, 10

;Light
Light = CreateLight()
PositionEntity Light, 0, 5, 10

While Not KeyHit(1)
	ms = ms + 1
	PointEntity Light, Cube
	TurnEntity Cube, 1, .5, 1.5
	TurnEntity Cube2, 1, .5, 1.5
	ResetShadowVolume()
	ShadowVolume(Cube, Light)
	ShadowVolume(Cube2, Light)
	RenderWorld
	Flip
Wend
FreeShadows()
End








;Types
Type Point3D
	Field x#, y#, z#
End Type
Type Edge
	Field Surf, Triangle
	Field Point0.Point3D, Point1.Point3D, Ray0.Point3D, Ray1.Point3D
End Type

Function InitShadows()
;Volume mesh
VolumeMesh = CreateMesh()
VolumeSurface = CreateSurface(VolumeMesh)
EntityAlpha VolumeMesh, .5
EntityColor VolumeMesh, 255, 0, 0
EntityFX VolumeMesh, 17
;Edges
For a = 0 To 65000
	Edge.Edge(a) = New Edge
	Edge(a)\Point0.Point3D = New Point3D
	Edge(a)\Point1.Point3D = New Point3D
	Edge(a)\Ray0.Point3D = New Point3D
	Edge(a)\Ray1.Point3D = New Point3D
Next
;Points
sh_v1.Point3D = New Point3D
sh_v2.Point3D = New Point3D
sh_v3.Point3D = New Point3D
sh_nv1.Point3D = New Point3D
sh_nv2.Point3D = New Point3D
sh_nv3.Point3D = New Point3D
sh_vect1.Point3D = New Point3D
sh_vect2.Point3D = New Point3D
sh_vect3.Point3D = New Point3D
sh_light.Point3D = New Point3D
sh_lenght.Point3D = New Point3D
sh_normal.Point3D = New Point3D
sh_NCamera.Point3D = New Point3D
End Function

Function FreeShadows()
If VolumeMesh Then FreeEntity VolumeMesh
Delete Each Point3D
Delete Each Edge
End Function

Function V3_Inc.Point3D(val1.Point3D, val2.Point3D)
val1\x = val1\x + val2\x
val1\y = val1\y + val2\y
val1\z = val1\z + val2\z
Return val1
End Function

Function V3_Dec.Point3D(val1.Point3D, val2.Point3D, val3.Point3D)
val3\x = val1\x - val2\x
val3\y = val1\y - val2\y
val3\z = val1\z - val2\z
End Function

Function V3_Mul.Point3D(val1.Point3D, val2.Point3D)
val1\x = val1\x * val2\x
val1\y = val1\y * val2\y
val1\z = val1\z * val2\z
Return val1
End Function

Function V3_Copy(a.Point3D, b.Point3D)
a\x# = b\x#
a\y# = b\y#
a\z# = b\z#
End Function

Function V3_Normalize(val.Point3D)
do# = 1.0 / Float(Sqr(val\x ^ 2 + val\y ^ 2 + val\z ^ 2))
val\x = val\x * do
val\y = val\y * do
val\z = val\z * do
End Function

Function V3_CheckVertex(a.Point3D, b.Point3D)
If a\x = b\x And a\y = b\y And a\z = b\z Then Return True Else Return False
End Function

Function ResetShadowVolume()
ClearSurface VolumeSurface
End Function

Function ShadowVolume(model, Light)
sh_light\x = EntityX(Light)
sh_light\y = EntityY(Light)
sh_light\z = EntityZ(Light)
sh_lenght\x = 1000
sh_lenght\y = 1000
sh_lenght\z = 1000
Norm.Point3D = New Point3D
MidPoint.Point3D = New Point3D
NormLight.Point3D = New Point3D
For n = 1 To CountSurfaces(model)
	surf = GetSurface(model, n)
	dwNumFaces = CountTriangles(surf) - 1
	For v = 0 To dwNumFaces
		vert0 = TriangleVertex(surf, v, 0)
		vert1 = TriangleVertex(surf, v, 1)
		vert2 = TriangleVertex(surf, v, 2)
		TFormPoint VertexX(surf, vert0), VertexY(surf, vert0), VertexZ(surf, vert0), model, 0
		sh_v1\x = TFormedX()
		sh_v1\y = TFormedY()
		sh_v1\z = TFormedZ()
		TFormPoint VertexX(surf, vert1), VertexY(surf, vert1), VertexZ(surf, vert1), model, 0
		sh_v2\x = TFormedX()
		sh_v2\y = TFormedY()
		sh_v2\z = TFormedZ()
		TFormPoint VertexX(surf, vert2), VertexY(surf, vert2), VertexZ(surf, vert2), model, 0
		sh_v3\x = TFormedX()
		sh_v3\y = TFormedY()
		sh_v3\z = TFormedZ()
		aa.Point3D = New Point3D
		bb.Point3D = New Point3D
		V3_Dec(sh_v3, sh_v2, aa.Point3D)
		V3_Dec(sh_v2, sh_v1, bb.Point3D)
		ax# = aa\y# * bb\z# - aa\z# * bb\y#
		ay# = aa\z# * bb\x# - aa\x# * bb\z#
		az# = aa\x# * bb\y# - aa\y# * bb\x#
		Norm\x# = ax#
		Norm\y# = ay#
		Norm\z# = az#
		Delete aa
		Delete bb
		MidPoint\x = (sh_v1\x# + sh_v2\x# + sh_v3\x) / 3
		MidPoint\y = (sh_v1\y# + sh_v2\y# + sh_v3\y) / 3
		MidPoint\z = (sh_v1\z# + sh_v2\z# + sh_v3\z) / 3
		V3_Dec(MidPoint, sh_light, NormLight)
		V3_Normalize(Norm)
		V3_Normalize(NormLight)
		Dot# = Norm\x# * NormLight\x# + Norm\y# * NormLight\y# + Norm\z# * NormLight\z#
		If Dot# => 0 And Dot# <= 1 Then
			ID_EdgeF.Edge = Edge(CNTFront)
			ID_EdgeF\Surf = surf
			ID_EdgeF\Triangle = v
			V3_Copy(ID_EdgeF\Point0, sh_v1)
			V3_Copy(ID_EdgeF\Point1, sh_v2)
			CNTFront = CNTFront + 1
			ID_EdgeF.Edge = Edge(CNTFront)
			ID_EdgeF\Surf = surf
			ID_EdgeF\Triangle = v
			V3_Copy(ID_EdgeF\Point0, sh_v2)
			V3_Copy(ID_EdgeF\Point1, sh_v3)
			CNTFront = CNTFront + 1
			ID_EdgeF.Edge = Edge(CNTFront)
			ID_EdgeF\Surf = surf
			ID_EdgeF\Triangle = v
			V3_Copy(ID_EdgeF\Point0, sh_v3)
			V3_Copy(ID_EdgeF\Point1, sh_v1)
			CNTFront = CNTFront + 1
		EndIf
	Next
Next
cntUguali = 0
cntDiverse = 0
For a = 0 To CNTFront
	If Edge(a)\surf > 0 Then
		Diverso = True
		MemB = 0
		ID_EdgeFA.Edge = Edge(a)
		ID_P0.Point3d = ID_EdgeFA\Point0
		ID_P1.Point3d = ID_EdgeFA\Point1
		For b = a + 1 To CNTFront
			ID_EdgeFB.Edge = Edge(b)
			If Edge(b)\surf > 0 Then
				check1 = V3_CheckVertex(ID_P0, ID_EdgeFB\Point0)
				check2 = V3_CheckVertex(ID_P1, ID_EdgeFB\Point1)
				If check1 And check2 Then
					MemB = b
					cntUguali = cntUguali + 1
					ID_EdgeFA\surf = 0
					ID_EdgeFB\surf = 0
					Diverso = False
					Exit
				Else
					check1 = V3_CheckVertex(ID_P0, ID_EdgeFB\Point1)
					check2 = V3_CheckVertex(ID_P1, ID_EdgeFB\Point0)
					If check1 And check2 Then
						MemB = b
						cntUguali = cntUguali + 1
						ID_EdgeFA\surf = 0
						ID_EdgeFB\surf = 0
						Diverso = False
						Exit
					EndIf
				EndIf
			EndIf
		Next
		If Diverso Then
			cntDiverse = cntDiverse + 1
			V3_Dec(ID_P0, sh_light, ID_EdgeFA\Ray0)
			V3_Normalize(ID_EdgeFA\Ray0)
			ID_EdgeFA\Ray0 = V3_Inc(V3_Mul(ID_EdgeFA\Ray0, sh_lenght), ID_P0)
			V3_Dec(ID_P1, sh_light, ID_EdgeFA\Ray1)
			V3_Normalize(ID_EdgeFA\Ray1)
			ID_EdgeFA\Ray1 = V3_Inc(V3_Mul(ID_EdgeFA\Ray1, sh_lenght), ID_P1)
			va = AddVertex(VolumeSurface, ID_P0\x, ID_P0\y, ID_P0\z)
			vb = AddVertex(VolumeSurface, ID_EdgeFA\Ray1\x, ID_EdgeFA\Ray1\y, ID_EdgeFA\Ray1\z)
			AddTriangle(VolumeSurface, va, AddVertex(VolumeSurface, ID_EdgeFA\Ray0\x, ID_EdgeFA\Ray0\y, ID_EdgeFA\Ray0\z), vb)
			AddTriangle(VolumeSurface, va, vb, AddVertex(VolumeSurface, ID_P1\x, ID_P1\y, ID_P1\z))
			ID_EdgeFA\surf = 0
			Edge(MemB)\surf = 0
		EndIf
	EndIf
Next
Delete Norm.Point3D
Delete MidPoint.Point3D
Delete NormLight.Point3D
End Function


Devils Child .. now that looks like it's supposed to .. Nice work :) You could get more raw speed by not calling your vector functions in the shadowvolume routine. Also, you create and delete Norm / MidPoint/ NormLight many times - just make them global and don't delete them so that they can be reused. Also in the normalize routine .. it's quicker to use x*x than using x^2.

I may have a play around and see if I can be speeded up.

So what's the next step?

Stevie

I Devils Child

the your system not have change result, the problem is generate silhouette, i have a solution, have a studi the system for fast silhouette this methods is based for adjacent triangle and a 1 for next (not nested)for generate sil.. I am creating this


bye

I all
this is a link for new systems generate silouette for blitz,
is not complete and optimized for my time is little, in order to complete servants the management fines object in sketched part

the new optimize are "simulate stencil buffer" is very slow

test this software

http://digilander.libero.it/enzo_light/shw03.zip

bye

is the createvolume function of shw03.zip faster than the old one?

very very fast!!!

i have create a new system for blitz Edge to edge remember?

if disable simulate stencil buffer and verify the difference

the include is changed

:)

there is a little bug... if i create a cylinder or a cone, the program crashes...

ok lock the program thanks
bye

The Bug is resolved

post the code
Bye :)

v
;======================================= 
;--------------------------------------- 
; 
;   Name file: Shadow_Include
; 
;   Programmatore: 
;      Caldarulo Vincenzo (Eye & Light) 
;   Descrizione: 
;			Creazione dei volumi d'ombra
; 
;--------------------------------------- 
;======================================= 
Include"commontype.bb"
;======================================= 
;--------------------------------------- 
; Variabili ShadowVolume 
;--------------------------------------- 
;======================================= 
;===>
Type EdgeToEdge
	Field IdModel
	Field Surfaces.ETE_Surface
End Type
;===>
Type ETE_Surface
	Field IdSurface
	Field cntTriangle
	Field IdTriangle.ETE_Triangle[ETE_MaxTriang]
End Type
;===>
Type ETE_Triangle
	Field Normal.Point3D
	Field a.Point3D
	Field b.Point3D
	Field c.Point3D
	Field Triangle
	Field ATriangle
	Field BTriangle
	Field CTriangle
End Type
;===>
;======================================= 
;===>
Const SHWTexSize = 128; Parametro di regolazione Ombra
Const sh_level# = 0.1
Const ETE_MaxTriang=15000
Const SHWL3D = 20000
;===>
;======================================= 
;===>
Dim BG1(SHWTexSize,SHWTexSize)
Dim BG2(SHWTexSize,SHWTexSize)
Dim  TriangleClone.ETE_Triangle(ETE_MaxTriang)
;===>
;======================================= 
;===>
Global Scena = CreatePivot(); CreateSphere(5)
Global MeshFront = CreateMesh(); 
Global SurfaceFront = CreateSurface(MeshFront); 
EntityAlpha MeshFront, sh_level 
EntityColor MeshFront, 255,0,0 
EntityFX MeshFront,1;4
EntityBlend MeshFront,3

Global cntLine3D=0
Dim Line3DAX#(SHWL3D)
Dim Line3DAY#(SHWL3D)
Dim Line3DAZ#(SHWL3D)
Dim Line3DBX#(SHWL3D)
Dim Line3DBY#(SHWL3D)
Dim Line3DBZ#(SHWL3D)
;===>
;Creiamo il piano che proietterà l'ombra
;===>
Global SHWSpriteFront=CreateSprite()
SpriteViewMode SHWSpriteFront,1
Global ShwTex1=CreateTexture(SHWTexSize,SHWTexSize,1+2+8+256+512)
EntityTexture SHWSpriteFront,ShwTex1
EntityFX SHWSpriteFront,1
EntityParent SHWSpriteFront,Camera
HideEntity SHWSpriteFront
;===>
Global sh_v1.Point3D			= New Point3D 
Global sh_v2.Point3D			= New Point3D 
Global sh_v3.Point3D			= New Point3D 
Global sh_light.Point3D		= New Point3D 
Global sh_lenght.Point3D	= New Point3D 
;===>
Global SHW_ETE_Object.EdgeToEdge
;===>
;======================================= 
;===>
;=======================
; 
Function CheckVertex%(a.Point3D,b.Point3D)
	If (a\x=b\x)And(a\y=b\y)And(a\z=b\z) Then
		Return True 
	Else
		Return False 
	EndIf 
End Function 

;======================================================================= 
;======================================================================= 
; Shadow Volume For silhouette Method Edge to Edge
;======================================================================= 
;======================================================================= 
;======================= 
; Inizialize Object Shadow
Function SHW_Init()

	;===>
	; Search surface and triangle object
	For n=0 To ETE_MaxTriang
	
		TriangleClone.ETE_Triangle(n) = New ETE_Triangle
		
		TriangleClone(n)\Normal.Point3D = New Point3D
		TriangleClone(n)\a.Point3D = New Point3D
		TriangleClone(n)\b.Point3D = New Point3D
		TriangleClone(n)\c.Point3D = New Point3D
	Next
End Function 

;=======================
; Inizialize Object Shadow
Function SHW_InitObject(model)

	Norm.Point3D = New Point3D
	
	SHW_ETE_Object.EdgeToEdge = New EdgeToEdge
	SHW_ETE_Object\IdModel = model
	;===>
	; Search surface and triangle object
	For n=1 To CountSurfaces(model)
		;===>
		surf = GetSurface(model,n)
		NumFaces = CountTriangles(surf)-1
		;===>
		SHW_ETE_Object\Surfaces.ETE_Surface = New  ETE_Surface
		IdSurface.ETE_Surface = SHW_ETE_Object\Surfaces
		;===>
		IdSurface\IdSurface = surf
		IdSurface\cntTriangle = NumFaces
		For v=0 To NumFaces
			;===>
			IdSurface\IdTriangle.ETE_Triangle[v] = New ETE_Triangle
			IdTriang.ETE_Triangle = IdSurface\IdTriangle[v]
			;===>
			IdTriang\normal.Point3D = New Point3D
			IdTriang\a.Point3D = New Point3D
			IdTriang\b.Point3D = New Point3D
			IdTriang\c.Point3D = New Point3D
			;===> 
			vert0 = TriangleVertex(surf,v,0)
			vert1 = TriangleVertex(surf,v,1)
			vert2 = TriangleVertex(surf,v,2)
			;===>
			IdTriang\a\x = VertexX( surf, vert0) : IdTriang\a\y = VertexY( surf, vert0) : IdTriang\a\z = VertexZ( surf, vert0)
			;===> 
			IdTriang\b\x = VertexX( surf, vert1) : IdTriang\b\y = VertexY( surf, vert1) : IdTriang\b\z = VertexZ( surf, vert1)
			;===> 
			IdTriang\c\x = VertexX( surf, vert2) : IdTriang\c\y = VertexY( surf, vert2) : IdTriang\c\z = VertexZ( surf, vert2)
			;===>
			IdTriang\Normal= CalcNormal( IdTriang\a, IdTriang\b, IdTriang\c)
			IdTriang\Normal = V_3Normalize(IdTriang\Normal) 
			;===>
			IdTriang\Triangle = v
			IdTriang\ATriangle = -1
			IdTriang\BTriangle = -1
			IdTriang\CTriangle = -1
			;===>
		Next 
		;===>
		; Search adjacent triangle
		For a=0 To IdSurface\cntTriangle
			;===>
			ATriang.ETE_Triangle = IdSurface\IdTriangle[a]
			;===>
			For b=a+1 To IdSurface\cntTriangle
				If a=b Then Goto jump
				;===>
				BTriang.ETE_Triangle = IdSurface\IdTriangle[b]
				;*********************************************************************
				; SIDE " A "
				;===>
				; Adjacent side A (il lato A del 1° triangolo confina con lato A del 2° Triangolo)
				check1 = CheckVertex( ATriang\a, BTriang\a )
				check2 = CheckVertex( ATriang\b, BTriang\b )
				check3 = CheckVertex( ATriang\a, BTriang\b )
				check4 = CheckVertex( ATriang\b, BTriang\a )
				;===>
				If  (check1 And check2) Or (check3 And check4) Then
					ATriang\ATriangle = b
					BTriang\ATriangle = a
					Goto SIDEA
					;Stop
				EndIf 
				;===>
				; Adjacent side A (il lato A del 1° triangolo confina con lato B del 2° Triangolo)
				check1 = CheckVertex( ATriang\a, BTriang\b )
				check2 = CheckVertex( ATriang\b, BTriang\c )
				check3 = CheckVertex( ATriang\a, BTriang\c )
				check4 = CheckVertex( ATriang\b, BTriang\b )
				;===>
				If  (check1 And check2) Or (check3 And check4) Then
					ATriang\ATriangle = b
					BTriang\BTriangle = a
					Goto SIDEA
					;Stop
				EndIf
				;===>
				; Adjacent side A (il lato A del 1° triangolo confina con lato C del 2° Triangolo)
				check1 = CheckVertex( ATriang\a, BTriang\c )
				check2 = CheckVertex( ATriang\b, BTriang\a )
				check3 = CheckVertex( ATriang\a, BTriang\a )
				check4 = CheckVertex( ATriang\b, BTriang\c )
				;===>
				If  (check1 And check2) Or (check3 And check4) Then
					ATriang\ATriangle = b
					BTriang\CTriangle = a
					;Stop
				EndIf
				.SIDEA
				;===>
				;*********************************************************************
				; SIDE " B "
				;===>
				; Adjacent side A (il lato B del 1° triangolo confina con lato A del 2° Triangolo)
				check1 = CheckVertex( ATriang\b, BTriang\a )
				check2 = CheckVertex( ATriang\c, BTriang\b )
				check3 = CheckVertex( ATriang\b, BTriang\b )
				check4 = CheckVertex( ATriang\c, BTriang\a )
				;===>
				If  (check1 And check2) Or (check3 And check4) Then
					ATriang\BTriangle = b
					BTriang\ATriangle = a
					Goto SIDEB
					;Stop
				EndIf 
				;===>
				; Adjacent side A (il lato B del 1° triangolo confina con lato B del 2° Triangolo)
				check1 = CheckVertex( ATriang\b, BTriang\b )
				check2 = CheckVertex( ATriang\c, BTriang\c )
				check3 = CheckVertex( ATriang\b, BTriang\c )
				check4 = CheckVertex( ATriang\c, BTriang\b )
				;===>
				If  (check1 And check2) Or (check3 And check4) Then
					ATriang\BTriangle = b
					BTriang\BTriangle = a
					Goto SIDEB
					;Stop
				EndIf
				;===>
				; Adjacent side A (il lato B del 1° triangolo confina con lato C del 2° Triangolo)
				check1 = CheckVertex( ATriang\b, BTriang\c )
				check2 = CheckVertex( ATriang\c, BTriang\a )
				check3 = CheckVertex( ATriang\b, BTriang\a )
				check4 = CheckVertex( ATriang\c, BTriang\c )
				;===>
				If  (check1 And check2) Or (check3 And check4) Then
					ATriang\BTriangle = b
					BTriang\CTriangle = a
					;Stop
				EndIf
				.SIDEB
			;===>
				;*********************************************************************
				; SIDE " C "
				;===>
				; Adjacent side A (il lato C del 1° triangolo confina con lato A del 2° Triangolo)
				check1 = CheckVertex( ATriang\c, BTriang\a )
				check2 = CheckVertex( ATriang\a, BTriang\b )
				check3 = CheckVertex( ATriang\c, BTriang\b )
				check4 = CheckVertex( ATriang\a, BTriang\a )
				;===>
				If  (check1 And check2) Or (check3 And check4) Then
					ATriang\CTriangle = b
					BTriang\ATriangle = a
					Goto SIDEC
					;Stop
				EndIf 
				;===>
				; Adjacent side A (il lato C del 1° triangolo confina con lato B del 2° Triangolo)
				check1 = CheckVertex( ATriang\c, BTriang\b )
				check2 = CheckVertex( ATriang\a, BTriang\c )
				check3 = CheckVertex( ATriang\c, BTriang\c )
				check4 = CheckVertex( ATriang\a, BTriang\b )
				;===>
				If  (check1 And check2) Or (check3 And check4) Then
					ATriang\CTriangle = b
					BTriang\BTriangle = a
					Goto SIDEC
					;Stop
				EndIf
				;===>
				; Adjacent side A (il lato C del 1° triangolo confina con lato C del 2° Triangolo)
				check1 = CheckVertex( ATriang\c, BTriang\c )
				check2 = CheckVertex( ATriang\a, BTriang\a )
				check3 = CheckVertex( ATriang\c, BTriang\a )
				check4 = CheckVertex( ATriang\a, BTriang\c )
				;===>
				If  (check1 And check2) Or (check3 And check4) Then
					ATriang\CTriangle = b
					BTriang\CTriangle = a
					;Stop
				EndIf
				.SIDEC
				;===>
				.jump
				;===>
			Next
			;===>
		Next 
		;===>
	Next
	;===>
	Delete Norm
	;===>
End Function 

;=======================
; Inizialize Object Shadow
Function CloneListTriangle(dst.ETE_Triangle,src.ETE_Triangle)
	;===>
	V_3Copy( dst\Normal, src\Normal)
	V_3Copy( dst\a, src\a)
	V_3Copy( dst\b, src\b)
	V_3Copy( dst\c, src\c)
	dst\Triangle = src\Triangle
	dst\ATriangle = src\ATriangle
	dst\BTriangle = src\BTriangle
	dst\CTriangle = src\CTriangle
	;===>
End Function 
;=======================
Function ResetShadowVolume() 
   ClearSurface SurfaceFront; 
End Function 
;======================= 
; Shadows Volume start 
Function ShadowVolume$( Light, LightLenght )
	ResetShadowVolume()
	;===>
	sh_light\x = EntityX(Light) : sh_light\y = EntityY(Light) : sh_light\z = EntityZ(Light) 
	sh_lenght\x = LightLenght 
	sh_lenght\y = LightLenght 
	sh_lenght\z = LightLenght 
	;===>
	cntLine3D=0
	;===>
	result$=ShadowVolumeCreate3()
	;===>
	ShadowVolumeCreateImage()
	;===>
	Return result$
	;===>
End Function 
;=======================
; Creazione immagine ombra
; ottimizzazione completata 
Function ShadowVolumeCreateImage()
	;===>
	; Fase 1
	;===>
	Local CaptureX = TextureWidth(ShwTex1)
	Local CaptureY = TextureHeight(ShwTex1)
	CameraViewport Camera,0,0,CaptureX, CaptureY
	;===>
	HideEntity SHWSpriteFront 
	;===>
	HideEntity MeshFront 
	ShowEntity Scena
	RenderWorld
	CameraClsMode camera,True,False
	;===>
	HideEntity Scena
	;per ottimizzare renderizzo prima il back
	ShowEntity MeshFront
	FlipMesh MeshFront ;Visualizzo il back face
	;preparo in back face
	EntityColor MeshFront,10,10,10
	RenderWorld
	;===>
	; Front Ground 1
	LockBuffer()
	For y=0 To 	CaptureY
		For x=0 To 	CaptureX
			;===>
			bg2(x,y)=ReadPixelFast(x,y)
			;===>
		Next
	Next
	UnlockBuffer()
	;proparo in front face
	FlipMesh MeshFront
	RenderWorld
	;===>
	; Back Ground 2
	LockBuffer()
	For y=0 To 	CaptureY
		For x=0 To 	CaptureX
			;===>
			bg1(x,y)=ReadPixelFast(x,y)
			;===>
		Next
	Next
	UnlockBuffer()
	;===>
	HideEntity MeshFront
	;===>
	;Ripristiniamo tutto prima di riprendere le normali attività
	;===>
	; Filter
	SetBuffer TextureBuffer(ShwTex1)
	LockBuffer()
	ShadowColor=(128 Shl 24)
	For y=0 To 	CaptureY
		For x=0 To 	CaptureX
			;===>
			Val=(Bg1(x,y)-Bg2(x,y))
			;Val=Abs(Bg1(x,y)-Bg2(x,y))
			If (Val)>0 Then
				WritePixelFast x,y,ShadowColor
			Else
				WritePixelFast x,y,0
			EndIf
			;===>
		Next
	Next
	UnlockBuffer()
	;===>
	CameraViewport Camera,0,0,GraphicsWidth(), GraphicsHeight()
	CameraClsMode camera,True,True
	;===>
	ShowEntity SHWSpriteFront 
	ShowEntity Scena
	;===>
	SetBuffer BackBuffer()
	Cls

	PositionEntity SHWSpriteFront,EntityX(Camera),EntityY(Camera),EntityZ(Camera)+1.001
	;===>
End Function 
;=======================
; Creazione volume
; forse si può fare ancora qualcosina!!
Function ShadowVolumeCreate3$()
	;===> 
	Local Result$ = ""
	Local Norm.Point3D = New Point3D 
	Local MidPoint.Point3D = New Point3D 
	Local NormLight.Point3D = New Point3D
	Local RayA.Point3D = New Point3D 
	Local RayB.Point3D = New Point3D 
	Local RayC.Point3D = New Point3D 
	;===> 
	Local CNTFront=0
	Local CNTBack=0
	Local surf=0
	Local check1 = -1
	Local check2 = -1
	Local check3 = -1
	;===> 
	t0=MilliSecs()
	;===>
	; Cerchiamoci i vertici faccia vista verso la luce
	For SHW_ETE_Object\surfaces.ETE_Surface = Each ETE_Surface
		;===>
		surf = SHW_ETE_Object\surfaces\IdSurface
		dwNumFaces = SHW_ETE_Object\surfaces\cntTriangle 
		;===>
		For v=0 To dwNumFaces
			;===>
			IdTriang.ETE_Triangle = SHW_ETE_Object\Surfaces\IdTriangle[v]
			CloneListTriangle(TriangleClone(v),IdTriang)
			IdCLT.ETE_Triangle = TriangleClone(v)
			;===>
			;associamo le trasformazioni ai vertici
			TFormPoint IdCLT\a\x, IdCLT\a\y , IdCLT\a\z, SHW_ETE_Object\IdModel, 0
			sh_v1\x = TFormedX() : sh_v1\y = TFormedY() : sh_v1\z = TFormedZ()
			;===> 
			TFormPoint IdCLT\b\x, IdCLT\b\y , IdCLT\b\z, SHW_ETE_Object\IdModel, 0
			sh_v2\x = TFormedX() : sh_v2\y = TFormedY() : sh_v2\z = TFormedZ() 
			;===> 
			TFormPoint IdCLT\c\x, IdCLT\c\y , IdCLT\c\z, SHW_ETE_Object\IdModel, 0
			sh_v3\x = TFormedX() : sh_v3\y = TFormedY() : sh_v3\z = TFormedZ() 
			;===>
			TFormNormal  IdCLT\Normal\x, IdCLT\Normal\y , IdCLT\Normal\z, SHW_ETE_Object\IdModel, 0
			Norm\x = TFormedX() : Norm\y = TFormedY() : Norm\z = TFormedZ() 
			MidPoint = V_3Mid(sh_v1,sh_v2,sh_v3) 
			NormLight = V_3Dec(MidPoint,sh_light) 
			NormLight  = V_3Normalize(NormLight) 
			Dot# = V_3Dot( Norm, NormLight ) 
			;===>
			; Marchiamo i vertici non rivolti verso la luce
			If Dot#=>0.1 Then
				;===>
				V_3Copy( IdCLT\a, sh_v1 )
				V_3Copy( IdCLT\b, sh_v2 )
				V_3Copy( IdCLT\c, sh_v3 )
				CNTFront=CNTFront+1
				;===>
			Else
				;===>
				IdCLT\Triangle  = -1
				CNTBack=CNTBack+1
				;===>
			EndIf
			;===> 
		Next
		;===>
		; Ora creiamo il volume
		;Stop
		For v=0 To dwNumFaces
			;===>
			IdCLT.ETE_Triangle = TriangleClone(v)
			;===>
			; Saltiamo il triangolo se è a -1
			If IdCLT\Triangle<0 Then Goto continue
			;===>
			If IdCLT\ATriangle>=0 Then check1 = TriangleClone(IdCLT\ATriangle)\Triangle Else check1 = -1
			If IdCLT\BTriangle>=0 Then check2 = TriangleClone(IdCLT\BTriangle)\Triangle Else check2 = -1
			If IdCLT\CTriangle>=0 Then check3 = TriangleClone(IdCLT\CTriangle)\Triangle Else check3 = -1
			;===>
			If check1>0 And check2>0 And check3>0  Then Goto continue
			;===>
			;Edge A
			If check1<0 Then
				;===>
				RayA = V_3Dec( IdCLT\a, sh_light ) 
				V_3Normalize(RayA ) 
				RayA = V_3Inc( V_3Mul(RayA, sh_lenght ), IdCLT\a )
				;===>
				RayB = V_3Dec( IdCLT\b,sh_light ) 
				V_3Normalize( RayB ) 
				RayB = V_3Inc( V_3Mul( RayB, sh_lenght ), IdCLT\b ) 
				;===>
				va = AddVertex(SurfaceFront,  IdCLT\a\x, 				IdCLT\a\y, 					IdCLT\a\z ); 
				vb = AddVertex(SurfaceFront,  RayA\x,						RayA\y,							RayA\z ); 
				vc = AddVertex(SurfaceFront,  RayB\x,						RayB\y,							RayB\z ); 
				vd = AddVertex(SurfaceFront,  IdCLT\b\x, 				IdCLT\b\y, 					IdCLT\b\z ); 
				;===>
				AddTriangle(SurfaceFront, va, vb, vc); faccia 1/3 a 
				AddTriangle(SurfaceFront, va, vc, vd); faccia 1/3 b
				;===>
				Line3DAX(cntLine3D) = IdCLT\a\x : Line3DAY(cntLine3D) = IdCLT\a\y : Line3DAZ(cntLine3D) = IdCLT\a\z
				Line3DBX(cntLine3D) = IdCLT\b\x : Line3DBY(cntLine3D) = IdCLT\b\y : Line3DBZ(cntLine3D) = IdCLT\b\z
				cntLine3D=cntLine3D+1
				;===>
			EndIf
			;===>
			;Edge B
			If check2<0 Then
				;===>
				RayB = V_3Dec( IdCLT\b,sh_light ) 
				V_3Normalize( RayB ) 
				RayB = V_3Inc( V_3Mul( RayB, sh_lenght ), IdCLT\b ) 
				;===>
				RayC = V_3Dec( IdCLT\c,sh_light ) 
				V_3Normalize( RayC ) 
				RayC = V_3Inc( V_3Mul( RayC, sh_lenght ), IdCLT\c ) 
				;===>
				va = AddVertex(SurfaceFront,  IdCLT\b\x, 				IdCLT\b\y, 					IdCLT\b\z ); 
				vb = AddVertex(SurfaceFront,  RayB\x,						RayB\y,							RayB\z ); 
				vc = AddVertex(SurfaceFront,  RayC\x,						RayC\y,							RayC\z ); 
				vd = AddVertex(SurfaceFront,  IdCLT\c\x, 				IdCLT\c\y, 					IdCLT\c\z ); 
				;===>
				AddTriangle(SurfaceFront, va, vb, vc); faccia 2/3 a 
				AddTriangle(SurfaceFront, va, vc, vd); faccia 2/3 b
				;===>
				Line3DAX(cntLine3D) = IdCLT\b\x : Line3DAY(cntLine3D) = IdCLT\b\y : Line3DAZ(cntLine3D) = IdCLT\b\z
				Line3DBX(cntLine3D) = IdCLT\c\x : Line3DBY(cntLine3D) = IdCLT\c\y : Line3DBZ(cntLine3D) = IdCLT\c\z
				cntLine3D=cntLine3D+1
				;===>
			EndIf 
			;===>
			;Edge C
			If check3<0 Then
				;===>
				RayA = V_3Dec( IdCLT\a, sh_light ) 
				V_3Normalize(RayA ) 
				RayA = V_3Inc( V_3Mul(RayA, sh_lenght ), IdCLT\a )
				;===>
				RayC = V_3Dec( IdCLT\c,sh_light ) 
				V_3Normalize( RayC ) 
				RayC = V_3Inc( V_3Mul( RayC, sh_lenght ), IdCLT\c ) 
				;===>
				va = AddVertex(SurfaceFront,  IdCLT\c\x, 				IdCLT\c\y, 					IdCLT\c\z ); 
				vb = AddVertex(SurfaceFront,  RayC\x,						RayC\y,							RayC\z ); 
				vc = AddVertex(SurfaceFront,  RayA\x,						RayA\y,							RayA\z ); 
				vd = AddVertex(SurfaceFront,  IdCLT\a\x, 				IdCLT\a\y, 					IdCLT\a\z ); 
				;===>
				AddTriangle(SurfaceFront, va, vb, vc); faccia 3/3 a 
				AddTriangle(SurfaceFront, va, vc, vd); faccia 3/3 b
				;===>
				Line3DAX(cntLine3D) = IdCLT\c\x : Line3DAY(cntLine3D) = IdCLT\c\y : Line3DAZ(cntLine3D) = IdCLT\c\z
				Line3DBX(cntLine3D) = IdCLT\a\x : Line3DBY(cntLine3D) = IdCLT\a\y : Line3DBZ(cntLine3D) = IdCLT\a\z
				cntLine3D=cntLine3D+1
				;===>
			EndIf 
			;===>
			.continue
			;===>
		Next 
		;===>
	Next
	;===>
	t1=MilliSecs()
	t2=t1-t0
	Result$=Result$+"==> Facce Front : "+CNTFront+"  Facce Back : "+CNTBack + " Tim-Vert: " + t2
	;===> 
	Delete RayA
	Delete RayB
	Delete RayC
	Delete Norm
	Delete MidPoint
	Delete NormLight
	;===> 
	Return Result$
	;===> 
End Function 
;=======================
;
Function SHWLine3D()
	;===>
	Color 255,0,0
	;===>
	For a=0 To cntLine3D-1
		Line3D( Line3DAX(a), Line3DAY(a), Line3DAZ(a), Line3DBX(a), Line3DBY(a), Line3DBZ(a))
	Next
	cntLine3D=0
	;===>
	Color 255,255,255
	;===>
End Function


the volume of the cylinder looks a little bit strange...

I'd imagine that cylinders and cones may look strange as they use 2 surfaces unlike spheres and cubes. For shadow volume creation you need to combine these surfaces into one. I have a simple function which does this if you want it?

Stevie

yes, please :)

Function MESHsingle( Mesh )

	Copy = CreateMesh()
	ns = CreateSurface( Copy )
	For su = 1 To CountSurfaces( Mesh )
		s = GetSurface( Mesh , su )
		For t = 0 To CountTriangles( s ) - 1
			v0 = TriangleVertex( s, t, 0 )
			v1 = TriangleVertex( s, t, 1 )
			v2 = TriangleVertex( s, t, 2 )
			Nv0 = AddVertex( ns , VertexX( s , v0 ) , VertexY( s, v0 ) , VertexZ( s, v0 ) )
			Nv1 = AddVertex( ns , VertexX( s , v1 ) , VertexY( s, v1 ) , VertexZ( s, v1 ) )
			Nv2 = AddVertex( ns , VertexX( s , v2 ) , VertexY( s, v2 ) , VertexZ( s, v2 ) )
			AddTriangle ns , Nv0 , Nv1 , Nv2
		Next
	Next
	FreeEntity mesh
	Return Copy

End Function	


Useage ....

MyCylinder = MESHsingle( createcylinder() )

You may need to retain the normals but this should be easy to implement.

Stevie

I *think* CopyMesh attemps to combine surfaces.

Doh .. so it does ... Copymesh combines surfaces which share the same brush so logically this works just fine .... why I never thought of that is beyond me ;)

So function becomes ..


Function MESHsingle( Mesh )

 copy = copymesh( Mesh )
 freeentity Mesh
 return copy

end function



dare devil:
with the code of you i cannot make 2 entitys casting a volume!!! there is a bug...

edit: ok, but another issue is, that if i take a sphere with 32 segments, the initobject() takes half a minute!? what's about that? can we make it work without long initialization times?

i have write a new update for the software,
1° optimize pre load mesh
2° resolved problem object multi surface
3° i ha create a new function simulate stencil 2 fast speed

and ......

the inizialize mesh required 5 seconds in released version.

The new link a version is:

http://digilander.libero.it/enzo_light/shw06.zip

for multi object i not have write "for Obj=each..." for test this software.

bye

ok, i will check it out:

ps: look what i have made out of your libary:
http://www.blitzbasic.com/gallery/view_pic.php?id=1336&gallery=&page=1

when it's ready it will be FREE*

i have look program the different speed is very lot
8 millisecs in the my new systems, and 100 millisecs in the old method from used you.

bye

well, i see...
but...can we make the initobject() time fast AND the shadowvolume() time fast? when we could do this, this would be the best...

the init object pre elaborate mesh, not function in real time the IntObject is a system the elaborate edge.

the phase 1 is complete ( the bug for 2 object is not resolved generate over face 2 cube )

the Phase 2 is Multi Light Zone, is the system based the lenght light ray all object present in the ray generate volume shadow ;)

PS:
(in the new demo the system is settings a 256 size texture and not 128)


ok bye

Hi all

post the new update file shadow, i have finished face 1 and start the new section OPTIMIZE InitObject

bye

size texture 512



;======================================= 
;--------------------------------------- 
; 
;   Name file: Shadow_Include
; 
;   Programmatore: 
;      Caldarulo Vincenzo (Eye & Light) 
;   Descrizione: 
;			Creazione dei volumi d'ombra
; 
;--------------------------------------- 
;======================================= 
Include"commontype.bb"
;======================================= 
;--------------------------------------- 
; Variabili ShadowVolume 
;--------------------------------------- 
;======================================= 
;===>
Type EdgeToEdge
	Field IdModel
	Field cntSurface
	Field Surfaces.ETE_Surface
End Type
;===>
Type ETE_Surface
	Field IdSurface
	Field cntTriangle
	Field IdTriangle.ETE_Triangle[ETE_MaxTriang]
End Type
;===>
Type ETE_Triangle
	Field Normal.Point3D
	Field a.Point3D
	Field b.Point3D
	Field c.Point3D
	Field Triangle
	Field ATriangle
	Field BTriangle
	Field CTriangle
End Type
;===>
;======================================= 
;===>
Const SHWTexSize = 128; Parametro di regolazione Ombra
Const sh_level# = 0.1
Const ETE_MaxTriang=65000
Const SHWL3D = 65000
;===>
;======================================= 
;===>
Dim BG1(SHWTexSize,SHWTexSize)
Dim BG2(SHWTexSize,SHWTexSize)
Dim  TriangleClone.ETE_Triangle(ETE_MaxTriang)
Dim AD(65000,2)
;===>
;======================================= 
;===>
Global Scena = CreatePivot(); CreateSphere(5)
;===>
Global MeshFront = CreateMesh(); 
Global SurfaceFront = CreateSurface(MeshFront); 
EntityAlpha MeshFront, sh_level 
EntityFX MeshFront,1;4
EntityBlend MeshFront,3
;===>
Global cntLine3D=0
Dim Line3DAX#(SHWL3D)
Dim Line3DAY#(SHWL3D)
Dim Line3DAZ#(SHWL3D)
Dim Line3DBX#(SHWL3D)
Dim Line3DBY#(SHWL3D)
Dim Line3DBZ#(SHWL3D)
;===>
;Creiamo il piano che proietterà l'ombra
;===>
Global SHWScreenImage = CreateImage(SHWTexSize,SHWTexSize)
Global SHWSpriteFront=CreateSprite()
SpriteViewMode SHWSpriteFront,1
Global ShwTex1=CreateTexture(SHWTexSize,SHWTexSize,1+2+8+256+512)
EntityTexture SHWSpriteFront,ShwTex1
EntityFX SHWSpriteFront,1
HideEntity SHWSpriteFront

;===>
Global sh_v1.Point3D			= New Point3D 
Global sh_v2.Point3D			= New Point3D 
Global sh_v3.Point3D			= New Point3D 
Global sh_light.Point3D		= New Point3D 
Global sh_lenght.Point3D	= New Point3D 
;===>
Global SHW_ETE_Object.EdgeToEdge
;===>
;======================================= 
;===>
;=======================
; 
Function CheckVertex%(a.Point3D,b.Point3D)
	If (a\x=b\x)And(a\y=b\y)And(a\z=b\z) Then
		Return True 
	Else
		Return False 
	EndIf 
End Function 

;======================================================================= 
;======================================================================= 
; Shadow Volume For silhouette Method Edge to Edge
;======================================================================= 
;======================================================================= 
;======================= 
; Inizialize Object Shadow
Function SHW_Init()

	;===>
	; Search surface and triangle object
	For n=0 To ETE_MaxTriang
	
		TriangleClone.ETE_Triangle(n) = New ETE_Triangle
		
		TriangleClone(n)\Normal.Point3D = New Point3D
		TriangleClone(n)\a.Point3D = New Point3D
		TriangleClone(n)\b.Point3D = New Point3D
		TriangleClone(n)\c.Point3D = New Point3D
	Next
	ShwInitDisplay()

End Function 

Function ShwInitDisplay()
	;===>
	EntityParent(SHWSpriteFront,Camera) 
	PositionEntity SHWSpriteFront,-0.005,+0.005,1.001 
	;===>
End Function 
;=======================
; Inizialize Object Shadow
Function SHW_InitObject$(model)
	Time$=""
	Tim1=MilliSecs()
	Norm.Point3D = New Point3D
	
	SHW_ETE_Object.EdgeToEdge = New EdgeToEdge
	SHW_ETE_Object\IdModel = model
	;===>
	; Search surface and triangle object
	SHW_ETE_Object\cntSurface = CountSurfaces(model)-1
	For n=0 To SHW_ETE_Object\cntSurface
		;===>
		surf = GetSurface(model,n+1)
		NumFaces = CountTriangles(surf)-1
		;===>
		SHW_ETE_Object\Surfaces.ETE_Surface = New  ETE_Surface
		IdSurface.ETE_Surface = SHW_ETE_Object\Surfaces
		;===>
		IdSurface\IdSurface = surf
		IdSurface\cntTriangle = NumFaces
		For v=0 To NumFaces
			;===>
			IdSurface\IdTriangle.ETE_Triangle[v] = New ETE_Triangle
			IdTriang.ETE_Triangle = IdSurface\IdTriangle[v]
			;===>
			IdTriang\normal.Point3D = New Point3D
			IdTriang\a.Point3D = New Point3D
			IdTriang\b.Point3D = New Point3D
			IdTriang\c.Point3D = New Point3D
			;===> 
			vert0 = TriangleVertex(surf,v,0)
			vert1 = TriangleVertex(surf,v,1)
			vert2 = TriangleVertex(surf,v,2)
			;===>
			IdTriang\a\x = VertexX( surf, vert0) : IdTriang\a\y = VertexY( surf, vert0) : IdTriang\a\z = VertexZ( surf, vert0)
			;===> 
			IdTriang\b\x = VertexX( surf, vert1) : IdTriang\b\y = VertexY( surf, vert1) : IdTriang\b\z = VertexZ( surf, vert1)
			;===> 
			IdTriang\c\x = VertexX( surf, vert2) : IdTriang\c\y = VertexY( surf, vert2) : IdTriang\c\z = VertexZ( surf, vert2)
			;===>
			IdTriang\Normal= CalcNormal( IdTriang\a, IdTriang\b, IdTriang\c)
			IdTriang\Normal = V_3Normalize(IdTriang\Normal) 
			;===>
			IdTriang\Triangle = v
			IdTriang\ATriangle = -1
			IdTriang\BTriangle = -1
			IdTriang\CTriangle = -1
			;===>
		Next 
		;===>
		; Search adjacent triangle
		;===>
		; ottimizzazione precalcolo
		For a=0 To IdSurface\cntTriangle
			AD(a,0)=1 : AD(a,1) = 1 : AD(a,2) = 1
		Next
		;===>
		For a=0 To IdSurface\cntTriangle
			;===>
			ATriang.ETE_Triangle = IdSurface\IdTriangle[a]
			;===>
			For b=a+1 To IdSurface\cntTriangle
				If a=b Or (AD(b,0)=0 And AD(b,1)=0 And AD(b,2)=0)Then Goto jump
				;===>
				BTriang.ETE_Triangle = IdSurface\IdTriangle[b]
				;*********************************************************************
				; SIDE " A "
				;===>
				; Adjacent side A (il lato A del 1° triangolo confina con lato A del 2° Triangolo)
				If (AD(b,0)=1)Then
					;===>
					check1 = CheckVertex( ATriang\a, BTriang\a )
					check2 = CheckVertex( ATriang\b, BTriang\b )
					check3 = CheckVertex( ATriang\a, BTriang\b )
					check4 = CheckVertex( ATriang\b, BTriang\a )
					;===>
					If  (check1 And check2) Or (check3 And check4) Then
						ATriang\ATriangle = b
						BTriang\ATriangle = a
						AD(b,0)=0
						Goto SIDEA
						;Stop
					EndIf
					;===>
				EndIf
				;===>
				; Adjacent side A (il lato A del 1° triangolo confina con lato B del 2° Triangolo)
				If (AD(b,1)=1)Then
					;===>
					check1 = CheckVertex( ATriang\a, BTriang\b )
					check2 = CheckVertex( ATriang\b, BTriang\c )
					check3 = CheckVertex( ATriang\a, BTriang\c )
					check4 = CheckVertex( ATriang\b, BTriang\b )
					;===>
					If  (check1 And check2) Or (check3 And check4) Then
						ATriang\ATriangle = b
						BTriang\BTriangle = a
						AD(b,1)=0
						Goto SIDEA
						;Stop
					EndIf
					;===>
				EndIf
				;===>
				; Adjacent side A (il lato A del 1° triangolo confina con lato C del 2° Triangolo)
				If (AD(b,2)=1)Then
					;===>
					check1 = CheckVertex( ATriang\a, BTriang\c )
					check2 = CheckVertex( ATriang\b, BTriang\a )
					check3 = CheckVertex( ATriang\a, BTriang\a )
					check4 = CheckVertex( ATriang\b, BTriang\c )
					;===>
					If  (check1 And check2) Or (check3 And check4) Then
						ATriang\ATriangle = b
						BTriang\CTriangle = a
						AD(b,2)=0
						;Stop
					EndIf
					;===>
				EndIf
				.SIDEA
				;===>
				;*********************************************************************
				; SIDE " B "
				;===>
				; Adjacent side A (il lato B del 1° triangolo confina con lato A del 2° Triangolo)
				If (AD(b,0)=1)Then
					;===>
					check1 = CheckVertex( ATriang\b, BTriang\a )
					check2 = CheckVertex( ATriang\c, BTriang\b )
					check3 = CheckVertex( ATriang\b, BTriang\b )
					check4 = CheckVertex( ATriang\c, BTriang\a )
					;===>
					If  (check1 And check2) Or (check3 And check4) Then
						ATriang\BTriangle = b
						BTriang\ATriangle = a
						AD(b,0)=0
						Goto SIDEB
						;Stop
					EndIf 
					;===>
				EndIf 
				;===>
				; Adjacent side A (il lato B del 1° triangolo confina con lato B del 2° Triangolo)
				If (AD(b,1)=1)Then
					;===>
					check1 = CheckVertex( ATriang\b, BTriang\b )
					check2 = CheckVertex( ATriang\c, BTriang\c )
					check3 = CheckVertex( ATriang\b, BTriang\c )
					check4 = CheckVertex( ATriang\c, BTriang\b )
					;===>
					If  (check1 And check2) Or (check3 And check4) Then
						ATriang\BTriangle = b
						BTriang\BTriangle = a
						AD(b,1)=0
						Goto SIDEB
						;Stop
					EndIf
					;===>
				EndIf
				;===>
				; Adjacent side A (il lato B del 1° triangolo confina con lato C del 2° Triangolo)
				If (AD(b,2)=1)Then
					;===>
					check1 = CheckVertex( ATriang\b, BTriang\c )
					check2 = CheckVertex( ATriang\c, BTriang\a )
					check3 = CheckVertex( ATriang\b, BTriang\a )
					check4 = CheckVertex( ATriang\c, BTriang\c )
					;===>
					If  (check1 And check2) Or (check3 And check4) Then
						ATriang\BTriangle = b
						BTriang\CTriangle = a
						AD(b,2)=0
						;Stop
					EndIf
					;===>
				EndIf
				.SIDEB
			;===>
				;*********************************************************************
				; SIDE " C "
				;===>
				; Adjacent side A (il lato C del 1° triangolo confina con lato A del 2° Triangolo)
				If (AD(b,0)=1)Then
					;===>
					check1 = CheckVertex( ATriang\c, BTriang\a )
					check2 = CheckVertex( ATriang\a, BTriang\b )
					check3 = CheckVertex( ATriang\c, BTriang\b )
					check4 = CheckVertex( ATriang\a, BTriang\a )
					;===>
					If  (check1 And check2) Or (check3 And check4) Then
						ATriang\CTriangle = b
						BTriang\ATriangle = a
						AD(b,0)=0
						Goto SIDEC
						;Stop
					EndIf
				;===>
				EndIf
				;===>
				; Adjacent side A (il lato C del 1° triangolo confina con lato B del 2° Triangolo)
				If (AD(b,1)=1)Then
					;===>
					check1 = CheckVertex( ATriang\c, BTriang\b )
					check2 = CheckVertex( ATriang\a, BTriang\c )
					check3 = CheckVertex( ATriang\c, BTriang\c )
					check4 = CheckVertex( ATriang\a, BTriang\b )
					;===>
					If  (check1 And check2) Or (check3 And check4) Then
						ATriang\CTriangle = b
						BTriang\BTriangle = a
						AD(b,1)=0
						Goto SIDEC
						;Stop
					EndIf
					;===>
				EndIf 
				;===>
				; Adjacent side A (il lato C del 1° triangolo confina con lato C del 2° Triangolo)
				If (AD(b,2)=1)Then
					;===>
					check1 = CheckVertex( ATriang\c, BTriang\c )
					check2 = CheckVertex( ATriang\a, BTriang\a )
					check3 = CheckVertex( ATriang\c, BTriang\a )
					check4 = CheckVertex( ATriang\a, BTriang\c )
					;===>
					If  (check1 And check2) Or (check3 And check4) Then
						ATriang\CTriangle = b
						BTriang\CTriangle = a
						AD(b,2)=0
						;Stop
					EndIf
					;===>
				EndIf
				.SIDEC
				;===>
				.jump
				;===>
			Next
			;===>
		Next 
		;===>
	Next
	;===>
	Delete Norm
	;===>
	Tim2=MilliSecs()
	Time$="Time Precalcolo: "+(Tim2-Tim1)
	Return Time$
	;===>
End Function 

;=======================
; Inizialize Object Shadow
Function CloneListTriangle(dst.ETE_Triangle,src.ETE_Triangle)
	;===>
	V_3Copy( dst\Normal, src\Normal)
	V_3Copy( dst\a, src\a)
	V_3Copy( dst\b, src\b)
	V_3Copy( dst\c, src\c)
	dst\Triangle = src\Triangle
	dst\ATriangle = src\ATriangle
	dst\BTriangle = src\BTriangle
	dst\CTriangle = src\CTriangle
	;===>
End Function 
;=======================
Function ResetShadowVolume()
   ClearSurface SurfaceFront; 
End Function 
;======================= 
; Shadows Volume start 
Function ShadowVolume$( Light, LightLenght )
	ResetShadowVolume()
	;===>
	sh_light\x = EntityX(Light) : sh_light\y = EntityY(Light) : sh_light\z = EntityZ(Light) 
	sh_lenght\x = LightLenght 
	sh_lenght\y = LightLenght 
	sh_lenght\z = LightLenght 
	;===>
	cntLine3D=0
	;===>
	result$=ShadowVolumeCreate3()
	;===>
	;ShadowVolumeSimulateStencil()
	ShadowVolumeSimulateStencilNew() ; è un pò più veloce della New1
	;ShadowVolumeSimulateStencilNew1()
	;===>
	;PositionEntity SHWSpriteFront,EntityX(Camera),EntityY(Camera),EntityZ(Camera)+1.001
	;RotateEntity SHWSpriteFront,-EntityPitch(Camera),EntityYaw(Camera),0
	;===>
	Return result$
	;===>
End Function 
;=======================
; Creazione volume
; forse si può fare ancora qualcosina!!
Function ShadowVolumeCreate3$()
	;===> 
	Local Result$ = ""
	Local Norm.Point3D = New Point3D 
	Local MidPoint.Point3D = New Point3D 
	Local NormLight.Point3D = New Point3D
	Local RayA.Point3D = New Point3D 
	Local RayB.Point3D = New Point3D 
	Local RayC.Point3D = New Point3D 
	;===> 
	Local CNTFront=0
	Local CNTBack=0
	Local surf=0
	Local check1 = -1
	Local check2 = -1
	Local check3 = -1
	;===> 
	t0=MilliSecs()


	For SHW_ETE_Object.EdgeToEdge = Each EdgeToEdge
		;===>
		; Cerchiamoci i vertici faccia vista verso la luce
		Surfaces.ETE_Surface = SHW_ETE_Object\Surfaces
		For aSurf = 0 To SHW_ETE_Object\cntSurface
			;===>
			surf = Surfaces\IdSurface
			dwNumFaces = Surfaces\cntTriangle 
			;===>
			For v=0 To dwNumFaces
				;===>
				IdTriang.ETE_Triangle = SHW_ETE_Object\Surfaces\IdTriangle[v]
				CloneListTriangle(TriangleClone(v),IdTriang)
				IdCLT.ETE_Triangle = TriangleClone(v)
				;===>
				;associamo le trasformazioni ai vertici
				TFormPoint IdCLT\a\x, IdCLT\a\y , IdCLT\a\z, SHW_ETE_Object\IdModel, 0
				sh_v1\x = TFormedX() : sh_v1\y = TFormedY() : sh_v1\z = TFormedZ()
				;===> 
				TFormPoint IdCLT\b\x, IdCLT\b\y , IdCLT\b\z, SHW_ETE_Object\IdModel, 0
				sh_v2\x = TFormedX() : sh_v2\y = TFormedY() : sh_v2\z = TFormedZ() 
				;===> 
				TFormPoint IdCLT\c\x, IdCLT\c\y , IdCLT\c\z, SHW_ETE_Object\IdModel, 0
				sh_v3\x = TFormedX() : sh_v3\y = TFormedY() : sh_v3\z = TFormedZ() 
				;===>
				TFormNormal  IdCLT\Normal\x, IdCLT\Normal\y , IdCLT\Normal\z, SHW_ETE_Object\IdModel, 0
				Norm\x = TFormedX() : Norm\y = TFormedY() : Norm\z = TFormedZ() 
				MidPoint = V_3Mid(sh_v1,sh_v2,sh_v3) 
				NormLight = V_3Dec(MidPoint,sh_light) 
				NormLight  = V_3Normalize(NormLight) 
				Dot# = V_3Dot( Norm, NormLight ) 
				;===>
				; Marchiamo i vertici non rivolti verso la luce
				If Dot#=>0.0 Then
					;===>
					V_3Copy( IdCLT\a, sh_v1 )
					V_3Copy( IdCLT\b, sh_v2 )
					V_3Copy( IdCLT\c, sh_v3 )
					CNTFront=CNTFront+1
					;===>
				Else
					;===>
					IdCLT\Triangle  = -1
					CNTBack=CNTBack+1
					;===>
				EndIf
				;===> 
			Next
			;===>
			; Ora creiamo il volume
			For v=0 To dwNumFaces
				;===>
				IdCLT.ETE_Triangle = TriangleClone(v)
				;===>
				; Saltiamo il triangolo se è a -1
				If IdCLT\Triangle<0 Then Goto continue
				;===>
				If IdCLT\ATriangle>=0 Then check1 = TriangleClone(IdCLT\ATriangle)\Triangle Else check1 = -1
				If IdCLT\BTriangle>=0 Then check2 = TriangleClone(IdCLT\BTriangle)\Triangle Else check2 = -1
				If IdCLT\CTriangle>=0 Then check3 = TriangleClone(IdCLT\CTriangle)\Triangle Else check3 = -1
				;===>
				If check1>0 And check2>0 And check3>0  Then Goto continue
				;===>
				;Edge A
				If check1<0 Then
					;===>
					RayA = V_3Dec( IdCLT\a, sh_light ) 
					V_3Normalize(RayA ) 
					RayA = V_3Inc( V_3Mul(RayA, sh_lenght ), IdCLT\a )
					;===>
					RayB = V_3Dec( IdCLT\b,sh_light ) 
					V_3Normalize( RayB ) 
					RayB = V_3Inc( V_3Mul( RayB, sh_lenght ), IdCLT\b ) 
					;===>
					va = AddVertex(SurfaceFront,  IdCLT\a\x,		IdCLT\a\y, 			IdCLT\a\z ); 
					vb = AddVertex(SurfaceFront,  RayA\x,				RayA\y,					RayA\z ); 
					vc = AddVertex(SurfaceFront,  RayB\x,				RayB\y,					RayB\z ); 
					vd = AddVertex(SurfaceFront,  IdCLT\b\x,		IdCLT\b\y, 			IdCLT\b\z ); 
					;===>
					AddTriangle(SurfaceFront, va, vb, vc); faccia 1/3 a 
					AddTriangle(SurfaceFront, va, vc, vd); faccia 1/3 b
					;===>
					Line3DAX(cntLine3D) = IdCLT\a\x : Line3DAY(cntLine3D) = IdCLT\a\y : Line3DAZ(cntLine3D) = IdCLT\a\z
					Line3DBX(cntLine3D) = IdCLT\b\x : Line3DBY(cntLine3D) = IdCLT\b\y : Line3DBZ(cntLine3D) = IdCLT\b\z
					cntLine3D=cntLine3D+1
					;===>
				EndIf
				;===>
				;Edge B
				If check2<0 Then
					;===>
					RayB = V_3Dec( IdCLT\b,sh_light ) 
					V_3Normalize( RayB ) 
					RayB = V_3Inc( V_3Mul( RayB, sh_lenght ), IdCLT\b ) 
					;===>
					RayC = V_3Dec( IdCLT\c,sh_light ) 
					V_3Normalize( RayC ) 
					RayC = V_3Inc( V_3Mul( RayC, sh_lenght ), IdCLT\c ) 
					;===>
					va = AddVertex(SurfaceFront,  IdCLT\b\x, 		IdCLT\b\y, 			IdCLT\b\z ); 
					vb = AddVertex(SurfaceFront,  RayB\x,				RayB\y,					RayB\z ); 
					vc = AddVertex(SurfaceFront,  RayC\x,				RayC\y,					RayC\z ); 
					vd = AddVertex(SurfaceFront,  IdCLT\c\x, 		IdCLT\c\y, 			IdCLT\c\z ); 
					;===>
					AddTriangle(SurfaceFront, va, vb, vc); faccia 2/3 a 
					AddTriangle(SurfaceFront, va, vc, vd); faccia 2/3 b
					;===>
					Line3DAX(cntLine3D) = IdCLT\b\x : Line3DAY(cntLine3D) = IdCLT\b\y : Line3DAZ(cntLine3D) = IdCLT\b\z
					Line3DBX(cntLine3D) = IdCLT\c\x : Line3DBY(cntLine3D) = IdCLT\c\y : Line3DBZ(cntLine3D) = IdCLT\c\z
					cntLine3D=cntLine3D+1
					;===>
				EndIf 
				;===>
				;Edge C
				If check3<0 Then
					;===>
					RayA = V_3Dec( IdCLT\a, sh_light ) 
					V_3Normalize(RayA ) 
					RayA = V_3Inc( V_3Mul(RayA, sh_lenght ), IdCLT\a )
					;===>
					RayC = V_3Dec( IdCLT\c,sh_light ) 
					V_3Normalize( RayC ) 
					RayC = V_3Inc( V_3Mul( RayC, sh_lenght ), IdCLT\c ) 
					;===>
					va = AddVertex(SurfaceFront,  IdCLT\c\x, 		IdCLT\c\y, 			IdCLT\c\z ); 
					vb = AddVertex(SurfaceFront,  RayC\x,				RayC\y,					RayC\z ); 
					vc = AddVertex(SurfaceFront,  RayA\x,				RayA\y,					RayA\z ); 
					vd = AddVertex(SurfaceFront,  IdCLT\a\x, 		IdCLT\a\y, 			IdCLT\a\z ); 
					;===>
					AddTriangle(SurfaceFront, va, vb, vc); faccia 3/3 a 
					AddTriangle(SurfaceFront, va, vc, vd); faccia 3/3 b
					;===>
					;===>
					Line3DAX(cntLine3D) = IdCLT\c\x : Line3DAY(cntLine3D) = IdCLT\c\y : Line3DAZ(cntLine3D) = IdCLT\c\z
					Line3DBX(cntLine3D) = IdCLT\a\x : Line3DBY(cntLine3D) = IdCLT\a\y : Line3DBZ(cntLine3D) = IdCLT\a\z
					cntLine3D=cntLine3D+1
					;===>
				EndIf 
				;===>
				.continue
				;===>
			Next 
			;===>
			Surfaces = After Surfaces
			;===>
		Next
		;===>
	Next
	;===>
	t1=MilliSecs()
	t2=t1-t0
	Result$=Result$+"==> Facce Front : "+CNTFront+"  Facce Back : "+CNTBack + " Tim-Vert: " + t2
	;===> 
	Delete RayA
	Delete RayB
	Delete RayC
	Delete Norm
	Delete MidPoint
	Delete NormLight
	;===> 
	Return Result$
	;===> 
End Function 
;=======================
;
Function SHWLine3D()
	;===>
	Color 255,0,0
	;===>
	For a=0 To cntLine3D-1
		Line3D( Line3DAX(a), Line3DAY(a), Line3DAZ(a), Line3DBX(a), Line3DBY(a), Line3DBZ(a))
	Next
	cntLine3D=0
	;===>
	Color 255,255,255
	;===>
End Function
;=======================
; Creazione immagine ombra
; ottimizzazione completata 
Function ShadowVolumeSimulateStencil()
	;===>
	; Fase 1
	;===>
	Local CaptureX = TextureWidth(ShwTex1)
	Local CaptureY = TextureHeight(ShwTex1)
	CameraViewport Camera,0,0,CaptureX, CaptureY
	;===>
	HideEntity SHWSpriteFront 
	;===>
	HideEntity MeshFront 
	ShowEntity Scena
	RenderWorld
	CameraClsMode camera,True,False
	;===>
	HideEntity Scena
	;per ottimizzare renderizzo prima il back
	ShowEntity MeshFront
	FlipMesh MeshFront ;Visualizzo il back face
	;preparo in back face
	EntityColor MeshFront,10,10,10
	EntityFX MeshFront,1;4

	RenderWorld
	;===>
	; Front Ground 1
	LockBuffer()
	For y=0 To 	CaptureY
		For x=0 To 	CaptureX
			;===>
			bg2(x,y)=ReadPixelFast(x,y)
			;===>
		Next
	Next
	UnlockBuffer()
	;proparo in front face
	FlipMesh MeshFront
	EntityColor MeshFront,10,10,10
	RenderWorld
	;===>
	; Back Ground 2
	LockBuffer()
	For y=0 To 	CaptureY
		For x=0 To 	CaptureX
			;===>
			bg1(x,y)=ReadPixelFast(x,y)
			;===>
		Next
	Next
	UnlockBuffer()
	;===>
	HideEntity MeshFront
	;===>
	;Ripristiniamo tutto prima di riprendere le normali attività
	;===>
	; Filter
	SetBuffer TextureBuffer(ShwTex1)
	LockBuffer()
	ShadowColor=(128 Shl 24)
	For y=0 To 	CaptureY
		For x=0 To 	CaptureX
			;===>
			Val=(Bg1(x,y)-Bg2(x,y))
			;Val=Abs(Bg1(x,y)-Bg2(x,y))
			If (Val)>0 Then
				WritePixelFast x,y,ShadowColor
			Else
				WritePixelFast x,y,0
			EndIf
			;===>
		Next
	Next
	UnlockBuffer()
	;===>
	CameraViewport Camera,0,0,GraphicsWidth(), GraphicsHeight()
	CameraClsMode camera,True,True
	;===>
	ShowEntity SHWSpriteFront 
	ShowEntity Scena
	;===>
	SetBuffer BackBuffer()
	Cls
	;===>
End Function 
;=======================
; Creazione immagine ombra
; Fast1
Function ShadowVolumeSimulateStencilNew()
	;===>
	Local MeshBack = CopyMesh(MeshFront)
	EntityAlpha MeshBack, sh_level 
	EntityBlend MeshBack,3
	;===>
	; Fase 1
	;===>
	Local CaptureX = TextureWidth(ShwTex1)
	Local CaptureY = TextureHeight(ShwTex1)
	CameraViewport Camera,0,0,CaptureX, CaptureY
	SetBuffer BackBuffer()
	;===>
	HideEntity SHWSpriteFront 
	;===>
	HideEntity MeshFront 
	HideEntity MeshBack 
	ShowEntity Scena
	RenderWorld
	CameraClsMode camera,True,False
	;===>
	HideEntity Scena
	;preparo il back face
	ShowEntity MeshBack
	EntityColor MeshBack,0,0,100
	EntityFX MeshBack,1;4
	FlipMesh MeshBack ;Visualizzo il back face
	;preparo il front face
	ShowEntity MeshFront
	EntityColor MeshFront,100,0,0
	EntityFX MeshFront,1;4
	RenderWorld

	;CopyRect 0, 0, CaptureX, CaptureY, 0, 0, BackBuffer(), ImageBuffer(ShwScreenImage)
	;===>
	; Front Ground 1
	LockBuffer BackBuffer()
	For y=0 To 	CaptureY
		For x=0 To 	CaptureX
			;===>
			pix=ReadPixelFast(x,y)
			bg1(x,y) = ((pix And $00FF0000) Shr 16)-(pix And $000000FF)
			;===>
		Next
	Next
	UnlockBuffer BackBuffer()
	;CopyRect 0, 0, CaptureX, CaptureY, 0, 0, BackBuffer(), ImageBuffer(ShwScreenImage)
;Goto Jump
	;===>
	HideEntity MeshFront
	HideEntity MeshBack
	;===>
	; Filter
	SetBuffer TextureBuffer(ShwTex1)
	LockBuffer()
	ShadowColor=(128 Shl 24)
	ShadowColor2=(64 Shl 24)

	If KeyHit(63) Then Stop
	
	For y=1 To 	CaptureY-1
		For x=1 To 	CaptureX-1
			;===>
			If bg1(x,y)<>0 Then
				;Blur image
;				If bg1( x-1, y-1 )=0 Or bg1( x, y-1 )=0 Or bg1( x+1, y-1 )=0 Or bg1( x-1, y )=0 Or bg1( x+1, y )=0 Or bg1( x-1, y+1 )=0 Or bg1( x, y+1 )=0 Or bg1( x+1, y+1 )=0  Then 
				If bg1( x, y-1 )=0 Or bg1( x-1, y )=0 Or bg1( x+1, y )=0 Or bg1( x, y+1 )=0  Then 
					WritePixelFast x,y,ShadowColor2
				Else
					WritePixelFast x,y,ShadowColor
				EndIf
			Else
				WritePixelFast x,y,0
			EndIf
			;===>
		Next
	Next
	UnlockBuffer()
	;===>
.Jump
	;===>
	;Ripristiniamo tutto prima di riprendere le normali attività
	FreeEntity MeshBack
	CameraViewport Camera,0,0,GraphicsWidth(), GraphicsHeight()
	CameraClsMode camera,True,True
	;===>
	ShowEntity SHWSpriteFront 
	ShowEntity Scena
	;===>
	SetBuffer BackBuffer()
	Cls
	;===>
End Function 
;=======================
; Creazione immagine ombra
; Fast2
Function ShadowVolumeSimulateStencilNew1()
	;===>
	Local MeshBack = CopyMesh(MeshFront)
	EntityAlpha MeshBack, sh_level 
	EntityBlend MeshBack,3
	;===>
	; Fase 1
	;===>
	Local CaptureX = TextureWidth(ShwTex1)
	Local CaptureY = TextureHeight(ShwTex1)
	CameraViewport Camera,0,0,CaptureX, CaptureY
	;===>
	HideEntity SHWSpriteFront 
	;===>
	HideEntity MeshFront 
	HideEntity MeshBack 
	ShowEntity Scena
	RenderWorld
	CameraClsMode camera,True,False
	;===>
	HideEntity Scena
	;preparo il back face
	ShowEntity MeshBack
	EntityColor MeshBack,0,0,100
	EntityFX MeshBack,1;4
	FlipMesh MeshBack ;Visualizzo il back face
	;preparo il front face
	ShowEntity MeshFront
	EntityColor MeshFront,100,0,0
	EntityFX MeshFront,1;4
	RenderWorld
	;===>
;Goto Jump
	;===>
	; Front Ground 1
	ShadowColor=(128 Shl 24)
	LockBuffer BackBuffer()
	LockBuffer TextureBuffer(ShwTex1)
	For y=0 To 	CaptureY
		For x=0 To 	CaptureX
			;===>
			pix=ReadPixelFast(x,y)
			Front = (pix And $00FF0000) Shr 16 ; Filtro il rosso
			Back  = (pix And $000000FF) ; Filtro il blu
			Val=Front-Back
			If Val>0 Then
				WritePixelFast x,y,ShadowColor,TextureBuffer(ShwTex1)
			Else
				WritePixelFast x,y,0,TextureBuffer(ShwTex1)
			EndIf
			;===>
		Next
	Next
	UnlockBuffer TextureBuffer(ShwTex1)
	UnlockBuffer BackBuffer()
	;===>
.Jump
	;===>
	;Ripristiniamo tutto prima di riprendere le normali attività
	FreeEntity MeshBack
	CameraViewport Camera,0,0,GraphicsWidth(), GraphicsHeight()
	CameraClsMode camera,True,True
	;===>
	ShowEntity SHWSpriteFront 
	ShowEntity Scena
	;===>
	SetBuffer BackBuffer()
	Cls
	;===>
End Function 



ok, when the initobject() works fast, i will intergrate this code into my stencil shadow system and you'll be the first who will know it :)

cya

look what i have done with your shadow code:
http://patrick-sch.de/bleibdafuerimmer/StencilShadowSystem.zip

Good !! the system is good :)

bye

hm, i get a "too many parameters" error at SetRenderState()

t3kMac ..I take it your using at least v1.88?

It works fine here ... a few clitches and some slowdown on demo 4. I still don't think it's fast enough for in-game use though :( Max FPS I got on the swwift demo was 60fps but that's without game logic / physics etc.. Your beethoven mesh is nowhere near the same polys as he was pushing.

Nice work none the less!!

It seems that the shadowvolume creation is still the bottleneck ... if only some smart guy could create a .dll for the volume building then you'd be cooking on gas :)

Stevie

yes, a volume dll would be revolutionary, because everybody could create his own shadow system, then remember: 90% of the work of a stencil shadow system is the shadow volume! the rest is as easy as clean up his ass :)

@stevieg: t3kMac ..I take it your using at least v1.88?

i am using blitz 1.96 and hmm don't know the version of dx7test.dll (mine is 77.824 Bytes) maybe i have an old one or old decals... can you send me yours please?

@ t3kMac ...

I just used the ones which came with the zip download and popped them into the uselibs directory and it worked fine.

Stevie

Now, get cracking on self shadowing :P Good work guys :o)

self shadowing should be simple. You only have to add the caster mesh to the list of the receiver surfaces.

One thing that is surely more a candidate for headache is the animated vertices problem. And after all we want to use shadows with characters, right?
Adding a pivot to every vertex is also very slow. Additionally there are weighted vertices, so this wouldn't work.

Somebody was working on a DLL that was capable of determinating the true vertex coords of animated meshes. Not sure what's going on there.

Anyway, good work!

@stevie: this dx7 dll looks way older than mine. now i have 3 different dx7.dlls. which one is the best?

dx7test.dll
DirectX7.dll
vardx7.dll

little chaos is coming up...

directx7.dll is the same as dx7test.dll
the name has just changed and i deleted the not-needed functions...

ps: daredevil, how is your progress?

the my proces is good i have found a litle bug in the initobject, this bug have effect in the load object that contain object null.

aptend a new version, what completed this you join the my system your.

ok!! bye ;)

thanks for the clear up.

I have integred your stencil buffer in the my systems is fast !!!

:)

GOOD!
a software stencil buffer is not very useful in games...

this is a link

http://digilander.libero.it/enzo_light/shw08.zip

lock software, the time systems is not correct o stencil buffer hardware has a slow speed

is fast the software simulate end not hardware?


bye

hey, thats not bad...man thats good! :)
yes, sure the hardware stencil buffer is faster... but there is a little bug...don't mid, i'll fix it soon!
the initobject() takes half a minute in the first sample, and there are >only< 2 spehres with 32 segments... quite to slowly for a real stencil shadow system ;)

have you got any idea what we could do?

edit: i noticed that you are better in creating volumes, and i am better in making it work with hardware, multilights and so on..

what about, that we could make s shadow system together? then we would be a team for this system! ok?
if you have icq or msn, you could give me your icq/msn number and we could chat a lil bit...

i'm not use icq :(

i have create the system silouette for permit a the new programmers the use software complet and simple that blitzbasic3d.

i'm ex programmer professional i have programmed wing commander prophecy for GBA and one part R-Type III by www.raylight.it studios Naples Italy.

http://www.mobygames.com/developer/sheet/view/developerId,166785/

The team for shadow? yes!!!

the my old team hobby is Eye&Light the link:

http://digilander.libero.it/eyeandlight/index.htm

bye

well, on www.icq.com you can download icq, then you must create an account and in my signature is my icq number, so you can easily find me :)

edit: here is OUR worklog :)
http://www.blitzbasic.com/logs/userlog.php?user=8270&log=660

i have played arround with shw08 for a few hours and i heve noticed that if you set the m4 mesh as a shadow caster, the shadow of that mesh looks anyhow...strange...

Good !!

i programmed the silouette in c++ for fast result and return the all


?????

bye

in c++? well... you may can make a volume dll for blitz, that would be the best :)

i have test the limits blitz, is view no screen the problem slow stencil, i have correct common type for max speed, and abjust your stencil sistem, lock gemedev site.

The new update:

digilander.libero.it/enzo_light/shw09.zip

You've got a major memory leak somewhere ... my system ran out of virtual memory after about 5 mins of running the shw example. Was a bugger to close it down.

Looks nice though .. assume the low res version is software stencils?

Stevie

how about making a solution in c++, and making a blitz dll? this would be the fastest solution EVER!

Ok new update:D silhouette fast speed up 10% resolved bug in common and general optimizzation .

Test this version

bye all

http://digilander.libero.it/enzo_light/shw10.zip

i have checked out the shw10 and there is a critical bug:



i don't know how this strip accures...the object has got only one surface. with the m4 model you see those strips, too!

I know this bug, but it has not been never resolved!!
perhaps the error is caused gives of connected the well faces not caused from the export
this bug I have an idea of like resolving it, I will insert a
tolerance on you concern to us
I have increased of an other 10% the performances of the silouette but it I have not still Posted perhaps why I succeed in 1/2 the speed

news: i have checked out the tfp libary from marksibly for tformpoint() commands on animated b3d meshes.
but there are too much bugs, so i cannot use it...

how is your progress?

I got those strips when my quad faces were oriented backwards.

Test a third vertex along either of the triangles that make up the edge. Use the orientation of that vertex relative to the plane equation created by the quad to test which direction the quad should face.

Geometry is at fault here, not your code!

The strip is because the mesh is not a closed mesh. Shadow volumes must be completely closed, or consist of groups of closed meshes.

See...


The red and green lines show where an edge is exposed. Idealy, the 'top lip' red edge and the 'mouth cavity' blue edge should be spanned with polys. similarly, the green line should be joint to the lower mouth cavity inside :)

Another tip:

When you are building the mesh edges, do NOT look for triangles that share vertices. You may have two different vertices in the same position, because of normals or texture mapping. Instead, look for triangles that share vertices that have an identical position. Compare the absolute value of the difference between each component of the vertex positions, and consider them the same if they less than a very small precision value, like 0.001:

Function VerticesMatch(surf,a,b)
If Abs(VertexX(surf,a)-VertexX(surf,b))<0.001
If Abs(VertexY(surf,a)-VertexY(surf,b))<0.001
If Abs(VertexZ(surf,a)-VertexZ(surf,b))<0.001
Return True
Endif
Endif
Endif
End Function

Ok!! for you the new update :D

the bug face is not resolved is the problem is object :(

ok pleace test the new version and check with others object


the new step is carmak sistem and multi light range

digilander.libero.it/enzo_light/shw11.zip

equation plane intersect rect?

bye

here is the new dll for the stencil buffer:
http://www.blitzbasic.com/Community/posts.php?topic=59699

use this instead of mine, because this one is better^^

the new version "shadowinclude", i have a problem for procedure tom for robust shadow pleace help me!!! :(
i have optmized other than for fast silhouette

the time render is very slow
;======================================= 
;--------------------------------------- 
; 
;   Name file: Shadow_Include
; 
;   Programmatore: 
;      Caldarulo Vincenzo (Eye & Light) 
;   Descrizione: 
;			Creazione dei volumi d'ombra
; 
;--------------------------------------- 
;======================================= 
Include"commontype.bb"
;Include"cost.bb"
;======================================= 
;--------------------------------------- 
; Variabili ShadowVolume 
;--------------------------------------- 
;=======================================
;
;D3DCULL
Const D3DCULL_NONE				= 1
Const D3DCULL_CW					= 2
Const D3DCULL_CCW					= 3
		
;D3DSHADE_MODE
Const D3DSHADE_FLAT			= 1
Const D3DSHADE_GOURAUD	= 2
Const D3DSHADE_PHONG		= 3

;D3DFILL_MODE
Const D3DFILL_POINT			= 1
Const D3DFILL_WIREFRAME	= 2
Const D3DFILL_SOLID			= 3

;D3DSTENCILOP
Const D3DSTENCILOP_KEEP           = 1
Const D3DSTENCILOP_ZERO           = 2
Const D3DSTENCILOP_REPLACE        = 3
Const D3DSTENCILOP_INCRSAT        = 4
Const D3DSTENCILOP_DECRSAT        = 5
Const D3DSTENCILOP_INVERT         = 6
Const D3DSTENCILOP_INCR           = 7
Const D3DSTENCILOP_DECR           = 8
Const D3DSTENCILOP_FORCE_DWORD    = $7fffffff	;force 32-bit size enum

;D3DCMPFUNC
Const D3DCMP_NEVER               = 1
Const D3DCMP_LESS                = 2
Const D3DCMP_EQUAL               = 3
Const D3DCMP_LESSEQUAL           = 4
Const D3DCMP_GREATER             = 5
Const D3DCMP_NOTEQUAL            = 6
Const D3DCMP_GREATEREQUAL        = 7
Const D3DCMP_ALWAYS              = 8
Const D3DCMP_FORCE_DWORD         = $7fffffff	;force 32-bit size enum

;D3DBLEND
Const D3DBLEND_ZERO              = 1
Const D3DBLEND_ONE               = 2
Const D3DBLEND_SRCCOLOR          = 3
Const D3DBLEND_INVSRCCOLOR       = 4
Const D3DBLEND_SRCALPHA          = 5
Const D3DBLEND_INVSRCALPHA       = 6
Const D3DBLEND_DESTALPHA         = 7
Const D3DBLEND_INVDESTALPHA      = 8
Const D3DBLEND_DESTCOLOR         = 9
Const D3DBLEND_INVDESTCOLOR      = 10
Const D3DBLEND_SRCALPHASAT       = 11
Const D3DBLEND_BOTHSRCALPHA      = 12
Const D3DBLEND_BOTHINVSRCALPHA   = 13
Const D3DBLEND_FORCE_DWORD       = $7fffffff	;force 32-bit size enum
;===>
Const D3DRS_ANTIALIAS          = 2    ; D3DANTIALIASMODE */
Const D3DRS_TEXTUREPERSPECTIVE = 4    ; True For perspective correction */
Const D3DRS_ZENABLE            = 7    ; D3DZBUFFERTYPE (Or True/False For legacy) */
Const D3DRS_FILLMODE           = 8    ; D3DFILL_MODE        */
Const D3DRS_SHADEMODE          = 9    ; D3DFILL_MODE */
Const D3DRS_LINEPATTERN        = 10   ; D3DLINEPATTERN */
Const D3DRS_ZWRITEENABLE       = 14   ; True To enable z writes */
Const D3DRS_ALPHATESTENABLE    = 15   ; True To enable alpha tests */
Const D3DRS_LASTPIXEL          = 16   ; True For Last-pixel on lines */
Const D3DRS_SRCBLEND           = 19   ; D3DBLEND */
Const D3DRS_DESTBLEND          = 20   ; D3DBLEND */
Const D3DRS_CULLMODE           = 22   ; D3DCULL */
Const D3DRS_ZFUNC              = 23   ; D3DCMPFUNC */
Const D3DRS_ALPHAREF           = 24   ; D3DFIXED (long) */
Const D3DRS_ALPHAFUNC          = 25   ; D3DCMPFUNC */
Const D3DRS_DITHERENABLE       = 26   ; True To enable dithering */
Const D3DRS_ALPHABLENDENABLE   = 27   ; True To enable alpha blending */
Const D3DRS_FOGENABLE          = 28   ; True To enable fog blending */
Const D3DRS_SPECULARENABLE     = 29   ; True To enable specular */
Const D3DRS_ZVISIBLE           = 30   ; True To enable z checking */
Const D3DRS_STIPPLEDALPHA      = 33   ; True To enable stippled alpha (RGB device only) */
Const D3DRS_FOGCOLOR           = 34   ; D3DCOLOR */  INT (((a) << 24) Or ((r) << 16) Or ((g) << 8) Or (b)))
Const D3DRS_FOGTABLEMODE       = 35   ; D3DFOGMODE */
Const D3DRS_FOGSTART           = 36   ; Float Fog start (For both vertex And pixel fog) 
Const D3DRS_FOGEND             = 37   ; Float Fog End      */
Const D3DRS_FOGDENSITY         = 38   ; Fog density  */
Const D3DRS_EDGEANTIALIAS      = 40   ; True To enable edge antialiasing */
Const D3DRS_COLORKEYENABLE     = 41   ; True To enable source colorkeyed textures */
Const D3DRS_ZBIAS              = 47   ; LONG Z bias */
Const D3DRS_RANGEFOGENABLE     = 48   ; Enables range-based fog */
; *** STENCIL OPS ***
Const D3DRS_STENCILENABLE      = 52   ; BOOL enable/disable stenciling
Const D3DRS_STENCILFAIL        = 53   ; D3DSTENCILOP To do If stencil test fails
Const D3DRS_STENCILZFAIL       = 54   ; D3DSTENCILOP To do If stencil test passes And Z test fails
Const D3DRS_STENCILPASS        = 55   ; D3DSTENCILOP To do If both stencil And Z tests pass */
Const D3DRS_STENCILFUNC        = 56   ; D3DCMPFUNC fn.  Stencil Test passes If ((ref & mask) stencilfn (stencil & mask)) is True */
Const D3DRS_STENCILREF         = 57   ; INT Reference value used in stencil test */
Const D3DRS_STENCILMASK        = 58   ; Mask value used in stencil test  e.g (0xffffffff)
Const D3DRS_STENCILWRITEMASK   = 59   ; Write mask applied To values written To stencil buffer e.g (0xffffffff)
Const D3DRS_TEXTUREFACTOR      = 60   ; D3DCOLOR used For multi-texture blend */
Const D3DCLEAR_TARGET					= $00000001	;Clear target surface
Const D3DCLEAR_ZBUFFER				= $00000002	;Clear target z buffer
Const D3DCLEAR_STENCIL				= $00000004	;Clear Stencil
;ERRORS
Const D3DERR_ZBUFFER_NOTPRESENT					= 2070
Const D3DERR_STENCILBUFFER_NOTPRESENT		= 2071
Const D3DERR_VIEWPORTHASNODEVICE				= 774
Const DDERR_INVALIDOBJECT								= 130
Const DDERR_INVALIDPARAMS								= $80070057

;===>
Global Direct3DDevice7 = SystemProperty$("Direct3DDevice7")
Global Direct3D7 = SystemProperty$("Direct3D7")
Global DirectDraw7 = SystemProperty$("DirectDraw7")
Global DirectInput7 = SystemProperty$("DirectInput7")
Global AppHWND = SystemProperty$("AppHWND")
Global AppHINSTANCE = SystemProperty$("AppHINSTANCE")

;===>
Type EdgeToEdge
	Field IdModel
	Field cntSurface
	Field Surfaces.ETE_Surface
End Type
;===>
Type ETE_Surface
	Field IdSurface
	Field cntTriangle
	Field IdTriangle.ETE_Triangle[ETE_MaxTriang]
End Type
;===>
Type ETE_Triangle
	Field Normal.Point3D
	Field a.Point3D
	Field b.Point3D
	Field c.Point3D
	Field Triangle
	Field ATriangle
	Field BTriangle
	Field CTriangle
End Type
;===>
;=======================================
;===>
Const SHWTexSize = 128; Parametro di regolazione Ombra
Const sh_level# = 0.1
Const ETE_MaxTriang=65000
Const SHWL3D = 65000
Const Tolerance#=0.01
Const MaxEdgeCamera=1000
;===>
;======================================= 
;===>
Dim TriangleClone.ETE_Triangle(ETE_MaxTriang)
Dim EdgeCamera.Point3D(MaxEdgeCamera)
Dim AD(65000,2)
;===>
;======================================= 
;===>
Global CNTEdgeCamera = 0
;===>
Global Scena = CreatePivot(); CreateSphere(5)
Global result$=""
;===>
Global MeshFront = CreateMesh(); 
Global SurfaceFront = CreateSurface(MeshFront); 
EntityAlpha MeshFront, sh_level 
EntityFX MeshFront,1;4
EntityBlend MeshFront,3
;===>
Global cntLine3D=0
Dim Line3DAX#(SHWL3D)
Dim Line3DAY#(SHWL3D)
Dim Line3DAZ#(SHWL3D)
Dim Line3DBX#(SHWL3D)
Dim Line3DBY#(SHWL3D)
Dim Line3DBZ#(SHWL3D)
;===>
;Creiamo il piano che proietterà l'ombra
;===>
Global SHWScreenImage = CreateImage(SHWTexSize,SHWTexSize)
Global SHWSpriteFront=CreateSprite()
SpriteViewMode SHWSpriteFront,1
EntityFX SHWSpriteFront,1
;===>
Global sh_light.Point3D = New Point3D 
;===>
Global SHW_ETE_Object.EdgeToEdge
;===>
Global sh_lenght# = 0
Global CRValX# = 0
Global CRValY# = 0
Global CRValZ# = 0
;===>
; Equazione del piano e intersezione della retta
Global PickX# = 0
Global PickY# = 0
Global PickZ# = 0
Global PickD# = 0
Global Zfail#=0.0 

;======================================= 
;===>
;=======================
; 
Function CheckVertex_orig%(a.Point3D,b.Point3D)
	If (a\x=b\x)And(a\y=b\y)And(a\z=b\z) Then
		Return True 
	Else
		Return False 
	EndIf 
End Function 

Function CheckVertex%(a.Point3D,b.Point3D)
	If Abs(a\x-b\x) < Tolerance
		If Abs(a\y-b\y) < Tolerance
			If Abs(a\z-b\z) < Tolerance
				Return True 
			Else
				Return False 
			EndIf
		Else
			Return False 
		EndIf
	Else
		Return False 
	EndIf

End Function 
;======================================================================= 
;======================================================================= 
; Shadow Volume For silhouette Method Edge to Edge
;======================================================================= 
;======================================================================= 
;======================= 
; Inizialize Object Shadow
Function SHW_Init()
;	DX_D3D=SystemProperty$("Direct3D7")
;	DX_DEV7=SystemProperty$("Direct3DDevice7")
;	DX_DRAW7=SystemProperty$("DirectDraw7")
;	DX_HWND=SystemProperty$("AppHWND")
;	DX_INSTANCE=SystemProperty$("AppHINSTANCE")
;
;	Direct3DDevice7 = SystemProperty$("Direct3DDevice7")
	;===>
	; Search surface and triangle object
	For n=0 To ETE_MaxTriang
		;===>
		TriangleClone.ETE_Triangle(n) = New ETE_Triangle
		;===>
		TriangleClone(n)\Normal.Point3D = New Point3D
		TriangleClone(n)\a.Point3D = New Point3D
		TriangleClone(n)\b.Point3D = New Point3D
		TriangleClone(n)\c.Point3D = New Point3D
	Next
	;===>
	For n=0 To MaxEdgeCamera
		EdgeCamera.Point3D(n) = New Point3D
	Next
	;===>

	ShwInitDisplay()

End Function 
;======================= 
;
Function ShwInitDisplay()
	;===>
	EntityParent(SHWSpriteFront,Camera) 
;	PositionEntity SHWSpriteFront,-0.005,+0.005,1.001 
	PositionEntity SHWSpriteFront,0,0,1.001 
	;===>
End Function 
;=======================
; Inizialize Object Shadow
Function SHW_InitObject$(model)
	Time$=""
	Tim1=MilliSecs()

	Local Norm.Point3D = New Point3D
	Local IdSurface.ETE_Surface
	Local IdTriang.ETE_Triangle
	Local BTriang.ETE_Triangle
	Local IdN.Point3D
	Local IdA.Point3D
	Local IdB.Point3D
	Local IdC.Point3D
	Local IdBA.Point3D
	Local IdBB.Point3D
	Local IdBC.Point3D
	Local a%
	Local b%
	Local check1%
	Local check2%
	Local check3%
	Local check4%
	Local state1%
	Local state2
	Local state3%
	;===>
	SHW_ETE_Object.EdgeToEdge = New EdgeToEdge
	SHW_ETE_Object\IdModel = model
	;===>
	; Search surface and triangle object
	SHW_ETE_Object\cntSurface = CountSurfaces(model)-1
	For n=0 To SHW_ETE_Object\cntSurface
		;===>
		surf = GetSurface(model,n+1)
		NumFaces = CountTriangles(surf)-1
		;===>
		SHW_ETE_Object\Surfaces.ETE_Surface = New  ETE_Surface
		IdSurface.ETE_Surface = SHW_ETE_Object\Surfaces
		;===>
		IdSurface\IdSurface = surf
		IdSurface\cntTriangle = NumFaces
		For v=0 To NumFaces
			;===>
			IdSurface\IdTriangle.ETE_Triangle[v] = New ETE_Triangle
			IdTriang.ETE_Triangle = IdSurface\IdTriangle[v]
			;===>
			IdTriang\normal.Point3D = New Point3D
			IdTriang\a.Point3D = New Point3D
			IdTriang\b.Point3D = New Point3D
			IdTriang\c.Point3D = New Point3D
			IdN.Point3D = IdTriang\normal
			IdA.Point3D = IdTriang\a
			IdB.Point3D = IdTriang\b
			IdC.Point3D = IdTriang\c
			;===> 
			vert0 = TriangleVertex(surf,v,0)
			vert1 = TriangleVertex(surf,v,1)
			vert2 = TriangleVertex(surf,v,2)
			;===>
			IdA\x = VertexX( surf, vert0) : IdA\y = VertexY( surf, vert0) : IdA\z = VertexZ( surf, vert0)
			;===> 
			IdB\x = VertexX( surf, vert1) : IdB\y = VertexY( surf, vert1) : IdB\z = VertexZ( surf, vert1)
			;===> 
			IdC\x = VertexX( surf, vert2) : IdC\y = VertexY( surf, vert2) : IdC\z = VertexZ( surf, vert2)
			;===>
			;IdN\x= (VertexNX( surf, vert0) + VertexNX( surf, vert1) + VertexNX( surf, vert2))/3
			;IdN\y= (VertexNY( surf, vert0) + VertexNY( surf, vert1) + VertexNY( surf, vert2))/3
			;IdN\z= (VertexNZ( surf, vert0) + VertexNZ( surf, vert1) + VertexNZ( surf, vert2))/3
			CalcNormal( IdN, IdA, IdB, IdC)
			V_3Normalize( IdN, IdN) 
			;===>
			IdTriang\Triangle = v
			IdTriang\ATriangle = -1
			IdTriang\BTriangle = -1
			IdTriang\CTriangle = -1
			;===>
		Next 
		;===>
		; Search adjacent triangle
		;===>
		; ottimizzazione precalcolo
		For a=0 To IdSurface\cntTriangle
			AD(a,0)=1 : AD(a,1) = 1 : AD(a,2) = 1
		Next
		;===>
		For a=0 To IdSurface\cntTriangle
			;===>
			ATriang.ETE_Triangle = IdSurface\IdTriangle[a]
			IdA.Point3D = ATriang\a
			IdB.Point3D = ATriang\b
			IdC.Point3D = ATriang\c
			;===>
			For b=a+1 To IdSurface\cntTriangle
				;===>
				state1=AD(b,0) : state2=AD(b,1) : state3=AD(b,2)
				If a=b Or ( state1=0 And state2=0 And state3=0 ) Then Goto SIDEC
				;===>
				BTriang.ETE_Triangle = IdSurface\IdTriangle[b]
				IdBA.Point3D = BTriang\a
				IdBB.Point3D = BTriang\b
				IdBC.Point3D = BTriang\c
				;*********************************************************************
				; SIDE " A "
				;===>
				; Adjacent side A (il lato A del 1° triangolo confina con lato A del 2° Triangolo)
				If (state1=1)Then
					;===>
					check1 = CheckVertex( IdA, IdBA )
					check2 = CheckVertex( IdB, IdBB )
					check3 = CheckVertex( IdA, IdBB )
					check4 = CheckVertex( IdB, IdBA )
					;===>
					If  (check1 And check2) Or (check3 And check4) Then
						ATriang\ATriangle = b
						BTriang\ATriangle = a
						AD(b,0)=0
						Goto SIDEA
						;Stop
					EndIf
					;===>
				EndIf
				;===>
				; Adjacent side A (il lato A del 1° triangolo confina con lato B del 2° Triangolo)
				If (state2=1)Then
					;===>
					check1 = CheckVertex( IdA, IdBB )
					check2 = CheckVertex( IdB, IdBC )
					check3 = CheckVertex( IdA, IdBC )
					check4 = CheckVertex( IdB, IdBB )
					;===>
					If  (check1 And check2) Or (check3 And check4) Then
						ATriang\ATriangle = b
						BTriang\BTriangle = a
						AD(b,1)=0
						Goto SIDEA
						;Stop
					EndIf
					;===>
				EndIf
				;===>
				; Adjacent side A (il lato A del 1° triangolo confina con lato C del 2° Triangolo)
				If (state3=1)Then
					;===>
					check1 = CheckVertex( IdA, IdBC )
					check2 = CheckVertex( IdB, IdBA )
					check3 = CheckVertex( IdA, IdBA )
					check4 = CheckVertex( IdB, IdBC )
					;===>
					If  (check1 And check2) Or (check3 And check4) Then
						ATriang\ATriangle = b
						BTriang\CTriangle = a
						AD(b,2)=0
						;Stop
					EndIf
					;===>
				EndIf
				.SIDEA
				;===>
				;*********************************************************************
				; SIDE " B "
				;===>
				; Adjacent side A (il lato B del 1° triangolo confina con lato A del 2° Triangolo)
				If (state1=1)Then
					;===>
					check1 = CheckVertex( IdB, IdBA )
					check2 = CheckVertex( IdC, IdBB )
					check3 = CheckVertex( IdB, IdBB )
					check4 = CheckVertex( IdC, IdBA )
					;===>
					If  (check1 And check2) Or (check3 And check4) Then
						ATriang\BTriangle = b
						BTriang\ATriangle = a
						AD(b,0)=0
						Goto SIDEB
						;Stop
					EndIf 
					;===>
				EndIf 
				;===>
				; Adjacent side A (il lato B del 1° triangolo confina con lato B del 2° Triangolo)
				If (state2=1)Then
					;===>
					check1 = CheckVertex( IdB, IdBB )
					check2 = CheckVertex( IdC, IdBC )
					check3 = CheckVertex( IdB, IdBC )
					check4 = CheckVertex( IdC, IdBB )
					;===>
					If  (check1 And check2) Or (check3 And check4) Then
						ATriang\BTriangle = b
						BTriang\BTriangle = a
						AD(b,1)=0
						Goto SIDEB
						;Stop
					EndIf
					;===>
				EndIf
				;===>
				; Adjacent side A (il lato B del 1° triangolo confina con lato C del 2° Triangolo)
				If (state3=1)Then
					;===>
					check1 = CheckVertex( IdB, IdBC )
					check2 = CheckVertex( IdC, IdBA )
					check3 = CheckVertex( IdB, IdBA )
					check4 = CheckVertex( IdC, IdBC )
					;===>
					If  (check1 And check2) Or (check3 And check4) Then
						ATriang\BTriangle = b
						BTriang\CTriangle = a
						AD(b,2)=0
						;Stop
					EndIf
					;===>
				EndIf
				.SIDEB
			;===>
				;*********************************************************************
				; SIDE " C "
				;===>
				; Adjacent side A (il lato C del 1° triangolo confina con lato A del 2° Triangolo)
				If (state1=1)Then
					;===>
					check1 = CheckVertex( IdC, IdBA )
					check2 = CheckVertex( IdA, IdBB )
					check3 = CheckVertex( IdC, IdBB )
					check4 = CheckVertex( IdA, IdBA )
					;===>
					If  (check1 And check2) Or (check3 And check4) Then
						ATriang\CTriangle = b
						BTriang\ATriangle = a
						AD(b,0)=0
						Goto SIDEC
						;Stop
					EndIf
				;===>
				EndIf
				;===>
				; Adjacent side A (il lato C del 1° triangolo confina con lato B del 2° Triangolo)
				If (state2=1)Then
					;===>
					check1 = CheckVertex( IdC, IdBB )
					check2 = CheckVertex( IdA, IdBC )
					check3 = CheckVertex( IdC, IdBC )
					check4 = CheckVertex( IdA, IdBB )
					;===>
					If  (check1 And check2) Or (check3 And check4) Then
						ATriang\CTriangle = b
						BTriang\BTriangle = a
						AD(b,1)=0
						Goto SIDEC
						;Stop
					EndIf
					;===>
				EndIf 
				;===>
				; Adjacent side A (il lato C del 1° triangolo confina con lato C del 2° Triangolo)
				If (state3=1)Then
					;===>
					check1 = CheckVertex( IdC, IdBC )
					check2 = CheckVertex( IdA, IdBA )
					check3 = CheckVertex( IdC, IdBA )
					check4 = CheckVertex( IdA, IdBC )
					;===>
					If  (check1 And check2) Or (check3 And check4) Then
						ATriang\CTriangle = b
						BTriang\CTriangle = a
						AD(b,2)=0
						;Stop
					EndIf
					;===>
				EndIf
				.SIDEC
				;===>
			Next
			;===>
		Next 
		;===>
	Next
	;===>
	Delete Norm
	;===>
	Tim2=MilliSecs()
	Time$="Time Precalcolo: "+(Tim2-Tim1)
	Return Time$
	;===>
End Function 
;=======================
; Inizialize Object Shadow
Function CloneListTriangle(dst.ETE_Triangle,src.ETE_Triangle)
	;===>
	V_3Copy( dst\Normal, src\Normal)
	V_3Copy( dst\a, src\a)
	V_3Copy( dst\b, src\b)
	V_3Copy( dst\c, src\c)
	dst\Triangle = src\Triangle
	dst\ATriangle = src\ATriangle
	dst\BTriangle = src\BTriangle
	dst\CTriangle = src\CTriangle
	;===>
End Function 
;=======================
Function ResetShadowVolume()
	ClearSurface SurfaceFront;
	CNTEdgeCamera = 0

End Function 
;======================= 
; Shadows Volume start 
Function ShadowVolume$( Light, LightLenght, ShowVol=False, SBHardware=False )
	;===>
	ResetShadowVolume()
	;===>
	sh_light\x = EntityX(Light) : sh_light\y = EntityY(Light) : sh_light\z = EntityZ(Light) 
	sh_lenght = LightLenght 
	;===>
	cntLine3D=0
	;===>
	UpdateWorld()
	;===>
	result$ = ShadowVolumeCreate3()
	;===>
	ShadowVolumeStenciBuffer( ShowVol ) ; gestione hardware
	;===>
	Return result$
	;===>
End Function 
;=======================
; Calcolo del raggio
; 
Function CalcRay(Rtn.Point3D,val1.Point3D, val2.Point3D, Leght#)
	;----> 
	CRValX# = val1\x - val2\x; 
	CRValY# = val1\y - val2\y; 
	CRValZ# = val1\z - val2\z;
	;----> 
	do# = (1.0 / Sqr( ( CRValX * CRValX ) + ( CRValY * CRValY ) + ( CRValZ * CRValZ ) ) ) * Leght
	;---->
	Rtn\x = val1\x + ( CRValX * do ); 
	Rtn\y = val1\y + ( CRValY * do ); 
	Rtn\z = val1\z + ( CRValZ * do );
	;----> 
End Function 

;=======================
; Intersezione piano - retta
; questa fuzione verrà divisa in equazione del piano e intersezione della retta  per ottimizzazione maggiore 
Function Pick_GetCoordinate( Retta.Point3D, RettaVect.Point3D, P1.Point3D, P2.Point3D, P3.Point3D )
	;===>
	Local DirCam.Point3D = New Point3D
	; fattori Equazione piano
	Local a#
	Local b#
	Local c#
	Local d#
	;===>
	Local k#
	;===>
	; Equazione del piano
	; a = (y2-y1)*(z3-z1) - (z2-z1)*(y3-y1)
	; b = (z2-z1)*(x3-x1) - (x2-x1)*(z3-z1);
	; c = (x2-x1)*(y3-y1) - (y2-y1)*(x3-x1);

	; d =((z2-z1)*(y3-y1) - (y2-y1)*(z3-z1))*x1 + 
	;		((x2-x1)*(z3-z1) - (z2-z1)*(x3-x1))*y1 + 
	;		((y2-y1)*(x3-x1) - (x2-x1)*(y3-y1))*z1;
	;===>
	a = ((P2\y-P1\y)*(P3\z-P1\z)) - ((P2\z-P1\z)*(P3\y-P1\y));
	b = ((P2\z-P1\z)*(P3\x-P1\x)) - ((P2\x-P1\x)*(P3\z-P1\z));
	c = ((P2\x-P1\x)*(P3\y-P1\y)) - ((P2\y-P1\y)*(P3\x-P1\x));

	d =	((P2\z-P1\z)*(P3\y-P1\y) - (P2\y-P1\y)*(P3\z-P1\z))*P1\x + ((P2\x-P1\x)*(P3\z-P1\z) - (P2\z-P1\z)*(P3\x-P1\x))*P1\y + ((P2\y-P1\y)*(P3\x-P1\x) - (P2\x-P1\x)*(P3\y-P1\y))*P1\z;

;	a =  (P1\y*P2\z)+(P2\y*P3\z)+(P1\z*P3\y)-(P3\y*P2\z)-(P3\z*P1\y)-(P2\y*P1\z);
;	b = -(P1\x*P2\z)-(P1\z*P3\x)-(P2\x*P3\z)+(P3\x*P2\z)+(P1\x*P3\z)+(P2\x*P1\z);
;	c =  (P1\x*P2\y)+(P1\y*P3\x)+(P2\x*P3\y)-(P2\y*P3\x)-(P1\x*P3\y)-(P2\x*P1\y);
;	d = -(P1\x*P2\y*P3\z)-(P1\y*P2\z*P3\x)-(P2\x*P3\y*P1\z)+(P3\x*P2\y*P1\z)+(P3\y*P2\z*P1\x)+(P2\x*P1\y*P3\z);

	; ax+by+cz+d=0   =>  a*x+b*y+c*z+d=0

	;===>
	; Assegnazione termini noti
	; Retta - Retta vettore ( l m n )
	;===>
	;k =   (( a*x0 + b*y0 + c*z0 + d ) 
	;		- ---------------------------
	;					( a*l + b*m + c*n));

	k = -(( a*Retta\x + b*Retta\y + c*Retta\z + d ) / ( a*RettaVect\x + b*RettaVect\y + c*RettaVect\z));

	;===>
	; Intersezione
	PickX = Retta\x + ( RettaVect\x*k );
	PickY= Retta\y + ( RettaVect\y*k );
	PickZ = Retta\z + ( RettaVect\z*k );
	;===>
	PickD = ( a*Retta\x + b*Retta\y + c*Retta\z + d )/Sqr( a*a + b*b + c*c );

End Function 

;=======================
; 
Function CreatePolygon( IdA.Point3D, RayA.Point3D, RayB.Point3D, IdB.Point3D)
	Local va=0
	Local vb=0
	Local vc=0
	Local vd=0
	;===>
	va = AddVertex(SurfaceFront,  IdA\x,			IdA\y, 			IdA\z ); 
	vb = AddVertex(SurfaceFront,  RayA\x,	RayA\y,		RayA\z ); 
	vc = AddVertex(SurfaceFront,  RayB\x,	RayB\y,		RayB\z ); 
	vd = AddVertex(SurfaceFront,  IdB\x,			IdB\y, 			IdB\z ); 
	;===>
	AddTriangle(SurfaceFront, va, vb, vc); faccia 1/3 a 
	AddTriangle(SurfaceFront, va, vc, vd); faccia 1/3 b
	;===>
	Line3DAX(cntLine3D) = IdA\x : Line3DAY(cntLine3D) = IdA\y : Line3DAZ(cntLine3D) = IdA\z
	Line3DBX(cntLine3D) = IdB\x : Line3DBY(cntLine3D) = IdB\y : Line3DBZ(cntLine3D) = IdB\z
	cntLine3D=cntLine3D+1
;	;===================================================
;	;===>
;	;TEST
;	Local Rrt.Point3D = New Point3D
;	Local P1.Point3D = New Point3D
;	Local P2.Point3D = New Point3D
;	Local P3.Point3D = New Point3D
;	Local PNormal.Point3D = New Point3D
;	;===>
;	TFormPoint 0, 0 , Zfail , SHWSpriteFront, 0
;	P1\x = TFormedX() : P1\y = TFormedY() : P1\z = TFormedZ()
;	TFormPoint 0, 1 , Zfail , SHWSpriteFront, 0
;	P2\x = TFormedX() : P2\y = TFormedY() : P2\z = TFormedZ()
;	TFormPoint 1, 0 , Zfail , SHWSpriteFront, 0
;	P3\x = TFormedX() : P3\y = TFormedY() : P3\z = TFormedZ()
;	CalcNormal(PNormal,P1,P2,P3)
;	V_3Normalize( PNormal, PNormal )
;	;coordinate di test 
;	P1\x = -5 : P1\y = -5 : P1\z = Zfail
;	P2\x = -5 : P2\y = 5 : P2\z = Zfail
;	P3\x = 5 : P3\y = -5 : P3\z = Zfail
;	V_3Dec(RayA,RayA,IdA)
;	V_3Normalize( RayA, RayA )
;	Dot# = V_3Dot( PNormal, RayA ) 
;	If Dot<0 Then 
;			;===>
;			V_3Dec(RayB,RayB,IdB)
;			V_3Normalize( RayB, RayB )
;			;===>
;			Pick_GetCoordinate( IdA, RayA, P1, P2, P3 )
;			Line3DAX(cntLine3D) = PickX : Line3DAY(cntLine3D) = PickY : Line3DAZ(cntLine3D) = PickZ
;			
;			EdgeCamera(CNTEdgeCamera)\x = PickX : EdgeCamera(CNTEdgeCamera)\y = PickY : EdgeCamera(CNTEdgeCamera)\z = PickZ
;			CNTEdgeCamera=CNTEdgeCamera+1
;			;===>
;			Pick_GetCoordinate(  IdB, RayB, P1, P2, P3 )
;			Line3DBX(cntLine3D) = PickX : Line3DBY(cntLine3D) = PickY : Line3DBZ(cntLine3D) = PickZ
;		
;			EdgeCamera(CNTEdgeCamera)\x = PickX : EdgeCamera(CNTEdgeCamera)\y = PickY : EdgeCamera(CNTEdgeCamera)\z = PickZ
;			CNTEdgeCamera=CNTEdgeCamera+1
;			;===>
;			cntLine3D=cntLine3D+1
;			;===>
;	EndIf 
;	;===>
;	Delete PNormal
;	Delete Rrt
;	Delete P1
;	Delete P2
;	Delete P3
;
End Function
;=======================
; Creazione volume
; forse si può fare ancora qualcosina!!
Function ShadowVolumeCreate3$()
	;===> 
	t0=MilliSecs()
	;===> 
	Local Result$ = ""
	;===> 
	Local RayA.Point3D = New Point3D 
	Local RayB.Point3D = New Point3D 
	Local RayC.Point3D = New Point3D
	Local Norm.Point3D = New Point3D
	Local MidPoint.Point3D = New Point3D
	Local NormLight.Point3D = New Point3D
	;===> 
	Local IdA.Point3D
	Local IdB.Point3D
	Local IdC.Point3D
	Local IdN.Point3D
	Local IdCLT.ETE_Triangle
	Local Surfaces.ETE_Surface
	;===> 
	Local CNTFront=0
	Local CNTBack=0
	Local surf=0
	Local Dot#=0
	Local check1 = -1
	Local check2 = -1
	Local check3 = -1

	Local TriangA = 0
	Local TriangB = 0
	Local TriangC = 0
	;===>
	Local v=0
	Local v1=0
	Local aSurf=0
	;===>
	
	For SHW_ETE_Object.EdgeToEdge = Each EdgeToEdge
		;===>
		; Cerchiamoci i vertici faccia vista verso la luce
		Surfaces = SHW_ETE_Object\Surfaces
		For aSurf = 0 To SHW_ETE_Object\cntSurface
			;===>
			If Surfaces=Null Then Goto ErrorSurf
			surf = Surfaces\IdSurface
			dwNumFaces = Surfaces\cntTriangle
			v1=0
			;===>
			For v=0 To dwNumFaces
				;===>
				IdCLT = TriangleClone(v)
				CloneListTriangle( IdCLT,Surfaces\IdTriangle[v] )
				IdA = IdCLT\a
				IdB = IdCLT\b
				IdC = IdCLT\c
				IdN = IdCLT\Normal
				;===>
				;associamo le trasformazioni ai vertici
				TFormPoint IdA\x, IdA\y , IdA\z, SHW_ETE_Object\IdModel, 0
				IdA\x = TFormedX() : IdA\y = TFormedY() : IdA\z = TFormedZ()
				;===> 
				TFormPoint IdB\x, IdB\y , IdB\z, SHW_ETE_Object\IdModel, 0
				IdB\x = TFormedX() : IdB\y = TFormedY() : IdB\z = TFormedZ() 
				;===> 
				TFormPoint IdC\x, IdC\y , IdC\z, SHW_ETE_Object\IdModel, 0
				IdC\x = TFormedX() : IdC\y = TFormedY() : IdC\z = TFormedZ() 
				;===>
				TFormNormal  IdN\x, IdN\y , IdN\z, SHW_ETE_Object\IdModel, 0
				Norm\x = TFormedX() : Norm\y = TFormedY() : Norm\z = TFormedZ()
				;Stop
				V_3Mid(MidPoint, IdA, IdB, IdC) 
				V_3Dec(NormLight, MidPoint, sh_light)
				V_3Normalize( NormLight, NormLight )
				Dot# = V_3Dot( Norm, NormLight ) 
				;===>
				; Marchiamo i vertici non rivolti verso la luce
				If Dot#=>0.0 Then
					;===>
					CNTFront=CNTFront+1
					v1=v1+1
					;===>
				Else
					;===>
					IdCLT\Triangle  = -1
					CNTBack=CNTBack+1
					;===>
				EndIf
				;===> 
			Next
			;===>
			; Ora creiamo il volume
			TriangA = 0
			TriangB = 0
			TriangC = 0
			For v=0 To dwNumFaces
				;===>
				IdCLT = TriangleClone(v)
				;===>
				; Saltiamo il triangolo se è a -1
				If IdCLT\Triangle<0 Then Goto continue
				;===>
				TriangA = IdCLT\ATriangle
				TriangB = IdCLT\BTriangle
				TriangC = IdCLT\CTriangle
				If TriangA>-1 Then check1 = TriangleClone(TriangA)\Triangle Else check1 = -1
				If TriangB>-1 Then check2 = TriangleClone(TriangB)\Triangle Else check2 = -1
				If TriangC>-1 Then check3 = TriangleClone(TriangC)\Triangle Else check3 = -1
				;===>
				If check1>-1 And check2>-1 And check3>-1  Then Goto continue
				;===>
				;Stop
				IdA =  IdCLT\a
				IdB =  IdCLT\b
				IdC =  IdCLT\c
				;===>
				;Edge A
				If check1<0 Then

					;===>
					;Calcolo raggio A
					CalcRay( RayA, IdA, sh_light, sh_lenght)
					;===>
					;Calcolo raggio B
					CalcRay( RayB, IdB, sh_light, sh_lenght)
					;===>
					CreatePolygon(IdA,RayA,RayB,IdB)
					;===>
				EndIf
				;===>
				;Edge B
				If check2<0 Then
					;===>
					;Calcolo raggio B
					CalcRay( RayB, IdB, sh_light, sh_lenght)
					;===>
					;Calcolo raggio C
					CalcRay( RayC, IdC, sh_light, sh_lenght)
					;===>
					CreatePolygon(IdB,RayB,RayC,IdC)
					;===>
				EndIf 
				;===>
				;Edge C
				If check3<0 Then
					;===>
					;Calcolo raggio A
					CalcRay( RayA, IdA, sh_light, sh_lenght)
					;===>
					;Calcolo raggio C
					CalcRay( RayC, IdC, sh_light, sh_lenght)
					;===>
					CreatePolygon(IdC,RayC,RayA,IdA)
					;===>
				EndIf 
				;===>
				.continue
				;===>
			Next 
			;===>
			Surfaces = After Surfaces
			.ErrorSurf
			;===>
		Next
		;===>
	Next
	;===> 
	For v=0 To CNTEdgeCamera-1 Step 2
		;===> 
		va = AddVertex(SurfaceFront,  EdgeCamera(v+0)\x, EdgeCamera(v+0)\y, EdgeCamera(v+0)\z ); 
		vc = AddVertex(SurfaceFront,  EdgeCamera(v+1)\x, EdgeCamera(v+1)\y, EdgeCamera(v+0)\z ); 
		vb = AddVertex(SurfaceFront,  EdgeCamera(v+2)\x, EdgeCamera(v+2)\y, EdgeCamera(v+0)\z ); 
		;===>
		AddTriangle(SurfaceFront, va, vb, vc); faccia 1/3 a 
		;===> 
	Next
	;===>
	Delete MidPoint
	Delete NormLight
	Delete Norm
	Delete RayA
	Delete RayB
	Delete RayC
	;===>
	t1=MilliSecs()
	t2=t1-t0
	Result$=Result$+"==> Face Front: "+CNTFront+"  Face Back: "+CNTBack+"  Edge: "+cntLine3D + " Tim-Vert: " + t2 
	;===> 
	Return Result$
	;===> 
End Function 
;=======================
;
Function SHWLine3D()
	;===>
	Color 0,255,0
	;===>
	For a=0 To cntLine3D-1
		Line3D( Line3DAX(a), Line3DAY(a), Line3DAZ(a), Line3DBX(a), Line3DBY(a), Line3DBZ(a))
	Next
	cntLine3D=0
	;===>
	Color 255,255,255
	;===>
End Function
;=======================
; Creazione immagine ombra
; Fast2 ?
Function ShadowVolumeStenciBuffer_orig(ShowVol)
	EntityColor SHWSpriteFront, 5, 5, 5
	EntityAlpha SHWSpriteFront, 0.3
	;===>
	;SetBuffer  TextureBuffer(ShwTex1)
	;Cls 
	SetBuffer BackBuffer()
	;======================================================================
	;PASS 1
	;===>
	;Render object modal standard
	;===>
	HideEntity SHWSpriteFront
	;colour buffer OFF
	SetRenderState(Direct3DDevice7, D3DRS_CULLMODE, D3DCULL_CCW)
	SetRenderState( Direct3DDevice7, D3DRS_ALPHABLENDENABLE, True );
	SetRenderState( Direct3DDevice7, D3DRS_SRCBLEND, D3DBLEND_ONE );
	SetRenderState( Direct3DDevice7, D3DRS_DESTBLEND, D3DBLEND_ONE );
	;lighting ON
	SetRenderState( Direct3DDevice7, D3DRS_AMBIENT, AMB_LIGHT );
	SetRenderState( Direct3DDevice7, D3DRS_LIGHTING, True );
	;depth buffer ON (Write+test)
	SetRenderState( Direct3DDevice7, D3DRS_ZENABLE, True );
	SetRenderState( Direct3DDevice7, D3DRS_ZWRITEENABLE, True );
	;stencil buffer OFF
	SetRenderState( Direct3DDevice7, D3DRS_STENCILENABLE, False );
	DeviceClear(Direct3DDevice7, 7, $00008080, 1, 0)
	CameraClsMode Camera, True, True
	;===>
	If ShowVol Then
		ShowEntity MeshFront
		EntityColor MeshFront, 255, 0,0
		EntityFX MeshFront,1;+16
	Else
		HideEntity MeshFront
	EndIf
	;===>
	ShowEntity scena
	;===>
	RenderWorld
	;===>
	EntityColor MeshFront,10,0,0
	EntityFX MeshFront,1
	;===>
	;======================================================================
	;PASS 2
	;===>
	CameraClsMode Camera, False, False
	HideEntity scena
	ShowEntity MeshFront
	SetRenderState(Direct3DDevice7, D3DRS_STENCILENABLE, True)
	SetRenderState(Direct3DDevice7, D3DRS_STENCILFUNC, D3DCMP_ALWAYS)
	SetRenderState(Direct3DDevice7, D3DRS_STENCILREF, 1)
	SetRenderState(Direct3DDevice7, D3DRS_SRCBLEND, D3DBLEND_ZERO)
	SetRenderState(Direct3DDevice7, D3DRS_DESTBLEND, D3DBLEND_ONE)
	;===>
	SetRenderState(Direct3DDevice7, D3DRS_CULLMODE, D3DCULL_CW)
	SetRenderState(Direct3DDevice7, D3DRS_STENCILPASS, D3DSTENCILOP_INCR)
	RenderWorld
	;===>
	SetRenderState(Direct3DDevice7, D3DRS_STENCILPASS, D3DSTENCILOP_DECR)
	SetRenderState(Direct3DDevice7, D3DRS_CULLMODE, D3DCULL_CCW)
	RenderWorld
	;===>
	HideEntity MeshFront
	SetRenderState(Direct3DDevice7, D3DRS_STENCILFUNC, D3DCMP_LESSEQUAL)
	SetRenderState(Direct3DDevice7, D3DRS_SRCBLEND, D3DBLEND_ONE )
	SetRenderState(Direct3DDevice7, D3DRS_DESTBLEND, D3DBLEND_ONE )
	SetRenderState(Direct3DDevice7, D3DRS_STENCILENABLE, True)
	SetRenderState(Direct3DDevice7, D3DRS_ALPHABLENDENABLE, True)
	ShowEntity SHWSpriteFront
	;===>
	RenderWorld
	;===>
	SetRenderState(Direct3DDevice7, D3DRS_STENCILENABLE, False)
	SetRenderState(Direct3DDevice7, D3DRS_ALPHABLENDENABLE, True)
	HideEntity SHWSpriteFront

End Function

Function ShadowVolumeStenciBuffer(ShowVol)
	EntityColor SHWSpriteFront, 5, 5, 5
	EntityAlpha SHWSpriteFront, 0.3
	;===>
	SetBuffer BackBuffer()
	;===>
	HideEntity SHWSpriteFront
	;======================================================================
	;PASS 1
	;===>
	;Render object modal standard
	;===>
	;colour buffer OFF
	SetRenderState(Direct3DDevice7, D3DRS_ZWRITEENABLE, True) 
	SetRenderState(Direct3DDevice7, D3DRS_STENCILENABLE, False)
	SetRenderState(Direct3DDevice7, D3DRS_ALPHABLENDENABLE, False)
	DeviceClear(Direct3DDevice7, 7,$00008080,1,0)
	CameraClsMode Camera, True, True
	;===>
	If ShowVol Then
		ShowEntity MeshFront
		EntityColor MeshFront, 255, 0,0
		EntityFX MeshFront,1;+16
	Else
		HideEntity MeshFront
	EndIf
	;===>
	ShowEntity scena
	;===>
	RenderWorld
	;===>
	HideEntity scena
	EntityColor MeshFront,10,0,0
	EntityFX MeshFront,1
	;===>
	;======================================================================
	;PASS 2
	;===>
	CameraClsMode Camera, False, False
	ShowEntity MeshFront
	;===>
	SetRenderState(Direct3DDevice7, D3DRS_ZWRITEENABLE,False)
	SetRenderState(Direct3DDevice7, D3DRS_STENCILENABLE,True)
	SetRenderState(Direct3DDevice7, D3DRS_STENCILFUNC, D3DCMP_ALWAYS)
	SetRenderState(Direct3DDevice7, D3DRS_STENCILFAIL, D3DSTENCILOP_KEEP)
	SetRenderState(Direct3DDevice7, D3DRS_STENCILPASS, D3DSTENCILOP_KEEP)
	SetRenderState(Direct3DDevice7, D3DRS_STENCILREF, 1)
	SetRenderState(Direct3DDevice7, D3DRS_STENCILMASK,$ffffffff)
	SetRenderState(Direct3DDevice7, D3DRS_STENCILWRITEMASK,$ffffffff)
	SetRenderState(Direct3DDevice7, D3DRS_STENCILZFAIL, D3DSTENCILOP_INCR)
	SetRenderState(Direct3DDevice7, D3DRS_ALPHABLENDENABLE, True)
	SetRenderState(Direct3DDevice7, D3DRS_SRCBLEND, D3DBLEND_ZERO)
	SetRenderState(Direct3DDevice7, D3DRS_DESTBLEND, D3DBLEND_ONE)
	;===>
	SetRenderState(Direct3DDevice7, D3DRS_CULLMODE, D3DCULL_CCW)
	RenderWorld
	;===>
	SetRenderState(Direct3DDevice7, D3DRS_CULLMODE, D3DCULL_CW)
	RenderWorld
	;===>
	SetRenderState(Direct3DDevice7, D3DRS_CULLMODE, D3DCULL_CCW)
	SetRenderState(Direct3DDevice7, D3DRS_STENCILZFAIL, D3DSTENCILOP_DECR)
	RenderWorld
	;===>
	SetRenderState(Direct3DDevice7, D3DRS_ZWRITEENABLE,     True )
	SetRenderState(Direct3DDevice7, D3DRS_STENCILENABLE,    False )
	SetRenderState(Direct3DDevice7, D3DRS_ALPHABLENDENABLE, False )			
	;===>
	;HideEntity MeshFront
	SetRenderState(Direct3DDevice7, D3DRS_ZENABLE,       False )
	SetRenderState(Direct3DDevice7, D3DRS_STENCILENABLE, True )
	SetRenderState(Direct3DDevice7, D3DRS_FOGENABLE, False)	

	SetRenderState(Direct3DDevice7, D3DRS_ALPHABLENDENABLE, True )
	SetRenderState(Direct3DDevice7, D3DRS_SRCBLEND, D3DBLEND_SRCALPHA )
	SetRenderState(Direct3DDevice7, D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA )

	SetRenderState(Direct3DDevice7, D3DRS_STENCILREF,  1 )
	SetRenderState(Direct3DDevice7, D3DRS_STENCILFUNC, D3DCMP_LESSEQUAL )
	SetRenderState(Direct3DDevice7, D3DRS_STENCILPASS, D3DSTENCILOP_KEEP )
	;===>
	ShowEntity SHWSpriteFront
	RenderWorld
	;===>
	SetRenderState(Direct3DDevice7, D3DRS_STENCILENABLE, False)
	SetRenderState(Direct3DDevice7, D3DRS_ALPHABLENDENABLE, True)
	HideEntity SHWSpriteFront
	RenderWorld

End Function


Please use forum tags for pasting code! :)

Look for code/codebox
http://www.blitzbasic.com/faq/faq_entry.php?id=2

ok thanks for link

you help me!!

progress??

yes in the old code posted i have insert multy light system :)

this is a progress!!

no speed up addizional :( stencil buffer in not very speed for 5 render execute

if you have a idea for speed software or new alghoritm this is your house :D


new update for code stencil:

;=======================
; Creazione immagine ombra
; Fast2 ?
Function ShadowVolumeStenciBuffer_orig(ShowVol)
	EntityColor SHWSpriteFront, 5, 5, 5
	EntityAlpha SHWSpriteFront, 0.3
	;===>
	;SetBuffer  TextureBuffer(ShwTex1)
	;Cls 
	SetBuffer BackBuffer()
	;======================================================================
	;PASS 1
	;===>
	;Render object modal standard
	;===>
	HideEntity SHWSpriteFront
	;colour buffer OFF
	SetRenderState(Direct3DDevice7, D3DRS_CULLMODE, D3DCULL_CCW)
	;SetRenderState( Direct3DDevice7, D3DRS_ALPHABLENDENABLE, True );
	;SetRenderState( Direct3DDevice7, D3DRS_SRCBLEND, D3DBLEND_ONE );
	;SetRenderState( Direct3DDevice7, D3DRS_DESTBLEND, D3DBLEND_ONE );
	;lighting ON
	SetRenderState( Direct3DDevice7, D3DRS_AMBIENT, AMB_LIGHT );


this is a last update :( i not have orther idea

link:

http://digilander.libero.it/enzo_light/shw13.zip


bye :(

i will check it out when i get back from school...
cya

you is a student?

i have 29 years

what old are you?

i am 14 years old, but a good coder...

i have seen your work, but the bug with the faces isn't resolved yet :(...

some of the edge faces are casting wrong...

so they should be flipped...

this bug is in the init object, if you change in the sphere 32 o over "The bug show" ;)

the check vertex have a bug ?!?!

what is a bug?

what are I?

what sale live?

pleace help me for resolved bug!

all for one!! one for all :D

I'd like to thank you guys again, I think you pushed stencil shadows to its limits for Blitz3D on an open source base.

Maybe the sooner or later somebody will add a fast volume creation.

Thanks!

Yeah, well done guys ... great work and alot of effort which is much appreciated. A damn shame it's not fast enough to use on a grander scale.

Hopefully if BRL can respond to Tom's renderworld() feature request and we'll all have super fast shadows soon!!

Stevie

i have search the bug for create object the time for resolved and is ok!!

sry, i do NOT understand your english...
please come to icq, download icq and post your icq numbere here!
´cya

ok the my number icq is 249548841

ok, thx :)