Shadow volume

Blitz3D Forums/Blitz3D Programming/Shadow volume

The forum is locked. These are the original blitzbasic.com forums, kept so they can still be read. No new topics, replies or edits can be made here. To join in, head over to the Blitz3D+ forums.

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